From 295f13b944be7ddcd4207cf5561482f24de3e746 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 13 Nov 2019 16:28:39 +0100 Subject: [PATCH] Add a system property to disable publishing of SHA-256 This commit adds an internal system property which can be used as a workaround whenever the remote repository doesn't accept SHA-256 and SHA-512 checksums. Gradle is fail-safe when it cannot upload those files, however, in some situations, the remote repository may not allow promoting the release if it finds such files. This is the case in older repositories, or currently with Maven Central. To disable publication of both SHA-256 and SHA-512 checksums, either: - add `-Dorg.gradle.internal.publish.checksums.insecure` to the CLI or - add `org.gradle.internal.publish.checksums.insecure=true` to your `gradle.properties` file Fixes #11308 --- .../resolver/ExternalResourceResolver.java | 11 +++++-- subprojects/docs/src/docs/release/notes.md | 5 ++++ .../test/fixtures/ivy/IvyFileModule.groovy | 18 +++++++++++- .../gradle/test/fixtures/ivy/IvyModule.java | 4 +++ .../server/http/DelegatingIvyModule.java | 12 ++++++++ .../ivy/IvyPublishHttpIntegTest.groovy | 29 ++++++++++++++----- .../maven/MavenPublishHttpIntegTest.groovy | 23 ++++++++++----- .../publisher/AbstractMavenPublisher.java | 9 ++++-- 8 files changed, 91 insertions(+), 20 deletions(-) diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/repositories/resolver/ExternalResourceResolver.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/repositories/resolver/ExternalResourceResolver.java index 940a7c78982a..df8ffe2c174c 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/repositories/resolver/ExternalResourceResolver.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/repositories/resolver/ExternalResourceResolver.java @@ -319,8 +319,10 @@ private void put(File src, ExternalResourceName destination) { private void publishChecksums(ExternalResourceName destination, File content) { publishChecksum(destination, content, "sha1", 40); - publishPossiblyUnsupportedChecksum(destination, content, "sha-256", 64); - publishPossiblyUnsupportedChecksum(destination, content, "sha-512", 128); + if (!ExternalResourceResolver.disableExtraChecksums()) { + publishPossiblyUnsupportedChecksum(destination, content, "sha-256", 64); + publishPossiblyUnsupportedChecksum(destination, content, "sha-512", 128); + } } private void publishPossiblyUnsupportedChecksum(ExternalResourceName destination, File content, String algorithm, int length) { @@ -584,4 +586,9 @@ public void listed(List versions) { result.listed(versions); } } + + public static boolean disableExtraChecksums() { + return Boolean.getBoolean("org.gradle.internal.publish.checksums.insecure"); + } + } diff --git a/subprojects/docs/src/docs/release/notes.md b/subprojects/docs/src/docs/release/notes.md index c3ccddf42034..b11b9b09ff23 100644 --- a/subprojects/docs/src/docs/release/notes.md +++ b/subprojects/docs/src/docs/release/notes.md @@ -276,6 +276,11 @@ Publication of SHA256 and SHA512 files is _not_ supported by the deprecated `mav In addition, the Gradle Module Metadata file also includes SHA256 and SHA512 checksums on referenced artifacts. +Since 6.0.1, if your external repository doesn't support SHA256 and/or SHA512 checksums, it is possible to disable upload of those checksums: + +- add `-Dorg.gradle.internal.publish.checksums.insecure` to the CLI or +- add `org.gradle.internal.publish.checksums.insecure=true` to your `gradle.properties` file + ### Support for in-memory signing with subkeys Gradle now supports [in-memory signing](userguide/signing_plugin.html#sec:in-memory-keys) with subkeys. diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/ivy/IvyFileModule.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/ivy/IvyFileModule.groovy index a8858cedeab9..878fd0978381 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/ivy/IvyFileModule.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/ivy/IvyFileModule.groovy @@ -55,6 +55,7 @@ class IvyFileModule extends AbstractModule implements IvyModule { String status = "integration" MetadataPublish metadataPublish = MetadataPublish.ALL boolean writeGradleMetadataRedirection = false + private boolean withExtraChecksums = true int publishCount = 1 XmlTransformer transformer = new XmlTransformer() @@ -246,6 +247,18 @@ class IvyFileModule extends AbstractModule implements IvyModule { return this } + @Override + IvyModule withoutExtraChecksums() { + withExtraChecksums = false + this + } + + @Override + IvyModule withExtraChecksums() { + withExtraChecksums = true + this + } + IvyFileModule nonTransitive(String config) { configurations[config].transitive = false return this @@ -581,7 +594,10 @@ class IvyFileModule extends AbstractModule implements IvyModule { void assertArtifactsPublished(String... names) { def expectedArtifacts = [] as Set for (name in names) { - expectedArtifacts.addAll([name, "${name}.sha1", "${name}.sha256", "${name}.sha512"]) + expectedArtifacts.addAll([name, "${name}.sha1"]) + if (withExtraChecksums) { + expectedArtifacts.addAll(["${name}.sha256", "${name}.sha512"]) + } } List publishedArtifacts = moduleDir.list().sort() diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/ivy/IvyModule.java b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/ivy/IvyModule.java index a322b46e108f..60349071dda8 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/ivy/IvyModule.java +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/ivy/IvyModule.java @@ -59,6 +59,10 @@ public interface IvyModule extends Module { IvyModule withoutGradleMetadataRedirection(); + IvyModule withoutExtraChecksums(); + + IvyModule withExtraChecksums(); + /** * Attributes: * organisation diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/server/http/DelegatingIvyModule.java b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/server/http/DelegatingIvyModule.java index 361a3072af50..7763f44d2f94 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/server/http/DelegatingIvyModule.java +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/test/fixtures/server/http/DelegatingIvyModule.java @@ -134,6 +134,18 @@ public IvyModule withoutGradleMetadataRedirection() { return t(); } + @Override + public IvyModule withoutExtraChecksums() { + backingModule.withoutExtraChecksums(); + return t(); + } + + @Override + public IvyModule withExtraChecksums() { + backingModule.withExtraChecksums(); + return t(); + } + @Override public IvyModule withBranch(String branch) { backingModule.withBranch(branch); diff --git a/subprojects/ivy/src/integTest/groovy/org/gradle/api/publish/ivy/IvyPublishHttpIntegTest.groovy b/subprojects/ivy/src/integTest/groovy/org/gradle/api/publish/ivy/IvyPublishHttpIntegTest.groovy index f26c6ca5fd77..8d92cb440535 100644 --- a/subprojects/ivy/src/integTest/groovy/org/gradle/api/publish/ivy/IvyPublishHttpIntegTest.groovy +++ b/subprojects/ivy/src/integTest/groovy/org/gradle/api/publish/ivy/IvyPublishHttpIntegTest.groovy @@ -55,7 +55,8 @@ credentials { server.expectUserAgent(matchesNameAndVersion("Gradle", GradleVersion.current().getVersion())) } - def "can publish to unauthenticated HTTP repository"() { + @Unroll + def "can publish to unauthenticated HTTP repository (extra checksums = #extraChecksums)"() { given: server.start() settingsFile << 'rootProject.name = "publish"' @@ -78,19 +79,30 @@ credentials { } """ + if (!extraChecksums) { + executer.withArgument("-Dorg.gradle.internal.publish.checksums.insecure=true") + module.withoutExtraChecksums() + } + and: module.jar.expectPut() module.jar.sha1.expectPut() - module.jar.sha256.expectPut() - module.jar.sha512.expectPut() + if (extraChecksums) { + module.jar.sha256.expectPut() + module.jar.sha512.expectPut() + } module.ivy.expectPut(HttpStatus.ORDINAL_201_Created) module.ivy.sha1.expectPut(HttpStatus.ORDINAL_201_Created) - module.ivy.sha256.expectPut(HttpStatus.ORDINAL_201_Created) - module.ivy.sha512.expectPut(HttpStatus.ORDINAL_201_Created) + if (extraChecksums) { + module.ivy.sha256.expectPut(HttpStatus.ORDINAL_201_Created) + module.ivy.sha512.expectPut(HttpStatus.ORDINAL_201_Created) + } module.moduleMetadata.expectPut() module.moduleMetadata.sha1.expectPut() - module.moduleMetadata.sha256.expectPut() - module.moduleMetadata.sha512.expectPut() + if (extraChecksums) { + module.moduleMetadata.sha256.expectPut() + module.moduleMetadata.sha512.expectPut() + } when: succeeds 'publish' @@ -103,6 +115,9 @@ credentials { progressLogging.uploadProgressLogged(module.moduleMetadata.uri) progressLogging.uploadProgressLogged(module.ivy.uri) progressLogging.uploadProgressLogged(module.jar.uri) + + where: + extraChecksums << [true, false] } def "can publish to a repository even if it doesn't support sha256/sha512 signatures"() { diff --git a/subprojects/maven/src/integTest/groovy/org/gradle/api/publish/maven/MavenPublishHttpIntegTest.groovy b/subprojects/maven/src/integTest/groovy/org/gradle/api/publish/maven/MavenPublishHttpIntegTest.groovy index 4f4803b0900f..e94a05687db7 100644 --- a/subprojects/maven/src/integTest/groovy/org/gradle/api/publish/maven/MavenPublishHttpIntegTest.groovy +++ b/subprojects/maven/src/integTest/groovy/org/gradle/api/publish/maven/MavenPublishHttpIntegTest.groovy @@ -54,10 +54,16 @@ class MavenPublishHttpIntegTest extends AbstractMavenPublishIntegTest { settingsFile << 'rootProject.name = "publish"' } - def "can publish to an unauthenticated http repo"() { + @Unroll + def "can publish to an unauthenticated http repo (with extra checksums = #extraChecksums)"() { given: buildFile << publicationBuild(version, group, mavenRemoteRepo.uri) - expectModulePublish(module) + + if (!extraChecksums) { + executer.withArgument("-Dorg.gradle.internal.publish.checksums.insecure=true") + module.withoutExtraChecksums() + } + expectModulePublish(module, extraChecksums) when: succeeds 'publish' @@ -74,6 +80,9 @@ class MavenPublishHttpIntegTest extends AbstractMavenPublishIntegTest { module.rootMetaData.verifyChecksums() module.rootMetaData.versions == ["2"] module.moduleMetadata.verifyChecksums() + + where: + extraChecksums << [true, false] } def "can publish to a repository even if it doesn't support sha256/sha512 signatures"() { @@ -352,12 +361,12 @@ class MavenPublishHttpIntegTest extends AbstractMavenPublishIntegTest { """ } - private void expectModulePublish(MavenHttpModule module) { - module.artifact.expectPublish() + private void expectModulePublish(MavenHttpModule module, boolean extraChecksums = true) { + module.artifact.expectPublish(extraChecksums) module.rootMetaData.expectGetMissing() - module.rootMetaData.expectPublish() - module.pom.expectPublish() - module.moduleMetadata.expectPublish() + module.rootMetaData.expectPublish(extraChecksums) + module.pom.expectPublish(extraChecksums) + module.moduleMetadata.expectPublish(extraChecksums) } private void expectModulePublishViaRedirect(MavenHttpModule module, URI targetServerUri, HttpServer httpServer, PasswordCredentials credentials = null) { diff --git a/subprojects/maven/src/main/java/org/gradle/api/publish/maven/internal/publisher/AbstractMavenPublisher.java b/subprojects/maven/src/main/java/org/gradle/api/publish/maven/internal/publisher/AbstractMavenPublisher.java index 16e8ee7716d3..46d7dfc31339 100644 --- a/subprojects/maven/src/main/java/org/gradle/api/publish/maven/internal/publisher/AbstractMavenPublisher.java +++ b/subprojects/maven/src/main/java/org/gradle/api/publish/maven/internal/publisher/AbstractMavenPublisher.java @@ -21,6 +21,7 @@ import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer; import org.gradle.api.UncheckedIOException; +import org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver; import org.gradle.api.internal.artifacts.repositories.transport.NetworkOperationBackOffAndRetry; import org.gradle.api.publish.maven.MavenArtifact; import org.gradle.internal.Factory; @@ -257,9 +258,10 @@ void publish(ExternalResourceName externalResource, File content) { private void publishChecksums(ExternalResourceName destination, File content) { publishChecksum(destination, content, "sha1", 40); publishChecksum(destination, content, "md5", 32); - - publishPossiblyUnsupportedChecksum(destination, content, "sha-256", 64); - publishPossiblyUnsupportedChecksum(destination, content, "sha-512", 128); + if (!ExternalResourceResolver.disableExtraChecksums()) { + publishPossiblyUnsupportedChecksum(destination, content, "sha-256", 64); + publishPossiblyUnsupportedChecksum(destination, content, "sha-512", 128); + } } private void publishPossiblyUnsupportedChecksum(ExternalResourceName destination, File content, String algorithm, int length) { @@ -295,4 +297,5 @@ public String toString() { }); } } + }