Skip to content

chore: per-file SPDX/copyright headers + reproducible build (OpenSSF Gold)#335

Merged
Cre-eD merged 7 commits into
mainfrom
chore/per-file-license-headers
Jun 21, 2026
Merged

chore: per-file SPDX/copyright headers + reproducible build (OpenSSF Gold)#335
Cre-eD merged 7 commits into
mainfrom
chore/per-file-license-headers

Conversation

@Cre-eD

@Cre-eD Cre-eD commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes three OpenSSF Best Practices Gold MUST criteria for project 12886:

  • copyright_per_file + license_per_file — every hand-written .go source file (550 files) now carries a per-file header:

    // SPDX-License-Identifier: MIT
    // Copyright (c) 2025 Simple Container

    The header is placed above any //go:build constraint (build tags preserved). The two auto-generated mock files under pkg/**/mocks/ are intentionally skipped — they carry mockery's Code generated by header and are overwritten on regeneration.

  • build_reproducible-trimpath added to the four release builds (sc, cloud-helpers, github-actions, github-actions-staging) so binaries embed no build-machine paths, plus a new docs/REPRODUCIBLE-BUILD.md documenting the reproducibility inputs (pinned Go toolchain via go.mod, CGO_ENABLED=0, -trimpath, deterministic version ld-flag, committed embeddings — no LLM at build time) and a build-twice-and-compare verify recipe.

Notes

  • Mechanical change: the header is comments only — no behaviour change, no API change, no new dependencies.
  • gofumpt-clean; go build ./... green; the full unit suite compiles and passes (the pre-existing pkg/provisioner Test_Init flake and the stale //go:build e2e signing/e2e_test.go are unrelated and not run by default CI).
  • Commits are SSH-signed + DCO Signed-off-by, no Co-Authored-By.

Test plan

  • go build ./... green
  • go test -run='^$' ./... (compile gate) green — all test code compiles with headers
  • gofumpt -l reports no unformatted files
  • //go:build-tagged files keep valid constraints (header above the tag + blank line)
  • CI green on this PR

Cre-eD added 2 commits June 20, 2026 23:29
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>
@github-actions

github-actions Bot commented Jun 20, 2026

Copy link
Copy Markdown

Semgrep Scan Results

Repository: api | Commit: 79754da

Check Status Details
⚠️ Semgrep Warning 1 warning(s), 1 total

Scanned at 2026-06-21 09:40 UTC

@github-actions

github-actions Bot commented Jun 20, 2026

Copy link
Copy Markdown

Security Scan Results

Repository: api | Commit: 79754da

Check Status Details
✅ Secret Scan Pass No secrets detected
✅ Dependencies (Trivy) Pass 0 total (no critical/high)
✅ Dependencies (Grype) Pass 0 total (no critical/high)
📦 SBOM Generated 522 components (CycloneDX)

Scanned at 2026-06-21 09:41 UTC

@github-actions

github-actions Bot commented Jun 20, 2026

Copy link
Copy Markdown

📊 Statement coverage

Measured on the documented included set (see docs/TESTING.md → Coverage scope). Observe-only — no regression gate is enforced yet.

Scope This PR main baseline Δ
Included set (Gold-tier denominator) 90.3% 90.3% +0.0 pp
Full set (whole repo, transparency) 27.6% 27.6% +0.0 pp

Baseline: main @ 570640c

Cre-eD added 4 commits June 21, 2026 00:09
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>
@Cre-eD Cre-eD closed this Jun 21, 2026
@Cre-eD Cre-eD reopened this Jun 21, 2026
@blacksmith-sh

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>
@Cre-eD
Cre-eD merged commit 6d0d0cb into main Jun 21, 2026
22 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.

3 participants