From 687cfbfe4c3dd5ce78a1797a7f07f2cf90bfdbfe Mon Sep 17 00:00:00 2001 From: Jeff Jensen Date: Mon, 22 Jun 2026 17:29:59 -0500 Subject: [PATCH 1/4] ci: Add Maven Central + GPG inputs to jdk-setup composite Extend the composite (previously JDK + cache only) with optional server-id, credential, and gpg inputs, matching the core and spring-boot copies, so the release workflow can sign and deploy through it. Backward compatible: callers without inputs still get the plain JDK setup. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_013DKrZ3wSe6H5HXPzg8iWC6 --- .github/actions/jdk-setup/action.yml | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.github/actions/jdk-setup/action.yml b/.github/actions/jdk-setup/action.yml index 90a8bdd..e81775f 100644 --- a/.github/actions/jdk-setup/action.yml +++ b/.github/actions/jdk-setup/action.yml @@ -1,11 +1,46 @@ name: "JDK Setup" description: "Set up Temurin JDK 21 with Maven dependency caching" +inputs: + server-id: + description: "Maven settings.xml server id for Maven Central authentication." + required: false + default: '' + server-username: + description: "Environment variable name for the Maven Central username." + required: false + default: '' + server-password: + description: "Environment variable name for the Maven Central password." + required: false + default: '' + gpg-private-key: + description: "GPG private key to import for artifact signing." + required: false + default: '' + gpg-passphrase: + description: "Environment variable name for the GPG passphrase." + required: false + default: '' runs: using: "composite" steps: - name: Set up JDK 21 + if: ${{ inputs.server-id == '' }} uses: actions/setup-java@v5 with: java-version: '21' distribution: 'temurin' cache: maven + + - name: Set up JDK 21 with Maven Central credentials + if: ${{ inputs.server-id != '' }} + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' + cache: maven + server-id: ${{ inputs.server-id }} + server-username: ${{ inputs.server-username }} + server-password: ${{ inputs.server-password }} + gpg-private-key: ${{ inputs.gpg-private-key }} + gpg-passphrase: ${{ inputs.gpg-passphrase }} From 61630d7ce298c923170cbb81ae1706fee02c80de Mon Sep 17 00:00:00 2001 From: Jeff Jensen Date: Mon, 22 Jun 2026 17:30:00 -0500 Subject: [PATCH 2/4] ci(release): Add tag-triggered Maven Central release workflow Commit release.yml so a pushed v* tag (created by release:prepare) deploys -Prelease (-N) to Maven Central. Use the jdk-setup composite and add the release-deploy concurrency group, the release environment approval gate, contents: read permissions, and checkout v7. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_013DKrZ3wSe6H5HXPzg8iWC6 --- .github/workflows/release.yml | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..597d6c4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,39 @@ +name: Release to Maven Central + +on: + push: + tags: ['v*'] # created by maven-release-plugin (tagNameFormat v@{project.version}) + +permissions: + contents: read + +concurrency: + group: release-deploy + cancel-in-progress: false + +env: + MAVEN_COMMAND: ./mvnw + MAVEN_CLI_COMMON: "-e -B -N" + +jobs: + release: + runs-on: ubuntu-latest + timeout-minutes: 30 + environment: release + steps: + - uses: actions/checkout@v7 + + - uses: ./.github/actions/jdk-setup + with: + server-id: central-publish + server-username: CENTRAL_USERNAME + server-password: CENTRAL_TOKEN + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg-passphrase: MAVEN_GPG_PASSPHRASE + + - name: Deploy release to Maven Central + env: + CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} + CENTRAL_TOKEN: ${{ secrets.CENTRAL_TOKEN }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + run: ${{ env.MAVEN_COMMAND }} ${{ env.MAVEN_CLI_COMMON }} deploy -Prelease -DskipTests From ef7752abeb39869b6195ef98da25de4875ec6974 Mon Sep 17 00:00:00 2001 From: Jeff Jensen Date: Mon, 22 Jun 2026 17:38:05 -0500 Subject: [PATCH 3/4] ci(release): Disable credential persistence on release checkout The release job only deploys (no git push-back), so the GITHUB_TOKEN that checkout persists in .git/config is unnecessary attack surface in a workflow handling GPG and Maven Central secrets. Set persist-credentials: false. Addresses the CodeRabbit/zizmor finding; SHA-pinning is deferred to a separate project-wide policy. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_013DKrZ3wSe6H5HXPzg8iWC6 --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 597d6c4..25a04bb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,6 +22,8 @@ jobs: environment: release steps: - uses: actions/checkout@v7 + with: + persist-credentials: false - uses: ./.github/actions/jdk-setup with: From fd719d63a79b486ea8bf6f1998c92ef16cfc2a20 Mon Sep 17 00:00:00 2001 From: Jeff Jensen Date: Mon, 22 Jun 2026 18:11:20 -0500 Subject: [PATCH 4/4] ci: Disable credential persistence on snapshot-deploy checkout deploy-snapshot also handles Maven Central credentials and never pushes back to git, so drop the persisted GITHUB_TOKEN. Same hardening as the release workflow. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_013DKrZ3wSe6H5HXPzg8iWC6 --- .github/workflows/deploy-snapshot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/deploy-snapshot.yml b/.github/workflows/deploy-snapshot.yml index b9fa935..e838470 100644 --- a/.github/workflows/deploy-snapshot.yml +++ b/.github/workflows/deploy-snapshot.yml @@ -17,6 +17,8 @@ jobs: timeout-minutes: 20 steps: - uses: actions/checkout@v7 + with: + persist-credentials: false - uses: actions/setup-java@v5 with: