From ab6e13597480f8be3a171a2f00cae16d59f0fdab Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Wed, 26 Aug 2026 16:32:51 +0200 Subject: [PATCH] feat(references): GitHub Actions upgrade guide with verified breaking changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New references/actions-upgrade-guide.md: the Node-runtime wave (runners default to Node 24 since 2026-06-16, Node 20 removed 2026-09-23, every recent major requires Actions Runner >= 2.327.1 — self-hosted must update first), the SHA-pin upgrade procedure (resolve majors from the tag list, never a latest-release endpoint, which hands back backport releases like download-artifact v3.1.0-node20; read every crossed major's notes; keep the # vX.Y.Z comment in sync), and a breaking-changes table verified against release notes on 2026-08-26 — checkout v6 credential isolation and v7 fork-PR checkout block, the download-artifact v5 path change and v8 hash-mismatch errors, upload-artifact v7 archive:false, and the runner-floor majors of cache, composer-install, buildx and login-action. The issue's original table (2026-03) had aged: checkout is at v7, not v6, composer-install at v4, and the Node timeline dates were revised upstream — everything in the guide is re-sourced, not copied. Also pins the remaining bare checkout tags in the examples (actionlint-guide.md 4x @v4, tag-validation.md 1x @v6) to the current v7.0.1 SHA, matching the skill's own Pinned-Dependencies rule, and moves the skill-repo-skill pre-commit pin v1.22.0 -> v1.36.0: the old copy still enforced the withdrawn 500-word SKILL.md cap and rejected the one-row References addition at 506 words, while CI validates against main, which counts body lines (112 here). Second repo hit by netresearch/skill-repo-skill#252 today — despite the config's comment that Renovate bumps these revs. Closes #35. Assisted-by: claude-code:claude-fable-5 Agent-Session: https://claude.ai/code/session_01C7S9rbgu5giqCwnzwafrHA Agent-Host: 0493f0 Signed-off-by: Sebastian Mendel --- .pre-commit-config.yaml | 2 +- skills/github-project/SKILL.md | 1 + .../references/actionlint-guide.md | 8 +- .../references/actions-upgrade-guide.md | 93 +++++++++++++++++++ .../references/tag-validation.md | 2 +- 5 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 skills/github-project/references/actions-upgrade-guide.md diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1914f98..ff2674a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: args: [--allow-multiple-documents] - repo: https://github.com/netresearch/skill-repo-skill - rev: v1.22.0 + rev: v1.36.0 hooks: - id: validate-skill - id: check-version-parity diff --git a/skills/github-project/SKILL.md b/skills/github-project/SKILL.md index f2f3187..dddde38 100644 --- a/skills/github-project/SKILL.md +++ b/skills/github-project/SKILL.md @@ -103,6 +103,7 @@ State what a change does, not how good it is. | Polyglot CI checklists | `references/repo-setup-guide.md` | | Scorecard, CodeQL, security | `references/security-config.md` | | actionlint | `references/actionlint-guide.md` | +| Actions upgrades, Node-runtime wave | `references/actions-upgrade-guide.md` | | Workflow bash pitfalls | `references/workflow-bash-patterns.md` | | Runner capacity | `references/ci-runner-capacity.md` | | No editorializing | `references/no-editorializing.md` | diff --git a/skills/github-project/references/actionlint-guide.md b/skills/github-project/references/actionlint-guide.md index dae5879..90fd78f 100644 --- a/skills/github-project/references/actionlint-guide.md +++ b/skills/github-project/references/actionlint-guide.md @@ -335,7 +335,7 @@ jobs: actionlint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install actionlint run: | curl -sL https://github.com/rhysd/actionlint/releases/latest/download/actionlint_linux_amd64.tar.gz \ @@ -361,7 +361,7 @@ jobs: actionlint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - uses: reviewdog/action-actionlint@v1 with: fail_level: error @@ -389,7 +389,7 @@ jobs: actionlint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install actionlint run: | curl -sL https://github.com/rhysd/actionlint/releases/latest/download/actionlint_linux_amd64.tar.gz \ @@ -412,7 +412,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 # Lint workflows - name: actionlint diff --git a/skills/github-project/references/actions-upgrade-guide.md b/skills/github-project/references/actions-upgrade-guide.md new file mode 100644 index 0000000..6a66397 --- /dev/null +++ b/skills/github-project/references/actions-upgrade-guide.md @@ -0,0 +1,93 @@ +# GitHub Actions Upgrade Guide + +Read this when bumping SHA-pinned actions across majors — a Renovate major PR, +or a manual sweep after a security advisory. It covers the one systemic change +driving most current majors (the Node-runtime wave), the upgrade procedure for +SHA pins, and the verified breaking changes per common action. + +Version facts and dates below were verified against the actions' release notes +and the GitHub changelog on **2026-08-26**. Versions age; the procedure does +not. Re-resolve current versions at upgrade time instead of trusting any table, +this one included. + +## The Node-runtime wave (2025–2026) + +GitHub is removing the Node 20 action runtime +([changelog, 2025-09-19](https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/), +dates since revised): + +- Since **2026-06-16**, runners execute `runs.using: node20` actions on Node 24 + by default. +- On **2026-09-23**, Node 20 is removed from the runner. Actions still + declaring `node20` and incompatible with Node 24 break outright. +- Opt in early per workflow with `FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true`. + +Nearly every 2026 major of the common actions is this same change wearing the +action's own version number: the action moves to `runs.using: node24`, which +**requires Actions Runner ≥ 2.327.1**. On GitHub-hosted runners that floor is +long met — just bump. On **self-hosted runners, update the runner first**, or +every bumped action fails at startup. Node 24 itself does not support +macOS ≤ 13.4 or ARM32 self-hosted runners. + +Many of the same majors also migrated to ESM. That is transparent to callers — +it only matters when you maintain a fork of the action. + +## Upgrade procedure for SHA-pinned actions + +Pinning conventions (`uses: owner/action@SHA # vX.Y.Z`, batch tooling) live in +[`security-config.md`](./security-config.md) and +[`org-security-settings.md`](./org-security-settings.md). For the bump itself: + +1. **Resolve the real current major from the tag list, never from a + "latest release" endpoint** — point releases for old majors land later and + take the latest-release slot (observed 2026-08-26: `actions/download-artifact` + answered `v3.1.0-node20` as latest release while the current major was v8). + + ```bash + gh api "repos/OWNER/ACTION/releases?per_page=15" --jq '.[].tag_name' | sort -Vr | head -5 + ``` + +2. **Read the release notes of every major you cross**, not only the target: + + ```bash + gh api repos/OWNER/ACTION/releases/tags/vX.0.0 --jq .body + ``` + +3. **Resolve tag → SHA and keep the comment in sync** — the comment is what + humans and Renovate read; a stale comment is worse than none: + + ```bash + gh api repos/OWNER/ACTION/commits/vX.Y.Z --jq .sha + ``` + +4. **Verify**: `actionlint` on the changed workflows + ([`actionlint-guide.md`](./actionlint-guide.md)), zizmor where wired, and + watch the first run on a PR — a runtime floor violation only surfaces at + execution. + +Renovate bumps SHA and comment together on its own; a major still needs step 2 +before approving the PR. + +## Breaking changes by action + +Verified from release notes, 2026-08-26. "Runner ≥ 2.327.1" is shorthand for +the Node 24 runtime change described above. + +| Action | Current | Major | What changes | +|---|---|---|---| +| `actions/checkout` | v7.0.1 | v6 | Credentials persisted to a separate file instead of `.git/config` ([#2286](https://github.com/actions/checkout/pull/2286)) — anything reading the token out of `.git/config` stops finding it | +| | | v7 | Checkout of a fork PR head is **blocked for `pull_request_target` and `workflow_run` events** ([#2454](https://github.com/actions/checkout/pull/2454)); workflows that deliberately check out fork code on those triggers must be restructured. ESM | +| `actions/cache` | v5.1.0 | v5 | Node 24, runner ≥ 2.327.1 | +| `actions/download-artifact` | v8.0.1 | v5 | **Breaking path behavior** for single-artifact downloads by ID ([#416](https://github.com/actions/download-artifact/pull/416)) | +| | | v6–v7 | Node 24 (v7 makes it the default runtime), runner ≥ 2.327.1 | +| | | v8 | ESM; **hash mismatches now error by default** (overridable per release notes) | +| `actions/upload-artifact` | v7.0.1 | v6 | Node 24 default, runner ≥ 2.327.1 | +| | | v7 | ESM; new `archive: false` uploads a single file unzipped (`name` input ignored in that mode) | +| `actions/setup-node` | v7.0.0 | v7 | ESM; adds `cache-primary-key`/`cache-matched-key` outputs — no caller-facing break found in the notes | +| `ramsey/composer-install` | 4.0.0 | v4 | Internal `actions/cache` v5 → runner ≥ 2.327.1 (breaking for self-hosted only) | +| `docker/setup-buildx-action` | v4.3.0 | v4 | Node 24, runner ≥ 2.327.1; **removes deprecated inputs/outputs** ([#464](https://github.com/docker/setup-buildx-action/pull/464)); ESM | +| `docker/login-action` | v4.6.0 | v4 | Node 24, runner ≥ 2.327.1; ESM | +| `step-security/harden-runner` | v2.21.0 | — | Still on the v2 line, no major crossed | + +The absence of a row is not evidence of a painless upgrade — it means the +action was not checked on 2026-08-26. Run step 2 of the procedure. diff --git a/skills/github-project/references/tag-validation.md b/skills/github-project/references/tag-validation.md index 8b15e47..be6b0b1 100644 --- a/skills/github-project/references/tag-validation.md +++ b/skills/github-project/references/tag-validation.md @@ -126,7 +126,7 @@ Add to `lint.yml` with `tags: ['v*']` trigger. Runs on every tag push as a safet name: Plugin Version runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Validate version file matches tag run: | # Adapt extraction per ecosystem (see table below)