Skip to content

ci: move workflow actions off the deprecated Node 20 runtime - #48

Merged
foureight84 merged 2 commits into
mainfrom
ci/bump-actions-node24
Aug 11, 2026
Merged

ci: move workflow actions off the deprecated Node 20 runtime#48
foureight84 merged 2 commits into
mainfrom
ci/bump-actions-node24

Conversation

@foureight84

@foureight84 foureight84 commented Aug 10, 2026

Copy link
Copy Markdown
Owner

The v2.5.0+35 release run warned that four actions target Node 20 and are being force-run on Node 24, and that setup-java v4 is EOL. Builds pass today; this closes it out before the forced-migration window does.

Action From To
actions/checkout v4 v7
actions/setup-java v4 v5
gradle/actions/setup-gradle v4 v6 + cache-provider: basic
actions/upload-artifact v4 v7
softprops/action-gh-release v2 v3

Every one of these majors is a Node 20 → 24 runtime bump. I read the release notes for each; none changes an input this repo passes. Specifically:

  • checkout v7 also blocks fork checkouts for pull_request_target and workflow_run — neither workflow uses those events (CI is on pull_request).
  • upload-artifact v7 adds an optional archive input and leaves name / path / if-no-files-found / retention-days untouched.
  • All require runner ≥ 2.327.1; GitHub-hosted ubuntu-latest is well past that.

setup-gradle: v6 with cache-provider: basic

v6 moved the default caching implementation into gradle-actions-caching, a proprietary component governed by Gradle's commercial Terms of Use. An earlier revision of this PR stopped at v5 to avoid that. Two things make v6 the better call:

  1. v5 is a dead line. Last release v5.0.2 (2026-02-23); v6.0.0 landed a month later and there has been nothing on v5 since. v6.0.0's notes cite dependency updates for security vulnerabilities — so pinning v5 would fix the Node 20 deprecation by parking on a branch that gets no security updates.
  2. v6 has an open-source caching mode, so the licensing concern implied a choice that doesn't actually exist. cache-provider selects between enhanced (default, the commercial component) and basic (the open-source GitHub Actions cache implementation).

cache-provider: basic therefore gets Node 24, an actively maintained line, security updates and caching, without accepting those terms:

v5 v6 default v6 + basic
Node 24
Security updates ❌ dead
Caching ✅ MIT ✅ commercial open source
Commercial terms none accepted none

Both workflows set the input explicitly and comment why, because the failure mode is silent: deleting the line doesn't break the build, it just opts into the commercial component on the next run.

v6 also drops the rudimentary configuration-cache support pending a reimplementation. These workflows run --no-daemon and never enabled the configuration cache, so that costs nothing here.

Note cache-provider exists as of v6.3.0, so this relies on the floating @v6 tag staying at 6.3.0+ — consistent with how this repo pins every other action. Pin @v6.3.0 exactly if you'd rather not depend on that.

Verification

Workflow YAML parses cleanly with the expected structure (ci: 1 job / 6 steps; release: 1 job / 8 steps). The real check is CI on this PR.

Caveat: this PR exercises ci.yml only. release.yml runs on tag pushes, so its changes stay unverified until the next release tag — worth knowing if the next release is time-sensitive. The changes are identical in kind to the ones CI does cover.

The v2.5.0+35 release run warned that checkout@v4, setup-java@v4,
setup-gradle@v4 and action-gh-release@v2 all target Node 20 and were being
force-run on Node 24, and that setup-java v4 is EOL. Builds still pass, but the
forced-migration window closes eventually.

  actions/checkout            v4 -> v7
  actions/setup-java          v4 -> v5
  gradle/actions/setup-gradle v4 -> v5   (not v6 — see below)
  actions/upload-artifact     v4 -> v7
  softprops/action-gh-release v2 -> v3

Every one of these majors is a Node 20 -> 24 runtime bump; none changes an input
this repo passes. checkout v7 also blocks fork checkouts for pull_request_target
and workflow_run, neither of which these workflows use. upload-artifact v7 adds
an optional `archive` input and leaves name/path/if-no-files-found/retention-days
untouched. All require runner >= 2.327.1, which GitHub-hosted ubuntu-latest is
well past.

**setup-gradle deliberately stops at v5, not the latest v6.** v6 extracts caching
into `gradle-actions-caching`, a proprietary component governed by Gradle's
commercial Terms of Use instead of the MIT licence, and using v6 with caching
enabled accepts those terms. v5 is the last MIT line and already runs on Node 24,
so it fully resolves the deprecation without taking on a licensing commitment on
behalf of an OSS project. Both workflows carry a comment saying so, with a link
to Gradle's blog post, so the next person doesn't "helpfully" bump it.

Note this PR exercises ci.yml only — release.yml runs on tag pushes, so its
changes stay unverified until the next release tag.
Supersedes this branch's earlier decision to stop at v5. Two things made that
the wrong call:

**v5 is a dead line.** Last release v5.0.2 (2026-02-23); v6.0.0 landed a month
later and there has been nothing on v5 since. v6.0.0's notes cite dependency
updates for security vulnerabilities. Pinning v5 would have fixed the Node 20
deprecation by parking on a branch that gets no security updates.

**v6 has an open-source caching mode**, which the earlier note missed. The
licensing concern was real but the choice it implied was false: `cache-provider`
selects between 'enhanced' (default, the proprietary `gradle-actions-caching`
under Gradle's commercial Terms of Use) and 'basic' (the open-source GitHub
Actions cache implementation). Setting it to 'basic' gets Node 24, an actively
maintained line, security updates and caching, without accepting those terms.

Both workflows set it explicitly and say why, because the failure mode is
silent: deleting the input doesn't break the build, it just opts into the
commercial component on the next run.

v6 also drops the rudimentary configuration-cache support pending a
reimplementation. These workflows run --no-daemon and never enabled the
configuration cache, so that costs nothing here.
@foureight84
foureight84 merged commit 2ab092a into main Aug 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant