Skip to content

test: assert CI action pinning and token-permission contract (tests/ci-supply-chain.test.mjs) - #301

Open
kubestellar-hive[bot] wants to merge 1 commit into
mainfrom
quality/test-ci-supply-chain
Open

kubestellar-hive[bot] wants to merge 1 commit into
mainfrom
quality/test-ci-supply-chain

Conversation

@kubestellar-hive

Copy link
Copy Markdown
Contributor

Test Improvement

Adds one new test-only file, tests/ci-supply-chain.test.mjs (7 tests), covering the supply-chain and token-surface contract of the CI definitions under .github/.

Files claimed by this PR: tests/ci-supply-chain.test.mjs (new). Nothing else — no CI definition, no production module, no package.json, no lockfile, no new dependency (yaml is already a devDependency and is used to parse the YAML rather than regexing it). The diff is one added test file.

The gap

All six CI definitions are currently correct: seven uses: references SHA-pinned with # vX comments, permissions: declared everywhere, no pull_request_target, Node 22 throughout. No test reads them, so none of that is held in place. A step added as uses: actions/setup-node@v4, a new job with no permissions: block, or a drift to another Node major all pass npm run test:unit today.

What the 7 assertions cover

  1. Every file parses as YAML and declares at least one job.
  2. Every third-party uses: is pinned to a 40-character commit SHA — local ./ actions and docker:// refs excluded, with a comment saying why.
  3. Every pinned action carries a trailing # vX comment, so the SHA stays reviewable.
  4. Every file constrains GITHUB_TOKEN via permissions: at top or job level.
  5. Nothing grants permissions: write-all.
  6. Nothing uses the pull_request_target trigger.
  7. Every actions/setup-node step declares node-version; a ${{ env.X }} reference must resolve in the same file; all files must agree on one Node major.

The suite globs the directory, so #295 removing pdf.yml needs no test edit. The on: key is read through both on and true because YAML 1.1 parses it as a boolean.

Disjointness

Disjoint from #278 (tests/workflow-scripts.test.mjs), which asserts the package.json <-> scripts/ <-> npm run wiring contract; it makes no assertion about uses: pinning, permissions:, triggers, or node-version, and the two PRs share no file.

Verification

Local clone of cncf/endusers at 00b44df, node v26.8.2:

  • npm run test:unit: 62 pass, 0 fail (55 before; the 7 new tests are the only change).

  • npx prettier --check tests/ci-supply-chain.test.mjs: clean.

  • Mutation-checked — every assertion was made to fail and then reverted; the working tree is clean:

    mutation result
    actions/setup-node@<sha> -> @v4 assertions 2 and 3 fail
    drop the # v4.4.0 comment assertion 3 fails
    delete the permissions: block assertion 4 fails
    permissions: write-all assertion 5 fails
    pull_request: -> pull_request_target: assertion 6 fails
    node-version: 22 -> 20 assertion 7 fails ("found: 20, 22")
    ${{ env.NODE_VERSION }} with no env: block assertion 7 fails (unresolved env ref)
    rename the jobs: key assertion 1 fails

Related Issue

Closes #300


Filed by quality agent (hold-gated mode). Human review required.

— hive: agent=quality backend=copilot model=claude-opus-5

Adds tests/ci-supply-chain.test.mjs, which parses the CI definitions
under .github/ with the existing yaml devDependency and asserts the
properties that keep CI's token and action surface safe: third-party
actions pinned to 40-character commit SHAs with a reviewable version
comment, explicit least-privilege permissions, no pull_request_target
trigger, and one agreed Node major across every setup-node step.

Test-only: no CI definition, production module, package.json or
lockfile is touched. The suite globs the directory, so adding or
removing a CI definition needs no test change.

Closes #300

Signed-off-by: kubestellar-hive[bot] <kubestellar-hive@hive.kubestellar.io>
@kubestellar-hive

Copy link
Copy Markdown
Contributor Author

Important

Held for human review by the hive's ACMM level gate.

This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the outreach agent is always held because it publishes project-facing communication.

Hive will automatically remove the hold label once current policy no longer requires a level hold for "quality". If this is an outreach PR, a human must review it and remove the label.

@kubestellar-hive kubestellar-hive Bot added hold quality Approved by a Hive merger/owner for auto-merge on green CI testing Approved by a Hive merger/owner for auto-merge on green CI agent/quality Approved by a Hive merger/owner for auto-merge on green CI hive/hosted-available-lke648397-260827-5n31 Approved by a Hive merger/owner for auto-merge on green CI labels Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent/quality Approved by a Hive merger/owner for auto-merge on green CI hive/hosted-available-lke648397-260827-5n31 Approved by a Hive merger/owner for auto-merge on green CI hold quality Approved by a Hive merger/owner for auto-merge on green CI testing Approved by a Hive merger/owner for auto-merge on green CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[quality] No test guards the .github/workflows supply-chain contract (uses: SHA pinning, permissions:, node-version)

0 participants