Merge pull request #30 from openjavaformat/upstream-prs-1707-1786 #4
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| # Tags only, and the tag is the version: the build reads it from GITHUB_REF_NAME, and jreleaserDeploy and | |
| # publishPlugins refuse anything that is not a clean X.Y.Z or X.Y.Z.N. | |
| # | |
| # Two deployments per tag, because a published groupId:artifactId:version can never gain files | |
| # afterwards: the jars go up as one, and every platform's native binary as another. Each is uploaded and | |
| # validated first, and the publish job publishes both only once both are in. A version whose native build | |
| # fails publishes nothing, and its deployments can be dropped in the Portal. | |
| # | |
| # Once Maven Central serves both, the Gradle plugins go to the Gradle Plugin Portal, signed with the same | |
| # release key. After publishing, a draft GitHub release on the tag collects the runnable jar, the Gradle | |
| # and IDE plugins and the native binaries. | |
| # | |
| # Needs six repository secrets: JRELEASER_MAVENCENTRAL_USERNAME and JRELEASER_MAVENCENTRAL_PASSWORD (the | |
| # Central Portal user token), JRELEASER_GPG_SECRET_KEY and JRELEASER_GPG_PASSPHRASE, and | |
| # GRADLE_PUBLISH_KEY and GRADLE_PUBLISH_SECRET (the Gradle Plugin Portal key). The draft release uses the | |
| # workflow's own GITHUB_TOKEN. | |
| on: | |
| push: | |
| tags: | |
| - '*' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| jars: | |
| name: jars | |
| runs-on: ubuntu-latest | |
| outputs: | |
| deployment-id: ${{ steps.deployment.outputs.id }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install JDK 21 | |
| uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| - name: Stage, sign and upload the jars | |
| run: ./gradlew jreleaserDeploy | |
| env: | |
| JRELEASER_DEPLOY_MAVEN_MAVENCENTRAL_SONATYPE_USERNAME: ${{ secrets.JRELEASER_MAVENCENTRAL_USERNAME }} | |
| JRELEASER_DEPLOY_MAVEN_MAVENCENTRAL_SONATYPE_PASSWORD: ${{ secrets.JRELEASER_MAVENCENTRAL_PASSWORD }} | |
| JRELEASER_GPG_SECRET_KEY: ${{ secrets.JRELEASER_GPG_SECRET_KEY }} | |
| JRELEASER_GPG_PASSPHRASE: ${{ secrets.JRELEASER_GPG_PASSPHRASE }} | |
| - name: Hand the deployment to the publish job | |
| id: deployment | |
| run: | | |
| id="$(sed -n 's/^deployMavenCentralSonatypeDeploymentId=//p' build/jreleaser/output.properties)" | |
| if [ -z "$id" ]; then | |
| echo "No deployment ID in build/jreleaser/output.properties" | |
| exit 1 | |
| fi | |
| echo "id=$id" >> "$GITHUB_OUTPUT" | |
| - name: Keep JReleaser's log | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: jreleaser-log-jars | |
| path: build/jreleaser/trace.log | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| # One job per platform, as in ci.yml, but here each one hands its binary to the deploy job below | |
| # instead of throwing it away. | |
| native-images: | |
| name: native image (${{ matrix.platform }}) | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: 90 | |
| # bash on Windows too, as in ci.yml. | |
| defaults: | |
| run: | |
| shell: bash | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: linux-x86-64 | |
| runner: ubuntu-latest | |
| - platform: linux-aarch64 | |
| runner: ubuntu-24.04-arm | |
| - platform: macos-aarch64 | |
| runner: macos-15 | |
| - platform: macos-x86-64 | |
| runner: macos-15-intel | |
| - platform: windows-x86-64 | |
| runner: windows-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| # The Java 21 toolchain for the jars, through JDK21_HOME, as in ci.yml: Gradle does not find the | |
| # runner's own JDK 21 on Windows. Installed before GraalVM, so that Gradle still runs on GraalVM. | |
| - name: Install JDK 21 for the jars | |
| id: jdk21 | |
| uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| - name: Install GraalVM 25 for the image | |
| uses: graalvm/setup-graalvm@5298d94fb55a4f185c602eeac5de1b553882abe2 # v1.6.4 | |
| with: | |
| java-version: '25' | |
| distribution: 'graalvm-community' | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Compile the native image | |
| run: ./gradlew -PnativeImage=true :open-java-format-native:nativeCompile | |
| env: | |
| JDK21_HOME: ${{ steps.jdk21.outputs.path }} | |
| - name: Hand the binary to the deploy job | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: native-image-${{ matrix.platform }} | |
| path: | | |
| open-java-format-native/build/native/nativeCompile/open-java-format-* | |
| !open-java-format-native/build/native/nativeCompile/*.txt | |
| if-no-files-found: error | |
| retention-days: 1 | |
| # Not `native`: ci.yml already has a job with that id, and `act --job native` could not tell them apart. | |
| native-deploy: | |
| name: native deploy | |
| needs: native-images | |
| runs-on: ubuntu-latest | |
| outputs: | |
| deployment-id: ${{ steps.deployment.outputs.id }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install JDK 21 | |
| uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| # merge-multiple: every platform's binary lands in one directory under the name it was built | |
| # with, which is where its Maven classifier is read from. | |
| - name: Collect every platform's binary | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: native-images | |
| pattern: native-image-* | |
| merge-multiple: true | |
| - name: Show what was collected | |
| run: ls -l native-images | |
| # No GraalVM here: nothing is compiled, the binaries are uploaded exactly as they arrived. | |
| - name: Stage, sign and upload the native images | |
| run: ./gradlew -PreleaseTarget=native -PnativeImages=native-images jreleaserDeploy | |
| env: | |
| JRELEASER_DEPLOY_MAVEN_MAVENCENTRAL_SONATYPE_USERNAME: ${{ secrets.JRELEASER_MAVENCENTRAL_USERNAME }} | |
| JRELEASER_DEPLOY_MAVEN_MAVENCENTRAL_SONATYPE_PASSWORD: ${{ secrets.JRELEASER_MAVENCENTRAL_PASSWORD }} | |
| JRELEASER_GPG_SECRET_KEY: ${{ secrets.JRELEASER_GPG_SECRET_KEY }} | |
| JRELEASER_GPG_PASSPHRASE: ${{ secrets.JRELEASER_GPG_PASSPHRASE }} | |
| - name: Hand the deployment to the publish job | |
| id: deployment | |
| run: | | |
| id="$(sed -n 's/^deployMavenCentralSonatypeDeploymentId=//p' build/jreleaser/output.properties)" | |
| if [ -z "$id" ]; then | |
| echo "No deployment ID in build/jreleaser/output.properties" | |
| exit 1 | |
| fi | |
| echo "id=$id" >> "$GITHUB_OUTPUT" | |
| - name: Keep JReleaser's log | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: jreleaser-log-native | |
| path: build/jreleaser/trace.log | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| # Both deployments are uploaded and validated by now. Publishing one is a JReleaser run given its ID, | |
| # which builds nothing. One leg per deployment, so that a re-run repeats only the leg that failed. | |
| publish: | |
| name: publish (${{ matrix.deployment }}) | |
| needs: [jars, native-deploy] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| include: | |
| - deployment: jars | |
| id: ${{ needs.jars.outputs.deployment-id }} | |
| - deployment: native | |
| id: ${{ needs.native-deploy.outputs.deployment-id }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install JDK 21 | |
| uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| - name: Publish the deployment | |
| run: ./gradlew jreleaserDeploy | |
| env: | |
| JRELEASER_MAVENCENTRAL_DEPLOYMENT_ID: ${{ matrix.id }} | |
| JRELEASER_DEPLOY_MAVEN_MAVENCENTRAL_SONATYPE_USERNAME: ${{ secrets.JRELEASER_MAVENCENTRAL_USERNAME }} | |
| JRELEASER_DEPLOY_MAVEN_MAVENCENTRAL_SONATYPE_PASSWORD: ${{ secrets.JRELEASER_MAVENCENTRAL_PASSWORD }} | |
| JRELEASER_GPG_SECRET_KEY: ${{ secrets.JRELEASER_GPG_SECRET_KEY }} | |
| JRELEASER_GPG_PASSPHRASE: ${{ secrets.JRELEASER_GPG_PASSPHRASE }} | |
| - name: Keep JReleaser's log | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: jreleaser-log-publish-${{ matrix.deployment }} | |
| path: build/jreleaser/trace.log | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| # The plugins depend on the version's jars and native images, so they go up only once Maven Central | |
| # serves both, which takes some minutes after the publish job. The Gradle Plugin Portal never takes a | |
| # version back. | |
| gradle-plugins: | |
| name: Gradle plugins | |
| needs: publish | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 90 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install JDK 21 | |
| uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| - name: Wait for Maven Central to serve the version | |
| env: | |
| VERSION: ${{ github.ref_name }} | |
| run: | | |
| for artifact in open-java-format open-java-format-native; do | |
| url="https://repo1.maven.org/maven2/dev/openjavaformat/${artifact}/${VERSION}/${artifact}-${VERSION}.pom" | |
| until curl --silent --fail --head --output /dev/null "$url"; do | |
| echo "Waiting for ${url}" | |
| sleep 30 | |
| done | |
| done | |
| - name: Sign and publish the Gradle plugins | |
| run: ./gradlew :gradle-open-java-format:publishPlugins | |
| env: | |
| GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }} | |
| GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }} | |
| JRELEASER_GPG_SECRET_KEY: ${{ secrets.JRELEASER_GPG_SECRET_KEY }} | |
| JRELEASER_GPG_PASSPHRASE: ${{ secrets.JRELEASER_GPG_PASSPHRASE }} | |
| # What Maven Central does not carry — the runnable formatter jar, the Gradle plugins' jar, the IntelliJ | |
| # plugin zip, the Eclipse plugin jar, and every platform's native binary as a plain download — goes into | |
| # a draft GitHub release on the tag, each file signed with the release key. Only once both deployments | |
| # are published; publishing the draft is a click on GitHub, and a re-run fails while a release for the | |
| # tag exists. | |
| github-release: | |
| name: draft GitHub release | |
| needs: publish | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install JDK 21 | |
| uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| - name: Collect every platform's binary | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: native-images | |
| pattern: native-image-* | |
| merge-multiple: true | |
| - name: Build the plugins and open the draft release | |
| run: ./gradlew -PreleaseTarget=github -PnativeImages=native-images jreleaserRelease | |
| env: | |
| JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| JRELEASER_GPG_SECRET_KEY: ${{ secrets.JRELEASER_GPG_SECRET_KEY }} | |
| JRELEASER_GPG_PASSPHRASE: ${{ secrets.JRELEASER_GPG_PASSPHRASE }} | |
| - name: Keep JReleaser's log | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: jreleaser-log-github | |
| path: build/jreleaser/trace.log | |
| if-no-files-found: ignore | |
| retention-days: 7 |