Fix Windows CI downloads failing on offline CA revocation - #885
Mikola Lysenko (mikolalysenko) wants to merge 2 commits into
Conversation
Windows curl uses schannel, which fails the TLS handshake with CRYPT_E_REVOCATION_OFFLINE (exit 35) whenever the CA's revocation server can't be reached. That turned Gradle's Install step and Composer's download step red before any test ran. --ssl-revoke-best-effort skips the revocation check only when the server is unreachable. A revoked certificate still fails, and every one of these downloads is checked against a digest right afterwards. On other TLS backends the flag does nothing. gradle-compatibility.yml also still used plain `--retry 3`, which doesn't retry refused connections or TLS errors. #868 fixed that for ci.yml and composer-compatibility.yml but missed this file. Claude-Session: https://claude.ai/code/session_01LS9AJhpVngXZxng8TRA2Kd Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
bugbot run Generated by Claude Code |
utils::digest's production_digests_go_through_the_helpers fails on main: three Gradle/JVM files compute digests inline. That makes `coverage`, `test` and `test-release` red on every PR. #878 routes them through utils::digest. This is the same change, ported so this PR's CI is green. It becomes a no-op once #878 lands. Claude-Session: https://claude.ai/code/session_01LS9AJhpVngXZxng8TRA2Kd Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Generated by Claude Code |
|
This failure isn't from this PR. The steps this PR changes (Install Maven 3.9.16 and Install Gradle 8.14.3) both passed in that job, and the failure is a download from Maven Central made inside the test itself. The same test failed the same way earlier today on an unrelated PR (run 37350580840, Generated by Claude Code |
|
CI status on 4d8cad2: every red or cancelled job (17 of them, across CI, Composer, npm, pnpm and Gradle) has the same GitHub annotation: I re-ran the npm and pnpm workflows once already, and they lost their runners again. CI, Composer and Gradle (including the Windows legs this PR targets) need a re-run once runner capacity recovers. Nothing in the diff needs to change. Generated by Claude Code |
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 4d8cad2. Configure here.
|
Burn-down agent: labeled Ready for review at
Generated by Claude Code |
Problem
Windows legs fail at the download step, before any test runs. curl on the Windows runners uses schannel, and schannel refuses the TLS handshake when the CA's revocation (CRL/OCSP) server is unreachable:
Seen in the last 3 days (2026-10-03 to 10-05):
Each one turns the whole run red and needs the matrix re-run (Gradle ~40 legs, Composer 19). Most of the other red Gradle/Composer runs in this window were PR bugs that failed every leg, or registry blips inside the tests. Those aren't touched here.
Separately,
gradle-compatibility.ymlstill downloads Maven and Gradle with plain--retry 3. That doesn't retry a refused connection (exit 7) or a TLS error (exit 35). #868 fixed this inci.ymlandcomposer-compatibility.ymlbut missed this file, and the failed Install Gradle step above made exactly one attempt.Root cause
schannel treats "revocation server unreachable" as a hard failure. The outage is on the CA's side, not the download host's, and can outlast curl's retry backoff (~31 s with
--retry 5). So--retry-all-errorsalone (#868) doesn't reliably cover it.Fix
Add
--ssl-revoke-best-effortto every download that runs on Windows legs and is checked against a digest:e2e(sha512/sha256).sha256sum(pinned + published sha256)The flag only skips the revocation check when the revocation server is unreachable. A certificate that is actually revoked still fails, and each body is checked against a digest right after. On other TLS backends (OpenSSL on Linux, macOS) curl accepts the flag and ignores it.
gradle-compatibility.yml:
--retry 3→--retry 5 --retry-all-errors, the same as Retry Composer/Maven/Gradle downloads on connect and TLS errors #868 and ci.yml's copy of these two steps.Proof
--ssl-revoke-best-efforton Linux/OpenSSL (the flag dates from curl 7.70; the runners ship 8.x). I can't reproduce a schannel revocation outage from Linux. The flag's documented purpose is exactly this error.actionlint1.7.7 gives the same 9 findings before and after, all from the existing YAML anchors.python3 -B -m unittest discover -s scripts/tests→ 254 tests OK (it includes the parser for ci.yml's vlt rows).Also in this PR: 4d8cad2 ports #878's fix, which routes the Gradle/JVM digests through
utils::digest.maincurrently failsproduction_digests_go_through_the_helpers, which makescoverage/test/test-releasered on every PR. The port becomes a no-op once #878 lands.Where tests run
No test, job, matrix leg or check name changes. Only the flags on 11 download commands change.
🤖 Generated with Claude Code
https://claude.ai/code/session_01LS9AJhpVngXZxng8TRA2Kd
Note
Low Risk
Workflow-only curl flags and a behavior-preserving digest refactor; no runtime security weakening beyond skipping unreachable revocation checks on Windows CI downloads that remain hash-verified.
Overview
CI downloads on Windows were failing before tests ran when schannel could not reach the CA revocation server (
CRYPT_E_REVOCATION_OFFLINE). Every digest-verifiedcurlinci.yml,composer-compatibility.yml, andgradle-compatibility.ymlnow passes--ssl-revoke-best-effort, which only relaxes the check when revocation is unreachable; revoked certs still fail and post-download hash checks are unchanged. On non-Windows runners the flag is ignored.gradle-compatibility.ymlMaven/Gradle installs are aligned with the other workflows:--retry 3becomes--retry 5 --retry-all-errorsso TLS and connection errors are retried like in #868.Gradle/JVM patching routes SHA-1/SHA-256 hex output through
crate::utils::digestingradle_cache,jvm_jar, and Maven sidecar code instead of ad hocsha1/sha2+hex::encode, matching the production-digest helper policy (ported from #878).Reviewed by Cursor Bugbot for commit 4d8cad2. Configure here.
Generated by Claude Code