| name | update-github-actions |
| description | Update outdated GitHub Actions in workflow files and pin them to commit hashes for supply-chain security. |
| when_to_use | Use when the user says 'update actions', 'update github actions', 'pin actions', 'update workflows', 'bump actions', 'outdated actions', 'update action versions', 'pin workflow actions', 'pin actions to hashes', 'update CI actions', or any variation of wanting to update, pin, or bump GitHub Actions in CI workflow files. |
| allowed-tools | Bash(gh api *) |
Update GitHub Actions in workflow files to their latest versions, pinned by commit SHA for security and reproducibility.
Step 1 — Find workflow files
Glob for .github/workflows/*.yml and .github/workflows/*.yaml. Read each file. If none are found, inform the user and stop.
Step 2 — Extract action references
For each workflow file, find all uses: lines that reference actions in owner/repo@ref format. Ignore:
- Local actions (paths starting with
./)
- Docker actions (paths starting with
docker://)
- Reusable workflow references (paths containing
.github/workflows/)
- Actions already pinned to a full 40-character SHA
Build a deduplicated list of actions with their current refs (e.g. actions/checkout@v4).
Step 3 — Resolve latest versions and commit SHAs
For each unique action, determine the latest version tag within the same major version and resolve its commit SHA. If any gh api call fails (auth error, rate limit, repo not found), skip that action with a warning rather than aborting the entire process.
3a — Find the latest tag for the current major version
Extract the major version from the current ref (e.g. @v4 → major 4, @v3.2.1 → major 3). Then find the latest release whose tag matches the same major version:
gh api repos/{owner}/{repo}/releases --jq '[.[] | select(.tag_name | test("^v{major}([.]|$)"))][0].tag_name'
If no matching release exists, fall back to listing tags:
gh api repos/{owner}/{repo}/tags --jq '[.[] | select(.name | test("^v{major}([.]|$)"))][0].name'
If both return empty, skip the action and report "no matching releases found" in the results table.
3b — Resolve the tag to a commit SHA
Fetch the git ref and check its object type in a single call:
gh api repos/{owner}/{repo}/git/ref/tags/{tag} --jq '.object | "\(.type) \(.sha)"'
If the type is commit, use the SHA directly. If the type is tag (annotated tag), dereference it:
gh api repos/{owner}/{repo}/git/tags/{sha} --jq '.object.sha'
Step 4 — Present proposed changes
Show the user a table of proposed updates before applying anything. Exclude actions that are already at the latest version/SHA.
| Workflow file | Action | Current ref | New pinned ref |
|---|
Ask the user to confirm before proceeding. If the user wants to skip specific actions, respect that.
Step 5 — Apply updates
For each confirmed action reference, update the uses: line to the pinned format with a tag comment for readability:
uses: actions/checkout@v4
uses: actions/checkout@<full-sha>
The comment after the SHA shows the tag name so humans can tell which version is pinned at a glance.
Do not commit or push changes unless also asked to do so.