Skip to content

Commit

Permalink
Merge pull request #683 from sigstore/signature-extension
Browse files Browse the repository at this point in the history
make signature extension .sigstore.json
  • Loading branch information
loosebazooka authored May 2, 2024
2 parents b5d777b + ab69961 commit 02ca8e7
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import org.gradle.api.provider.Property
import org.gradle.api.publish.Publication
import org.gradle.api.publish.PublicationArtifact
import org.gradle.api.publish.internal.PublicationInternal
import org.gradle.api.publish.maven.MavenArtifact
import org.gradle.api.publish.maven.internal.artifact.AbstractMavenArtifact
import org.gradle.api.publish.maven.internal.artifact.DerivedMavenArtifact
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.named
import org.gradle.kotlin.dsl.register
Expand Down Expand Up @@ -88,28 +91,34 @@ abstract class SigstoreSignExtension(private val project: Project) {
val artifacts = mutableMapOf<PublicationArtifact, T>()
publication.allPublishableArtifacts {
val publishableArtifact = this
if (file.extension !in listOf("asc", SigstoreSignature.EXTENSION)) {
if (!file.name.endsWith(".asc") && !file.name.endsWith(SigstoreSignature.DOT_EXTENSION)) {
val signatureLocation =
signatureDirectory.map { it.file(file.name + "." + SigstoreSignature.EXTENSION) }
signatureDirectory.map { it.file(file.name + SigstoreSignature.DOT_EXTENSION) }
signTask.configure {
sign(publishableArtifact.file, builtBy = publishableArtifact)
.outputSignature.set(signatureLocation)
}
artifacts[publishableArtifact] = publication.addDerivedArtifact(
publishableArtifact,
DefaultDerivedArtifactFile(project.tasks.named<DefaultTask>(signTask.name), signatureLocation)
).apply { builtBy(signTask) }
val dervied = DefaultDerivedArtifactFile(project.tasks.named<DefaultTask>(signTask.name), signatureLocation)
artifacts[publishableArtifact] = publication.addDerivedArtifact(publishableArtifact, dervied).apply {
builtBy(signTask)
// TODO: workaround for https://github.com/gradle/gradle/issues/28969
// TODO: Behavior is undefined for non-maven artifacts.
if (publishableArtifact is AbstractMavenArtifact) {
(this as DerivedMavenArtifact).setExtension((publishableArtifact as AbstractMavenArtifact).extension + SigstoreSignature.DOT_EXTENSION)
}
}
// Gradle's signing plugin reacts on adding artifacts, and it might add .asc signature
// So we need to remove .sigstore.asc as it is unwanted in most of the cases
// So we need to remove .sigstore.json.asc as it is unwanted in most of the cases
if (removeSigstoreAsc) {
project.tasks.withType<Sign>()
.matching { it.name.contains(publicationName, ignoreCase = true) }
.configureEach {
// Remove .sigstore.asc signature.
// Remove .sigstore.json.asc signature.
// Unfortunately, it will scan all the signatures every time,
// however, it seems to be the only way to do it since the artifacts can be added
// within afterEvaluate block, so we can't use afterEvaluate
// to "remove all .sigstore.asc" at once
// to "remove all .sigstore.json.asc" at once
signatures.removeIf { it.name.endsWith(SigstoreSignature.DOT_EXTENSION + ".asc") }
signatures.removeIf { it.name.endsWith(".sigstore.asc") }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import javax.inject.Inject

abstract class SigstoreSignature @Inject constructor(private val name: String) : Named {
companion object {
const val EXTENSION = "sigstore"
const val EXTENSION = "sigstore.json"
const val DOT_EXTENSION = ".$EXTENSION";
}

// Gradle 6.8.3: Cannot have abstract method SigstoreSignature.getName
Expand Down Expand Up @@ -73,7 +74,7 @@ abstract class SigstoreSignature @Inject constructor(private val name: String) :

init {
outputSignature.convention(
signatureDirectory.map { it.file(file.singleFile.name + ".$EXTENSION") }
signatureDirectory.map { it.file(file.singleFile.name + DOT_EXTENSION) }
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.*
import org.gradle.jvm.toolchain.JavaLauncher
import org.gradle.jvm.toolchain.JavaToolchainService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ class PluginSmokeTest : BaseGradleTest() {
project {
apply(plugin = "dev.sigstore.sign-base")
val hello by tasks.registering(WriteProperties::class) {
outputFile = layout.buildDirectory.file("props/$name.properties").get().asFile
destinationFile = layout.buildDirectory.file("props/$name.properties")
property("hello", "world")
}

// It should be eagerly created to access signOutput
val signFile by tasks.registering(SigstoreSignFilesTask::class) {
signFile(hello.map { it.outputFile })
signFile(hello.map { it.destinationFile.asFile.get() })
}

Assertions.assertThat(signFile.flatMap { it.singleSignature() }.get().asFile)
.hasFileName("hello.properties.sigstore")
.hasFileName("hello.properties.sigstore.json")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class SigstoreSignTest: BaseGradleTest() {
}
def signFile = tasks.register("signFile", SigstoreSignFilesTask) {
signFile(helloProps.map { it.outputFile })
.outputSignature.set(file("build/helloProps.txt.sigstore"))
.outputSignature.set(file("build/helloProps.txt.sigstore.json"))
}
""".trimIndent()
)
Expand All @@ -57,7 +57,7 @@ class SigstoreSignTest: BaseGradleTest() {
enableConfigurationCache(case.gradle)
prepare(case.gradle.version, "signFile", "-s")
.build()
assertThat(projectDir.resolve("build/helloProps.txt.sigstore"))
assertThat(projectDir.resolve("build/helloProps.txt.sigstore.json"))
.content()
.basicSigstoreStructure()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,11 @@ package dev.sigstore.gradle
import dev.sigstore.testkit.BaseGradleTest
import dev.sigstore.testkit.TestedGradle
import dev.sigstore.testkit.TestedGradleAndSigstoreJava
import dev.sigstore.testkit.TestedSigstoreJava
import dev.sigstore.testkit.annotations.EnabledIfOidcExists
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.SoftAssertions
import org.gradle.util.GradleVersion
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.Arguments.arguments
import org.junit.jupiter.params.provider.MethodSource

@EnabledIfOidcExists
Expand Down Expand Up @@ -89,8 +86,8 @@ class RemoveSigstoreAscTest : BaseGradleTest() {
projectDir.resolve("gradle.properties").toFile().appendText(
"""
# By default, dev.sigstore.sign asks Gradle to avoid signing .sigstore as .sigstore.asc
# This is an opt-out hatch for those who need .sigstore.asc
# By default, dev.sigstore.sign asks Gradle to avoid signing .sigstore.json as
# .sigstore.json.asc This is an opt-out hatch for those who need .sigstore.json.asc
dev.sigstore.sign.remove.sigstore.asc=false
""".trimIndent()
)
Expand Down Expand Up @@ -153,7 +150,7 @@ class RemoveSigstoreAscTest : BaseGradleTest() {
}

private fun SoftAssertions.assertSignatures(name: String, expectSigstoreAsc: Boolean = false) {
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/$name.sigstore"))
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/$name.sigstore.json"))
.describedAs("$name should be signed with Sigstore")
.content()
.basicSigstoreStructure()
Expand All @@ -163,14 +160,14 @@ class RemoveSigstoreAscTest : BaseGradleTest() {
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/$name.asc.sigstore"))
.describedAs("$name.asc should NOT be signed with Sigstore")
.doesNotExist()
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/$name.sigstore.asc"))
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/$name.sigstore.json.asc"))
.apply {
if (expectSigstoreAsc) {
describedAs("$name.sigstore should be signed with PGP")
describedAs("$name.sigstore.json should be signed with PGP")
exists()
} else {
// We don't want to sign .sigstore files with PGP
describedAs("$name.sigstore should NOT be signed with PGP")
// We don't want to sign .sigstore.json files with PGP
describedAs("$name.sigstore.json should NOT be signed with PGP")
doesNotExist()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
package dev.sigstore.gradle

import dev.sigstore.testkit.BaseGradleTest
import dev.sigstore.testkit.TestedGradle
import dev.sigstore.testkit.TestedGradleAndSigstoreJava
import dev.sigstore.testkit.TestedSigstoreJava
import dev.sigstore.testkit.annotations.EnabledIfOidcExists
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.params.ParameterizedTest
Expand Down Expand Up @@ -70,16 +68,16 @@ class SigstorePublishSignTest : BaseGradleTest() {
prepare(case.gradle.version, "publishAllPublicationsToTmpRepository", "-s")
.build()

assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/sigstore-test-1.0.pom.sigstore"))
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/sigstore-test-1.0.pom.sigstore.json"))
.content()
.basicSigstoreStructure()
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/sigstore-test-1.0.jar.sigstore"))
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/sigstore-test-1.0.jar.sigstore.json"))
.content()
.basicSigstoreStructure()
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/sigstore-test-1.0-sources.jar.sigstore"))
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/sigstore-test-1.0-sources.jar.sigstore.json"))
.content()
.basicSigstoreStructure()
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/sigstore-test-1.0.module.sigstore"))
assertThat(projectDir.resolve("build/tmp-repo/dev/sigstore/test/sigstore-test/1.0/sigstore-test-1.0.module.sigstore.json"))
.content()
.basicSigstoreStructure()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ open class BaseGradleTest {
ON, OFF
}

// to debug these tests, add .withDebug(true) before running a test in debug mode
protected val gradleRunner = GradleRunner.create().withPluginClasspath()

companion object {
Expand Down

0 comments on commit 02ca8e7

Please sign in to comment.