Skip to content

Add THIRD_PARTY_NOTICES.md and a generator for it - #77

Merged
abrarshivani merged 2 commits into
NVIDIA:mainfrom
abrarshivani:third-party-notices
Aug 15, 2026
Merged

Add THIRD_PARTY_NOTICES.md and a generator for it#77
abrarshivani merged 2 commits into
NVIDIA:mainfrom
abrarshivani:third-party-notices

Conversation

@abrarshivani

@abrarshivani abrarshivani commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Adds THIRD_PARTY_NOTICES.md for this module's third-party Go deps, the script
that generates it, and a CI check that fails when deps change without the notices
being refreshed.

The same change is already merged in gpu-operator, mig-parted, k8s-device-plugin,
k8s-driver-manager and nvidia-container-toolkit.

What to review

Half the diff is generated. Hand-written:

File Lines
hack/generate-third-party-notices.sh 403
Makefile 16
.github/workflows/golang.yml 16
versions.mk 2
.gitignore 1

Generated: THIRD_PARTY_NOTICES.md (569 lines).

hack/ is new. The pin lives in versions.mk, which is this repo's existing
version mechanism, since there is no tools.go or tools module here.

How it works

make third-party-notices runs hack/generate-third-party-notices.sh:

  1. Use ./bin/go-licenses so the pinned version runs
  2. Run go-licenses save and csv once per platform, then merge
  3. Join all licenses per package instead of picking one
  4. Add module@version from vendor/modules.txt
  5. Reproduce bundled non-Go files that go-licenses cannot see
  6. Write to a temp file, then move it into place

make check-third-party-notices regenerates and diffs. It runs as a job in
golang.yml on every build, with no changed-paths filter: the inventory is the
import closure of ./..., so it moves whenever an ordinary .go file changes
its imports, not only when go.mod or vendor/ change.

Implementation notes

  • Scope is ./..., not ./cmd/.... This is a library. Nothing releases a
    binary, so there is no shipped set to narrow to; the module itself is the
    distributed artifact.
  • examples/ is in scope. It has no go.mod of its own, so it lands on
    disk for anyone running go get, and make build already builds it via
    go build ./.... Its closure is identical to the library's today, so including
    it costs nothing and keeps the file correct if that changes.
  • CGO_ENABLED=1 is set explicitly. Measured: with cgo off,
    go-nvml/pkg/dl leaves the graph and go-licenses reports
    go-nvml/pkg/nvml instead of go-nvml/pkg. That is real host-dependence, not
    a theoretical one.
  • Only the local module goes to --ignore. It matches raw string prefixes,
    not path segments, so passing a stdlib list adds the bare token go and
    silently drops golang.org/x/*, google.golang.org/* and gopkg.in/*.
  • Output must match on every machine. LC_ALL=C on every sort and grep.
    Whole-line sort -u rather than sort -t, -k1,1 -u. The awk counts instead of
    using in, which mawk and BSD awk disagree on. grep -a so a NUL byte cannot
    change the fence width.
  • Moved with mv, not cp, so an interrupted run cannot leave a
    half-written file.

Scope

Three third-party modules are linked: go-nvlib, go-nvml and google/uuid.

One bundled file needs naming.
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/nvml.h is the NVML API header copied
from the CUDA redistributable. It carries NVIDIA's own "NOTICE TO USER" terms
rather than go-nvml's Apache-2.0, and go-licenses cannot inspect it. Without
handling, this file would have implied Apache-2.0 covers it. It now has its own
section. cgo_helpers.h is listed alongside it for completeness.

Rather than a static list that rots, the script fails two ways: a declared file
that disappears, and any undeclared non-Go file appearing under an in-scope
vendored module.

testify, go-spew, go-difflib and yaml.v3 are vendored for tests and are
correctly absent, with no filter needed.

This repo has no Dockerfile and publishes no image, so there is no base image or
bundled system component to account for.

Shipping

Committed to the repo. Nothing about the module's build or contents changes.

Testing

  • Determinism. Two runs on macOS byte-identical, sha256 e9b45c7c…,
    matching the committed file.
  • Cross-host. Same sha256 from golang:1.24.4-bookworm, the image
    versions.mk pins, on both linux/amd64 and linux/arm64. /usr/bin/awk is
    mawk there, so the license join is exercised on the awk that breaks the naive
    form, against BWK awk on macOS.
  • The awk paths this repo does not reach. Driven directly, on both mawk and
    BWK awk with identical output: a package carrying two licenses joins as
    BSD-3-Clause / MPL-2.0 with no leading separator and duplicates collapsed,
    a => replace resolves to the replacement's module@version, and a
    replace pointing at a local path exits 1.
  • Completeness against go list -deps ./... over both platforms: 4 linked
    third-party packages, 3 index rows, 0 uncovered, 0 unused.
  • Content. 3 index rows, 3 license sections, 4 license-text blocks, 2
    bundled-asset sections, 0 Unknown, 0 missing text, 0 unresolved
    module@version.
  • The check passes and fails. Passes on the committed file; fails with the
    right message when stale and when untracked.
  • Error paths. Missing vendor/modules.txt, unreadable vendor/modules.txt,
    absent go-licenses, a declared bundled asset that vanished, and an undeclared
    one that appeared. Each exits non-zero with a clear message, leaves the
    committed file untouched, and writes no partial file.
  • Lint. shellcheck clean. actionlint reports nothing on the new job that
    it does not already report identically on the three existing ones. make build
    and make test pass in the container.

Note make build does not run on macOS here, which predates this change:
go-nvml/pkg/nvml needs cgo and Linux. Verification was done in the container
for that reason.

@abrarshivani
abrarshivani marked this pull request as ready for review August 11, 2026 05:41
@abrarshivani
abrarshivani force-pushed the third-party-notices branch 4 times, most recently from 70e669f to 7eb2499 Compare August 14, 2026 18:47
Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
Comment thread THIRD_PARTY_NOTICES.md Outdated
The generator declared vendored non-Go files that carry their own license
terms and reproduced their headers, which meant restating nvml.h's NVIDIA
notice. Whether that belongs in a third-party notices file is unsettled,
so leave it out and cover only what go-licenses reports, matching the
generators in nvidia-container-toolkit, mig-parted and k8s-device-plugin.

Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
@tariq1890

Copy link
Copy Markdown
Contributor

Thank you @abrarshivani !

@abrarshivani
abrarshivani merged commit 876e7b7 into NVIDIA:main Aug 15, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants