Wiki - https://fedoraproject.org/wiki/Changes/GolangPackagesVendoredByDefault
Discussion thread -
https://discussion.fedoraproject.org/t/f43-change-proposal-golang-packages-vendored-by-default-system-wide/154986

This is a proposed Change for Fedora Linux.
This document represents a proposed Change. As part of the Changes
process, proposals are publicly announced in order to receive
community feedback. This proposal will only be implemented if approved
by the Fedora Engineering Steering Committee.


== Summary ==

Use vendored dependencies as the default and preferred option when
building Golang applications, instead of relying on pre-packaged
dependencies. This includes adopting
[https://fedora.gitlab.io/sigs/go/go-vendor-tools/ Go Vendor Tools], a
new set of tooling to handle license scanning, generating a cumulative
SPDX expression for all dependencies, and creating reproducible vendor
archives.

== Owner ==
* Name: [[User:Gotmax23| Maxwell G]], [[User:fale| Fale]], [[User:asm|
Alex Saez]] , [[User:mikelo2| Mikel Olasagasti]]

== Detailed Description ==

=== Plan ===

* Adopt Go Vendor Tools as the main method to package Golang applications.
** Update the [https://docs.fedoraproject.org/en-US/packaging-guidelines/Golang/
Golang packaging guidelines] to reflect this Change.
** Change `go2rpm` to make vendored the default option to create new specs.
** Finalize tasks in
https://gitlab.com/fedora/sigs/go/go-vendor-tools/-/milestones/5,
create a stable 1.0.0 release, and package {{package|go-vendor-tools}}
for EPEL
* Encourage current "binary" Golang packages to migrate to `go-vendor-tools`.
** This is per-package manual process maintainers need to work on and
not mandatory.
* Retire [https://gitlab.com/fedora/sigs/go/package-data/-/blob/main/leaves
leaf packages] as more packages become unused.

=== Current state ===

Golang packages can be packaged either by having all dependencies
available as packages (current default) or by using vendored
dependencies. Non-vendored builds require defining `GO111MODULE=off`
and having all dependencies available as RPM packages.

The current [https://docs.fedoraproject.org/en-US/packaging-guidelines/Golang/
Packaging Guidelines] state: At the moment golang projects packaged in
Fedora SHOULD be unbundled by default. It means projects are built
from dependencies packaged in Fedora. As part of this proposal, this
would be changed to favor vendoring.

Golang packages can be any of these types:

* Binary only package: provides only the compiled binary and no
sources/libraries. The package is usually named after the original
name of the source. For example: `doctl`, `gh` or `opentofu`. Some of
these packages have already moved to vendored dependencies (or used
them from the beginning), while many still use the dependencies
packaged in Fedora.
* Source only package: provides only the sources that will be imported
as dependencies when building other packages, including for just
tests. The naming of this packages is created by normalizing the
"goipath" with `golang-` prefix and the `-devel` suffix: for example:
`golang-github-spf13-cobrad-devel` or
`golang-github-prometheus-common-devel`.
* Binary and source packages: a package that provides a binary that is
useful for Fedora users, but also provides the "source only package"
that is needed to build other packages, for example:
`golang-github-cpuguy83-md2man` or `golang-github-prometheus`.

As of 2025-05-08, the Go SIG tracks
[https://gitlab.com/fedora/sigs/go/package-data/-/blob/main/all_packages
1898 packages]. Of these
[https://gitlab.com/fedora/sigs/go/package-data/-/blob/main/binaries
484 include a binary], meaning that approximately 1400 source-only
packages could potentially be eliminated.

As 
[https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/KA3KKE2ESYWXEOTP4C4B6K2ZFI4L2CRV/
posted] a few months ago, a simple package like `doctl` (a CLI app to
manage DigitalOcean resources) had 122 dependencies listed in the
`go.mod` file, but requires 752 packages to be installed to build it,
where 629 of them are golang-*-devel source-only packages. This is
because each package not using non-vendored builds has to have the
full dependency chain available in the buildroot, even if a project
only depends on a single import path from a larger Go module.

=== Current method's challenges ===

* Many packages, at various points in time, were out of date, failed
to build, or failed to install due to difficulties in maintaining such
a large number of dependencies in a language ecosystem
[https://gtmx.me/blog/fedora-go-unbundling-is-broken/#compatibility-and-maintainability
not suited to the non-vendored packaging model].
* Importing a new binary Golang package for Fedora or updating any of
the existing ones may require adding new source-only packages that are
not shared with any other package. Packages like `rclone` or `acme`
require many new packages as new clouds are supported on each release.
In the case of `rclone` the Fedora package disables some
backends/clouds ([https://bugzilla.redhat.com/show_bug.cgi?id=2254045
storj] & [https://bugzilla.redhat.com/show_bug.cgi?id=2336979 proton
drive] for example) due to the complexity of adding new packages.
* If upstream does not adhere to Semantic Versioning (or has no tagged
versions at all), two binary packages may require different versions
of the same source-only package, that have non versioned `goipath`.
Example: [https://github.com/prometheus/common/releases/tag/v0.48.0
prometheus-common 0.48.0 introducing a backward incompatible change].
* Fast moving package stacks, like the whole Kubernetes or OTEL,
require compat packages to avoid breakages in packages that import
them but are not updated that often.
* The entire Docker and Containerd stacks were moved to vendored
packages after multiple groups of maintainers could not contend with
its fast-moving, circular dependency tree.
* Some Cloud SDK packages like some Azure's or Google's modules are
packaged in bootstrap mode (no dependency check or tests) to avoid
extra dependencies.
* Sharing work with EPEL for packages with large dependency chains
make it nearly impossible.
* Many source-only packages are owned by single owners and this
[https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/DTER326F536GKL56PDGCSSZDSZPLFESW/
caused issues in the past] after non-responsive processes.
* A minor update in a package can break the whole dependency chain of
many packages. Examples: [https://pagure.io/releng/issue/11471
releng-11471], [https://pagure.io/releng/issue/11498 releng-11498],
[https://pagure.io/releng/issue/11565 releng-11565],
[https://pagure.io/releng/issue/11684 releng-11684] or
[https://pagure.io/releng/issue/11966 releng-11966]

=== Downsides of the proposal ===

* If a vulnerability exists on a dependency, with the new approach all
the affected packages would need to be updated and rebuilt. With
non-vendored builds, the fix would be applied to the dependency
package (usually a source-only package) and a simple rebuild of
affected packages is enough. With vendored builds, each package would
need to be updated or patched. `go-vendor-tools`
[https://fedora.gitlab.io/sigs/go/go-vendor-tools/scenarios/#security-updates
makes it easy to update vendored dependencies] and has been used to
address 
[https://src.fedoraproject.org/rpms/opentofu/c/6079da76a9fea8c2a74ecfcadedffb59bf01f884?branch=rawhide
CVE-2024-6257 CVE-2024-6104 CVE-2024-24789 in OpenTofu] for example.
* If a maintainer wants to import a non-vendored package, it will
require extra effort because many source-only dependency packages will
be retired once binary packages adopt vendoring.
* Packagers need to be more aware of the license terms for each
vendored dependency. Go Vendor Tools does have license scanning
functionality to mitigate this burden.

See also https://gtmx.me/blog/fedora-go-unbundling-is-broken/ from
last year that discusses the issues that prompted this Change in
greater depth.

== Feedback ==

This topic has been discussed many times during Go SIG meetings and in
the Matrix Channel. The initial
[https://pagure.io/GoSIG/go-sig/issue/43 ticket] that is the root of
the proposed change was opened more than 2.5 years ago.

As current recommendation is causing several issues, multiple
discussions happened in different places like:

* [https://pagure.io/fesco/issue/3330 FESCo ticket]
* 
[https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/DXEQZBARCOVV6O7BHIVFXAQ3LRKORVGG/
devel-list discussion]
* [https://lwn.net/Articles/1005655/ LWN news + discussion]

Additionally, the Go Vendor Tools beta has already been adopted by
[https://gitlab.com/fedora/sigs/go/package-data/-/blob/main/go-vendor-tools-users
30+ packages], and we have received positive feedback from
maintainers.

== Benefit to Fedora ==

* Simplify packaging Golang applications and potentially increase the
number of packaged applications.
* Reduce maintainer burnout by simplifying the packaging and updating process.
* Reduce the amount of packages in Fedora by removing source only
Golang packages.
** There are 
[https://gitlab.com/fedora/sigs/go/package-data/-/blob/main/all_packages
1898 packages] tracked by the Go SIG. Of those
[https://gitlab.com/fedora/sigs/go/package-data/-/blob/main/binaries
484 include a binary], so ~1400 packages could be potentially removed.
* Eliminate the version drift of dependencies between upstream
projects and what Fedora can provide.

== Scope ==
* Proposal owners:
** Change the [https://docs.fedoraproject.org/en-US/packaging-guidelines/Golang/
Golang packaging guidelines] to reflect the new default method for
packaging Golang applications.
** Migrate packages to use the new method.
** Retire leaf packages that are no longer required.

* Other developers:
** Adopt the new default method of packaging for their packages. While
existing packages that build successfully can continue using the
non-vendored method, it will not be the encouraged approach.

* Release engineering:
** Nothing will be required from Release engineering.

* Policies and guidelines:
** The [https://docs.fedoraproject.org/en-US/packaging-guidelines/Golang/
Golang packaging guidelines] will need to be updated.

* Trademark approval: N/A (not needed for this Change)


* Alignment with the Fedora Strategy:
** Better collaborative with EPEL.
** Potentially more active Go SIG.
** Ease latest version adoption.

== Upgrade/compatibility impact ==
Users consume Golang application packages that only include the
binaries, so this new way of packaging won't affect users or upgrades.

For packagers that manage Golang packages, if they adopt the new
method of vendoring they would reduce the churn of having to maintain
multiple packages for dependencies.

== Early Testing (Optional) ==

Several packages exist that are using `go-vendor-tools` to vendor the
dependencies like: `opentofu`, `gopass`, or `helm`.

Do you require 'QA Blueprint' support? No.

== How To Test ==

# Create the package with `go2rpm -p vendor --name $application_name
$goipath`. For example: `go2rpm -p vendor --name opentofu
github.com/opentofu/opentofu`.
# Manually adjust licenses if required as described in
[https://fedora.gitlab.io/sigs/go/go-vendor-tools/scenarios/#manually-detecting-licenses
Manually detecting licenses].
# Modify `go-vendor-tools.toml` if required as described in
[https://fedora.gitlab.io/sigs/go/go-vendor-tools/config/ Go Vendor
Tools Configuration].
# Build the package.

== User Experience ==

* Packages will be easier to update, so users will get up-to-date
software more quickly, and Fedora will be closer to upstream.
Maintainers will primarily focus on the consumable binary-only
package, reducing the need to manage all new dependencies or update
them while ensuring nothing breaks.
* Packages will use the same dependency versions as upstream,
providing all features present in upstream binary distributions.
* It will be easier to package Golang applications for Fedora.

== Dependencies ==

* `go-vendor-tools` package would be critical for the Go SIG.

== Contingency Plan ==
* Contingency mechanism: (What to do?  Who will do it?) Go-sig to keep
the lights on maintaining source-only packages requried for current
binaries.
* Contingency deadline: Before F43 branches.
* Blocks release? No

== Documentation ==
* [https://docs.fedoraproject.org/en-US/packaging-guidelines/Golang/
Golang Packaging Guidelines] needs to be updated to reflect the
changes
* [https://fedora.gitlab.io/sigs/go/go-vendor-tools/ Go Vendor Tools
documentation]

== Release Notes ==


-- 
Aoife Moloney

Fedora Operations Architect

Fedora Project

Matrix: @amoloney:fedora.im

IRC: amoloney

-- 
_______________________________________________
devel-announce mailing list -- devel-annou...@lists.fedoraproject.org
To unsubscribe send an email to devel-announce-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel-annou...@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue
-- 
_______________________________________________
devel mailing list -- devel@lists.fedoraproject.org
To unsubscribe send an email to devel-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue

Reply via email to