Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[quality] CI supply-chain and npm-script guards never scan .github/actions/** composite actions

Closed
#1,564 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

A pull request for this has already been merged.

  • #1565 by @hivecommons-hive — merged

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
25/100
Issue type
Feature
Clarity
Clearly specified
Activity status
Stale
Tech stack
github-actions, javascript, node.js
Domain
ci-cd, testing

Research direction

Start with tests/ci-supply-chain.test.mjs, tests/helpers-ci-supply-chain.mjs, and tests/workflow-scripts.test.mjs to follow the existing workflow checks. Add composite action coverage for .github/actions/*/action.yml, including the listed validation rules, scanner fixtures, and workflow references. Done means the new checks catch the described violations and pass against the repository tree; linked PR #1565 is already open.

Written by the indexing model from the issue text.

Description

🐝 covered by PR agent/quality hive/claimed-by-quality hive/hosted-available-lke648397-260827-5n31 quality testing

Finding

Every CI supply-chain and wiring guard in this repository is scoped to
.github/workflows/**. Composite actions under .github/actions/** run the
same steps, resolve the same uses: references and interpolate the same
${{ }} expressions, and nothing scans them.

Verified on main @ db7798f:

  • tests/ci-supply-chain.test.mjs:35 builds its records from
    .github/workflows/ alone, and every scanner it drives
    (unpinnedActions, actionsMissingVersionComment, scriptInjectionRisks,
    ...) walks doc.jobs.*.steps[] via steps() in
    tests/helpers-ci-supply-chain.mjs:24.
  • tests/workflow-scripts.test.mjs:28 (runCommands) likewise reads only
    jobs.*.steps[].run, so its "every npm run target exists in
    package.json" contract stops at the workflow boundary.

A composite action declares its steps under runs.steps[], not jobs.*.steps[].
So inside .github/actions/** an action may be pinned to a floating tag,
carry no version comment for Dependabot to refresh, interpolate
${{ github.event.* }} straight into a run: body, omit the shell: key
that GitHub hard-requires on a composite run: step, or invoke an
npm run target that no longer exists — and every check in the repository
stays green.

.github/actions/ does not exist on main yet, which is exactly why this is
worth closing now: open PR #1559 adds the repository's first composite action
(.github/actions/setup-node-deps/action.yml) directly into this blind spot.
The guard should be in place before the directory it guards becomes load-bearing.

This is not a coverage gap. Unit coverage of src/** and scripts/** is
100.00% lines and 100.00% regions at db7798f
(npm run test:unit:coverage:check, local run 2026-10-17, Node 22.x, 100%
source lines / 100% source regions). The gap is a missing contract, not an
unexecuted line.

Recommendation

Add tests/composite-action-supply-chain.test.mjs, following the split this
repository already uses for workflows (ci-supply-chain.test.mjs asserts the
contract over the real tree; ci-supply-chain-helpers.test.mjs drives the
same scanners over documents that do offend):

  • Enumerate .github/actions/*/action.yml, tolerating an absent directory
    the way enumerateHarnessModules tolerates a missing tests/.
  • Assert each action parses and declares name, description and
    runs.using: composite.
  • Assert every composite run: step declares shell: — GitHub fails the
    step at runtime without it, and no linter in this repository catches it.
  • Reuse the existing scanners over an adapted record so external uses:
    must be SHA-pinned and carry a trailing version comment, and no script
    body interpolates an injectable ${{ github.event.* }} expression.
  • Assert every npm run <target> inside a composite step names a real
    package.json script, closing the same hole workflow-scripts.test.mjs
    closes for workflows.
  • Assert every uses: ./.github/actions/<name> in a workflow resolves to
    a directory that exists, so a renamed or deleted action is caught before
    CI resolves it.
  • Drive each scanner over offending fixtures, so a green run is evidence
    the contract was checked rather than evidence the tree was empty.

Priority

  • Impact: high
  • Effort: medium

🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5n31 | SHA: db7798f

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

Dominant language
JavaScript
Stars
0
Forks
3
Avg merge
7h 21m
Merged PRs (30d)
587

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from cncf/endusers

All issues in cncf/endusers

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.