Skip to content

Pinned every action to a commit SHA, and moved them off Node 20 - #660

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:chore/pin-actions-to-shas
Aug 25, 2026
Merged

Pinned every action to a commit SHA, and moved them off Node 20#660
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:chore/pin-actions-to-shas

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

Node 20 is removed from the GitHub runners on 16 September 2026. Every run in this repository currently carries the deprecation warning, naming actions/checkout, actions/configure-pages, actions/upload-artifact, LouisBrunner/checks-action and marocchino/sticky-pull-request-comment. After that date those actions stop working rather than warning — so this is a deadline, not housekeeping.

Two problems, one change

Referencing was inconsistent and unpinned. actions/checkout appeared as both @v4 and @v4.2.2 in the same repository, and nothing was pinned to a commit. Every reference is now a 40-character SHA with the version in a trailing comment:

uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

A tag can be repointed at any commit; a SHA cannot. That is what makes "which code ran in our CI" answerable from the repository rather than from whatever the tag meant at the time — worth having on its own for a project building an SBOM story.

Nothing has ever reported that an action moved, so the versions had drifted by as much as four majors:

Action Was Now
actions/download-artifact v4.3.0 v8.0.1
actions/checkout v4 / v4.2.2 v7.0.1
actions/upload-artifact v4.6.2 v7.0.1
actions/cache v4 v6.1.0
actions/upload-pages-artifact v3.0.1 v5.0.0
actions/configure-pages v5.0.0 v6.0.0
actions/deploy-pages v4.0.5 v5.0.0
LouisBrunner/checks-action v2.0.0 v3.1.0
marocchino/sticky-pull-request-comment v2.9.4 v3.0.5
geekyeggo/delete-artifact v5.1.0 v6.0.0
EnricoMi/publish-unit-test-result-action v2.11.0 v2.24.0
irongut/CodeCoverageSummary v1.3.0 v1.3.0 — already current, pinned not moved

19 references across 4 files. All of the new versions run on node24 (or are composite).

Compatibility checked, not assumed

Against each new action.yml, for every input this repository actually passes:

  • checkoutsubmodules unchanged. cachepath, key unchanged.
  • upload-artifactname, path, retention-days unchanged.
  • download-artifactpattern, merge-multiple, path unchanged.
  • configure-pages — takes no input here, and none became required.
  • deploy-pages — still exposes page_url, which the job reads via steps.deployment.outputs.page_url.
  • upload-pages-artifactpath unchanged.
  • checks-actiontoken, name, conclusion, output, output_text_description_file all survive v2 → v3.
  • sticky-commentheader and path survive v2 → v3, and the new GITHUB_TOKEN input defaults to ${{ github.token }}, which is what v2 used implicitly. No change needed.
  • delete-artifactname survives v5 → v6, and useGlob still defaults to true, so the coverage_report-* glob from Published the coverage report instead of everything the run produced #655 still matches.

The artifact pair, verified on a runner

They move together, as they must. Before this commit I ran the round trip on a real runner — upload-artifact v7 → download-artifact v8, through the pattern + merge-multiple selection #655 introduced:

Found 4 artifact(s)
Filtering artifacts by pattern 'coverage_report-*'
Total of 2 artifact(s) downloaded

cov/SMP/index.html
cov/ThreadX/index.html
cov/default_build_coverage.xml

Exactly the tree the deploy expects. That is the one four-major jump in here and the only place with documented breaking changes, so it seemed worth more than a reading of the release notes.

Two behaviour changes worth knowing

  • download-artifact v8 adds a digest-mismatch input defaulting to error. A corrupted artifact now fails the job rather than passing through. That is the right default, but it is a change.
  • upload-artifact v6 and above require a runner of at least 2.327.1. The hosted runners satisfy this; a self-hosted runner would need checking — relevant if the FVP work ever moves to one.

What comes next

This PR is deliberately the catch-up only. A .github/dependabot.yml follows separately, so that the pins are moved by something that opens one reviewable PR per change instead of drifting for another three years. Doing it the other way round would have had Dependabot open a wall of PRs against the backlog above.

Node 20 is removed from the GitHub runners on 16 September 2026. Every run
in this repository currently emits the deprecation warning for it, naming
actions/checkout, actions/configure-pages, actions/upload-artifact,
LouisBrunner/checks-action and marocchino/sticky-pull-request-comment among
others. After that date those actions stop working rather than warning, so
this is a deadline and not housekeeping.

Every action is now referenced by a 40-character commit SHA with the version
in a trailing comment. A tag can be repointed at any commit; a SHA cannot, so
this is what makes "which code ran in our CI" answerable from the repository
rather than from whatever the tag meant at the time. The versions were behind
by as much as four majors -- download-artifact was on v4.3.0 against v8.0.1 --
because nothing in this repository has ever reported that an action moved.

Compatibility was checked against each new action.yml rather than assumed,
for every input this repository actually passes:

  checkout            submodules is unchanged
  cache               path and key are unchanged
  upload-artifact     name, path and retention-days are unchanged
  download-artifact   pattern, merge-multiple and path are unchanged
  configure-pages     takes no input here, and none became required
  deploy-pages        still exposes page_url, which the job reads
  upload-pages-art.   path is unchanged
  checks-action       token, name, conclusion, output and
                      output_text_description_file all survive v2 to v3
  sticky-comment      header and path survive v2 to v3, and the new
                      GITHUB_TOKEN input defaults to github.token, which is
                      what v2 used implicitly
  delete-artifact     name survives v5 to v6, and useGlob still defaults to
                      true, so the coverage_report-* glob from eclipse-threadx#655 still
                      matches
  CodeCoverageSummary already current at v1.3.0; pinned, not moved

The artifact pair moves together, as it must. The round trip was verified on
a runner before this commit: upload-artifact v7 to download-artifact v8,
through the pattern and merge-multiple selection eclipse-threadx#655 introduced, filtered 4
artifacts to 2 and produced exactly the tree the deploy expects.

Two behaviour changes worth knowing. download-artifact v8 adds a
digest-mismatch input defaulting to error, so a corrupted artifact now fails
the job instead of passing through -- the right default, but a change.
upload-artifact v6 and above require a runner of at least 2.327.1, which the
hosted runners satisfy and a self-hosted runner would need checking for.

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 3d852eb into eclipse-threadx:dev Aug 25, 2026
15 checks passed
@fdesbiens
fdesbiens deleted the chore/pin-actions-to-shas branch August 25, 2026 19:52
fdesbiens added a commit that referenced this pull request Aug 25, 2026
The action references were pinned to commit SHAs in #660, and a SHA pin with
nothing moving it is worse than a floating tag -- it holds CI on whatever was
current the day it was written. That is exactly how actions/cache@v1 stayed in
ci_cortex_m.yml until GitHub began auto-failing every request that used it.
The drift measured before that catch-up: download-artifact four majors behind,
checkout and upload-artifact three each, cache and upload-pages-artifact two,
with nothing ever reporting it. This closes the loop, and the reference to
.github/dependabot.yml that #660 left in each workflow's pinning comment.

Weekly, github-actions only. Patch and minor are grouped into one pull request
because they are the routine traffic and a queue reviewed one item at a time is
a queue that gets ignored. Majors stay ungrouped, one each, because every
breaking change this repository has met in an action has been a major.

Two choices worth stating rather than leaving to be rediscovered.

target-branch is dev. Dependabot reads this file from the default branch, which
is master, but master is deliberately kept behind dev and pull requests belong
where the regression suites gate them. The consequence is that landing this on
dev arms it without firing it: nothing happens until a release merge carries
the file to master. Setting target-branch also opts out of Dependabot security
updates, which only run against the default branch -- a small cost for this
ecosystem, since an action advisory arrives as an ordinary bump on the weekly
run, but a real one.

The pull-request limit is raised from the default five to ten. Nine actions are
in use, and five would hold majors back with nothing saying that it had.

No other ecosystem is configured, deliberately: external dependencies are
forbidden, there are no submodules, and the one pinned tool -- gcovr in
scripts/install.sh -- lives in a shell script no ecosystem can parse, so that
pin keeps moving by hand.

No sibling eclipse-threadx repository has a Dependabot configuration, so this
sets the pattern rather than following one. The dependencies label it uses
already exists here.

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
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