Add THIRD_PARTY_NOTICES.md and tooling to generate it - #2723
Open
abrarshivani wants to merge 1 commit into
Open
Conversation
abrarshivani
force-pushed
the
third-party-notices
branch
from
August 7, 2026 19:07
f102f7c to
7d621df
Compare
abrarshivani
marked this pull request as ready for review
August 7, 2026 22:01
abrarshivani
requested review from
cdesiniotis,
karthikvetrivel,
rahulait,
rajathagasthya,
shivamerla and
tariq1890
as code owners
August 7, 2026 22:01
rahulait
reviewed
Aug 10, 2026
rahulait
reviewed
Aug 10, 2026
Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
abrarshivani
force-pushed
the
third-party-notices
branch
from
August 11, 2026 00:37
2579435 to
813a7ca
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
THIRD_PARTY_NOTICES.mdandtools/generate-notices.sh, the script thatproduces it, so the Go deps behind the released artifacts have their licenses
listed in the repo.
make noticesregenerates itmake notices-checkregenerates and diffs it, and runs in CI on every buildWhat to review
98% of the diff is generated. Hand-written, 715 lines across 8 files:
tools/generate-notices.sh.github/workflows/release-third-party-notices.yaml.github/workflows/notices-check.yamlMakefiletools/go.mod.github/workflows/ci.yaml.gitignoretools/tools.gotools/generate-notices.shis the one to read: named functions behind amain(),about 120 lines of it comments.
tools/go.modpinsgo-licenses v2.0.1, and.gitignorecovers/.licenses-cache, the generator's scratch tree. Generated:THIRD_PARTY_NOTICES.md(27,778 lines) andtools/go.sum(97). The two indextables at the top of the notices file are the summary; the rest is verbatim
license text.
How it works
Needs Go (from
versions.mk) andgo-licenses, whichmake install-toolsputsin
./binfrom the pin intools/go.mod. The runtime pass readsvendor/andneeds no network; the toolchain pass uses the module cache.
./bin/go-licensesahead of$PATHso the pinned version runsPLATFORMSagainstDOCKER_BUILD_PLATFORM_OPTIONSinmulti-arch.mk,fail if out of sync
go-licenses saveandcsvonce per platform over./cmd/...withGOFLAGS=-mod=vendorandCGO_ENABLED=0, then merge. Platforms arelinux/amd64andlinux/arm64.tools/go.modover four platforms includingdarwin, reading the tool list from
tools/tools.goso it stays in step withmake install-toolsmodule@versionby longest-prefix match againstvendor/modules.txtfenced wide enough to survive licenses that are themselves Markdown
To add a dep: change
go.mod,go mod vendor,make notices, commit. CI failsthe PR if you forget.
Implementation notes
go-licensesresolves only the host'sgraph, and build-tagged sources pull different deps per platform.
--ignore. It matches raw string prefixes,not path segments, so a stdlib list from
go list std | cut -d/ -f1yieldsthe bare token
goand dropsgolang.org/x/*,google.golang.org/*,gopkg.in/*andgo.uber.org/*: 18 runtime and 14 toolchain modules.go-licensesalready excludes the stdlib.go-licensesemits one row per license,so collapsing on the package field loses the rest:
filepath-securejoinwouldshow as BSD-3-Clause without its MPL-2.0. Which one survived was unstable too,
since a keyed
sort -ucompares only that key and BSD and GNU sort break tiesdifferently.
sort -u, notsort -t, -k1,1 -u.LC_ALL=Con every sort and grep, or thefilename match misses
LICENSEunder a Turkish locale. The awk counts insteadof testing
in, which mawk and gawk evaluate differently, and mawk is/usr/bin/awkon Debian and Ubuntu.grep -aso a NUL byte cannot change thefence width.
module@versionfromvendor/modules.txt, sincego-licensesin vendor mode reports aHEADURL into this repo that stopsdescribing released content once
mainmoves. No resolved version fails therun.
mv, notcp.cptruncates the target first, so an interrupted runleaves a half-written file.
Scope
Covers
./cmd/..., not./....CMDSis a wildcard over./cmd/*and theDockerfile builds by running
make cmds, so this tracks the build rather than ahand-kept list. Against
./...the only extras areginkgoandgomegafromthe never-shipped e2e suite.
gpuop-cfgis scanned even though it is a buildhelper not copied into the image; listing slightly more than ships is the safe
direction.
Not covered: the non-Go contents of the image, meaning the base image packages,
the BusyBox tree, the CUDA sample and the CUDA compat libraries. Base image deps
go through that image's own compliance process, the rest through separate flows
including any source-distribution obligations. The generated file says so in its
header.
Shipping
Not copied into the runtime image, so image size is unchanged. It ships as a
GitHub Release asset:
release-third-party-notices.yamltriggers onrelease: published, checks out the tagged commit and uploads the committedfile, failing if it is missing or empty. Nothing is regenerated at release time,
since
notices-checkalready proves the file matches the tree. It followsrelease-image-list.yaml, and also takesworkflow_dispatchwith a tag forbackfilling an existing release.
notices-checkruns on every build, with no changed-paths filter. The runtimelist is the set of packages
./cmd/...imports, so it goes stale when a.gofile changes its imports, not only when
go.modorvendor/move. A filterwould pass green while the file rotted, and the failure would surface on
maininstead of on the PR that caused it.
Testing
Current output: 124 runtime packages, 74 build toolchain packages, 1.44 MB.
Index rows are per package; one module can own several.
golang:1.26.5(GNU coreutils,gawk). Two runs on each host also match.
go list -deps ./cmd/...for both released platforms,mapped to license-owning dirs: 124 expected, 124 present, 0 missing, 0 extra.
Unknownlicenses, 0 "Licensetext unavailable", 0 unresolved module versions.
filepath-securejoin(BSD-3-Clause / MPL-2.0),klauspost/compress,sigs.k8s.io/yaml,sigs.k8s.io/json.make notices-checkpasses on the committed file, fails when stale, and failswhen untracked.
git diffreports nothing for an untracked path, so that gatewould otherwise pass silently.
macOS reproduces byte-identically on the Linux runner.
platform matrix, a filesystem
replaceinvendor/modules.txt, and anunreadable module list. A versioned
replacecorrectly uses thereplacement.
shellcheckclean on the generator.actionlintandyamllintclean on bothworkflows.