From ce18899902fea7520d727b5c61fd4f6afafa028a Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 15:33:35 +0000 Subject: [PATCH 1/2] Publish SBOM + build provenance and enable reproducible, GPG-signed releases - Add CycloneDX SBOM generation (JSON+XML) to core/processor release profile and attach SBOMs to the GitHub release. - Add a build-provenance attestation step for the published jars. - Enable reproducible builds via project.build.outputTimestamp. - Document supply-chain artifacts in RELEASE.md. Refs java-helpers/simple-builders#158 Co-Authored-By: Andreas Igel --- .github/workflows/maven-central-release.yml | 23 ++++++++++++++++++- RELEASE.md | 18 +++++++++++---- core/pom.xml | 25 +++++++++++++++++++++ processor/pom.xml | 25 +++++++++++++++++++++ 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/.github/workflows/maven-central-release.yml b/.github/workflows/maven-central-release.yml index 83285e49..4e264803 100644 --- a/.github/workflows/maven-central-release.yml +++ b/.github/workflows/maven-central-release.yml @@ -19,6 +19,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + # Required to create build-provenance attestations for the released jars. + id-token: write + attestations: write steps: - name: Checkout code @@ -91,6 +94,12 @@ jobs: env: MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_SIGNING_KEY_PASSWORD }} run: mvn -B clean verify -Prelease + + - name: Generate SBOM (CycloneDX) + run: | + # Emit a CycloneDX SBOM (JSON + XML) for each published module. + mvn -B -Prelease -pl core,processor \ + org.cyclonedx:cyclonedx-maven-plugin:makeBom -DskipTests - name: Deploy to Maven Central env: @@ -99,6 +108,14 @@ jobs: MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_SIGNING_KEY_PASSWORD }} run: | mvn -B deploy -Prelease -pl core,processor -DskipTests=true -Dcentral.autoPublish=true + + - name: Attest build provenance for published jars + if: success() + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 + with: + subject-path: | + core/target/simple-builders-core-*.jar + processor/target/simple-builders-processor-*.jar - name: Push changes to repository if: success() @@ -151,9 +168,13 @@ jobs: core/target/simple-builders-core-${VERSION}.jar \ core/target/simple-builders-core-${VERSION}-sources.jar \ core/target/simple-builders-core-${VERSION}-javadoc.jar \ + core/target/simple-builders-core-${VERSION}-sbom.json \ + core/target/simple-builders-core-${VERSION}-sbom.xml \ processor/target/simple-builders-processor-${VERSION}.jar \ processor/target/simple-builders-processor-${VERSION}-sources.jar \ - processor/target/simple-builders-processor-${VERSION}-javadoc.jar + processor/target/simple-builders-processor-${VERSION}-javadoc.jar \ + processor/target/simple-builders-processor-${VERSION}-sbom.json \ + processor/target/simple-builders-processor-${VERSION}-sbom.xml # Clean up rm -f release_notes.md diff --git a/RELEASE.md b/RELEASE.md index db326d03..c6b14531 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -19,11 +19,13 @@ Configure these GitHub secrets in **Settings** → **Secrets and variables** → 1. Updates POM versions to release version 2. Commits changes and creates tag `v0.2.0` -3. Builds and verifies project with `-Prelease` +3. Builds and verifies project with `-Prelease` (reproducible builds via `project.build.outputTimestamp`) 4. Signs artifacts with GPG -5. Deploys and **auto-publishes** to Maven Central -6. Pushes commit and tag to `main` -7. Creates **draft** GitHub release (requires manual publish) +5. Generates a CycloneDX **SBOM** (JSON + XML) for each published module +6. Deploys and **auto-publishes** to Maven Central +7. Creates a **build-provenance attestation** for the published jars +8. Pushes commit and tag to `main` +9. Creates **draft** GitHub release (jars, sources, javadoc **and SBOMs** attached; requires manual publish) ## After Release @@ -60,6 +62,14 @@ mvn clean deploy -Prelease -Dcentral.autoPublish=true - **Version conflicts**: Maven Central versions are immutable; increment and re-release - **Workflow fails on push**: Ensure GitHub Actions has write permissions (**Settings** → **Actions** → **General** → **Workflow permissions**) +## Supply-chain artifacts + +Each release produces, in addition to the GPG-signed jars: + +- **SBOM** (CycloneDX `*-sbom.json` / `*-sbom.xml`) per module, attached to the GitHub release, so consumers can inventory/scan transitive dependencies. +- **Build provenance** attestation (`actions/attest-build-provenance`) for the jars, verifiable with `gh attestation verify --repo java-helpers/simple-builders`. +- **Reproducible builds**: `project.build.outputTimestamp` is set so archive entries are deterministic. For a meaningful per-release timestamp, override it with `-Dproject.build.outputTimestamp=`. + ## Notes - Project uses [Semantic Versioning](https://semver.org/) (MAJOR.MINOR.PATCH) diff --git a/core/pom.xml b/core/pom.xml index 787dee7c..d287e136 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -54,6 +54,9 @@ UTF-8 + + 2025-01-01T00:00:00Z 17 @@ -70,6 +73,7 @@ 0.10.0 + 2.9.1 2.29 3.15.0 3.4.0 @@ -169,6 +173,27 @@ ${central.autoPublish} + + + org.cyclonedx + cyclonedx-maven-plugin + ${plugin.cyclonedx.version} + + + generate-sbom + package + + makeBom + + + + + ${project.artifactId}-${project.version}-sbom + all + library + false + + org.apache.maven.plugins maven-source-plugin diff --git a/processor/pom.xml b/processor/pom.xml index c0597d5d..d18aab9a 100644 --- a/processor/pom.xml +++ b/processor/pom.xml @@ -51,6 +51,9 @@ UTF-8 + + 2025-01-01T00:00:00Z 1.1.1 @@ -72,6 +75,7 @@ 0.10.0 + 2.9.1 3.15.0 3.4.0 3.12.0 @@ -251,6 +255,27 @@ ${central.autoPublish} + + + org.cyclonedx + cyclonedx-maven-plugin + ${plugin.cyclonedx.version} + + + generate-sbom + package + + makeBom + + + + + ${project.artifactId}-${project.version}-sbom + all + library + false + + org.apache.maven.plugins maven-source-plugin From a54b68aa45bff421aead4fdbda5149a904d2c685 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 22:59:40 +0000 Subject: [PATCH 2/2] docs/build: clarify attestation usage, derive SBOM name, auto-update reproducible timestamp Co-Authored-By: Andreas Igel --- .github/workflows/maven-central-release.yml | 14 +++++++++++++- RELEASE.md | 2 +- core/pom.xml | 7 ++++--- processor/pom.xml | 7 ++++--- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.github/workflows/maven-central-release.yml b/.github/workflows/maven-central-release.yml index af0a337b..429e916a 100644 --- a/.github/workflows/maven-central-release.yml +++ b/.github/workflows/maven-central-release.yml @@ -73,6 +73,14 @@ jobs: # Update module POMs mvn versions:set -DnewVersion=$VERSION -DgenerateBackupPoms=false -pl core mvn versions:set -DnewVersion=$VERSION -DgenerateBackupPoms=false -pl processor + + - name: Update reproducible build timestamp + run: | + VERSION=${{ steps.version.outputs.VERSION }} + TIMESTAMP="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" + echo "Setting project.build.outputTimestamp to $TIMESTAMP for release $VERSION" + # Pin archive entry timestamps to the release moment for reproducible builds. + mvn versions:set-property -Dproperty=project.build.outputTimestamp -DnewVersion="$TIMESTAMP" -DgenerateBackupPoms=false -pl core,processor - name: Commit version changes id: commit @@ -136,9 +144,13 @@ jobs: # to Maven Central without human approval. mvn -B deploy -Prelease -pl core,processor -Dcentral.autoPublish=false + # Generates a signed build-provenance attestation for the released JARs. This is + # GitHub's official attestation action; the resulting SLSA attestation is stored in + # the repository's Attestations page and can be verified by consumers with: + # gh attestation verify --repo java-helpers/simple-builders - name: Attest build provenance for published jars if: success() - uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 (GitHub official) with: subject-path: | core/target/simple-builders-core-*.jar diff --git a/RELEASE.md b/RELEASE.md index 749ad75a..8c5ecd27 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -69,7 +69,7 @@ Each release produces, in addition to the GPG-signed jars: - **SBOM** (CycloneDX `*-sbom.json` / `*-sbom.xml`) per module, attached to the GitHub release, so consumers can inventory/scan transitive dependencies. - **Build provenance** attestation (`actions/attest-build-provenance`) for the jars, verifiable with `gh attestation verify --repo java-helpers/simple-builders`. -- **Reproducible builds**: `project.build.outputTimestamp` is set so archive entries are deterministic. For a meaningful per-release timestamp, override it with `-Dproject.build.outputTimestamp=`. +- **Reproducible builds**: `project.build.outputTimestamp` is set so archive entries are deterministic. The release workflow updates it automatically; it can be overridden per build with `-Dproject.build.outputTimestamp=`. ## Notes diff --git a/core/pom.xml b/core/pom.xml index 6eb89426..532d0d47 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -54,8 +54,8 @@ UTF-8 - + 2025-01-01T00:00:00Z @@ -188,7 +188,8 @@ - ${project.artifactId}-${project.version}-sbom + + ${project.build.finalName}-sbom all library false diff --git a/processor/pom.xml b/processor/pom.xml index e844270f..8a5af0ca 100644 --- a/processor/pom.xml +++ b/processor/pom.xml @@ -51,8 +51,8 @@ UTF-8 - + 2025-01-01T00:00:00Z @@ -270,7 +270,8 @@ - ${project.artifactId}-${project.version}-sbom + + ${project.build.finalName}-sbom all library false