From ai-dev-extensions
Use when reviewing, writing, or modifying GitHub Actions workflows or referencing any GitHub Action - enforces version pinning by commit SHA, latest version verification, and version commenting
How this skill is triggered — by the user, by Claude, or both
Slash command
/ai-dev-extensions:github-actionsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Every GitHub Action reference in a workflow MUST be pinned to a full commit SHA (not a tag or branch) with the human-readable version noted in an inline comment. Before writing or reviewing any workflow, always verify that the latest version of each action is being used.
Every GitHub Action reference in a workflow MUST be pinned to a full commit SHA (not a tag or branch) with the human-readable version noted in an inline comment. Before writing or reviewing any workflow, always verify that the latest version of each action is being used.
.github/workflows/*.yml)uses: directive) to a workflowNever reference actions by tag or branch:
# BAD - tag reference, vulnerable to tag mutation
- uses: actions/checkout@v4
# BAD - branch reference, non-deterministic
- uses: actions/checkout@main
# GOOD - full SHA pin with version comment
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
Before writing or approving any action reference:
To verify a SHA for a given tag:
git ls-remote --tags https://github.com/{owner}/{repo}.git refs/tags/{tag}
Or via GitHub API:
gh api repos/{owner}/{repo}/releases/latest --jq '.tag_name'
gh api repos/{owner}/{repo}/git/ref/tags/{tag} --jq '.object.sha'
The inline comment after the SHA MUST contain the human-readable version so that:
Format: {owner}/{action}@{sha} # {tag}
run scripts — use environment variablesInterpolating ${{ }} expressions directly in run: blocks (bash, PowerShell, or any shell) creates script injection vulnerabilities. An attacker who controls the expression value (e.g., a PR title, branch name, or issue body) can inject arbitrary commands.
Always pass untrusted values through environment variables:
# BAD - direct interpolation, vulnerable to command injection
- run: echo "Hello ${{ github.event.pull_request.title }}"
# BAD - same issue in PowerShell
- run: Write-Host "Hello ${{ github.event.issue.body }}"
shell: pwsh
# GOOD - pass through env, shell handles escaping
- run: echo "Hello $TITLE"
env:
TITLE: ${{ github.event.pull_request.title }}
# GOOD - PowerShell equivalent
- run: Write-Host "Hello $env:BODY"
shell: pwsh
env:
BODY: ${{ github.event.issue.body }}
These expressions are user-controlled and MUST always go through env::
| Source | Example |
|---|---|
| PR title / body | github.event.pull_request.title, github.event.pull_request.body |
| Issue title / body | github.event.issue.title, github.event.issue.body |
| Comment body | github.event.comment.body |
| Commit message | github.event.head_commit.message |
| Branch / tag name | github.head_ref, github.ref_name |
| Review body | github.event.review.body |
needs.*.outputs.*)Job outputs are only as safe as how they were produced. If a job output originates from user-controlled data (commit messages, PR titles, branch names) — even indirectly via a third-party action — it MUST go through env: when used in run: or script: blocks.
# BAD - output may contain injected content from commit messages
- run: echo "Releasing ${{ needs.version.outputs.new_tag }}"
# GOOD - passed through env
- run: echo "Releasing ${NEW_TAG}"
env:
NEW_TAG: ${{ needs.version.outputs.new_tag }}
# OK - with: inputs are action parameters, not shell-interpolated
with:
commit_message: "chore(release): v${{ needs.version.outputs.new_version }}"
Note: with: inputs are passed as strings to actions, not shell-interpolated — they are safe from script injection. The env: rule applies specifically to run: and script: blocks.
These are generally safe but using env: is still best practice for consistency:
github.repository, github.actor, github.shagithub.run_id, github.run_numbersecrets.*, vars.*This applies to every action, including:
actions/checkoutactions/setup-nodeactions/cachedocker/login-actionNo exceptions.
When reviewing a workflow PR, verify each uses: line:
# v4.2.2)Keep these up to date. When writing workflows, always verify current latest versions:
| Action | Check latest |
|---|---|
actions/checkout | gh api repos/actions/checkout/releases/latest --jq '.tag_name' |
actions/setup-node | gh api repos/actions/setup-node/releases/latest --jq '.tag_name' |
actions/setup-python | gh api repos/actions/setup-python/releases/latest --jq '.tag_name' |
actions/cache | gh api repos/actions/cache/releases/latest --jq '.tag_name' |
docker/build-push-action | gh api repos/docker/build-push-action/releases/latest --jq '.tag_name' |
docker/login-action | gh api repos/docker/login-action/releases/latest --jq '.tag_name' |
azure/login | gh api repos/azure/login/releases/latest --jq '.tag_name' |
aws-actions/configure-aws-credentials | gh api repos/aws-actions/configure-aws-credentials/releases/latest --jq '.tag_name' |
google-github-actions/auth | gh api repos/google-github-actions/auth/releases/latest --jq '.tag_name' |
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub using-system/ai-dev-extensions --plugin ai-dev-extensions