From c223d6fdb095782c458b41e8f72c64ad58cdee5a Mon Sep 17 00:00:00 2001 From: Chris Nighswonger Date: Tue, 28 Jul 2026 18:52:02 +0000 Subject: [PATCH 1/4] CI: re-enable Windows and macOS with per-platform isolation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restores the full three-OS test matrix and makes each matrix cell report independently so platform results are readable. ## Reasoning CI here was pinned to Linux-only in Jan 2026 as a workaround for failures tracked in PDF-Reuse#9 (Windows) and PDF-Reuse#10 (macOS), both of which were recorded as affecting the whole PDF-Reuse family. Both have now been resolved and verified in PDF-Reuse PR #25, where the identical change produced 12/12 green cells. #9 was an upstream PerlToolsTeam toolchain problem on Windows, fixed by their eb7e0211 / d8e20b78 / 1fba8505 between February and April 2026; we inherit those via @main. #10 was never a macOS fault at all — it was matrix fail-fast cancelling healthy macOS cells when a Windows cell in the same matrix failed first. The cpan-test.yml reusable workflow fixes its own strategy block at the default fail-fast: true and exposes no override, so the only way to set it is to call the cpan-test composite action that the reusable workflow itself wraps. Same action, same inputs, one layer down. Omitting testing_context is equivalent to before: the reusable workflow only passed its own identical default of '[ ]' through. Alternative considered: leave this repo pinned to Linux and let the PDF-Reuse fix stand alone. Rejected — the workaround was applied family- wide for a cause that no longer exists, and leaving it in place would keep hiding genuine platform regressions in this distribution. Deliberately not done: pinning the action to a SHA. Every workflow reference in this repo tracks @main; changing that is a separate supply-chain decision, not part of a CI re-enablement. Not load-bearing: affects CI configuration only, no shipped code. --- .github/workflows/ci.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c62244f..773a366 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,11 +8,23 @@ on: workflow_dispatch: jobs: + # Calls the cpan-test composite action directly rather than the cpan-test.yml + # reusable workflow: the latter fixes its own matrix strategy at the default + # fail-fast: true, which cancels healthy cells when an unrelated one fails and + # makes per-platform results unreadable. test: - uses: PerlToolsTeam/github_workflows/.github/workflows/cpan-test.yml@main - with: - os: '["ubuntu-latest"]' - perl_version: '["5.24", "5.30", "5.36", "5.40"]' + runs-on: ${{ matrix.os }} + name: Perl ${{ matrix.perl }} on ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest, macos-latest, windows-latest ] + perl: [ "5.24", "5.30", "5.36", "5.40" ] + steps: + - uses: PerlToolsTeam/github_workflows/.github/actions/cpan-test@main + with: + perl_version: ${{ matrix.perl }} + os: ${{ matrix.os }} coverage: uses: PerlToolsTeam/github_workflows/.github/workflows/cpan-coverage.yml@main From 91ef135fecf155e80f916fdeec2b0c38b728ad39 Mon Sep 17 00:00:00 2001 From: Chris Nighswonger Date: Tue, 28 Jul 2026 19:00:00 +0000 Subject: [PATCH 2/4] CI: pin upstream workflow refs to a SHA and add Dependabot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces @main on all three PerlToolsTeam/github_workflows references with b4ba4e5553820e802da91d58eba295575945ad95, and adds a weekly Dependabot github-actions update so the pins stay current. ## Reasoning Tracking @main means CI can change with no commit in this repo, so a green run is not reproducible and a break can arrive from upstream unannounced. This is not hypothetical here: the six-month Windows CI outage behind PDF-Reuse#9 was upstream drift, and the fix that ended it also arrived by drift. We only discovered both by re-measuring, months late, by chance. The chosen SHA is not simply upstream's current head — it is the exact tree that produced the verified-green runs on this branch. Upstream has landed no commits since it (b4ba4e55 is dated 2026-06-23; the green runs are 2026-07-28), so this pins to a measured-good state rather than to whatever "latest" happened to mean at commit time. Alternative considered: pin to a tag. Not available — upstream publishes no tags at all, so SHA is the only pinning mechanism on offer. Alternative considered: pin and stop there. Rejected — an unmaintained pin rots, and silently missing upstream fixes is how #9 stayed open for six months. Dependabot inverts the default: upstream changes now arrive as a reviewable PR with a CI run attached, instead of arriving unnoticed in the next push. Upstream runs Dependabot on themselves for the same reason. The trailing "# main @ 2026-06-23" comments record what the opaque SHA corresponds to, so a future reader can tell how stale the pin is without querying the API. Not load-bearing: affects CI configuration only, no shipped code. --- .github/dependabot.yml | 10 ++++++++++ .github/workflows/ci.yml | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e6ac61a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + + # Upstream workflow refs are pinned to a SHA so CI cannot change without a + # commit here. Dependabot proposes the bumps, keeping the pins current + # without giving up reproducibility. + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 773a366..654a938 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,15 +21,15 @@ jobs: os: [ ubuntu-latest, macos-latest, windows-latest ] perl: [ "5.24", "5.30", "5.36", "5.40" ] steps: - - uses: PerlToolsTeam/github_workflows/.github/actions/cpan-test@main + - uses: PerlToolsTeam/github_workflows/.github/actions/cpan-test@b4ba4e5553820e802da91d58eba295575945ad95 # main @ 2026-06-23 with: perl_version: ${{ matrix.perl }} os: ${{ matrix.os }} coverage: - uses: PerlToolsTeam/github_workflows/.github/workflows/cpan-coverage.yml@main + uses: PerlToolsTeam/github_workflows/.github/workflows/cpan-coverage.yml@b4ba4e5553820e802da91d58eba295575945ad95 # main @ 2026-06-23 perlcritic: - uses: PerlToolsTeam/github_workflows/.github/workflows/cpan-perlcritic.yml@main + uses: PerlToolsTeam/github_workflows/.github/workflows/cpan-perlcritic.yml@b4ba4e5553820e802da91d58eba295575945ad95 # main @ 2026-06-23 with: level: 5 From 3464c47df8387b67a577a12556b2aea65053f0d4 Mon Sep 17 00:00:00 2001 From: Chris Nighswonger Date: Tue, 28 Jul 2026 23:05:08 +0000 Subject: [PATCH 3/4] Correct the Dependabot claim on the CI SHA pins The dependabot.yml comment claimed Dependabot would keep the upstream SHA pins current. It will not. Replaces the claim with an accurate one and adds docs/ci-pin-maintenance.md describing the manual process. ## Reasoning Verified in dependabot-core: github_actions/update_checker.rb, latest_commit_sha opens with "latest_tag = latest_version_finder.latest_version_tag; return unless latest_tag". A SHA-pinned ref is only advanced when the upstream repo publishes tags. PerlToolsTeam/github_workflows has none, so no update PR will ever be opened for these three refs. dependabot-core#15577 reports the same shape for another untagged path-based action. The pins stay -- they do the job they were added for, which is stopping upstream from changing our CI with no commit here. Only the maintenance story was wrong, and a comment asserting automation that does not exist is worse than no comment: it converts a known manual task into an assumed-handled one. Alternative considered: drop the pins and return to @main, since the automation is unavailable. Rejected -- that restores exactly the failure mode that cost six months of Windows CI. A pin needing a quarterly manual check is strictly better than no pin. Alternative considered: ask upstream to publish semver tags, which would make Dependabot work here. Worth doing, but it is a request to a third party with no guaranteed timeline, so it cannot be what this depends on today. The new doc also records what the pin does NOT freeze -- tag-based actions inside the pinned upstream files, and the floating :latest container images in the coverage and perlcritic workflows -- so the boundary is not overstated in the other direction either. Found by Codex re-review of PR #25, which caught that the previous approval predated this commit. Not load-bearing: CI configuration and documentation only. --- .github/dependabot.yml | 11 +++++-- docs/ci-pin-maintenance.md | 63 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 docs/ci-pin-maintenance.md diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e6ac61a..cb814fe 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,9 +1,14 @@ version: 2 updates: - # Upstream workflow refs are pinned to a SHA so CI cannot change without a - # commit here. Dependabot proposes the bumps, keeping the pins current - # without giving up reproducibility. + # Covers actions/* and other tagged refs that appear in workflows here. + # + # It does NOT maintain the PerlToolsTeam/github_workflows SHA pins in + # ci.yml. Dependabot only advances a SHA-pinned ref when the upstream repo + # publishes tags (dependabot-core github_actions/update_checker.rb, + # latest_commit_sha returns early without a latest_version_tag), and that + # repo has none. Those pins must be reviewed by hand -- see + # docs/ci-pin-maintenance.md. - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/docs/ci-pin-maintenance.md b/docs/ci-pin-maintenance.md new file mode 100644 index 0000000..d8e06f5 --- /dev/null +++ b/docs/ci-pin-maintenance.md @@ -0,0 +1,63 @@ +# CI pin maintenance + +`.github/workflows/ci.yml` pins every `PerlToolsTeam/github_workflows` +reference to a commit SHA rather than `@main`. + +## Why pinned + +Tracking `@main` meant upstream could change this repository's CI with no +commit here. That is not hypothetical: PDF-Reuse lost Windows CI for six +months to an upstream regression, and the eventual fix arrived the same way. +Neither event produced a commit in any of these repositories, and both were +found only by re-measuring months later. + +## Why this needs a human + +**Dependabot does not maintain these pins.** It advances a SHA-pinned GitHub +Actions ref only when the upstream repository publishes tags — see +`github_actions/lib/dependabot/github_actions/update_checker.rb` in +dependabot-core, where `latest_commit_sha` returns early unless +`latest_version_tag` is present. `PerlToolsTeam/github_workflows` has no +tags, so no update PR is ever opened for these refs. + +The `.github/dependabot.yml` in this repo is still useful — it covers tagged +`actions/*` refs — but it is inert for the pins below. + +## What the pin does and does not freeze + +Frozen: the `PerlToolsTeam/github_workflows` files themselves (the composite +action and the reusable workflows). + +Not frozen: + +- Actions invoked *inside* the pinned upstream files, which use tag refs + (`actions/checkout@v5`, `shogo82148/actions-setup-perl@v1`, + `ilammy/msvc-dev-cmd@v1`, `actions/upload-artifact@v5`). Tags can move. +- Container images in the coverage and perlcritic workflows + (`davorg/perl-coveralls:latest`, `davorg/perl-perlcritic`), which float. + +So the pin is a boundary around one upstream repository, not a full CI lock. +It removes the failure mode that actually bit us; it does not make CI +bit-for-bit reproducible. + +## How to review the pin + +Roughly quarterly, or when CI behaves unexpectedly: + + gh api repos/PerlToolsTeam/github_workflows/commits/main \ + --jq '"\(.sha) \(.commit.author.date) \(.commit.message|split("\n")[0])"' + +Compare against the SHA in `ci.yml`. To see what changed since the pin: + + gh api "repos/PerlToolsTeam/github_workflows/commits?sha=main&since=" \ + --jq '.[] | "\(.commit.author.date) \(.sha[0:8]) \(.commit.message|split("\n")[0])"' + +To advance: update all three refs in `ci.yml` plus the trailing +`# main @ ` comments, push to a branch, and let the PR's own CI run be +the verification. Do not advance a pin without a green run — the point of the +pin is that upstream changes arrive as a reviewable event rather than a +surprise. + +Keep the same SHA across all five distributions (PDF-Reuse, PDF-Reuse-Barcode, +PDF-Reuse-OverlayChart, PDF-Reuse-Tutorial, Business-US-USPS-IMB) so a +divergence between them is always a signal rather than noise. From 31793883d8903d181e866a0f57e400a250db6305 Mon Sep 17 00:00:00 2001 From: Chris Nighswonger Date: Tue, 28 Jul 2026 23:13:24 +0000 Subject: [PATCH 4/4] Note actions/checkout@v7 in the pin maintenance doc The transitive-actions list only cited the composite action's refs. The coverage and perlcritic reusable workflows pull actions/checkout@v7, so the list understated which tag-based refs sit behind the pin. Verified against upstream at the pinned SHA rather than assumed: the composite action uses checkout@v5, the two reusable workflows use checkout@v7. Raised as a non-blocking note in Codex round-3 review of PDF-Reuse PR #25. --- docs/ci-pin-maintenance.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/ci-pin-maintenance.md b/docs/ci-pin-maintenance.md index d8e06f5..6ce88bc 100644 --- a/docs/ci-pin-maintenance.md +++ b/docs/ci-pin-maintenance.md @@ -30,9 +30,11 @@ action and the reusable workflows). Not frozen: -- Actions invoked *inside* the pinned upstream files, which use tag refs - (`actions/checkout@v5`, `shogo82148/actions-setup-perl@v1`, - `ilammy/msvc-dev-cmd@v1`, `actions/upload-artifact@v5`). Tags can move. +- Actions invoked *inside* the pinned upstream files, which use tag refs. + In the composite action: `actions/checkout@v5`, + `shogo82148/actions-setup-perl@v1`, `ilammy/msvc-dev-cmd@v1`, + `actions/upload-artifact@v5`. In the coverage and perlcritic reusable + workflows: `actions/checkout@v7`. Tags can move. - Container images in the coverage and perlcritic workflows (`davorg/perl-coveralls:latest`, `davorg/perl-perlcritic`), which float.