Skip to content

CI: re-enable Windows and macOS with per-platform isolation - #2

Merged
cnighswonger merged 4 commits into
masterfrom
ci/re-enable-windows-macos
Jul 28, 2026
Merged

CI: re-enable Windows and macOS with per-platform isolation#2
cnighswonger merged 4 commits into
masterfrom
ci/re-enable-windows-macos

Conversation

@cnighswonger

Copy link
Copy Markdown
Owner

Restores the full three-OS test matrix, dropped in 1ae89b5 ("Restrict CI to Linux-only for now"), and makes each matrix cell report independently.

Companion to PDF-Reuse#25, where this identical change produced 12/12 green.

What changed

.github/workflows/ci.yml — the test job now calls the cpan-test composite action directly with our own matrix strategy, instead of the cpan-test.yml reusable workflow:

  • fail-fast: false, so one failing cell no longer cancels its healthy siblings
  • os: [ ubuntu-latest, macos-latest, windows-latest ] restored
  • Perl versions unchanged: 5.24, 5.30, 5.36, 5.40

coverage and perlcritic untouched. Diff is byte-identical to the PDF-Reuse one.

Reasoning

CI here was pinned Linux-only in Jan 2026 as a workaround for PDF-Reuse#9 (Windows) and PDF-Reuse#10 (macOS), both explicitly recorded as affecting the whole PDF-Reuse family. Both are now resolved:

  • #9 — an upstream PerlToolsTeam toolchain fault on Windows (No MYMETA file is found after configure), fixed by their eb7e0211 (PowerShell instead of bash, 2026-02-11), d8e20b78 (up-to-date toolchain, 2026-03-12) and 1fba8505 (2026-04-20). We track @main, so we inherit them.
  • #10 — never a macOS fault. Matrix fail-fast cancelled healthy macOS cells when a Windows cell failed first.

The reusable workflow fixes its own strategy block at default fail-fast: true and exposes no override, so the only way to set it is to call the composite action 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 '[ ]' through (verified against upstream source).

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 keeping it would go on hiding genuine platform regressions in this distribution.

Deliberately not done

Pinning the action to a SHA. Every workflow reference here tracks @main; changing that is a separate supply-chain decision, not part of a CI re-enablement.

Verification

This PR's own CI run is the verification. This distribution is documentation and examples with an empty PREREQ_PM and a single t/1.t, so it is the lowest-risk member of the family — its main value here is confirming the family-wide workaround can be lifted uniformly.

Load-bearing: no. CI configuration only; no shipped code changes.

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.
@coveralls

coveralls commented Jul 28, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 30407288234

Warning

No base build found for commit 3c0594d on master.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 100.0%

Details

  • Patch coverage: No coverable lines changed in this PR.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 1
Covered Lines: 1
Line Coverage: 100.0%
Coverage Strength: 1.0 hits per line

💛 - Coveralls

@cnighswonger

Copy link
Copy Markdown
Owner Author

CI result: 12/12 green, plus coverage and perlcritic — run 30389461299.

Perl ubuntu macos windows
5.24
5.30
5.36
5.40

Matches PDF-Reuse#25 exactly. The family-wide Linux-only workaround can be lifted here.

One correction to the reasoning in the PR description, carried over from the parent PR. A control experiment on PDF-Reuse (run 30389331620) ran the unmodified reusable workflow on Windows against upstream's current @main and it passed. So the Windows fix is entirely upstream's — the composite-action switch was not what fixed Windows. That switch is justified by the macOS fail-fast isolation alone, which the reusable workflow cannot express. Windows is green either way.

Ready for review.

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.
@cnighswonger

Copy link
Copy Markdown
Owner Author

Added a second commit: SHA-pin the upstream workflow refs and add Dependabot.

All three PerlToolsTeam/github_workflows refs move from @main to b4ba4e5553820e802da91d58eba295575945ad95, plus a new .github/dependabot.yml (weekly github-actions).

Re-verified after pinning — 12/12 green, plus coverage and perlcritic (run 30390029330).

Why this SHA

It is not merely upstream's current head. b4ba4e55 is dated 2026-06-23 and upstream has landed zero commits since, so it is the exact tree that produced the verified-green runs earlier in this PR. Pinning here freezes a measured-good state rather than whatever "latest" happens to mean.

Why pin at all

The rationale is this PR's own history. The six-month Windows outage was upstream drift, and the fix that ended it was also upstream drift — proven by control experiment. Neither event produced a commit in this repo, and both were found only by re-measuring months later. Pinning converts that class of surprise into a reviewable PR.

Alternatives: tags aren't available (upstream publishes none, so SHA is the only mechanism); pinning without Dependabot was rejected because an unmaintained pin rots, which is the same failure mode in slower motion. Upstream runs Dependabot on themselves for this reason.

Trailing # main @ 2026-06-23 comments record what the opaque SHA means so a future reader can judge staleness without hitting the API.

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.
@cnighswonger

Copy link
Copy Markdown
Owner Author

Pushed a correction to the Dependabot rationale, following a Codex re-review of the parent PR (PDF-Reuse#25).

The claim that Dependabot keeps these SHA pins current was wrong. Verified in dependabot-core (github_actions/update_checker.rb, latest_commit_sha): a SHA-pinned ref is only advanced when the upstream repo publishes tags, and PerlToolsTeam/github_workflows has none. No update PR will ever be opened for these three refs.

Ironically the confirming fact was already in this PR's own reasoning — I used "upstream publishes no tags" to argue SHA was the only pinning option, without following it through to what it does to Dependabot.

The pins stay; only the maintenance story changes:

  • .github/dependabot.yml — comment now states plainly it does not maintain these pins, cites the reason, points at the new doc. Retained because it still covers tagged actions/* refs.
  • New docs/ci-pin-maintenance.md — why pinned, why it needs a human, what the pin does and does not freeze, and the gh api commands to audit or advance it.

Reverting to @main was considered and rejected: it restores the exact failure mode that cost six months of Windows CI. A pin needing a quarterly manual check beats no pin.

The doc also records the limits in the other direction — the pin freezes the upstream workflow files but not the tag-based actions inside them (actions/checkout@v5 etc.) nor the floating davorg/* container images in the coverage and perlcritic jobs. It is a boundary around one upstream repo, not a full CI lock.

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.
@cnighswonger
cnighswonger merged commit 8c610b6 into master Jul 28, 2026
15 checks 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.

2 participants