Skip to main content

github-actions-patterns

Procedure to add or change a GitHub Actions workflow: pin actions, set token permissions, cache, reuse workflows, and debug a failed run. Use when you edit files under .github/workflows/.

Source facts

Repository
sawrus/agent-guides
Last source activity
October 27, 2026 at 11:23
Detected SKILL.md language
English
Stars
19
Forks
4

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
github-actions-patterns
description
Procedure to add or change a GitHub Actions workflow: pin actions, set token permissions, cache, reuse workflows, and debug a failed run. Use when you edit files under .github/workflows/.
# GitHub Actions: change and debug a workflow ## 1. Read the current workflows 1. List `.github/workflows/*.yml` and the `on:` triggers of each file. 2. Find reusable workflows (`on: workflow_call`) and composite actions under `.github/actions/`. 3. Change the reusable workflow only when the task says so; otherwise change the caller. ## 2. Make the change 1. Set `permissions:` at the top of the workflow to the minimum, for example `contents: read`. Grant more per job only where a step needs it. 2. Pin every third-party action to a full commit SHA and keep the version in a comment: `uses: actions/checkout@<40-char-sha> # v4.2.2`. 3. Use `actions/setup-python`, `actions/setup-go`, or `actions/setup-java` with their built-in `cache:` input before you add a separate `actions/cache` step. 4. Set `timeout-minutes:` on every job. 5. Add `concurrency:` with `cancel-in-progress: true` for pull request workflows. 6. Move steps that two workflows share into a reusable workflow or a composite action. 7. Use `pull_request`, not `pull_request_target`, for code from forks. If `pull_request_target` is required, do not check out the fork head in that job. 8. Do not put `${{ github.event.* }}` text such as titles or branch names directly into `run:`; pass it through `env:` and quote the variable. 9. Read cloud credentials with OIDC (`permissions: id-token: write`) instead of long-lived secrets. 10. Put deploys behind a GitHub Environment with required reviewers. Ask the user first before you trigger a production deploy. ## 3. Validate before you push ```bash actionlint # syntax, expressions, shellcheck of run: blocks zizmor .github/workflows/ # security findings (optional) ``` If `actionlint` is not installed, run it as a container: `docker run --rm -v "$PWD":/repo -w /repo rhysd/actionlint`. ## 4. Debug a failed run 1. Get the log: `gh run list --limit 5`, then `gh run view <run-id> --log-failed`. 2. Find the first failing step and its first error line. 3. Decide the cause class: - **Permissions** — a `403` or `Resource not accessible by integration` needs a `permissions:` entry. - **Secret missing** — secrets are empty in workflows from forks and in environments that do not define them. - **Cache** — check the cache key inputs; a changed lock file must change the key. - **Runner image** — compare the tool versions with the last green run. 4. Rerun failed jobs with debug logs once: `gh run rerun <run-id> --failed --debug`. 5. Fix the cause and push. Do not add `continue-on-error: true` to make the run green. ## 5. Done - `actionlint` passes and the workflow run on the branch is green. - No action is referenced by a tag or a branch.
View on GitHub