Skip to content

PREQ-6264: Add Gradle wrapper download retries in config-gradle#288

Merged
tomverin merged 4 commits into
masterfrom
bugfix/tom/PREQ-6264-gradle-wrapper-retries
Jun 9, 2026
Merged

PREQ-6264: Add Gradle wrapper download retries in config-gradle#288
tomverin merged 4 commits into
masterfrom
bugfix/tom/PREQ-6264-gradle-wrapper-retries

Conversation

@tomverin

@tomverin tomverin commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add a Configure Gradle wrapper download resilience step to config-gradle that sets networkTimeout=60000, retries=3, and retryBackOffMs=1000 in gradle/wrapper/gradle-wrapper.properties at CI runtime
  • Mitigates flaky Gradle distribution downloads (e.g. services.gradle.org timeouts on sonar-scanner-engine) without requiring per-repo wrapper property changes

Jira: https://sonarsource.atlassian.net/browse/PREQ-6264

Related: Julien Henry reported Gradle download timeout in https://github.com/SonarSource/sonar-scanner-engine/actions/runs/27123611072/job/80050116778 — wrapper had retries=0 and networkTimeout=10000.

Test plan

  • CI passes on this PR
  • After release on @v1, verify sonar-scanner-engine Gradle build no longer flakes on distribution download

@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Jun 8, 2026

Copy link
Copy Markdown

PREQ-6264

Comment thread config-gradle/action.yml
Comment thread config-gradle/action.yml
Comment thread config-gradle/action.yml
@tomverin tomverin marked this pull request as ready for review June 9, 2026 07:35
@tomverin tomverin requested a review from a team as a code owner June 9, 2026 07:35
Copilot AI review requested due to automatic review settings June 9, 2026 07:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a CI-time hardening step to the config-gradle composite action to reduce flakiness when downloading the Gradle distribution via the wrapper, without requiring per-repo wrapper changes.

Changes:

  • Introduces a new “Configure Gradle wrapper download resilience” step that edits gradle/wrapper/gradle-wrapper.properties at runtime.
  • Ensures networkTimeout=60000, retries=3, and retryBackOffMs=1000 are present/updated when a wrapper properties file exists.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tomverin tomverin enabled auto-merge (squash) June 9, 2026 13:03
@sonarqubecloud

sonarqubecloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

@tomverin tomverin merged commit ef4be97 into master Jun 9, 2026
17 checks passed
@tomverin tomverin deleted the bugfix/tom/PREQ-6264-gradle-wrapper-retries branch June 9, 2026 13:05
@gitar-bot

gitar-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 3 resolved / 3 findings

Adds Gradle wrapper download resilience through increased timeouts and retries, resolving the potential for file corruption by ensuring a trailing newline is present before appending properties.

✅ 3 resolved
Edge Case: Appending wrapper prop without trailing newline corrupts file

📄 config-gradle/action.yml:153-160
In the new update_prop function, when a property key is not already present, it is appended with echo "${key}=${value}" >> "$WRAPPER_PROPS". If gradle-wrapper.properties does not end with a trailing newline (not guaranteed — files edited by some tools or generated without a final newline), the new line is concatenated onto the previous line. For example if the file's last line is distributionUrl=https://...gradle-8.5-bin.zip with no trailing newline, the result becomes distributionUrl=https://...gradle-8.5-bin.zipnetworkTimeout=60000, which corrupts the distributionUrl and breaks the Gradle wrapper entirely — the opposite of the intended resilience improvement.

Guard the append by ensuring the file ends with a newline first, e.g.:

else
  [[ -n "$(tail -c1 "$WRAPPER_PROPS")" ]] && echo >> "$WRAPPER_PROPS"
  echo "${key}=${value}" >> "$WRAPPER_PROPS"
fi

This appends a newline only when the file does not already end with one.

Bug: retries/retryBackOffMs are not recognized gradle-wrapper.properties keys

📄 config-gradle/action.yml:163-165
The new step writes networkTimeout, retries, and retryBackOffMs into gradle/wrapper/gradle-wrapper.properties. Only networkTimeout (Gradle 7.6+) is a wrapper property that Gradle actually reads. The Gradle wrapper's recognized keys are distributionBase, distributionPath, distributionUrl, distributionSha256Sum, zipStoreBase, zipStorePath, networkTimeout, and validateDistributionUrl. retries and retryBackOffMs do not appear to be honored by the wrapper's distribution download logic, so they would be silently ignored.

If that is the case, this PR's primary goal — adding download retries to mitigate flaky services.gradle.org downloads — would not be achieved; only the timeout bump from 10000ms to 60000ms would take effect. Please verify against the Gradle version in use that retries/retryBackOffMs are read by the wrapper. If they are not supported, retries should be implemented differently (e.g. wrapping the ./gradlew invocation with a retry loop, or pre-downloading/caching the distribution with retry), and the unsupported keys should be removed to avoid polluting the wrapper file and the cache key.

Edge Case: Mutating wrapper props before cache-key step silently shifts the cache key

📄 config-gradle/action.yml:142-156 📄 config-gradle/action.yml:178-191
This step rewrites gradle/wrapper/gradle-wrapper.properties, and the later 'Generate Gradle Cache Key' step (line 184) includes that same file in the md5 sum used for GRADLE_CACHE_KEY. Because the file is modified in place at CI runtime before the key is computed, the cache key now reflects the rewritten values rather than the repository's committed wrapper file. This is consistent across runs (so caching still works), but it means the key silently diverges from what a developer would compute locally from the checked-in file, and any future change to the injected values will invalidate all existing Gradle caches. Consider documenting this coupling, or computing the cache key from the original file contents before mutation.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

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.

3 participants