Skip to content

feat(ci): harden the reusable workflows and stubs - #65

Merged
laurenhitchon merged 1 commit into
mainfrom
feat/reusable-workflow-hardening
Jul 29, 2026
Merged

feat(ci): harden the reusable workflows and stubs#65
laurenhitchon merged 1 commit into
mainfrom
feat/reusable-workflow-hardening

Conversation

@laurenhitchon

Copy link
Copy Markdown
Contributor

Batch A of the fleet remediation (single PR = single sync fan-out wave).

Reusables

  • Runtime supply chain: the two npm install @commitlint/* lines are pinned exact (21.2.1 / 21.2.0); npx vitest run and npx semantic-release gain --no-install so a missing local dependency fails loudly instead of executing latest from the registry (all 24 consumers carry semantic-release; the only vitest config in the fleet has its dep).
  • timeout-minutes on every job (10 lint-class / 15 install / 20 test / 30 release) — a hung release previously held the serialized release queue for up to 6h.
  • New format job in reusable-ci: npx --no-install prettier --check . when the repo has a Prettier config (file or package.json prettier key — probe step, same pattern as the npm-test probe). CI_SKIP_FORMAT=true opt-out. Advisory context (install / format) until repos add it to rulesets.
  • alert-on-failure job in reusable-release (ported from nswds-ui's bespoke release.yml): every release failure files/bumps a labelled issue instead of failing silently post-merge.

Stubs (fan out via sync)

  • secrets: inherit replaced with explicit mappings: OPENAI_API_KEY (ai-pr-title, openai-pr-description), RELEASE_DEPLOY_KEY (release); removed entirely from ci/commitlint/validate-branch-name/commit-types-sync, which consume no secrets. Verified safe against live @v1 — the reusables already declare these as optional workflow_call secrets. This is what turns a hypothetical v1-tag compromise from CI-tampering into not org-wide secret exfiltration.
  • Dogfood callers updated to match.

Notes

  • Reusable changes are inert for consumers until the next v1 promotion; stub changes are live on merge of each repo's sync PR.
  • This merge is the sync App's first production run on create-github-app-token@v3 — watching it.
  • actionlint -ignore SC2016 clean on workflows and the stub scratch tree.

- pin the runtime commitlint installs to exact versions
- npx --no-install for vitest and semantic-release (fail loudly, never fetch latest)
- timeout-minutes on every central job
- explicit stub secret mappings replacing secrets: inherit (4 stubs pass none)
- format gate job in reusable-ci (prettier --check, CI_SKIP_FORMAT opt-out)
- alert-on-failure issue-filing job in reusable-release (ported from nswds-ui)
Copilot AI review requested due to automatic review settings July 29, 2026 09:02
@DFSIdigital

DFSIdigital commented Jul 29, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@laurenhitchon
laurenhitchon merged commit a160be4 into main Jul 29, 2026
11 checks passed
@laurenhitchon
laurenhitchon deleted the feat/reusable-workflow-hardening branch July 29, 2026 09:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the GitHub Actions reusable workflows and their stub callers to reduce secret exposure risk, improve supply-chain safety, and prevent hung CI/release jobs from blocking the fleet.

Changes:

  • Replaced secrets: inherit in stubs/callers with least-privilege explicit secret mappings (or removed secrets entirely where unused).
  • Added timeout-minutes across jobs and tightened npx usage with --no-install; pinned commitlint install versions.
  • Added a reusable CI format gate (Prettier) and a reusable release alert-on-failure job that files/bumps a release-failure issue.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
workflow-stubs/validate-branch-name.yml Removes secrets: inherit from the validate-branch-name stub.
workflow-stubs/release.yml Maps only RELEASE_DEPLOY_KEY explicitly for release stub.
workflow-stubs/openai-pr-description.yml Maps only OPENAI_API_KEY explicitly for OpenAI PR description stub.
workflow-stubs/commitlint.yml Removes secrets: inherit from commitlint stub.
workflow-stubs/commit-types-sync.yml Removes secrets: inherit from commit-types-sync stub.
workflow-stubs/ci.yml Removes secrets: inherit from CI stub.
workflow-stubs/ai-pr-title.yml Maps only OPENAI_API_KEY explicitly for AI PR title stub.
.github/workflows/validate-branch-name.yml Removes secrets: inherit from local reusable caller.
.github/workflows/sync.yml Adds job timeout for the sync workflow.
.github/workflows/reusable-validate-branch-name.yml Adds a timeout to reusable validate-branch-name.
.github/workflows/reusable-release.yml Adds timeouts, --no-install semantic-release, and a release-failure alert job.
.github/workflows/reusable-openai-pr-description.yml Updates secret description and adds a timeout.
.github/workflows/reusable-commitlint.yml Adds a timeout to reusable commitlint.
.github/workflows/reusable-commit-types-sync.yml Adds a timeout and pins commitlint install versions.
.github/workflows/reusable-ci.yml Adds job timeouts, introduces format job, and uses --no-install for vitest.
.github/workflows/reusable-ai-pr-title.yml Updates secret description, adds a timeout, and pins commitlint install versions.
.github/workflows/release.yml Replaces secrets: inherit with explicit RELEASE_DEPLOY_KEY mapping.
.github/workflows/openai-pr-description.yml Replaces secrets: inherit with explicit OPENAI_API_KEY mapping.
.github/workflows/confluence-sync.yml Adds a job timeout for confluence sync.
.github/workflows/commitlint.yml Removes secrets: inherit from local commitlint caller.
.github/workflows/commit-types-sync.yml Removes secrets: inherit from local commit-types-sync caller.
.github/workflows/ci.yml Adds timeouts to internal linting jobs.
.github/workflows/ccc-v10-canary.yml Adds a timeout to the canary probe job.
.github/workflows/ai-pr-title.yml Replaces secrets: inherit with explicit OPENAI_API_KEY mapping.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +95 to +97
name: File release-failure issue
needs: release
if: failure()
Comment on lines +136 to +140
if ls .prettierrc .prettierrc.* prettier.config.* >/dev/null 2>&1; then
present=true
elif [ -f package.json ] && node -e "process.exit(require('./package.json').prettier ? 0 : 1)"; then
present=true
fi
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