GitHub Actions runtime upgrade conventions
Modernize GitHub Actions action versions without changing workflow behavior: select compatible stable major releases, pin runtime/dependency actions immutably, validate post-upgrade workflow parsing and execution, and document each upgrade.
When to invoke
- "Fix this GitHub Actions deprecated runtime warning."
- "Upgrade actions/setup-node to a supported runtime."
- "Review workflow action pins in
.github/workflows."
- "Move this workflow off an old Node.js action runtime."
- "Prepare PR notes for action runtime upgrades."
Upgrade rules
| Rule |
Required behavior |
| Stable major |
Prefer the latest stable major version compatible with the workflow. |
| Immutable pin |
Resolve the target release to a full commit SHA and use that SHA in uses:. |
| Version comment |
Add an optional version comment such as # v4.3.1 beside the SHA. |
| No mutable final pins |
Do not leave final uses: values pinned to @v4, @main, branches, or moving tags. |
| Small changes |
Upgrade one action at a time per commit, or one tightly related group. |
| Behavior preservation |
Keep triggers/permissions, inputs, outputs, release/signing/artifact behavior unchanged unless intentionally requested. |
Actions to prioritize
| Group |
Examples |
Why |
| First-party actions |
actions/* |
They commonly drive runtime deprecation warnings and have clear release lines; review first-party actions before third-party guesses. |
| Setup actions |
actions/setup-*, actions/setup-node, actions/setup-python, actions/setup-dotnet |
Runtime migrations often appear here first and affect downstream build steps. |
| Warning-named actions |
Any action explicitly named in workflow logs |
The log identifies the actual blocker. |
Pinning pattern
Use a full SHA in uses: and keep the human-readable release only as a comment:
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.3.1
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.4
When recommending an upgrade, first identify the latest compatible release, then resolve the release tag to its commit SHA, then update the workflow.
Verification checklist
| Check |
Evidence |
| Workflow parse |
Edited .github/workflows/*.yml or .github/workflows/*.yaml remains valid YAML. |
| Behavior preservation |
Triggers, permissions, env, with, secrets, matrix strategy, and job dependencies are unchanged unless documented. |
| Run validation |
Affected workflows re-run successfully, or equivalent local build/test commands pass when workflow execution is unavailable. |
| Output validation |
Release, signing, cache, and artifact steps still produce expected outputs where applicable. |
| Runtime warning scan |
New logs contain no new deprecation warnings or runtime migration notes. |
PR note content
Include these details in PR summaries or comments:
| Item |
Format |
| Actions upgraded |
<owner/action> from <old ref> -> <new sha> # <version>. |
| Compatibility caveat |
Any action that could not move to a new major and why. |
| Validation |
Workflow run links, rerun names, or local command results. |
| Behavior changes |
State none unless a change was intentional. |
Gotchas
- Do not pin to mutable tags in final recommendations:
@v4 and @main can move after review.
- Do not "fix" runtime warnings by changing unrelated workflow logic: isolate action upgrades from behavior changes.
- Do not batch unrelated actions: small upgrade sets make failures attributable.
- Dependabot is not a substitute for validation: automated bumps still need behavior-preserving checks.
Output template
## GitHub Actions runtime upgrade
**Status:** complete | needs validation | blocked
**Workflow:** `.github/workflows/<name>.yml`
| Action | Old ref | New ref | Reason | Validation |
| --- | --- | --- | --- | --- |
| `<owner/action>` | `<old>` | `<sha> # <version>` | <runtime warning or upgrade> | <run or command> |
### Behavior preservation
- Triggers changed: yes | no
- Permissions changed: yes | no
- Inputs/outputs changed: yes | no
### PR notes
- <summary line>
Quality gate
1---2name: github-actions-runtime-upgrade-conventions3description: Upgrade GitHub Actions workflow dependencies to supported runtimes while preserving behavior. Use this skill when logs report deprecated Node.js action runtimes, when editing `.github/workflows/*.yml` or `.github/workflows/*.yaml`, or when choosing pinned action versions and validating upgraded workflow runs.4---56<!-- Generated from harness/github-copilot/skills/github-actions-runtime-upgrade-conventions/SKILL.md by harness/claude-code/scripts/convert_from_copilot.py. Edit the source, not this file. -->78# GitHub Actions runtime upgrade conventions910Modernize GitHub Actions action versions without changing workflow behavior: select compatible stable major releases, pin runtime/dependency actions immutably, validate post-upgrade workflow parsing and execution, and document each upgrade.1112## When to invoke1314- "Fix this GitHub Actions deprecated runtime warning."15- "Upgrade actions/setup-node to a supported runtime."16- "Review workflow action pins in `.github/workflows`."17- "Move this workflow off an old Node.js action runtime."18- "Prepare PR notes for action runtime upgrades."1920## Upgrade rules2122| Rule | Required behavior |23| --- | --- |24| Stable major | Prefer the latest stable major version compatible with the workflow. |25| Immutable pin | Resolve the target release to a full commit SHA and use that SHA in `uses:`. |26| Version comment | Add an optional version comment such as `# v4.3.1` beside the SHA. |27| No mutable final pins | Do not leave final `uses:` values pinned to `@v4`, `@main`, branches, or moving tags. |28| Small changes | Upgrade one action at a time per commit, or one tightly related group. |29| Behavior preservation | Keep triggers/permissions, inputs, outputs, release/signing/artifact behavior unchanged unless intentionally requested. |3031## Actions to prioritize3233| Group | Examples | Why |34| --- | --- | --- |35| First-party actions | `actions/*` | They commonly drive runtime deprecation warnings and have clear release lines; review first-party actions before third-party guesses. |36| Setup actions | `actions/setup-*`, `actions/setup-node`, `actions/setup-python`, `actions/setup-dotnet` | Runtime migrations often appear here first and affect downstream build steps. |37| Warning-named actions | Any action explicitly named in workflow logs | The log identifies the actual blocker. |3839## Pinning pattern4041Use a full SHA in `uses:` and keep the human-readable release only as a comment:4243```yaml44steps:45 - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.3.146 - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.447```4849When recommending an upgrade, first identify the latest compatible release, then resolve the release tag to its commit SHA, then update the workflow.5051## Verification checklist5253| Check | Evidence |54| --- | --- |55| Workflow parse | Edited `.github/workflows/*.yml` or `.github/workflows/*.yaml` remains valid YAML. |56| Behavior preservation | Triggers, `permissions`, `env`, `with`, `secrets`, matrix strategy, and job dependencies are unchanged unless documented. |57| Run validation | Affected workflows re-run successfully, or equivalent local build/test commands pass when workflow execution is unavailable. |58| Output validation | Release, signing, cache, and artifact steps still produce expected outputs where applicable. |59| Runtime warning scan | New logs contain no new deprecation warnings or runtime migration notes. |6061## PR note content6263Include these details in PR summaries or comments:6465| Item | Format |66| --- | --- |67| Actions upgraded | `<owner/action>` from `<old ref>` -> `<new sha> # <version>`. |68| Compatibility caveat | Any action that could not move to a new major and why. |69| Validation | Workflow run links, rerun names, or local command results. |70| Behavior changes | State `none` unless a change was intentional. |7172## Gotchas7374- **Do not pin to mutable tags in final recommendations**: `@v4` and `@main` can move after review.75- **Do not "fix" runtime warnings by changing unrelated workflow logic**: isolate action upgrades from behavior changes.76- **Do not batch unrelated actions**: small upgrade sets make failures attributable.77- **Dependabot is not a substitute for validation**: automated bumps still need behavior-preserving checks.7879## Output template8081```markdown82## GitHub Actions runtime upgrade8384**Status:** complete | needs validation | blocked85**Workflow:** `.github/workflows/<name>.yml`8687| Action | Old ref | New ref | Reason | Validation |88| --- | --- | --- | --- | --- |89| `<owner/action>` | `<old>` | `<sha> # <version>` | <runtime warning or upgrade> | <run or command> |9091### Behavior preservation92- Triggers changed: yes | no93- Permissions changed: yes | no94- Inputs/outputs changed: yes | no9596### PR notes97- <summary line>98```99100## Quality gate101102- [ ] Every changed `uses:` reference is pinned to a full commit SHA, not a mutable tag or branch.103- [ ] The target release is the latest compatible stable major or the exception is documented.104- [ ] Workflow triggers, permissions, inputs, outputs, and artifacts are preserved unless intentionally changed.105- [ ] Edited workflow YAML parses.106- [ ] The affected workflow or equivalent validation ran successfully, or the blocker is reported.107- [ ] PR notes list old -> new action refs, validation, and any action that could not upgrade.