-
Notifications
You must be signed in to change notification settings - Fork 0
455 lines (390 loc) · 17 KB
/
Copy pathrelease.yml
File metadata and controls
455 lines (390 loc) · 17 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
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
name: Release
on:
pull_request:
paths:
- '.github/workflows/release.yml'
- 'build.gradle'
- 'settings.gradle'
- 'common/**'
- 'paper/**'
- 'fabric/**'
- 'fabric-legacy/**'
- 'scripts/**'
schedule:
- cron: '23 3 * * *'
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
minimum_minecraft_version:
description: 'Oldest Minecraft release to package'
required: true
default: '1.20.5'
tag_name:
description: 'Release tag, or auto for v<plugin-version>-mc<latest-version>'
required: true
default: 'auto'
prerelease:
description: 'Force the release to be marked as a prerelease'
required: true
default: false
type: boolean
permissions:
contents: write
jobs:
discover:
name: Discover Paper and Fabric targets
runs-on: ubuntu-latest
outputs:
paper_targets: ${{ steps.matrix.outputs.paper_targets }}
fabric_matrix: ${{ steps.matrix.outputs.fabric_matrix }}
paper_target_count: ${{ steps.matrix.outputs.paper_target_count }}
fabric_target_count: ${{ steps.matrix.outputs.fabric_target_count }}
latest_minecraft_version: ${{ steps.matrix.outputs.latest_minecraft_version }}
latest_paper_build: ${{ steps.matrix.outputs.latest_paper_build }}
latest_paper_channel: ${{ steps.matrix.outputs.latest_paper_channel }}
fabric_loader_version: ${{ steps.matrix.outputs.fabric_loader_version }}
fabric_loader_stable: ${{ steps.matrix.outputs.fabric_loader_stable }}
auto_prerelease: ${{ steps.matrix.outputs.auto_prerelease }}
release_tag: ${{ steps.release_tag.outputs.release_tag }}
project_version: ${{ steps.release_tag.outputs.project_version }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Resolve release matrix
id: matrix
shell: bash
env:
MINIMUM_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.minimum_minecraft_version || '1.20.5' }}
run: bash ./scripts/resolve-release-matrix.sh "$MINIMUM_VERSION"
- name: Decide release tag
id: release_tag
shell: bash
env:
INPUT_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag_name || 'auto' }}
LATEST_MINECRAFT_VERSION: ${{ steps.matrix.outputs.latest_minecraft_version }}
run: |
set -euo pipefail
PROJECT_VERSION=$(grep -o "version = '[^']*'" build.gradle | head -n 1 | cut -d"'" -f2)
if [[ "${GITHUB_REF_TYPE:-}" == "tag" ]]; then
TAG="${GITHUB_REF_NAME}"
elif [[ -n "${INPUT_TAG}" && "${INPUT_TAG}" != "auto" ]]; then
TAG="${INPUT_TAG}"
else
TAG="v${PROJECT_VERSION}-mc${LATEST_MINECRAFT_VERSION}"
fi
echo "project_version=${PROJECT_VERSION}" >> "$GITHUB_OUTPUT"
echo "release_tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "Release tag: ${TAG}"
common-tests:
name: Test shared configuration parser
needs: discover
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Java 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
cache: gradle
- name: Make Gradle script executable
run: chmod +x ./gradlew
- name: Run common tests
run: ./gradlew :common:test --configure-on-demand --no-daemon --stacktrace -PjavaVersion=21
paper-builds:
name: Build universal Paper jar and version aliases
needs: [discover, common-tests]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Java 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
cache: gradle
- name: Make Gradle script executable
run: chmod +x ./gradlew
- name: Build Paper compatibility jar
run: |
./gradlew :paper:jar --configure-on-demand --no-daemon --stacktrace \
-PjavaVersion=21 \
-PminecraftVersion=1.20.5 \
-PpaperApiVersion=1.20.6-R0.1-SNAPSHOT \
-PpaperApiVersionShort=1.20.5
- name: Package Paper aliases
shell: bash
env:
PAPER_TARGETS: ${{ needs.discover.outputs.paper_targets }}
PROJECT_VERSION: ${{ needs.discover.outputs.project_version }}
run: |
set -euo pipefail
mkdir -p out/status
PAPER_JAR=$(find paper/build/libs -maxdepth 1 -type f -name '*-paper.jar' | sort | head -n 1)
if [[ -z "${PAPER_JAR}" ]]; then
echo 'Paper jar was not produced.' >&2
exit 1
fi
cp "$PAPER_JAR" "out/ConfigStackMC-${PROJECT_VERSION}-paper-universal-mc1.20.5-plus.jar"
jq -r '.[].minecraft_version' <<<"$PAPER_TARGETS" | while IFS= read -r minecraft_version; do
cp "$PAPER_JAR" "out/ConfigStackMC-${PROJECT_VERSION}-paper-mc${minecraft_version}.jar"
done
jq -n \
--arg status success \
--arg minimum_minecraft_version 1.20.5 \
--argjson targets "$PAPER_TARGETS" \
'{status: $status, minimum_minecraft_version: $minimum_minecraft_version, targets: $targets}' \
> out/status/paper.json
- name: Upload Paper builds
uses: actions/upload-artifact@v4
with:
name: paper-builds
path: out
if-no-files-found: error
fabric-builds:
name: Fabric ${{ matrix.minecraft_version }} (${{ matrix.loom_generation }})
needs: [discover, common-tests]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.discover.outputs.fabric_matrix) }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Java ${{ matrix.java_version }}
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ matrix.java_version }}
cache: gradle
- name: Make Gradle script executable
run: chmod +x ./gradlew
- name: Build Fabric target
shell: bash
env:
MINECRAFT_VERSION: ${{ matrix.minecraft_version }}
PAPER_BUILD: ${{ matrix.paper_build }}
PAPER_CHANNEL: ${{ matrix.paper_channel }}
FABRIC_API_VERSION: ${{ matrix.fabric_api_version }}
FABRIC_LOADER_VERSION: ${{ matrix.fabric_loader_version }}
FABRIC_PROJECT: ${{ matrix.fabric_project }}
JAVA_VERSION: ${{ matrix.java_version }}
LOOM_GENERATION: ${{ matrix.loom_generation }}
PROJECT_VERSION: ${{ needs.discover.outputs.project_version }}
run: |
set -uo pipefail
mkdir -p out/status
set +e
./gradlew ":${FABRIC_PROJECT}:build" --configure-on-demand --no-daemon --stacktrace \
-PjavaVersion="${JAVA_VERSION}" \
-PminecraftVersion="${MINECRAFT_VERSION}" \
-PfabricLoaderVersion="${FABRIC_LOADER_VERSION}" \
-PfabricApiVersion="${FABRIC_API_VERSION}"
gradle_exit=$?
set -e
status=failure
reason="Gradle exited with code ${gradle_exit}"
if [[ $gradle_exit -eq 0 ]]; then
jar_path=$(find "${FABRIC_PROJECT}/build/libs" -maxdepth 1 -type f -name '*.jar' \
! -name '*sources*' ! -name '*dev*' | sort | head -n 1)
if [[ -n "${jar_path}" ]]; then
cp "$jar_path" "out/ConfigStackMC-${PROJECT_VERSION}-fabric-mc${MINECRAFT_VERSION}.jar"
status=success
reason='Build completed'
else
reason='Gradle succeeded but no distributable jar was found'
fi
fi
jq -n \
--arg status "$status" \
--arg reason "$reason" \
--arg minecraft_version "$MINECRAFT_VERSION" \
--arg paper_build "$PAPER_BUILD" \
--arg paper_channel "$PAPER_CHANNEL" \
--arg fabric_api_version "$FABRIC_API_VERSION" \
--arg fabric_loader_version "$FABRIC_LOADER_VERSION" \
--arg fabric_project "$FABRIC_PROJECT" \
--arg java_version "$JAVA_VERSION" \
--arg loom_generation "$LOOM_GENERATION" \
'{
status: $status,
reason: $reason,
minecraft_version: $minecraft_version,
paper_build: $paper_build,
paper_channel: $paper_channel,
fabric_api_version: $fabric_api_version,
fabric_loader_version: $fabric_loader_version,
fabric_project: $fabric_project,
java_version: $java_version,
loom_generation: $loom_generation
}' > "out/status/fabric-mc${MINECRAFT_VERSION}.json"
if [[ "$status" == success ]]; then
echo "### Fabric ${MINECRAFT_VERSION}: built successfully" >> "$GITHUB_STEP_SUMMARY"
else
echo "### Fabric ${MINECRAFT_VERSION}: build unavailable" >> "$GITHUB_STEP_SUMMARY"
echo "${reason}" >> "$GITHUB_STEP_SUMMARY"
fi
# One unavailable historical target must not cancel the remaining matrix.
exit 0
- name: Upload Fabric target result
uses: actions/upload-artifact@v4
with:
name: fabric-mc${{ matrix.minecraft_version }}
path: out
if-no-files-found: error
assemble-release:
name: Assemble and validate multi-version release
needs: [discover, common-tests, paper-builds, fabric-builds]
if: ${{ always() && needs.common-tests.result == 'success' && needs.paper-builds.result == 'success' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download Paper builds
uses: actions/download-artifact@v4
with:
name: paper-builds
path: release
- name: Download Fabric target results
uses: actions/download-artifact@v4
with:
pattern: fabric-mc*
path: release
merge-multiple: true
- name: Validate artifacts and write release report
id: asset_order
shell: bash
env:
RELEASE_TAG: ${{ needs.discover.outputs.release_tag }}
PROJECT_VERSION: ${{ needs.discover.outputs.project_version }}
PAPER_TARGETS: ${{ needs.discover.outputs.paper_targets }}
LATEST_MINECRAFT_VERSION: ${{ needs.discover.outputs.latest_minecraft_version }}
LATEST_PAPER_BUILD: ${{ needs.discover.outputs.latest_paper_build }}
LATEST_PAPER_CHANNEL: ${{ needs.discover.outputs.latest_paper_channel }}
FABRIC_LOADER_VERSION: ${{ needs.discover.outputs.fabric_loader_version }}
FABRIC_LOADER_STABLE: ${{ needs.discover.outputs.fabric_loader_stable }}
PAPER_TARGET_COUNT: ${{ needs.discover.outputs.paper_target_count }}
FABRIC_TARGET_COUNT: ${{ needs.discover.outputs.fabric_target_count }}
run: |
set -euo pipefail
mapfile -t status_files < <(find release/status -maxdepth 1 -type f -name 'fabric-*.json' | sort -V)
if [[ ${#status_files[@]} -eq 0 ]]; then
echo 'No Fabric status files were downloaded.' >&2
exit 1
fi
success_count=0
failure_count=0
for status_file in "${status_files[@]}"; do
if [[ "$(jq -r '.status' "$status_file")" == success ]]; then
((success_count += 1))
else
((failure_count += 1))
fi
done
cat > release/BUILD_REPORT.md <<EOF_REPORT
# ConfigStackMC ${RELEASE_TAG}
This release packages normal Minecraft releases discovered from Paper starting at 1.20.5. Minecraft snapshots, pre-releases and release candidates are excluded. Paper channels are not restricted to STABLE, so beta or experimental Paper builds are included as soon as they are available for a released Minecraft version.
## Latest discovered target
- Minecraft: ${LATEST_MINECRAFT_VERSION}
- Paper build: ${LATEST_PAPER_BUILD}
- Paper channel: ${LATEST_PAPER_CHANNEL}
- Fabric Loader used for compilation: ${FABRIC_LOADER_VERSION} (stable=${FABRIC_LOADER_STABLE})
## Results
- Paper version aliases: ${PAPER_TARGET_COUNT}
- Fabric targets attempted: ${FABRIC_TARGET_COUNT}
- Fabric jars built: ${success_count}
- Fabric targets unavailable: ${failure_count}
Paper files are aliases of one Java 21 jar compiled against the Paper 1.20.6 API while declaring Paper 1.20.5 as the minimum runtime. Fabric files are compiled separately for their exact Minecraft version.
### Fabric builds, oldest to newest
EOF_REPORT
for status_file in "${status_files[@]}"; do
jq -r '
"- Minecraft " + .minecraft_version
+ ": **" + .status + "**"
+ " | " + .loom_generation
+ " | Java " + .java_version
+ " | Fabric API " + .fabric_api_version
+ (if .status == "success" then "" else " | " + .reason end)
' "$status_file" >> release/BUILD_REPORT.md
done
universal="release/ConfigStackMC-${PROJECT_VERSION}-paper-universal-mc1.20.5-plus.jar"
[[ -f "$universal" ]] || { echo "Missing universal Paper jar: $universal" >&2; exit 1; }
ordered_jars=("$universal")
while IFS= read -r minecraft_version; do
paper_jar="release/ConfigStackMC-${PROJECT_VERSION}-paper-mc${minecraft_version}.jar"
[[ -f "$paper_jar" ]] || { echo "Missing Paper alias: $paper_jar" >&2; exit 1; }
ordered_jars+=("$paper_jar")
fabric_jar="release/ConfigStackMC-${PROJECT_VERSION}-fabric-mc${minecraft_version}.jar"
if [[ -f "$fabric_jar" ]]; then
ordered_jars+=("$fabric_jar")
fi
done < <(jq -r '.[].minecraft_version' <<<"$PAPER_TARGETS" | sort -V)
: > release/SHA256SUMS.txt
for jar in "${ordered_jars[@]}"; do
sha256sum "$jar" | sed 's# release/# #' >> release/SHA256SUMS.txt
done
{
echo 'release/BUILD_REPORT.md'
echo 'release/SHA256SUMS.txt'
printf '%s\n' "${ordered_jars[@]}"
} > release/ASSET_ORDER.txt
actual_jar_count=$(find release -maxdepth 1 -type f -name '*.jar' | wc -l | tr -d ' ')
if [[ "$actual_jar_count" -ne "${#ordered_jars[@]}" ]]; then
echo "Asset order contains ${#ordered_jars[@]} jars, but ${actual_jar_count} jars exist." >&2
find release -maxdepth 1 -type f -name '*.jar' -print | sort -V >&2
exit 1
fi
{
echo 'files<<EOF_FILES'
cat release/ASSET_ORDER.txt
echo 'EOF_FILES'
} >> "$GITHUB_OUTPUT"
echo '### Release asset order' >> "$GITHUB_STEP_SUMMARY"
echo 'Oldest versions are uploaded first; the newest Minecraft version is last.' >> "$GITHUB_STEP_SUMMARY"
sed 's#^release/#- #' release/ASSET_ORDER.txt >> "$GITHUB_STEP_SUMMARY"
- name: Upload validated release bundle
uses: actions/upload-artifact@v4
with:
name: ConfigStackMC-${{ needs.discover.outputs.release_tag }}
path: |
release/*.jar
release/SHA256SUMS.txt
release/BUILD_REPORT.md
release/ASSET_ORDER.txt
if-no-files-found: error
- name: Check whether release already exists
id: release_guard
shell: bash
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ needs.discover.outputs.release_tag }}
EVENT_NAME: ${{ github.event_name }}
run: |
set -euo pipefail
if [[ "$EVENT_NAME" == pull_request ]]; then
echo 'publish=false' >> "$GITHUB_OUTPUT"
echo 'PR validation completed; publishing is intentionally skipped.'
elif gh api "repos/${GITHUB_REPOSITORY}/releases/tags/${RELEASE_TAG}" >/dev/null 2>&1; then
echo 'publish=false' >> "$GITHUB_OUTPUT"
echo "Release ${RELEASE_TAG} already exists; leaving the immutable release untouched."
else
echo 'publish=true' >> "$GITHUB_OUTPUT"
fi
- name: Create GitHub Release
if: steps.release_guard.outputs.publish == 'true'
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ needs.discover.outputs.release_tag }}
target_commitish: ${{ github.sha }}
name: ConfigStackMC ${{ needs.discover.outputs.release_tag }}
prerelease: ${{ (github.event_name == 'workflow_dispatch' && inputs.prerelease) || needs.discover.outputs.auto_prerelease == 'true' }}
generate_release_notes: false
body_path: release/BUILD_REPORT.md
overwrite_files: true
preserve_order: true
fail_on_unmatched_files: true
files: ${{ steps.asset_order.outputs.files }}