Skip to content

feat: Add download retry support to startup scripts - #2461

Merged
maxandersen merged 5 commits into
mainfrom
feature/download-retry-2459
May 22, 2026
Merged

feat: Add download retry support to startup scripts#2461
maxandersen merged 5 commits into
mainfrom
feature/download-retry-2459

Conversation

@maxandersen

@maxandersen maxandersen commented May 9, 2026

Copy link
Copy Markdown
Collaborator

Fixes #2459

Problem

A single transient network error during JDK or JBang bootstrap download fails the entire setup, which is particularly painful in CI environments.

Solution

Adds a JBANG_DOWNLOAD_RETRY environment variable (default: 5) that controls retry attempts for downloads across all platforms:

Platform Tool Retry mechanism
Linux/macOS (bash) curl --retry N --retry-delay 1
Linux/macOS (bash) wget --tries=N --waitretry=1
Windows (PowerShell) Invoke-WebRequest Invoke-Download retry loop with 1s backoff
Windows (CMD) delegates to PS1 Inherits PowerShell retry behavior

Usage

# Increase retries for flaky CI networks
export JBANG_DOWNLOAD_RETRY=10

# Disable retries
export JBANG_DOWNLOAD_RETRY=0

Changes

  • src/main/scripts/jbang — Added retry flags to curl and wget in the download() function
  • src/main/scripts/jbang.ps1 — Added Invoke-Download function with retry loop; replaced raw Invoke-WebRequest calls (PS5-compatible, no dependency on PS7's -MaximumRetryCount)
  • src/test/java/dev/jbang/cli/TestScriptRetry.java — 7 unit tests validating retry support in script contents
  • docs/modules/ROOT/pages/installation.adoc — New "Download Retries" section
  • docs/modules/ROOT/pages/troubleshooting.adoc — Updated "Network Issues" section

Summary by CodeRabbit

  • New Features

    • Startup scripts now support configurable download retries, retry delays, and customizable download URL via environment variables.
  • Documentation

    • Installation guide adds "Download Retries" and "Startup Script Environment Variables".
    • Troubleshooting updated to cover transient download failures and retry guidance.
  • Tests

    • New functional tests verify startup-script retry behavior against flaky download scenarios.

Review Change Stack

@maxandersen maxandersen changed the title Add download retry support to startup scripts feat: Add download retry support to startup scripts May 9, 2026
@maxandersen

Copy link
Copy Markdown
Collaborator Author

the tests are bogus - not testing it works; just testing the scripts has retry logic.

@maxandersen
maxandersen force-pushed the feature/download-retry-2459 branch 3 times, most recently from 5e3e390 to 703aa12 Compare May 9, 2026 13:10
@maxandersen

Copy link
Copy Markdown
Collaborator Author

updated tests to be "real" via wiremock test that fails so can see retry work.

@maxandersen
maxandersen force-pushed the feature/download-retry-2459 branch 4 times, most recently from c90402b to 95893e8 Compare May 9, 2026 13:43
Add JBANG_DOWNLOAD_RETRY env var (default: 5) to control retry attempts
for JDK and JBang bootstrap downloads across all platforms:

- bash: curl gets --retry/--retry-delay, wget gets --tries/--waitretry
- PowerShell: new Invoke-Download function with retry loop and backoff
- CMD: inherits PowerShell behavior (delegates downloads to jbang.ps1)

Also adds:
- JBANG_DOWNLOAD_RETRY_DELAY env var (default: 1s) for retry backoff
- JBANG_DOWNLOAD_URL env var to override the JBang download URL
  (useful for corporate mirrors and testing)
@maxandersen
maxandersen force-pushed the feature/download-retry-2459 branch from 95893e8 to 60a1226 Compare May 9, 2026 13:46
@maxandersen
maxandersen marked this pull request as ready for review May 9, 2026 13:48
@maxandersen

Copy link
Copy Markdown
Collaborator Author

ok, now tests are real, use progressive backoff by default, env vars added for user and test control + documented the various env vars.

@quintesse wdyt? and should all those vars be treated equally supported ? :)

@quintesse

Copy link
Copy Markdown
Contributor

wdyt?

LGTM 👍

and should all those vars be treated equally supported ? :)

Not sure what you mean by this?

@maxandersen

Copy link
Copy Markdown
Collaborator Author

wdyt?

LGTM 👍

and should all those vars be treated equally supported ? :)

Not sure what you mean by this?

Wether all the env vars in the script that this PR add should be considered all equally supported/stable.

@quintesse

Copy link
Copy Markdown
Contributor

Well I think most of them are okay. Perhaps the USE_NATIVE one because it's supposed to be for internal testing?

@maxandersen

Copy link
Copy Markdown
Collaborator Author

@quintesse any idea why powershell specifically would fail here ..just on java 11 ?

@quintesse

Copy link
Copy Markdown
Contributor

No idea really

@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 508d5a80-409c-4b26-8d9b-93f16f8a4cf0

📥 Commits

Reviewing files that changed from the base of the PR and between 94a04bb and a31ef50.

📒 Files selected for processing (1)
  • src/main/scripts/jbang.ps1
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/scripts/jbang.ps1

📝 Walkthrough

Walkthrough

Adds configurable download retry behavior to JBang startup scripts (Bash and PowerShell), exposes JBANG_DOWNLOAD_RETRY, JBANG_DOWNLOAD_RETRY_DELAY, and JBANG_DOWNLOAD_URL, updates download helpers to respect these, documents the variables, and adds integration tests simulating flaky HTTP endpoints to validate retry behavior.

Changes

Download Retry Feature

Layer / File(s) Summary
Documentation and env var reference
docs/modules/ROOT/pages/installation.adoc, docs/modules/ROOT/pages/troubleshooting.adoc
Adds "Download Retries" and "Startup Script Environment Variables" sections documenting JBANG_DOWNLOAD_RETRY, JBANG_DOWNLOAD_RETRY_DELAY, JBANG_DOWNLOAD_URL, defaults, and troubleshooting guidance for transient CI download failures.
Bash retry configuration and download helper
src/main/scripts/jbang
Reads JBANG_DOWNLOAD_RETRY/JBANG_DOWNLOAD_RETRY_DELAY into downloadRetry/downloadRetryDelay; updates download() to add curl --retry/--retry-delay and conditional wget --waitretry behavior; supports JBANG_DOWNLOAD_URL override for distribution downloads.
PowerShell retry configuration and download helper
src/main/scripts/jbang.ps1
Adds Invoke-Download helper using env:JBANG_DOWNLOAD_RETRY/env:JBANG_DOWNLOAD_RETRY_DELAY, applies fixed delay or exponential backoff, uses it for JBang zip and JDK bootstrap downloads, and supports JBANG_DOWNLOAD_URL; note a default-delay variable appears misassigned in the new code.
Integration tests and test infrastructure
src/test/java/dev/jbang/cli/TestScriptRetry.java
Adds WireMock-driven integration tests exercising the real jbang and jbang.ps1 scripts against flaky endpoints, with helpers for stubbing, process execution, concurrent IO capture, timeouts, and assertions for success-after-retries, retries-exhausted failure, and zero-retry failure.

Sequence Diagram(s)

sequenceDiagram
  participant StartupScript as Startup Script (Bash/PowerShell)
  participant DownloadHelper as download()/Invoke-Download
  participant Remote as HTTP Endpoint
  StartupScript->>DownloadHelper: request URL (JBANG_DOWNLOAD_URL or computed)
  loop attempts up to JBANG_DOWNLOAD_RETRY
    DownloadHelper->>Remote: HTTP GET
    alt success (200)
      Remote-->>DownloadHelper: payload (archive)
      DownloadHelper-->>StartupScript: success (save/archive)
    else error (5xx/timeout)
      Remote-->>DownloadHelper: error
      DownloadHelper->>DownloadHelper: wait (fixed or backoff via JBANG_DOWNLOAD_RETRY_DELAY)
    end
  end
  alt exhausted without success
    DownloadHelper-->>StartupScript: failure (exit 1)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~35 minutes

A rabbit hops through scripts with glee, 🐰
Retry logic sings, "Try again," said she,
Transient fails bounce back to green,
WireMock and scripts in a debugging scene,
Bash and PowerShell nibble success unseen.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the primary change: adding download retry support to startup scripts, which is the core objective of the PR.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #2459: adds configurable retry support via JBANG_DOWNLOAD_RETRY across curl, wget, and PowerShell for JDK and JBang bootstrap downloads.
Out of Scope Changes check ✅ Passed All changes are in scope: retry logic in startup scripts, comprehensive documentation of new environment variables, troubleshooting updates, and thorough test coverage via WireMock.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/download-retry-2459

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/scripts/jbang.ps1`:
- Around line 67-89: The Invoke-Download retry loop currently uses "$attempt -ge
$downloadRetry" which makes only $downloadRetry total attempts; change the
termination check so the function allows the initial attempt plus $downloadRetry
retries (i.e. fail only when $attempt -gt ($downloadRetry + 1) or otherwise
compare against $downloadRetry + 1) to match curl's semantics; update any
retry-progress text (the Console::Error message) to reflect the total attempts
as $downloadRetry + 1 if present.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 52da3b3a-b28b-4c25-a7d1-ed69fccd9271

📥 Commits

Reviewing files that changed from the base of the PR and between 9927a54 and 60a1226.

📒 Files selected for processing (5)
  • docs/modules/ROOT/pages/installation.adoc
  • docs/modules/ROOT/pages/troubleshooting.adoc
  • src/main/scripts/jbang
  • src/main/scripts/jbang.ps1
  • src/test/java/dev/jbang/cli/TestScriptRetry.java

Comment thread src/main/scripts/jbang.ps1
@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • src/main/scripts/jbang.ps1

Commit: 94a04bbb1f56e600d95651d2c75bef0db115abff

The changes have been pushed to the feature/download-retry-2459 branch.

Time taken: 2m 5s

coderabbitai Bot and others added 2 commits May 14, 2026 22:26
Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
PowerShell's 'break' outside a loop/switch terminates the script but
always exits with code 0. This meant download failures were silently
swallowed — the error message was printed to stderr but the process
reported success.

Replace 'break' with 'exit 1' in the two download error paths (JBang
archive and JDK archive) so callers and CI can detect the failure.

Also remove the stale $err reference that was left over after the
Invoke-WebRequest→Invoke-Download refactor (the variable was never set
by Invoke-Download, so it always printed an empty line).
@maxandersen

Copy link
Copy Markdown
Collaborator Author

CI failure analysis & fix

The failures are not Java 11-specific — unit tests only run on Java 11 in the CI matrix, so that's the only place they surface. The same tests would fail on any Java version.

Two bugs found and fixed

Bug 1: break exits with code 0 (fixed in 46bbafd)

The PowerShell script uses break to bail out on download failures. However, break outside of a loop/switch terminates the script with exit code 0 — so download failures were silently reported as success. The two failing tests (downloadFailsWhenRetriesExhausted and downloadFailsWithZeroRetries) correctly expected a non-zero exit code but the script never provided one.

Fix: Replaced break with exit 1 in the two download error paths (JBang archive and JDK archive).

Bug 2: stale $err variable (fixed in same commit)

The old code captured the exception into $err via catch { $ok=$false; $err=$_ }. After the refactor to Invoke-Download, the $err variable is never set, so the line [Console]::Error.WriteLine($err) printed nothing useful. Removed the stale reference.

@maxandersen

Copy link
Copy Markdown
Collaborator Author

llms to the rescue again - dumb logic error :) tests passes. lets merge and things should hopefully still work :)

@maxandersen
maxandersen merged commit 1a6383b into main May 22, 2026
5 checks passed
@maxandersen
maxandersen deleted the feature/download-retry-2459 branch May 22, 2026 05:38
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.

Set retry options for curl in the JBang startup scripts

2 participants