diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cdcdd2b..844d4ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,18 +44,18 @@ jobs: timeout-minutes: 10 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 # full history for commitlint - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 with: go-version: '1.24' cache: true - name: golangci-lint - uses: golangci/golangci-lint-action@v8 + uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8 with: # Pin golangci-lint to a version built against Go >= 1.24. # When go.mod's `go` directive advances, bump this accordingly. @@ -69,7 +69,7 @@ jobs: args: --timeout=5m - name: commitlint - uses: wagoid/commitlint-github-action@v5 + uses: wagoid/commitlint-github-action@9763196e10f27aef304c9b8b660d31d97fce0f99 # v5 with: # NOTE: input name is camelCase `configFile`, not kebab-case. # The wrong name silently falls back to the action's defaults. @@ -88,10 +88,10 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 with: go-version-file: 'go.mod' cache: true @@ -106,7 +106,7 @@ jobs: - name: Upload coverage if: matrix.os == 'ubuntu-latest' - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4 with: file: coverage.out flags: unittests @@ -129,10 +129,10 @@ jobs: - { goos: windows, goarch: amd64 } steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 with: go-version-file: 'go.mod' cache: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a36ae4b..91f8b02 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,12 +53,12 @@ jobs: timeout-minutes: 30 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 with: # MUST match `go.mod`'s `go` directive (currently 1.24.0) # AND `.github/workflows/ci.yml`'s lint job — the test @@ -74,7 +74,7 @@ jobs: cache: true - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v6 + uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6 with: version: latest args: release --clean @@ -110,10 +110,10 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: # Node 24 ships npm 11.x, which is the minimum for OIDC # trusted publishing (npm >= 11.5.1, Node >= 22.14.0). @@ -132,4 +132,8 @@ jobs: - name: Publish nodeup-cli working-directory: ./nodeup-npm - run: npm publish --access public \ No newline at end of file + # --provenance attaches a SLSA-style attestation to the + # published package, generated from this OIDC token. + # npm's "Built and signed on GitHub Actions" badge depends + # on this flag — see docs/release-checklist.md and #67. + run: npm publish --provenance --access public \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index dbae87e..11df0a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -730,6 +730,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `make test` produces `coverage.out`; renamed to `coverage.out` so a contributor running the documented `make test` sees the same filename CI consumes. Closes #69. +- CI/CD supply-chain hardening from issue #67: + `.github/workflows/release.yml` now passes `--provenance` to + `npm publish` so the published `nodeup-cli` package carries a + SLSA-style attestation generated from the OIDC token (npm's + "Built and signed on GitHub Actions" badge, which the + release-checklist docs already called for — Option A). + All 14 `uses:` lines in `.github/workflows/ci.yml` and + `release.yml` are now pinned to commit SHAs with a + `# v` comment for readability, instead of mutable + major-version tags. Action SHAs were resolved at pin time + via `git/refs/tags/` for each release. This closes the + supply-chain class where a compromised or force-pushed + action tag would silently pull unreviewed code into + `release.yml` (which runs with `contents: write` and + handles publish secrets). Closes #67. ## [0.0.0] - 2024-07-01