Skip to content

fix(02-04): publish Spring Boot BOM as platform constraint in kore-sp… #5

fix(02-04): publish Spring Boot BOM as platform constraint in kore-sp…

fix(02-04): publish Spring Boot BOM as platform constraint in kore-sp… #5

Workflow file for this run

# 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.