[H1][GITHUB-ACTIONS]
Dictum: Workflow generation and validation enforce security, performance, and supply chain integrity.
Generate and validate production-ready GitHub Actions workflows and custom actions.
Tasks:
- Gather requirements — triggers, runners, dependencies, environments, security posture.
- Read best-practices.md — security hardening, supply chain, performance, anti-patterns.
- Read version-discovery.md — SHA resolution protocol, action index, permissions.
- Read expressions-and-contexts.md — contexts, functions, injection prevention.
- (advanced triggers) Read advanced-triggers.md — workflow_run, dispatch, ChatOps, merge queue.
- (custom actions) Read custom-actions.md — composite, Docker, JavaScript action authoring.
- Resolve action versions —
git ls-remote, Context7 MCP, or WebSearch for latest SHA.
- Generate — SHA-pinned actions, minimal permissions, concurrency, caching, timeouts, harden-runner.
- Validate — Read validation references, run actionlint, apply 11 best practice checks.
- Fix and re-validate until passing (max 3 iterations).
Scope:
- Workflow files (
.github/workflows/*.yml).
- Custom actions — composite, Docker, JavaScript (
.github/actions/*/action.yml).
- Reusable workflows (
workflow_call).
- Supply chain — SLSA attestation, SBOM, Cosign signing.
- Monorepo CI — Nx affected detection, sparse checkout, pnpm workspace caching.
References:
| Domain |
File |
| Best Practices |
best-practices.md |
| Version Discovery |
version-discovery.md |
| Expressions |
expressions-and-contexts.md |
| Advanced Triggers |
advanced-triggers.md |
| Custom Actions |
custom-actions.md |
| Common Errors |
common_errors.md |
| Supply Chain |
supply_chain.md |
| Modern Features |
modern_features.md |
| Runners |
runners.md |
| Actionlint + Act |
act_usage.md |
| Template |
basic-workflow.template.yml |
| Template |
reusable-workflow.template.yml |
| Template |
composite-action.template.yml |
| Template |
docker-action.template.yml |
| Template |
javascript-action.template.yml |
| Example |
nodejs-ci.yml |
| Example |
docker-build-push.yml |
| Example |
monorepo-ci.yml |
| Example |
dependency-review.yml |
| Example |
sbom-attestation.yml |
| Example |
setup-node-cached-action.yml |
| Example |
chatops-dispatch.yml |
| Example |
oidc-cloud-auth-action.yml |
| Example |
release-deploy.yml |
| Example |
docker-lint-scan-action.yml |
| Example |
pr-change-router-action.yml |
[1][STANDARDS]
Dictum: Mandatory standards enforce baseline quality across all generated workflows.
Every generated workflow enforces defense-in-depth: supply chain integrity prevents compromised actions from executing, minimal permissions limit blast radius if a job is compromised, and harden-runner detects anomalous behavior at runtime. These layers are independent — failure of one leaves others intact.
[CRITICAL]:
- [ALWAYS] SHA-pin every
uses: reference — mutable tags (@v1, @main) enable supply chain attacks. The tj-actions incident (CVE-2025-30066) compromised 23,000+ repos via tag retargeting.
- [ALWAYS]
step-security/harden-runner as first step in every job — detected the tj-actions breach before any other tool.
- [ALWAYS] Top-level
permissions: {} (deny-all default); grant minimal per-job permissions.
- [ALWAYS]
timeout-minutes: on every job — prevents runaway billing on stuck workflows.
[IMPORTANT]:
- [ALWAYS] OIDC federation (
id-token: write) for cloud auth — eliminates static credentials entirely.
- [ALWAYS]
actions/create-github-app-token for cross-repo ops — scoped, 1-hour expiry, survives offboarding.
- [ALWAYS]
>> $GITHUB_OUTPUT for step outputs; >> $GITHUB_STEP_SUMMARY for job summaries.
- [NEVER] Direct
${{ }} interpolation of untrusted input in run: blocks — route through env: indirection.
[REFERENCE] best-practices.md — Security checklist, supply chain controls, anti-patterns.
[2][TEMPLATES]
Dictum: Templates scaffold canonical workflow and action structure.
Templates use [PLACEHOLDER] syntax for generation-time substitution. SHA resolution happens at generation time via the discovery protocol — templates contain placeholder SHAs, not static pins.
[2.1][PLACEHOLDER_CONVENTION]
All templates use a unified [UPPER_SNAKE_CASE] placeholder convention:
| [CATEGORY] |
[PLACEHOLDERS] |
| Identity |
[ACTION_NAME], [WORKFLOW_NAME], [DESCRIPTION], [AUTHOR_NAME] |
| Runtime |
[RUNTIME_VERSION], [RUNTIME_ENV_KEY], [ENABLE_CMD] |
| Package Mgr |
[PACKAGE_MANAGER], [INSTALL_CMD] |
| Build/Test |
[BUILD_CMD], [LINT_CMD], [TEST_CMD], [BUILD_PATH], [RESULTS_PATH] |
| Deploy |
[ENV_NAME], [ENV_URL], [DEPLOY_CMD], [VERIFY_CMD] |
| Secrets |
[SECRET_KEY], [SECRET_NAME], [REGISTRY_TOKEN] |
| Docker |
[BASE_IMAGE], [BUILDER_IMAGE], [ENTRYPOINT] |
[2.2][HARDEN_RUNNER_SCOPE]
harden-runner is included as the first step in every workflow job template (basic, reusable). Action templates (composite, Docker, JavaScript) do NOT include harden-runner — the calling workflow is responsible for adding it as the first step in the job that invokes the action. Actions are steps, not jobs.
[2.3][TEMPLATE_INDEX]
| [INDEX] |
[TEMPLATE] |
[PATH] |
[SCAFFOLDS] |
| [1] |
Basic Workflow |
templates/basic-workflow.template.yml |
CI pipeline: lint, test, build, deploy with parameterized runtime. |
| [2] |
Reusable Workflow |
templates/reusable-workflow.template.yml |
workflow_call with typed inputs, secrets, version extraction. |
| [3] |
Composite Action |
templates/composite-action.template.yml |
Multi-step action with parameterized runtime and error handling. |
| [4] |
Docker Action |
templates/docker-action.template.yml |
Container action with distroless multi-stage Dockerfile pattern. |
| [5] |
JavaScript Action |
templates/javascript-action.template.yml |
Node 24 action with pre/post lifecycle, typed error handling. |
[REFERENCE] custom-actions.md — Action type selection, metadata, runtime deprecation.
[3][EXAMPLES]
Dictum: Examples demonstrate production patterns for common scenarios.
Each example demonstrates distinct patterns with minimal overlap. Load relevant examples before generation to match the target scenario.
| [INDEX] |
[EXAMPLE] |
[PATH] |
[DEMONSTRATES] |
| [1] |
Node.js CI |
examples/nodejs-ci.yml |
Matrix testing, caching, artifact upload, coverage, summaries. |
| [2] |
Docker Build + Push |
examples/docker-build-push.yml |
Multi-platform builds, GHCR, BuildKit caching, SLSA provenance. |
| [3] |
Monorepo CI |
examples/monorepo-ci.yml |
Nx affected detection, pnpm workspace, sparse checkout. |
| [4] |
PR Security Gate |
examples/dependency-review.yml |
Multi-job security: dep review, CodeQL, Gitleaks, triage. |
| [5] |
Container Supply Chain |
examples/sbom-attestation.yml |
SBOM, Trivy severity gating, Cosign, gh attestation verify. |
| [6] |
Composite Action (setup-node-cached) |
examples/setup-node-cached-action.yml |
Smart caching, corepack detection, cache-dir resolution. |
| [7] |
ChatOps Dispatch |
examples/chatops-dispatch.yml |
Slash commands, injection prevention, App token, env indirection. |
| [8] |
Multi-Cloud OIDC Auth |
examples/oidc-cloud-auth-action.yml |
Composite action: AWS/GCP/Azure OIDC, output normalization. |
| [9] |
Release + Deploy |
examples/release-deploy.yml |
Environment promotion, reusable workflow, concurrency groups. |
| [10] |
Docker Lint + Scan |
examples/docker-lint-scan-action.yml |
Composite action: Trivy scan, hadolint, SARIF output. |
| [11] |
PR Change Router |
examples/pr-change-router-action.yml |
Composite action: paths-filter, dynamic matrix, label sync. |
[4][ACTION_DISCOVERY]
Dictum: Runtime version resolution prevents stale SHA pins and supply chain drift.
Static SHA catalogs decay — actions release frequently and stale pins miss security patches. Resolve versions at generation time. Never embed hardcoded SHAs in reference docs or templates.
Resolution protocol:
git ls-remote --tags https://github.com/{owner}/{repo} — verify tag exists.
gh api repos/{owner}/{repo}/git/ref/tags/{tag} --jq '.object.sha' — resolve tag to full SHA.
- Format:
owner/repo@<40-char-SHA> # vX.Y.Z.
Fallback methods:
- Context7 MCP:
resolve-library-id then get-library-docs for action documentation.
- WebSearch:
"[owner/repo] [version] github action" for release notes.
[IMPORTANT]:
- [ALWAYS] Verify the tag exists before pinning — deleted tags return empty results.
- [ALWAYS] Include version comment suffix (
# vX.Y.Z) — Dependabot/Renovate parse these for automated updates.
- [NEVER] Embed static SHAs in reference files — they decay within weeks.
[REFERENCE] version-discovery.md — Discovery protocol, SHA pinning format, common actions index, automated maintenance.
[5][VALIDATION]
Dictum: Three-stage pipeline and 11 best practice checks gate workflow quality.
Validation pipeline:
| [INDEX] |
[STAGE] |
[TOOL] |
[VALIDATES] |
| [1] |
Static Analysis |
actionlint 1.7.10 |
YAML syntax, expressions, runner labels, action inputs, CRON, globs. |
| [2] |
Best Practices |
11 custom checks |
SHA pinning, permissions, injection, timeouts, harden-runner. |
| [3] |
Local Execution |
act v0.2.84 |
Dry-run validation against Docker images (requires Docker). |
Best practice checks (11):
| [INDEX] |
[CHECK] |
[TAG] |
[DETECTS] |
| [1] |
Deprecated commands |
[DEPRECATED-CMD] |
::set-output, ::save-state, ::set-env, ::add-path. |
| [2] |
Missing permissions |
[PERMISSIONS] |
No top-level permissions: {} deny-all default. |
| [3] |
Unpinned actions |
[UNPINNED] |
Mutable tags (@v1, @main), abbreviated SHAs. |
| [4] |
SHA without comment |
[SHA-NO-COMMENT] |
SHA-pinned but missing # vX.Y.Z version comment. |
| [5] |
Missing timeout |
[TIMEOUT] |
Jobs without timeout-minutes: (default is 6 hours). |
| [6] |
Deprecated runners |
[RUNNER] |
ubuntu-20.04, macos-12, macos-13, windows-2019. |
| [7] |
Missing concurrency |
[CONCURRENCY] |
No concurrency: group or missing cancel-in-progress. |
| [8] |
PAT usage |
[APP-TOKEN] |
PATs for cross-repo ops (use create-github-app-token). |
| [9] |
No harden-runner |
[HARDEN] |
Missing or not first step in job (CVE-2025-30066 detection). |
| [10] |
Expression injection |
[INJECTION] |
Direct ${{ github.event.* }} in run: blocks. |
| [11] |
Immutable actions |
[IMMUTABLE] |
Action publishing without immutable OCI (informational). |
Error routing: Match error patterns to reference files — common_errors.md (syntax, expressions, deprecated), runners.md (labels, deprecations), supply_chain.md (SHA, OIDC, SBOM, harden-runner), modern_features.md (reusable workflows, concurrency, matrix, node runtime), act_usage.md (actionlint rules, act limitations).
Troubleshooting:
| [INDEX] |
[ISSUE] |
[SOLUTION] |
| [1] |
Tools not found |
Install actionlint + act (see act_usage.md). |
| [2] |
Docker not running |
Start Docker or validate with actionlint only. |
| [3] |
act fails, GitHub works |
See act_usage.md — Limitations. |
| [4] |
ARM Mac arch mismatch |
Add --container-architecture linux/amd64. |
| [5] |
Custom runner labels |
Declare in .github/actionlint.yaml. |
[VERIFY] Completion:
[REFERENCE] best-practices.md — Anti-patterns with specific remediations.
1---2name: github-actions3description: Generates and validates GitHub Actions workflows and custom actions (composite/Docker/JavaScript) with SHA-pinned supply chain security, SLSA attestation, OIDC federation, and harden-runner enforcement. Use when creating, editing, reviewing, or validating CI/CD pipelines, reusable workflows, monorepo CI patterns, container build/deploy orchestration, or advanced triggers (workflow_run, dispatch, ChatOps).4---56# [H1][GITHUB-ACTIONS]7>**Dictum:** *Workflow generation and validation enforce security, performance, and supply chain integrity.*89<br>1011Generate and validate production-ready GitHub Actions workflows and custom actions.1213**Tasks:**141. Gather requirements — triggers, runners, dependencies, environments, security posture.152. Read [best-practices.md](./references/best-practices.md) — security hardening, supply chain, performance, anti-patterns.163. Read [version-discovery.md](./references/version-discovery.md) — SHA resolution protocol, action index, permissions.174. Read [expressions-and-contexts.md](./references/expressions-and-contexts.md) — contexts, functions, injection prevention.185. (advanced triggers) Read [advanced-triggers.md](./references/advanced-triggers.md) — workflow_run, dispatch, ChatOps, merge queue.196. (custom actions) Read [custom-actions.md](./references/custom-actions.md) — composite, Docker, JavaScript action authoring.207. Resolve action versions — `git ls-remote`, Context7 MCP, or WebSearch for latest SHA.218. Generate — SHA-pinned actions, minimal permissions, concurrency, caching, timeouts, harden-runner.229. Validate — Read validation references, run actionlint, apply 11 best practice checks.2310. Fix and re-validate until passing (max 3 iterations).2425**Scope:**26- Workflow files (`.github/workflows/*.yml`).27- Custom actions — composite, Docker, JavaScript (`.github/actions/*/action.yml`).28- Reusable workflows (`workflow_call`).29- Supply chain — SLSA attestation, SBOM, Cosign signing.30- Monorepo CI — Nx affected detection, sparse checkout, pnpm workspace caching.3132**References:**3334| Domain | File |35| ----------------- | -------------------------------------------------------------------------- |36| Best Practices | [best-practices.md](references/best-practices.md) |37| Version Discovery | [version-discovery.md](references/version-discovery.md) |38| Expressions | [expressions-and-contexts.md](references/expressions-and-contexts.md) |39| Advanced Triggers | [advanced-triggers.md](references/advanced-triggers.md) |40| Custom Actions | [custom-actions.md](references/custom-actions.md) |41| Common Errors | [common_errors.md](references/common_errors.md) |42| Supply Chain | [supply_chain.md](references/supply_chain.md) |43| Modern Features | [modern_features.md](references/modern_features.md) |44| Runners | [runners.md](references/runners.md) |45| Actionlint + Act | [act_usage.md](references/act_usage.md) |46| Template | [basic-workflow.template.yml](templates/basic-workflow.template.yml) |47| Template | [reusable-workflow.template.yml](templates/reusable-workflow.template.yml) |48| Template | [composite-action.template.yml](templates/composite-action.template.yml) |49| Template | [docker-action.template.yml](templates/docker-action.template.yml) |50| Template | [javascript-action.template.yml](templates/javascript-action.template.yml) |51| Example | [nodejs-ci.yml](examples/nodejs-ci.yml) |52| Example | [docker-build-push.yml](examples/docker-build-push.yml) |53| Example | [monorepo-ci.yml](examples/monorepo-ci.yml) |54| Example | [dependency-review.yml](examples/dependency-review.yml) |55| Example | [sbom-attestation.yml](examples/sbom-attestation.yml) |56| Example | [setup-node-cached-action.yml](examples/setup-node-cached-action.yml) |57| Example | [chatops-dispatch.yml](examples/chatops-dispatch.yml) |58| Example | [oidc-cloud-auth-action.yml](examples/oidc-cloud-auth-action.yml) |59| Example | [release-deploy.yml](examples/release-deploy.yml) |60| Example | [docker-lint-scan-action.yml](examples/docker-lint-scan-action.yml) |61| Example | [pr-change-router-action.yml](examples/pr-change-router-action.yml) |6263---64## [1][STANDARDS]65>**Dictum:** *Mandatory standards enforce baseline quality across all generated workflows.*6667<br>6869Every generated workflow enforces defense-in-depth: supply chain integrity prevents compromised actions from executing, minimal permissions limit blast radius if a job is compromised, and harden-runner detects anomalous behavior at runtime. These layers are independent — failure of one leaves others intact.7071[CRITICAL]:72- [ALWAYS] SHA-pin every `uses:` reference — mutable tags (`@v1`, `@main`) enable supply chain attacks. The tj-actions incident (CVE-2025-30066) compromised 23,000+ repos via tag retargeting.73- [ALWAYS] `step-security/harden-runner` as first step in every job — detected the tj-actions breach before any other tool.74- [ALWAYS] Top-level `permissions: {}` (deny-all default); grant minimal per-job permissions.75- [ALWAYS] `timeout-minutes:` on every job — prevents runaway billing on stuck workflows.7677[IMPORTANT]:78- [ALWAYS] OIDC federation (`id-token: write`) for cloud auth — eliminates static credentials entirely.79- [ALWAYS] `actions/create-github-app-token` for cross-repo ops — scoped, 1-hour expiry, survives offboarding.80- [ALWAYS] `>> $GITHUB_OUTPUT` for step outputs; `>> $GITHUB_STEP_SUMMARY` for job summaries.81- [NEVER] Direct `${{ }}` interpolation of untrusted input in `run:` blocks — route through `env:` indirection.8283[REFERENCE] [best-practices.md](./references/best-practices.md) — Security checklist, supply chain controls, anti-patterns.8485---86## [2][TEMPLATES]87>**Dictum:** *Templates scaffold canonical workflow and action structure.*8889<br>9091Templates use `[PLACEHOLDER]` syntax for generation-time substitution. SHA resolution happens at generation time via the discovery protocol — templates contain placeholder SHAs, not static pins.9293### [2.1][PLACEHOLDER_CONVENTION]9495All templates use a unified `[UPPER_SNAKE_CASE]` placeholder convention:9697| [CATEGORY] | [PLACEHOLDERS] |98| --------------- | --------------------------------------------------------------------------- |99| **Identity** | `[ACTION_NAME]`, `[WORKFLOW_NAME]`, `[DESCRIPTION]`, `[AUTHOR_NAME]` |100| **Runtime** | `[RUNTIME_VERSION]`, `[RUNTIME_ENV_KEY]`, `[ENABLE_CMD]` |101| **Package Mgr** | `[PACKAGE_MANAGER]`, `[INSTALL_CMD]` |102| **Build/Test** | `[BUILD_CMD]`, `[LINT_CMD]`, `[TEST_CMD]`, `[BUILD_PATH]`, `[RESULTS_PATH]` |103| **Deploy** | `[ENV_NAME]`, `[ENV_URL]`, `[DEPLOY_CMD]`, `[VERIFY_CMD]` |104| **Secrets** | `[SECRET_KEY]`, `[SECRET_NAME]`, `[REGISTRY_TOKEN]` |105| **Docker** | `[BASE_IMAGE]`, `[BUILDER_IMAGE]`, `[ENTRYPOINT]` |106107### [2.2][HARDEN_RUNNER_SCOPE]108109`harden-runner` is included as the first step in every **workflow** job template (basic, reusable). **Action** templates (composite, Docker, JavaScript) do NOT include `harden-runner` — the **calling workflow** is responsible for adding it as the first step in the job that invokes the action. Actions are steps, not jobs.110111### [2.3][TEMPLATE_INDEX]112113| [INDEX] | [TEMPLATE] | [PATH] | [SCAFFOLDS] |114| :-----: | --------------------- | ------------------------------------------ | ------------------------------------------------------------------ |115| [1] | **Basic Workflow** | `templates/basic-workflow.template.yml` | CI pipeline: lint, test, build, deploy with parameterized runtime. |116| [2] | **Reusable Workflow** | `templates/reusable-workflow.template.yml` | `workflow_call` with typed inputs, secrets, version extraction. |117| [3] | **Composite Action** | `templates/composite-action.template.yml` | Multi-step action with parameterized runtime and error handling. |118| [4] | **Docker Action** | `templates/docker-action.template.yml` | Container action with distroless multi-stage Dockerfile pattern. |119| [5] | **JavaScript Action** | `templates/javascript-action.template.yml` | Node 24 action with pre/post lifecycle, typed error handling. |120121[REFERENCE] [custom-actions.md](./references/custom-actions.md) — Action type selection, metadata, runtime deprecation.122123---124## [3][EXAMPLES]125>**Dictum:** *Examples demonstrate production patterns for common scenarios.*126127<br>128129Each example demonstrates distinct patterns with minimal overlap. Load relevant examples before generation to match the target scenario.130131| [INDEX] | [EXAMPLE] | [PATH] | [DEMONSTRATES] |132| :-----: | ---------------------------------------- | --------------------------------------- | ----------------------------------------------------------------- |133| [1] | **Node.js CI** | `examples/nodejs-ci.yml` | Matrix testing, caching, artifact upload, coverage, summaries. |134| [2] | **Docker Build + Push** | `examples/docker-build-push.yml` | Multi-platform builds, GHCR, BuildKit caching, SLSA provenance. |135| [3] | **Monorepo CI** | `examples/monorepo-ci.yml` | Nx affected detection, pnpm workspace, sparse checkout. |136| [4] | **PR Security Gate** | `examples/dependency-review.yml` | Multi-job security: dep review, CodeQL, Gitleaks, triage. |137| [5] | **Container Supply Chain** | `examples/sbom-attestation.yml` | SBOM, Trivy severity gating, Cosign, gh attestation verify. |138| [6] | **Composite Action (setup-node-cached)** | `examples/setup-node-cached-action.yml` | Smart caching, corepack detection, cache-dir resolution. |139| [7] | **ChatOps Dispatch** | `examples/chatops-dispatch.yml` | Slash commands, injection prevention, App token, env indirection. |140| [8] | **Multi-Cloud OIDC Auth** | `examples/oidc-cloud-auth-action.yml` | Composite action: AWS/GCP/Azure OIDC, output normalization. |141| [9] | **Release + Deploy** | `examples/release-deploy.yml` | Environment promotion, reusable workflow, concurrency groups. |142| [10] | **Docker Lint + Scan** | `examples/docker-lint-scan-action.yml` | Composite action: Trivy scan, hadolint, SARIF output. |143| [11] | **PR Change Router** | `examples/pr-change-router-action.yml` | Composite action: paths-filter, dynamic matrix, label sync. |144145---146## [4][ACTION_DISCOVERY]147>**Dictum:** *Runtime version resolution prevents stale SHA pins and supply chain drift.*148149<br>150151Static SHA catalogs decay — actions release frequently and stale pins miss security patches. Resolve versions at generation time. Never embed hardcoded SHAs in reference docs or templates.152153**Resolution protocol:**1541. `git ls-remote --tags https://github.com/{owner}/{repo}` — verify tag exists.1552. `gh api repos/{owner}/{repo}/git/ref/tags/{tag} --jq '.object.sha'` — resolve tag to full SHA.1563. Format: `owner/repo@<40-char-SHA> # vX.Y.Z`.157158**Fallback methods:**159- Context7 MCP: `resolve-library-id` then `get-library-docs` for action documentation.160- WebSearch: `"[owner/repo] [version] github action"` for release notes.161162[IMPORTANT]:163- [ALWAYS] Verify the tag exists before pinning — deleted tags return empty results.164- [ALWAYS] Include version comment suffix (`# vX.Y.Z`) — Dependabot/Renovate parse these for automated updates.165- [NEVER] Embed static SHAs in reference files — they decay within weeks.166167[REFERENCE] [version-discovery.md](./references/version-discovery.md) — Discovery protocol, SHA pinning format, common actions index, automated maintenance.168169---170## [5][VALIDATION]171>**Dictum:** *Three-stage pipeline and 11 best practice checks gate workflow quality.*172173<br>174175**Validation pipeline:**176177| [INDEX] | [STAGE] | [TOOL] | [VALIDATES] |178| :-----: | ------------------- | ----------------- | -------------------------------------------------------------------- |179| [1] | **Static Analysis** | actionlint 1.7.10 | YAML syntax, expressions, runner labels, action inputs, CRON, globs. |180| [2] | **Best Practices** | 11 custom checks | SHA pinning, permissions, injection, timeouts, harden-runner. |181| [3] | **Local Execution** | act v0.2.84 | Dry-run validation against Docker images (requires Docker). |182183**Best practice checks (11):**184185| [INDEX] | [CHECK] | [TAG] | [DETECTS] |186| :-----: | ------------------------ | ------------------ | ------------------------------------------------------------ |187| [1] | **Deprecated commands** | `[DEPRECATED-CMD]` | `::set-output`, `::save-state`, `::set-env`, `::add-path`. |188| [2] | **Missing permissions** | `[PERMISSIONS]` | No top-level `permissions: {}` deny-all default. |189| [3] | **Unpinned actions** | `[UNPINNED]` | Mutable tags (`@v1`, `@main`), abbreviated SHAs. |190| [4] | **SHA without comment** | `[SHA-NO-COMMENT]` | SHA-pinned but missing `# vX.Y.Z` version comment. |191| [5] | **Missing timeout** | `[TIMEOUT]` | Jobs without `timeout-minutes:` (default is 6 hours). |192| [6] | **Deprecated runners** | `[RUNNER]` | `ubuntu-20.04`, `macos-12`, `macos-13`, `windows-2019`. |193| [7] | **Missing concurrency** | `[CONCURRENCY]` | No `concurrency:` group or missing `cancel-in-progress`. |194| [8] | **PAT usage** | `[APP-TOKEN]` | PATs for cross-repo ops (use `create-github-app-token`). |195| [9] | **No harden-runner** | `[HARDEN]` | Missing or not first step in job (CVE-2025-30066 detection). |196| [10] | **Expression injection** | `[INJECTION]` | Direct `${{ github.event.* }}` in `run:` blocks. |197| [11] | **Immutable actions** | `[IMMUTABLE]` | Action publishing without immutable OCI (informational). |198199**Error routing:** Match error patterns to reference files — [common_errors.md](references/common_errors.md) (syntax, expressions, deprecated), [runners.md](references/runners.md) (labels, deprecations), [supply_chain.md](references/supply_chain.md) (SHA, OIDC, SBOM, harden-runner), [modern_features.md](references/modern_features.md) (reusable workflows, concurrency, matrix, node runtime), [act_usage.md](references/act_usage.md) (actionlint rules, act limitations).200201**Troubleshooting:**202203| [INDEX] | [ISSUE] | [SOLUTION] |204| :-----: | --------------------------- | ---------------------------------------------- |205| [1] | **Tools not found** | Install actionlint + act (see act_usage.md). |206| [2] | **Docker not running** | Start Docker or validate with actionlint only. |207| [3] | **act fails, GitHub works** | See act_usage.md — Limitations. |208| [4] | **ARM Mac arch mismatch** | Add `--container-architecture linux/amd64`. |209| [5] | **Custom runner labels** | Declare in `.github/actionlint.yaml`. |210211[VERIFY] Completion:212- [ ] Supply chain: Every `uses:` reference SHA-pinned with `# vX.Y.Z` comment suffix.213- [ ] Security: Top-level `permissions: {}`, per-job minimal grants, `harden-runner` first step.214- [ ] Injection: No direct `${{ github.event.* }}` in `run:` blocks — all through `env:` indirection.215- [ ] Performance: Caching enabled, `concurrency` groups set, `timeout-minutes:` on every job.216- [ ] Structure: Descriptive `name:` on workflow/jobs/steps, lowercase-hyphen filenames.217- [ ] Outputs: `>> $GITHUB_OUTPUT` for data, `>> $GITHUB_STEP_SUMMARY` for summaries.218- [ ] Harden-runner: Workflow jobs include it; action templates note caller responsibility.219- [ ] All errors resolved with reference-backed fixes; warnings documented.220221[REFERENCE] [best-practices.md](./references/best-practices.md) — Anti-patterns with specific remediations.