VOID v0.6 public baseline #1
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
| name: CVE Appendix (per-release snapshot) | |
| # Per-release, lockfile-complete CVE appendix (Task #255). | |
| # | |
| # `docs/security-audit-cve-appendix.md` is the public per-release snapshot | |
| # of every advisory `pnpm audit --json --audit-level=info` returns against | |
| # the lockfile. The committed file embeds the lockfile sha256 and the | |
| # commit hash that last touched the lockfile (deterministic, stable across | |
| # unrelated commits). | |
| # | |
| # Three jobs: | |
| # 1. `enforce-current` — on PRs that touch the lockfile / appendix / | |
| # parser, regenerate in `--check` mode and fail on drift. The PR | |
| # author runs `node scripts/regen-cve-appendix.mjs` locally and | |
| # commits the regenerated file. | |
| # 2. `regen-and-commit-on-main` — on `main` pushes that touch the | |
| # lockfile, regenerate the appendix and commit it directly to | |
| # `main` (only when the appendix actually changed). This means the | |
| # next release tag is taken from a commit whose tree already | |
| # contains a current appendix; no tag rewrite is needed. | |
| # 3. `attach-to-release` — on `v*` tag pushes, verify the committed | |
| # appendix is current for the tagged tree (`--check`) and upload a | |
| # tag-stamped copy as an immutable GitHub Release asset. Tags are | |
| # never force-pushed. | |
| # | |
| # Division of labor with Task #254: | |
| # - Task #254 workflow: build-fail on release branch, daily scheduled | |
| # scan that opens / dedupes / closes operator-private issues. | |
| # - This workflow: per-release static markdown snapshot, committed | |
| # to the tag's tree and attached to the GitHub Release as an asset. | |
| # Both reuse `scripts/lib/pnpm-audit-parser.mjs` — same JSON-shape | |
| # handling, same pnpm-version pin, same severity classifier. | |
| on: | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - "pnpm-lock.yaml" | |
| - "docs/security-audit-cve-appendix.md" | |
| - "scripts/regen-cve-appendix.mjs" | |
| - "scripts/lib/pnpm-audit-parser.mjs" | |
| - ".github/workflows/cve-appendix-release.yml" | |
| push: | |
| branches: [main] | |
| paths: | |
| - "pnpm-lock.yaml" | |
| - "scripts/regen-cve-appendix.mjs" | |
| - "scripts/lib/pnpm-audit-parser.mjs" | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| enforce-current: | |
| name: Enforce appendix is current for the lockfile (PRs) | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up pnpm | |
| # Keep this version in sync with PNPM_PINNED_MAJOR in | |
| # scripts/lib/pnpm-audit-parser.mjs. The parser will refuse to | |
| # run against a different pnpm major to prevent silent | |
| # JSON-shape drift between this snapshot path and the Task #254 | |
| # monitoring path that imports the same module. | |
| uses: pnpm/action-setup@v4 | |
| - name: Set up Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - name: Install dependencies (frozen lockfile) | |
| run: pnpm install --frozen-lockfile | |
| - name: Verify appendix is current | |
| run: node scripts/regen-cve-appendix.mjs --check | |
| - name: Gate on unmapped High/Critical advisories | |
| # Strict release gate: fail the PR if any High/Critical advisory has | |
| # no audit-ledger entry, so a fresh High/Critical cannot merge toward | |
| # a release tag until it is mapped into AUDIT_LEDGER / the audit doc. | |
| run: node scripts/regen-cve-appendix.mjs --strict | |
| regen-and-commit-on-main: | |
| name: Regenerate appendix and commit on main | |
| # Canonical-repo only: this job commits back to `main`. A fork inherits the | |
| # workflow but must not get bot commits pushed into it. `fork == false` is | |
| # true on the canonical repo and is populated for push events. | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' && github.event.repository.fork == false | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout main | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Set up Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - name: Install dependencies (frozen lockfile) | |
| run: pnpm install --frozen-lockfile | |
| - name: Regenerate appendix | |
| run: node scripts/regen-cve-appendix.mjs | |
| - name: Commit if changed | |
| run: | | |
| set -euo pipefail | |
| if git diff --quiet -- docs/security-audit-cve-appendix.md; then | |
| echo "Appendix already current; nothing to commit." | |
| exit 0 | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add docs/security-audit-cve-appendix.md | |
| git commit -m "Regenerate CVE appendix for $(git rev-parse --short HEAD)" | |
| git push origin HEAD:main | |
| attach-to-release: | |
| name: Attach CVE appendix to GitHub Release | |
| # Canonical-repo only: this job creates/uploads GitHub Releases. Forks | |
| # inherit the workflow but must not publish releases. `fork == false` is | |
| # true on the canonical repo and is populated for tag-push events. | |
| if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && github.event.repository.fork == false | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout tag | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Set up Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - name: Install dependencies (frozen lockfile) | |
| run: pnpm install --frozen-lockfile | |
| - name: Verify committed appendix matches the tagged lockfile | |
| # The committed file is deterministic from the lockfile sha256 | |
| # plus the lockfile-touching commit hash, so this check is | |
| # stable for the tagged tree. | |
| run: node scripts/regen-cve-appendix.mjs --check | |
| - name: Gate on unmapped High/Critical advisories | |
| # Strict release gate: block the tag from publishing if any | |
| # High/Critical advisory has no audit-ledger entry. This runs before | |
| # any Release is created/uploaded, so a non-zero exit here aborts the | |
| # job and the GitHub Release asset is never attached. | |
| run: node scripts/regen-cve-appendix.mjs --strict | |
| - name: Render Release-asset copy with explicit tag | |
| # The asset copy embeds the tag in the `Release` field. The | |
| # committed file is left untouched. | |
| run: | | |
| mkdir -p .release-artifacts | |
| node scripts/regen-cve-appendix.mjs \ | |
| --stdout --release="${GITHUB_REF_NAME}" \ | |
| > .release-artifacts/security-audit-cve-appendix.md | |
| - name: Upload appendix as Release asset | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| # Tag is the source of truth; we never rewrite it. We attach | |
| # the tag-stamped appendix as an immutable Release asset so | |
| # operators can download "the appendix as it stood at release | |
| # time" without having to clone the tag. | |
| # | |
| # If a Release for this tag does not yet exist (e.g. the | |
| # tag was pushed without a corresponding Release being | |
| # created elsewhere), create a draft so the upload has a | |
| # target. A maintainer can then publish the draft with the | |
| # appendix already attached. | |
| if ! gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then | |
| gh release create "${GITHUB_REF_NAME}" \ | |
| --draft \ | |
| --title "${GITHUB_REF_NAME}" \ | |
| --notes "Auto-created by cve-appendix-release workflow to attach the lockfile-complete CVE appendix. Edit and publish when ready." | |
| fi | |
| gh release upload "${GITHUB_REF_NAME}" \ | |
| .release-artifacts/security-audit-cve-appendix.md \ | |
| --clobber |