diff --git a/.github/workflows/RELEASE.md b/.github/workflows/RELEASE.md new file mode 100644 index 00000000..02927346 --- /dev/null +++ b/.github/workflows/RELEASE.md @@ -0,0 +1,18 @@ +# Release workflow + +`release.yml` publishes to Maven Central (Sonatype Central Portal) via the `central` Maven profile. It runs on a published GitHub Release or a manual `workflow_dispatch`; it doesn't create releases. + +## Flow +1. Cut a GitHub Release (or dispatch the workflow, which won't create a github release). +2. A maintainer approves the `maven-central` environment prompt. +3. The job builds, signs, and uploads to the Portal, where it's staged. +4. Someone with publish access in the Sonatype Portal (org membership on the `com.sap.hcp.cf.logging` namespace) publishes in the Portal to release to Central. This could be automated if deemed useful (https://central.sonatype.org/publish/publish-portal-maven/#autopublish). + +## Secrets +Kept on the `maven-central` GitHub Environment, not repo or org secrets. This is essential for security, if you ever need to set this up yourself (https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments): + +- `MAVEN_CENTRAL_USERNAME` / `MAVEN_CENTRAL_PASSWORD` +- `MAVEN_GPG_PRIVATE_KEY` +- `MAVEN_GPG_PASSPHRASE` + +They only inject after the environment rules pass: review, and allowed refs limited to `main`. Other runs are not able to retrieve the credentials. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..afeb172c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +name: Release to Maven Central + +# Publishes to Maven Central (Sonatype Central Portal) via the `central` profile +# in pom.xml. Uses signing/publishing secrets; see RELEASE.md before +# changing triggers, permissions or the environment. + +on: + release: + types: [published] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: release-maven-central + cancel-in-progress: false + +jobs: + publish: + runs-on: ubuntu-latest + timeout-minutes: 30 + environment: maven-central # secrets live here, gated by required reviewers + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false + + - name: Set up JDK, Maven settings, GPG + uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 # v4.9.1 + with: + distribution: temurin + java-version: '17' + server-id: central + # username/password/passphrase are env-var NAMES: setup-java writes them + # into settings.xml and Maven resolves them from env at runtime (never on disk). + # gpg-private-key is the actual key value: setup-java imports it here. + server-username: MAVEN_CENTRAL_USERNAME + server-password: MAVEN_CENTRAL_PASSWORD + gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} + gpg-passphrase: MAVEN_GPG_PASSPHRASE + + - name: Deploy (uploads and stages; Publish is a manual click in the Portal) + run: mvn -B -ntp -P central deploy + env: + MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}