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