Skip to content

CI: retry sbt runs that failed on a dependency download, cache the pinned snapshots - #112

Closed
MateuszKubuszok wants to merge 1 commit into
masterfrom
ci-download-retry
Closed

MateuszKubuszok wants to merge 1 commit into
masterfrom
ci-download-retry

Conversation

@MateuszKubuszok

Copy link
Copy Markdown
Member

Cause

Coursier does not retry a download that is cut off partway (download error: Caught java.io.IOException (Premature EOF)). Between 2026-10-14 and 10-16, 5 ssg jobs failed this way on the 8 MB balticporter-engine_3 snapshot jar while the project definition loaded. Each of the ~20 jobs in a run downloads that jar fresh. In the same window, one generate job got 404s from repo1.maven.org for 18 poms that were published long ago, and one JVM job got a 502 while fetching the sbt launcher's jars. All 7 were download failures, not build failures, and a rerun passed.

Changes

  1. Retry on download failure. .github/scripts/sbt-download-retry.sh now runs every sbt command: sbt-guarded, the generator command in generated-port, format, compile, the tree-sitter update, the re-scale install and the release. A run is retried only when all of these hold: the command failed, its output matches Premature EOF|Error fetching artifacts|Error downloading|ResolveException|could not retrieve sbt, and no test ran and nothing was published. Before each retry it deletes coursier's .*.error files, then waits 20s, 60s and 120s, printing "dependency download failed, retrying (n/3)". When every retry fails it reports a download failure; sbt-guarded no longer reports it as a crashed test process. A real test failure is never retried.
  2. Cache only the hand-pinned snapshots. setup-scala caches only …/central.sonatype.com/repository/maven-snapshots under the Linux, macOS and Windows coursier caches. The key is per OS and hashes project/plugins.sbt and project/Versions.scala. That is about 15 MB per entry, well inside the quota that keeps the general dependency cache off.
  3. Codecov. The upload now runs on success() instead of always(), so a failed JVM job shows one error instead of two.
  4. Lint. actionlint 1.7.12 is clean on both workflows. actionlint does not read composite actions, so their run: blocks were checked with shellcheck.

How to verify

  • actionlint .github/workflows/*.yml and shellcheck .github/scripts/sbt-download-retry.sh.
  • The script was exercised locally on three cases: a download failure followed by a pass is retried once and exits 0; a download error together with a munit failure is not retried; a compile error is not retried.
  • In this PR's CI, the setup-scala step shows a coursier-snapshots-<OS>-… cache miss on the first run and a hit on later runs.
  • verifyLocal passed on this commit.

…nned snapshots

Coursier does not retry a download that is cut off partway ("download error: Caught
java.io.IOException (Premature EOF)"). Between 2026-10-14 and 10-16, 5 ssg jobs failed that way
on the 8 MB balticporter-engine_3 snapshot jar while the project definition loaded; each of the
~20 jobs of a run downloads it afresh. In the same window one generate job got 404s from
repo1.maven.org for 18 long-published poms and one JVM job a 502 fetching the sbt launcher's
jars. All 7 were download failures, not build or test failures; a rerun passed.

- every sbt run (sbt-guarded, the generator command, format, compile, the tree-sitter update,
  the re-scale install, the release) goes through .github/scripts/sbt-download-retry.sh: when the
  command failed, its output names a download failure and no test ran and nothing was published,
  it deletes coursier's recorded download errors and retries up to 3 times after 20s, 60s, 120s.
  sbt-guarded no longer reports such a run as a crashed test process.
- setup-scala caches only the hand-pinned snapshot repository directory, per OS, keyed on
  project/plugins.sbt and project/Versions.scala (about 15 MB per entry, inside the quota that
  keeps the general dependency cache off).
- the Codecov upload runs only when the tests passed, so a failed JVM job shows one error.
@codecov

codecov Bot commented Oct 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@MateuszKubuszok

Copy link
Copy Markdown
Member Author

Merged via signed rebase onto master as 5bd08f8 (GitHub's UI rebase drops commit signatures; this repo requires signed commits + linear history).

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