-
Notifications
You must be signed in to change notification settings - Fork 0
147 lines (131 loc) · 6.36 KB
/
Copy pathrelease.yml
File metadata and controls
147 lines (131 loc) · 6.36 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
# kore-runtime release workflow — Maven Central publish on v-tag push.
#
# Trust boundary (T-04-10): this workflow runs on the org-owned
# `arc-runner-unityinflow` self-hosted runner pool. Only UnityInFlow org
# admins can modify the runner group or the jobs that execute here. A
# compromised runner = org compromise, which is out of scope for this plan;
# the human RC dry-run checkpoint (see docs/RELEASE-CHECKLIST.md) catches
# anomalous staging bundles via Sonatype portal inspection before the
# manual "Publish" button is pressed.
#
# Provenance (T-04-09): `fetch-depth: 0` + `generate_release_notes: true`
# ensures the GitHub Release is linked to the exact tag commit with a
# full history-derived changelog.
#
# GPG key handling (T-04-07 / Pitfall 11): `--no-configuration-cache` on
# every Gradle invocation forces `providers.environmentVariable(...)` to
# re-read SIGNING_KEY / SIGNING_PASSWORD at execution time rather than
# serializing a stale copy into the configuration cache.
#
# Runner label (Pitfall 10): `arc-runner-unityinflow` is the CLAUDE.md
# default and resolves only to X64 Hetzner runners — the ARM orangepi
# runner does NOT carry this label. An explicit `X64` pin is deliberately
# omitted per the PF-02 pre-flight runner label audit.
name: Release
on:
push:
tags:
- 'v*.*.*'
jobs:
publish:
# Hetzner X64 fleet (arc-runner-unityinflow) offline at v0.1.0 release time;
# JVM artifacts are arch-independent, so run on the ARM64 orangepi runner
# (same fallback proven for budget-breaker 0.1.0). Revert to arc-runner-unityinflow when the fleet is back.
runs-on: [orangepi]
permissions:
contents: write # required by softprops/action-gh-release@v2
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# The Maven coordinates come from the Gradle `version` property (the
# single-source allprojects block), while the release notes derive the
# version from the git tag. Fail fast if they disagree — otherwise the
# release page would instruct users to depend on a version that does not
# match the published Sonatype bundle.
- name: Verify tag matches Gradle version
run: |
GRADLE_VERSION=$(./gradlew properties -q --no-configuration-cache | awk '/^version:/ {print $2}')
TAG_VERSION="${GITHUB_REF_NAME#v}"
if [ "$GRADLE_VERSION" != "$TAG_VERSION" ]; then
echo "Tag $TAG_VERSION does not match Gradle version $GRADLE_VERSION" >&2
exit 1
fi
- name: Lint + build + unit tests
run: ./gradlew clean build --no-configuration-cache
# ---------------------------------------------------------------------------
# Pre-publish assertion gates (verify-before-publish). Maven Central releases
# are immutable (RESEARCH Pitfall 5), so the aggregation membership is proven
# correct here BEFORE the irreversible Publish step below.
# ---------------------------------------------------------------------------
# KORE-05 / D-04 / D-05: the aggregation must be the curated 10 (9 stable
# modules + kore-bom). kore-budget (the 05→08 published deliverable) MUST be
# present; the three experimental modules MUST NOT be.
- name: Gate — aggregation membership is the curated 10 (9 modules + BOM)
run: |
COUNT=$(grep -c "nmcpAggregation(project" build.gradle.kts)
if [ "$COUNT" -ne 10 ]; then
echo "Aggregation count $COUNT != 10 (curated 9 + BOM)" >&2
exit 1
fi
if ! grep -q 'nmcpAggregation(project(":kore-budget"))' build.gradle.kts; then
echo "kore-budget missing from aggregation (the 05→08 published deliverable would be unpublished)" >&2
exit 1
fi
if ! grep -q 'nmcpAggregation(project(":kore-bom"))' build.gradle.kts; then
echo "kore-bom missing from aggregation (D-05)" >&2
exit 1
fi
for excluded in kore-dashboard kore-kafka kore-rabbitmq; do
if grep -q "nmcpAggregation(project(\":$excluded\"))" build.gradle.kts; then
echo "Excluded module $excluded still aggregated (D-04 violation)" >&2
exit 1
fi
done
echo "Aggregation membership OK — curated 10 incl. kore-budget + kore-bom; no experimental modules"
- name: Gate — kore-bom is in the aggregation
run: |
grep -q 'nmcpAggregation(project(":kore-bom"))' build.gradle.kts || {
echo "kore-bom missing from aggregation" >&2
exit 1
}
echo "kore-bom present in aggregation"
- name: Publish aggregated bundle to Sonatype Central Portal
env:
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
run: ./gradlew publishAggregationToCentralPortal --no-configuration-cache
- name: Extract version
id: version
run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: kore-runtime ${{ github.ref_name }}
generate_release_notes: true
draft: false
prerelease: false
body: |
kore-runtime **${{ github.ref_name }}** is now available on Maven Central under `io.github.unityinflow`.
```kotlin
dependencies {
implementation("io.github.unityinflow:kore-spring:${{ steps.version.outputs.version }}")
}
```
**NOTE:** With `publishingType = "USER_MANAGED"`, artifacts land in a
Sonatype Central Portal staging bundle after this workflow succeeds.
A human must press "Publish" in the portal UI to promote them to
Maven Central. Replication to `repo.maven.apache.org` takes ~30
minutes after the button press.
See the auto-generated notes below for highlights from Phases 1–4.