chore: per-file SPDX/copyright headers + reproducible build (OpenSSF Gold)#335
Merged
Conversation
Prepend a two-line header // SPDX-License-Identifier: MIT // Copyright (c) 2025 Simple Container to every hand-written .go file (550 files), placed above any //go:build constraint. Satisfies the OpenSSF Gold criteria copyright_per_file and license_per_file (per-file copyright + SPDX license identifier). The two auto-generated mock files (pkg/**/mocks/) are skipped — they carry the generators "Code generated by" header and are overwritten on regen. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
Add -trimpath to the four release builds (sc, cloud-helpers, github-actions, github-actions-staging) so binaries carry no build-machine filesystem paths, and add docs/REPRODUCIBLE-BUILD.md documenting the reproducibility inputs (pinned Go toolchain, CGO_ENABLED=0, -trimpath, deterministic version ld-flag, committed embeddings) and a verify recipe. Satisfies the OpenSSF Gold criterion build_reproducible. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
Cre-eD
requested review from
Laboratory,
smecsia and
universe-ops
as code owners
June 20, 2026 19:45
Semgrep Scan ResultsRepository:
Scanned at 2026-06-21 09:40 UTC |
Security Scan ResultsRepository:
Scanned at 2026-06-21 09:41 UTC |
📊 Statement coverageMeasured on the documented included set (see
Baseline: |
getValPart converted a strconv.ParseInt(64-bit) result to int and used it as a slice index with only an upper-bound check, so a negative key (e.g. "-1") passed the check and panicked, and the narrowing int(i) conversion was a signed-overflow hazard on 32-bit. Compare in int64 (no narrowing) and reject negative indices. Adds a regression test. Resolves the CodeQL "Incorrect conversion between integer types" alert surfaced on this PR. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
Revert an incidental gofumpt reformat of the two generated mock files (pkg/**/mocks/) picked up by the repo-wide format pass. They carry the generators "Code generated by" header, get no SPDX/copyright header, and are regenerated by go generate, so this PR must not modify them. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
Code-review (codex) follow-up: -trimpath was only on the welder tasks, but releases are published by .github/workflows/push.yaml via raw `go build` without it, and the tarball used `tar -czf` (records mtime/owner + gzip timestamp) — so the published binaries embedded runner paths and the archive digest was non-deterministic, making the build_reproducible claim untrue for real releases. - push.yaml: add -trimpath to the `sc` and matrix (`cloud-helpers`, `github-actions`) release builds; make the sc tarball deterministic (`tar --sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner | gzip -n`). - welder.yaml: pin CGO_ENABLED=0 on build-cloud-helpers + build-github-actions (parity with build / build-github-actions-staging); same deterministic tar in the `build` task so `welder run build` reproduces the published archive. - docs/REPRODUCIBLE-BUILD.md: correct the verify recipe to use the bare CalVer embedded in build.Version (no v prefix), document the publish path + archive determinism, and compare against the published tarball/cosign digest. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
Per maintainer decision: the per-file copyright notice is year-less (// Copyright (c) Simple Container) so it is written once and never needs an annual bump across the tree. Enforcement is wired into the existing golangci-lint gate via the native `goheader` linter (no new workflow, action, or dependency): any .go file missing the SPDX + copyright header now fails CI. Generated mocks (pkg/**/mocks/) are excluded — they carry the mockery header and are regenerated. Verified: goheader flags a header-less file and passes the 551 headered files + excluded mocks. Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
This comment has been minimized.
This comment has been minimized.
…te and umask
Review-round hardening so the build_reproducible claim is bit-for-bit
true for the actual publish path, not just nominally:
- add -buildvcs=false to every release `go build` (push.yaml sc + matrix
targets; welder build / build-cloud-helpers / build-github-actions /
build-github-actions staging). Go embeds vcs.revision/time/modified by
default and -trimpath does NOT strip them, so a rebuild from a source
tarball without .git failed outright ("error obtaining VCS status"),
and a rebuild from a dirty tree diverged.
- pin the archived file mode with tar --mode='u=rwx,go=rx' so a stricter
builder umask (e.g. 077) no longer changes the stored permission bits
and the .tar.gz digest reproduces.
- docs/REPRODUCIBLE-BUILD.md: correct the archive recipe to gzip -9 -n,
document the -buildvcs=false requirement + forced mode, drop the
build-github-actions staging over-claim, and note the GNU-tar boundary.
Verified: two builds under umask 022 and 077 produce identical binary
(a97d983) and archive (10ad9f4) sha256 digests.
Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
smecsia
approved these changes
Jun 21, 2026
universe-ops
approved these changes
Jun 21, 2026
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.
Summary
Closes three OpenSSF Best Practices Gold MUST criteria for project 12886:
copyright_per_file+license_per_file— every hand-written.gosource file (550 files) now carries a per-file header:The header is placed above any
//go:buildconstraint (build tags preserved). The two auto-generated mock files underpkg/**/mocks/are intentionally skipped — they carry mockery'sCode generated byheader and are overwritten on regeneration.build_reproducible—-trimpathadded to the four release builds (sc,cloud-helpers,github-actions,github-actions-staging) so binaries embed no build-machine paths, plus a newdocs/REPRODUCIBLE-BUILD.mddocumenting the reproducibility inputs (pinned Go toolchain viago.mod,CGO_ENABLED=0,-trimpath, deterministic versionld-flag, committed embeddings — no LLM at build time) and a build-twice-and-compare verify recipe.Notes
gofumpt-clean;go build ./...green; the full unit suite compiles and passes (the pre-existingpkg/provisioner Test_Initflake and the stale//go:build e2esigning/e2e_test.goare unrelated and not run by default CI).Signed-off-by, noCo-Authored-By.Test plan
go build ./...greengo test -run='^$' ./...(compile gate) green — all test code compiles with headersgofumpt -lreports no unformatted files//go:build-tagged files keep valid constraints (header above the tag + blank line)