3.0 KiB
paths
| paths |
|---|
| .github/workflows/**/*.yml |
GitHub Actions Workflow Guidelines
Use ubuntu-slim for Lightweight Tasks
Prefer ubuntu-slim over ubuntu-latest for simple jobs (e.g., labeling, commenting, notifications).
Note: ubuntu-slim has a 15-minute timeout limit. Use ubuntu-latest for long-running jobs (e.g., polling).
# Bad
runs-on: ubuntu-latest
# Good
runs-on: ubuntu-slim
Use Workflow Context Instead of Fetching
If the trigger event already carries the data, read it from the github context instead of calling gh or actions/github-script. Extra API calls burn rate-limit budget and add a flaky network hop for nothing.
# Bad
- env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
HEAD_SHA=$(gh pr view "$PR_NUMBER" --json headRefOid -q .headRefOid)
# Good
- env:
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: echo "$HEAD_SHA"
Only fetch when the data isn't in the payload (e.g., check runs, review threads, changed files on issue_comment).
Prefer gh CLI over actions/github-script
For simple GitHub API operations (commenting, labeling, cancelling runs, etc.),
use gh CLI instead of actions/github-script. It avoids the need for
actions/checkout and JavaScript boilerplate.
# Bad
- uses: actions/checkout@...
- uses: actions/github-script@...
with:
script: |
const script = require(".github/workflows/my-script.js");
await script({ context, github });
# Good
- env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr comment ...
Use sparse-checkout When Only a Subset of Files Is Needed
When a workflow only needs a small subset of the repo (e.g., a single script under .github/), pass sparse-checkout to actions/checkout instead of cloning the whole tree. A full checkout of this repo takes around 10 seconds on average; a sparse checkout finishes in a fraction of that.
# Bad: clones the entire repo just to run one script
- uses: actions/checkout@...
- run: bash .github/scripts/my-script.sh
# Good: only fetches what the job actually reads
- uses: actions/checkout@...
with:
sparse-checkout: |
.github/scripts/my-script.sh
sparse-checkout-cone-mode: false
- run: bash .github/scripts/my-script.sh
When listing directories, leave cone mode on (the default):
- uses: actions/checkout@...
with:
sparse-checkout: |
.github/scripts
dev
Set sparse-checkout-cone-mode: false only when you need to target individual files or non-prefix glob patterns.
pipefail Is Already On
Every workflow in this repo sets top-level defaults.run.shell: bash (enforced by .github/policy.rego). GitHub Actions runs shell: bash as bash --noprofile --norc -eo pipefail {0}, so pipefail is already enabled. Don't ask for set -o pipefail in workflow run: steps. (docs)