diff --git a/.github/workflows/java-build-for-release.yml b/.github/workflows/java-release.yml similarity index 61% rename from .github/workflows/java-build-for-release.yml rename to .github/workflows/java-release.yml index 1310a4e0..9eeaa228 100644 --- a/.github/workflows/java-build-for-release.yml +++ b/.github/workflows/java-release.yml @@ -22,13 +22,11 @@ jobs: build: runs-on: ubuntu-latest needs: [ci, strip-tag] - outputs: - hashes: ${{ steps.hash.outputs.hashes }} + permissions: + id-token: write # to sign with sigstore steps: - name: checkout tag - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - with: - ref: "${{ github.ref }}" + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Set up JDK 11 uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 @@ -37,23 +35,16 @@ jobs: distribution: 'temurin' - name: Build project + working-directory: ./java run: | # override the version in gradle.properties - cd java - ./gradlew clean createReleaseBundle -Pversion=${{ needs.strip-tag.outputs.version }} - - - name: Hash Artifacts - id: hash - run: | - cd java/build/release - echo "hashes=$(sha256sum ./* | base64 -w0)" >> $GITHUB_OUTPUT - sha256sum ./* - + # we have to do some post processing with pgp signatures, cause those secrets aren't online yet + ./gradlew clean createReleaseBundle -Pversion=${{ needs.strip-tag.outputs.version }} -Prelease -PskipPgpSigning - name: Upload build artifacts uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: project-release-artifacts - path: ./java/build/release/ + path: ./java/build/libs/protobuf-specs-*-bundle.jar if-no-files-found: error create-release: @@ -67,23 +58,9 @@ jobs: with: name: project-release-artifacts path: ./release/ - - name: Create draft release + - name: Create release uses: softprops/action-gh-release@69320dbe05506a9a39fc8ae11030b214ec2d1f87 # v2.0.5 with: name: ${{ github.ref_name }} tag_name: ${{ github.ref_name }} files: ./release/* - prerelease: true - - provenance: - needs: [build, strip-tag, create-release] - permissions: - actions: read # To read the workflow path. - id-token: write # To sign the provenance. - contents: write - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 - with: - attestation-name: "protobuf-specs-${{ needs.strip-tag.outputs.version }}.attestation.intoto.jsonl" - upload-assets: true - base64-subjects: "${{ needs.build.outputs.hashes }}" - upload-tag-name: "${{ github.ref_name }}" # Upload to tag rather than generate a new release diff --git a/java/build.gradle.kts b/java/build.gradle.kts index cd473ce3..71bae2d1 100644 --- a/java/build.gradle.kts +++ b/java/build.gradle.kts @@ -1,29 +1,23 @@ -import org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication - plugins { `java-library` `maven-publish` - id("com.google.protobuf") version "0.9.4" + id("dev.sigstore.sign") version "0.8.0" id("com.diffplug.spotless") version "6.25.0" + `signing` } -description = "Code generated library for the Sigstore bundle format protobufs" - -sourceSets { - main { - proto { - srcDir("../protos/") - } - } -} +description = "Sigstore protobuf spec protos bundled into a jar" repositories { mavenCentral() } -dependencies { - implementation("com.google.protobuf:protobuf-java:4.26.1") - implementation("com.google.api.grpc:proto-google-common-protos:2.37.1") +sourceSets { + main { + resources { + srcDirs("../protos") + } + } } // gradle reproducible jar builds @@ -37,12 +31,6 @@ java { withSourcesJar() } -protobuf { - protoc { - artifact = "com.google.protobuf:protoc:4.26.1" - } -} - spotless { kotlinGradle { target("*.gradle.kts") // default target for kotlinGradle @@ -62,19 +50,11 @@ val repoUrl = "https://github.com/sigstore/protobuf-specs" publishing { publications { - create("mavenJava") { + create("proto") { artifactId = project.name from(components["java"]) - versionMapping { - usage(Usage.JAVA_RUNTIME) { - fromResolutionResult() - } - usage(Usage.JAVA_API) { - fromResolutionOf("runtimeClasspath") - } - } pom { name.set( (project.findProperty("artifact.name") as? String) @@ -114,20 +94,48 @@ publishing { } } } + repositories { + maven { + name = "releaseStaging" + url = uri(layout.buildDirectory.dir("releaseStaging")) + } + } } -// this task should be used by github actions to create release artifacts along with a slsa -// attestation. -tasks.register("createReleaseBundle") { - val releaseDir = layout.buildDirectory.dir("release") - outputs.dir(releaseDir) - dependsOn((publishing.publications["mavenJava"] as DefaultMavenPublication).publishableArtifacts) - doLast { - project.copy { - from((publishing.publications["mavenJava"] as DefaultMavenPublication).publishableArtifacts.files) - into(releaseDir) - rename("pom-default.xml", "${project.name}-${project.version}.pom") - rename("module.json", "${project.name}-${project.version}.module") - } +tasks.register("createReleaseBundle") { + dependsOn("publishProtoPublicationToReleaseStagingRepository") + from(layout.buildDirectory.dir("releaseStaging/dev/sigstore/protobuf-specs/$version")) { + include("*.jar") + include("*.pom") + include("*.module") + include("*.sigstore") + include("*.sigstore.json") + include("*.asc") + } + archiveFileName = "${project.name}-${project.version}-bundle.jar" +} + +signing { + val signingKey: String? by project + val signingPassword: String? by project + useInMemoryPgpKeys(signingKey, signingPassword) + sign(publishing.publications["proto"]) +} + +tasks.withType().configureEach { + onlyIf("Is a release") { + project.hasProperty("release") + } + onlyIf("PGP Signing is not skipped") { + !project.hasProperty("skipPgpSigning") + } +} + +tasks.withType().configureEach { + onlyIf("Is a release") { + project.hasProperty("release") + } + onlyIf("Sigstore Signing is not skipped") { + !project.hasProperty("skipSigstoreSigning") } } diff --git a/java/scripts/sign_and_bundle_release.sh b/java/scripts/sign_and_bundle_release.sh index 110d1cc8..1bb0c8e9 100755 --- a/java/scripts/sign_and_bundle_release.sh +++ b/java/scripts/sign_and_bundle_release.sh @@ -62,20 +62,18 @@ main() { done cd "$RELEASE_DIR" - # cosign sign all the files - echo "Signing with cosign" - for file in *; do - # skip intoto attestations, they are already signed - if [[ "$file" == *.intoto.jsonl ]] ; then - continue; - fi - COSIGN_EXPERIMENTAL=1 cosign sign-blob --yes "$file" --output-signature="$file.sig" --output-certificate="$file.pem" --bundle "$file.bundle" - done + jar -xf *.jar + rm protobuf-specs-*-bundle.jar + rm META-INF/MANIFEST.MF + rmdir META-INF # then gpg sign all the files (including sigstore files) # this command uses gpgs default password acceptance mechansim accept a passcode echo "Signing with gpg" for file in *; do + if [[ $file == *.sigstore.json ]]; then + continue; + fi gpg --batch --detach-sign --armor -o "$file.asc" "$file" done