From fadd3892db91f229e4516174b4147e495afd9cd6 Mon Sep 17 00:00:00 2001 From: Jeff Jensen Date: Sun, 28 Jun 2026 12:11:09 -0500 Subject: [PATCH] ci: Add Maven Central release workflow with GitHub Release Deploy on dbunit-* tags via the release profile, then publish a GitHub Release with auto-generated notes. Extend the jdk-setup action to supply Maven Central and GPG signing credentials. Resolve the version from the POM, fail unless the tag encodes exactly that version, and title the GitHub Release from the resolved version. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_0133BgD2ro4ZJh1TaXHrZSff --- .github/actions/jdk-setup/action.yml | 40 +++++++++++++- .github/workflows/release.yml | 83 ++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/actions/jdk-setup/action.yml b/.github/actions/jdk-setup/action.yml index 1201744..e81775f 100644 --- a/.github/actions/jdk-setup/action.yml +++ b/.github/actions/jdk-setup/action.yml @@ -1,10 +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 8 - uses: actions/setup-java@v4 + - 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 }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..7a45c23 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,83 @@ +name: Release to Maven Central + +on: + push: + tags: ['plugin-*'] # release tags are prefixed with "plugin-" + +permissions: + contents: read + +concurrency: + group: release-deploy + cancel-in-progress: false + +env: + MAVEN_COMMAND: ./mvnw + MAVEN_CLI_COMMON: "-e -B" + +jobs: + release: + runs-on: ubuntu-latest + timeout-minutes: 120 + environment: release + outputs: + version: ${{ steps.resolve.outputs.version }} + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + + - 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 + + # Guard against a mistyped tag releasing the wrong version: the POM is the + # source of truth for what gets deployed, so the tag must encode exactly that + # version. The resolved version also titles the GitHub Release below. + - name: Verify tag matches project version + id: resolve + env: + TAG: ${{ github.ref_name }} + run: | + version="$(${{ env.MAVEN_COMMAND }} help:evaluate -Dexpression=project.version -q -DforceStdout)" + expected="plugin-${version}" + if [ "$TAG" != "$expected" ]; then + echo "::error::Tag '$TAG' does not match project version (expected '$expected'). Refusing to release." + exit 1 + fi + echo "version=${version}" >> "$GITHUB_OUTPUT" + + # Tests already ran during release:prepare. + - 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 + + # Publish a GitHub Release for the tag once the Central deploy succeeds. Notes are + # auto-generated by the GitHub Release Notes API from merged PRs/commits since the + # previous tag. Isolated from the deploy job so contents:write is not granted while + # GPG keys and Central credentials are in scope. + github-release: + needs: release + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write # required to create the GitHub Release + steps: + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.ref_name }} # via env to avoid script injection + VERSION: ${{ needs.release.outputs.version }} + run: | + gh release create "$TAG" \ + --repo "${{ github.repository }}" \ + --title "$VERSION" \ + --generate-notes \ + --verify-tag