Skip to content

Commit 1f37320

Browse files
authored
Migrate from services.gradle.org to downloads.gradle.org (#6823)
* Migrate from services.gradle.org to downloads.gradle.org services.gradle.org now returns 301 redirects to downloads.gradle.org. Update all distribution and version API URLs to use the new canonical domain directly, avoiding unnecessary redirect hops. The old services.gradle.org domain is still accepted in existing wrapper properties files for backward compatibility. * Restore explicit Lombok annotations * Keep Gradle versions API URL on services.gradle.org The /versions/all endpoint does not exist on downloads.gradle.org (returns 404), so GRADLE_VERSIONS_ALL_URL must remain on services.gradle.org while distribution URLs use downloads.gradle.org. * Rewrite services.gradle.org URLs from versions API to downloads.gradle.org The /versions/all API on services.gradle.org returns download URLs using the services.gradle.org domain. These URLs need to be rewritten to downloads.gradle.org to match the migration. * No need to deprecate services URL just yet
1 parent 886de26 commit 1f37320

11 files changed

Lines changed: 95 additions & 93 deletions

File tree

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
3+
distributionUrl=https\://downloads.gradle.org/distributions/gradle-9.3.1-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

rewrite-core/src/test/resources/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
distributionBase=GRADLE_USER_HOME
1818
distributionPath=wrapper/dists
19-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
19+
distributionUrl=https\://downloads.gradle.org/distributions/gradle-7.6.1-bin.zip
2020
networkTimeout=10000
2121
zipStoreBase=GRADLE_USER_HOME
2222
zipStorePath=wrapper/dists

rewrite-gradle-tooling-model/model/src/test/java/org/openrewrite/gradle/toolingapi/AssertionsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void customInitScript() {
9393
}
9494
9595
""";
96-
GradleWrapper gradleWrapper = GradleWrapper.create(URI.create("https://services.gradle.org/distributions/gradle-8.6-bin.zip"), null);
96+
GradleWrapper gradleWrapper = GradleWrapper.create(URI.create("https://downloads.gradle.org/distributions/gradle-8.6-bin.zip"), null);
9797
rewriteRun(
9898
spec -> spec.beforeRecipe(Assertions.withToolingApi(gradleWrapper, alternateInit)),
9999
//language=groovy

rewrite-gradle/src/main/java/org/openrewrite/gradle/UpdateGradleWrapper.java

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,31 +46,28 @@
4646
import static org.openrewrite.gradle.util.GradleWrapper.*;
4747
import static org.openrewrite.internal.StringUtils.isBlank;
4848

49+
@Getter
4950
@RequiredArgsConstructor
50-
@FieldDefaults(level = AccessLevel.PRIVATE)
51+
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
5152
@EqualsAndHashCode(callSuper = false)
5253
public class UpdateGradleWrapper extends ScanningRecipe<UpdateGradleWrapper.GradleWrapperState> {
5354

54-
@Getter
55-
final String displayName = "Update Gradle wrapper";
55+
String displayName = "Update Gradle wrapper";
5656

57-
@Getter
58-
final String description = "Update the version of Gradle used in an existing Gradle wrapper. " +
59-
"Queries services.gradle.org to determine the available releases, but prefers the artifact repository URL " +
57+
String description = "Update the version of Gradle used in an existing Gradle wrapper. " +
58+
"Queries `downloads.gradle.org` to determine the available releases, but prefers the artifact repository URL " +
6059
"which already exists within the wrapper properties file. " +
61-
"If your artifact repository does not contain the same Gradle distributions as services.gradle.org, " +
60+
"If your artifact repository does not contain the same Gradle distributions as `downloads.gradle.org`, " +
6261
"then the recipe may suggest a version which is not available in your artifact repository.";
6362

64-
@Getter
6563
@Option(displayName = "New version",
6664
description = "An exact version number or node-style semver selector used to select the version number. " +
67-
"Defaults to the latest release available from services.gradle.org if not specified.",
65+
"Defaults to the latest release available from `downloads.gradle.org` if not specified.",
6866
example = "7.x",
6967
required = false)
7068
@Nullable
71-
final String version;
69+
String version;
7270

73-
@Getter
7471
@Option(displayName = "Distribution type",
7572
description = "The distribution of Gradle to use. \"bin\" includes Gradle binaries. " +
7673
"\"all\" includes Gradle binaries, source code, and documentation. " +
@@ -79,17 +76,15 @@ public class UpdateGradleWrapper extends ScanningRecipe<UpdateGradleWrapper.Grad
7976
required = false
8077
)
8178
@Nullable
82-
final String distribution;
79+
String distribution;
8380

84-
@Getter
8581
@Option(displayName = "Add if missing",
8682
description = "Add a Gradle wrapper, if it's missing. Defaults to `true`.",
8783
required = false)
8884
@Nullable
89-
final Boolean addIfMissing;
85+
Boolean addIfMissing;
9086

91-
@Getter
92-
@Option(example = "https://services.gradle.org/distributions/gradle-8.5-bin.zip",
87+
@Option(example = "https://downloads.gradle.org/distributions/gradle-8.5-bin.zip",
9388
displayName = "Wrapper URI",
9489
description = "The URI of the Gradle wrapper distribution.\n" +
9590
"Specifies a custom location from which to download the Gradle wrapper scripts (gradlew, gradlew.bat, etc.). This is useful for setting up the Gradle wrapper without relying on Gradle's official distribution services.\n\n" +
@@ -98,16 +93,15 @@ public class UpdateGradleWrapper extends ScanningRecipe<UpdateGradleWrapper.Grad
9893
"If the URI is inaccessible, the recipe will leave the existing wrapper files in the repository unchanged, as they are generally compatible with various Gradle versions.",
9994
required = false)
10095
@Nullable
101-
final String wrapperUri;
96+
String wrapperUri;
10297

103-
@Getter
10498
@Option(example = "29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda",
10599
displayName = "SHA-256 checksum",
106100
description = "The SHA-256 checksum of the Gradle distribution. " +
107101
"If specified, the recipe will add the checksum along with the custom distribution URL.",
108102
required = false)
109103
@Nullable
110-
final String distributionChecksum;
104+
String distributionChecksum;
111105

112106
@Override
113107
public String getInstanceNameSuffix() {
@@ -202,7 +196,7 @@ public Properties visitEntry(Properties.Entry entry, ExecutionContext ctx) {
202196
return entry;
203197
}
204198

205-
// Typical example: https://services.gradle.org/distributions/gradle-7.4-all.zip or https://company.com/repo/gradle-8.2-bin.zip
199+
// Typical example: https://downloads.gradle.org/distributions/gradle-7.4-all.zip or https://company.com/repo/gradle-8.2-bin.zip
206200
String currentDistributionUrl = entry.getValue().getText();
207201
acc.currentDistributionUrl = currentDistributionUrl;
208202

rewrite-gradle/src/main/java/org/openrewrite/gradle/util/GradleWrapper.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@
5151

5252
@Value
5353
public class GradleWrapper {
54+
private static final String GRADLE_DOWNLOADS_URL = "https://downloads.gradle.org";
55+
private static final String GRADLE_DISTRIBUTIONS_URL = GRADLE_DOWNLOADS_URL + "/distributions";
5456
private static final String GRADLE_SERVICES_URL = "https://services.gradle.org";
55-
private static final String GRADLE_DISTRIBUTIONS_URL = GRADLE_SERVICES_URL + "/distributions";
5657
private static final String GRADLE_VERSIONS_ALL_URL = GRADLE_SERVICES_URL + "/versions/all";
5758
public static final String WRAPPER_JAR_LOCATION_RELATIVE_PATH = "gradle/wrapper/gradle-wrapper.jar";
5859
public static final String WRAPPER_PROPERTIES_LOCATION_RELATIVE_PATH = "gradle/wrapper/gradle-wrapper.properties";
@@ -69,7 +70,7 @@ public class GradleWrapper {
6970

7071
/**
7172
* Construct a Gradle wrapper from a distribution type and version.
72-
* Used in contexts where services.gradle.org is available.
73+
* Used in contexts where downloads.gradle.org is available.
7374
*/
7475
public static GradleWrapper create(@Nullable String distributionTypeName, @Nullable String version, ExecutionContext ctx) {
7576
return create(null, distributionTypeName, version, ctx);
@@ -96,15 +97,15 @@ public static GradleWrapper create(@Nullable String currentDistributionUrl, @Nul
9697

9798
private static GradleVersion determineGradleVersion(@Nullable String currentDistributionUrl, @Nullable String version, VersionComparator versionComparator,
9899
DistributionType distributionType, ExecutionContext ctx) {
99-
if (currentDistributionUrl == null || currentDistributionUrl.startsWith(GRADLE_SERVICES_URL)) {
100+
if (currentDistributionUrl == null || currentDistributionUrl.startsWith(GRADLE_DOWNLOADS_URL) || currentDistributionUrl.startsWith(GRADLE_SERVICES_URL)) {
100101
// Only list all versions via services endpoint if a wildcard notation was requested or null, e.g. 8.x
101102
if (!(versionComparator instanceof ExactVersion)) {
102103
List<GradleVersion> allVersions = listAllPublicVersions(ctx);
103104
return allVersions.stream()
104105
.filter(v -> versionComparator.isValid(null, v.version))
105106
.filter(v -> v.distributionType == distributionType)
106107
.max((v1, v2) -> versionComparator.compare(null, v1.version, v2.version))
107-
.orElseThrow(() -> new IllegalStateException(String.format("Expected to find at least one Gradle wrapper version to select from %s.", GRADLE_SERVICES_URL)));
108+
.orElseThrow(() -> new IllegalStateException(String.format("Expected to find at least one Gradle wrapper version to select from %s.", GRADLE_DOWNLOADS_URL)));
108109
}
109110

110111
return new GradleVersion(version,
@@ -150,19 +151,22 @@ public static List<GradleVersion> listAllPublicVersions(ExecutionContext ctx) {
150151
});
151152
List<GradleVersion> allGradleVersions = new ArrayList<>(gradleVersions.size() * 2);
152153
for (GradleVersion gradleVersion : gradleVersions) {
154+
String downloadUrl = migrateToDownloadsUrl(gradleVersion.downloadUrl);
155+
String checksumUrl = migrateToDownloadsUrl(gradleVersion.checksumUrl);
156+
String wrapperChecksumUrl = migrateToDownloadsUrl(gradleVersion.wrapperChecksumUrl);
153157
allGradleVersions.add(new GradleVersion(
154158
gradleVersion.version,
155-
gradleVersion.downloadUrl,
159+
downloadUrl,
156160
DistributionType.Bin,
157-
gradleVersion.checksumUrl,
158-
gradleVersion.wrapperChecksumUrl
161+
checksumUrl,
162+
wrapperChecksumUrl
159163
));
160164
allGradleVersions.add(new GradleVersion(
161165
gradleVersion.version,
162-
gradleVersion.downloadUrl.replace("-bin.zip", "-all.zip"),
166+
downloadUrl.replace("-bin.zip", "-all.zip"),
163167
DistributionType.All,
164-
gradleVersion.checksumUrl == null ? null : gradleVersion.checksumUrl.replace("-bin.zip", "-all.zip"),
165-
gradleVersion.wrapperChecksumUrl
168+
checksumUrl == null ? null : checksumUrl.replace("-bin.zip", "-all.zip"),
169+
wrapperChecksumUrl
166170
));
167171
}
168172
return allGradleVersions;
@@ -200,11 +204,15 @@ private static List<GradleVersion> listAllPrivateArtifactoryVersions(String arti
200204
}
201205
}
202206

207+
private static @Nullable String migrateToDownloadsUrl(@Nullable String url) {
208+
return url == null ? null : url.replace(GRADLE_SERVICES_URL, GRADLE_DOWNLOADS_URL);
209+
}
210+
203211
private static final Pattern GRADLE_VERSION_PATTERN = Pattern.compile("gradle-([0-9.]+)");
204212

205213
/**
206214
* Construct a Gradle wrapper from a URI.
207-
* Can be used in contexts where services.gradle.org, normally used for version lookups, is unavailable.
215+
* Can be used in contexts where downloads.gradle.org, normally used for version lookups, is unavailable.
208216
*/
209217
public static GradleWrapper create(URI fullDistributionUri, @SuppressWarnings("unused") ExecutionContext ctx) {
210218
String version = "";

rewrite-gradle/src/main/resources/META-INF/rewrite/examples.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -715,13 +715,13 @@ examples:
715715
- before: |
716716
distributionBase=GRADLE_USER_HOME
717717
distributionPath=wrapper/dists
718-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
718+
distributionUrl=https\://downloads.gradle.org/distributions/gradle-7.4-bin.zip
719719
zipStoreBase=GRADLE_USER_HOME
720720
zipStorePath=wrapper/dists
721721
after: |
722722
distributionBase=GRADLE_USER_HOME
723723
distributionPath=wrapper/dists
724-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
724+
distributionUrl=https\://downloads.gradle.org/distributions/gradle-7.4.2-bin.zip
725725
zipStoreBase=GRADLE_USER_HOME
726726
zipStorePath=wrapper/dists
727727
distributionSha256Sum=29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda
@@ -1281,13 +1281,13 @@ examples:
12811281
- before: |
12821282
distributionBase=GRADLE_USER_HOME
12831283
distributionPath=wrapper/dists
1284-
distributionUrl=https\\://services.gradle.org/distributions/gradle-7.4-all.zip
1284+
distributionUrl=https\\://downloads.gradle.org/distributions/gradle-7.4-all.zip
12851285
zipStoreBase=GRADLE_USER_HOME
12861286
zipStorePath=wrapper/dists
12871287
after: |
12881288
distributionBase=GRADLE_USER_HOME
12891289
distributionPath=wrapper/dists
1290-
~~>distributionUrl=https\\://services.gradle.org/distributions/gradle-7.4-all.zip
1290+
~~>distributionUrl=https\\://downloads.gradle.org/distributions/gradle-7.4-all.zip
12911291
zipStoreBase=GRADLE_USER_HOME
12921292
zipStorePath=wrapper/dists
12931293
path: gradle/wrapper/gradle-wrapper.properties

rewrite-gradle/src/main/resources/META-INF/rewrite/recipes.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ The recipe will:
3434
* Preserve project dependencies unchanged
3535
3636
**Note:** If a version catalog already exists, the recipe will not modify it.",1,,Gradle,,
37-
maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.UpdateGradleWrapper,Update Gradle wrapper,"Update the version of Gradle used in an existing Gradle wrapper. Queries services.gradle.org to determine the available releases, but prefers the artifact repository URL which already exists within the wrapper properties file. If your artifact repository does not contain the same Gradle distributions as services.gradle.org, then the recipe may suggest a version which is not available in your artifact repository.",1,,Gradle,"[{""name"":""version"",""type"":""String"",""displayName"":""New version"",""description"":""An exact version number or node-style semver selector used to select the version number. Defaults to the latest release available from services.gradle.org if not specified."",""example"":""7.x""},{""name"":""distribution"",""type"":""String"",""displayName"":""Distribution type"",""description"":""The distribution of Gradle to use. \""bin\"" includes Gradle binaries. \""all\"" includes Gradle binaries, source code, and documentation. Defaults to \""bin\""."",""valid"":[""bin"",""all""]},{""name"":""addIfMissing"",""type"":""Boolean"",""displayName"":""Add if missing"",""description"":""Add a Gradle wrapper, if it's missing. Defaults to `true`.""},{""name"":""wrapperUri"",""type"":""String"",""displayName"":""Wrapper URI"",""description"":""The URI of the Gradle wrapper distribution.\nSpecifies a custom location from which to download the Gradle wrapper scripts (gradlew, gradlew.bat, etc.). This is useful for setting up the Gradle wrapper without relying on Gradle's official distribution services.\n\nWhen this option is set, the version and distribution fields must not be specified — only one source of truth is allowed. The URI should point to a valid and reachable Gradle wrapper distribution (typically a .zip archive containing the wrapper files).\nThis is particularly helpful in environments where access to Gradle's central services is restricted or where custom Gradle wrapper setups are required.\nIf the URI is inaccessible, the recipe will leave the existing wrapper files in the repository unchanged, as they are generally compatible with various Gradle versions."",""example"":""https://services.gradle.org/distributions/gradle-8.5-bin.zip""},{""name"":""distributionChecksum"",""type"":""String"",""displayName"":""SHA-256 checksum"",""description"":""The SHA-256 checksum of the Gradle distribution. If specified, the recipe will add the checksum along with the custom distribution URL."",""example"":""29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda""}]",
37+
maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.UpdateGradleWrapper,Update Gradle wrapper,"Update the version of Gradle used in an existing Gradle wrapper. Queries downloads.gradle.org to determine the available releases, but prefers the artifact repository URL which already exists within the wrapper properties file. If your artifact repository does not contain the same Gradle distributions as downloads.gradle.org, then the recipe may suggest a version which is not available in your artifact repository.",1,,Gradle,"[{""name"":""version"",""type"":""String"",""displayName"":""New version"",""description"":""An exact version number or node-style semver selector used to select the version number. Defaults to the latest release available from downloads.gradle.org if not specified."",""example"":""7.x""},{""name"":""distribution"",""type"":""String"",""displayName"":""Distribution type"",""description"":""The distribution of Gradle to use. \""bin\"" includes Gradle binaries. \""all\"" includes Gradle binaries, source code, and documentation. Defaults to \""bin\""."",""valid"":[""bin"",""all""]},{""name"":""addIfMissing"",""type"":""Boolean"",""displayName"":""Add if missing"",""description"":""Add a Gradle wrapper, if it's missing. Defaults to `true`.""},{""name"":""wrapperUri"",""type"":""String"",""displayName"":""Wrapper URI"",""description"":""The URI of the Gradle wrapper distribution.\nSpecifies a custom location from which to download the Gradle wrapper scripts (gradlew, gradlew.bat, etc.). This is useful for setting up the Gradle wrapper without relying on Gradle's official distribution services.\n\nWhen this option is set, the version and distribution fields must not be specified — only one source of truth is allowed. The URI should point to a valid and reachable Gradle wrapper distribution (typically a .zip archive containing the wrapper files).\nThis is particularly helpful in environments where access to Gradle's central services is restricted or where custom Gradle wrapper setups are required.\nIf the URI is inaccessible, the recipe will leave the existing wrapper files in the repository unchanged, as they are generally compatible with various Gradle versions."",""example"":""https://downloads.gradle.org/distributions/gradle-8.5-bin.zip""},{""name"":""distributionChecksum"",""type"":""String"",""displayName"":""SHA-256 checksum"",""description"":""The SHA-256 checksum of the Gradle distribution. If specified, the recipe will add the checksum along with the custom distribution URL."",""example"":""29e49b10984e585d8118b7d0bc452f944e386458df27371b49b4ac1dec4b7fda""}]",
3838
maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.UpgradeDependencyVersion,Upgrade Gradle dependency versions,"Upgrade the version of a dependency in a build.gradle file. Supports updating dependency declarations of various forms:
3939
* `String` notation: `""group:artifact:version""`
4040
* `Map` notation: `group: 'group', name: 'artifact', version: 'version'`

0 commit comments

Comments
 (0)