forked from palantir/palantir-java-format
-
Notifications
You must be signed in to change notification settings - Fork 0
356 lines (317 loc) · 14.2 KB
/
Copy pathrelease.yml
File metadata and controls
356 lines (317 loc) · 14.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
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, and the IntelliJ plugin goes to the JetBrains Marketplace, verified against the IDEs it
# supports first. After publishing, a draft GitHub release on the tag collects the runnable jar, the Gradle
# and IDE plugins and the native binaries.
#
# Needs seven repository secrets: JRELEASER_MAVENCENTRAL_USERNAME and JRELEASER_MAVENCENTRAL_PASSWORD (the
# Central Portal user token), JRELEASER_GPG_SECRET_KEY and JRELEASER_GPG_PASSPHRASE, GRADLE_PUBLISH_KEY and
# GRADLE_PUBLISH_SECRET (the Gradle Plugin Portal key) and JETBRAINS_MARKETPLACE_TOKEN (a permanent token of
# the Marketplace account that owns the plugin). 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@0426e2e191540e8514dff98dc52a5f5146a2a276 # v1.6.6
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 }}
# The IntelliJ plugin carries the formatter jars inside its zip, so it does not wait for Maven Central. It
# waits for the publish job like everything else, so that a version whose jars or native images failed
# stays off the Marketplace too. The plugin is checked against the IDEs it declares support for before it
# goes up; a plugin that fails there would fail JetBrains' own check after the upload anyway. The
# Marketplace never takes a version back and rejects a version it already has, so a re-run of this job
# fails once the upload went through.
jetbrains-plugin:
name: JetBrains Marketplace
needs: publish
runs-on: ubuntu-latest
timeout-minutes: 60
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: Verify the plugin against the IDEs it supports
run: ./gradlew :open-java-format-idea-plugin:verifyPlugin
- name: Keep the verifier's report
if: ${{ failure() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: plugin-verifier-report
path: open-java-format-idea-plugin/build/reports/pluginVerifier
if-no-files-found: ignore
retention-days: 7
- name: Upload the plugin
run: ./gradlew :open-java-format-idea-plugin:publishPlugin
env:
JETBRAINS_MARKETPLACE_TOKEN: ${{ secrets.JETBRAINS_MARKETPLACE_TOKEN }}
# 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