Skip to content

Commit 324a98b

Browse files
michalharakalclaude
andcommitted
Add CI guard that rejects invalid coordinates in published POMs
Publishes the whole project to Maven local and scans every generated .pom under ~/.m2/repository/sk/ainet/core/**. Fails if any POM contains <version>unspecified</version> or declares a <dependency> on a skainet-* artifact under a group other than sk.ainet.core — the exact shape of the 0.19.0 regression fixed in the previous commit. Runs on push and pull_request, independent of the main build workflow so a failing POM check cannot be masked by unrelated test failures. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c73c543 commit 324a98b

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env bash
2+
# Fails the build if any published SKaiNET POM contains invalid coordinates.
3+
#
4+
# Catches the class of bug shipped in 0.19.0, where `skainet-backend-cpu`'s POM
5+
# declared `sk.ainet:skainet-backend-api-jvm:unspecified` because
6+
# `skainet-backend-api` was not configured to publish and the root
7+
# `allprojects { group = "sk.ainet" }` disagreed with `GROUP=sk.ainet.core`.
8+
#
9+
# Two checks per generated POM under ~/.m2/repository/sk/ainet/core/**:
10+
# 1. No `<version>unspecified</version>` anywhere in the POM.
11+
# 2. Every `<dependency>` whose `<artifactId>` starts with `skainet-` uses
12+
# `<groupId>sk.ainet.core</groupId>` — `project(...)` deps on sibling
13+
# modules must resolve to the same publish group.
14+
15+
set -euo pipefail
16+
17+
REPO_ROOT="${HOME}/.m2/repository/sk/ainet/core"
18+
19+
if [[ ! -d "${REPO_ROOT}" ]]; then
20+
echo "ERROR: no published artifacts found under ${REPO_ROOT}" >&2
21+
echo "Did ./gradlew publishToMavenLocal run successfully?" >&2
22+
exit 1
23+
fi
24+
25+
mapfile -t POMS < <(find "${REPO_ROOT}" -type f -name '*.pom' | sort)
26+
27+
if [[ ${#POMS[@]} -eq 0 ]]; then
28+
echo "ERROR: no .pom files under ${REPO_ROOT}" >&2
29+
exit 1
30+
fi
31+
32+
echo "Scanning ${#POMS[@]} published POMs..."
33+
34+
report_file="$(mktemp)"
35+
trap 'rm -f "${report_file}"' EXIT
36+
37+
for pom in "${POMS[@]}"; do
38+
rel="${pom#${REPO_ROOT}/}"
39+
40+
if grep -Fq '<version>unspecified</version>' "${pom}"; then
41+
{
42+
echo "FAIL ${rel}: contains <version>unspecified</version>"
43+
grep -n '<version>unspecified</version>' "${pom}" | sed 's/^/ /'
44+
} >> "${report_file}"
45+
fi
46+
47+
bad_deps="$(awk '
48+
/<dependency>/ { inDep=1; block=""; next }
49+
inDep { block = block "\n" $0 }
50+
/<\/dependency>/ {
51+
inDep=0
52+
if (block ~ /<artifactId>skainet-/ && block !~ /<groupId>sk\.ainet\.core<\/groupId>/) {
53+
print block
54+
}
55+
}
56+
' "${pom}")"
57+
58+
if [[ -n "${bad_deps}" ]]; then
59+
{
60+
echo "FAIL ${rel}: skainet-* dependency with non-sk.ainet.core group"
61+
printf '%s\n' "${bad_deps}" | sed 's/^/ /'
62+
} >> "${report_file}"
63+
fi
64+
done
65+
66+
if [[ -s "${report_file}" ]]; then
67+
cat "${report_file}" >&2
68+
echo "" >&2
69+
echo "POM validation failed. See the 0.19.1 CHANGELOG entry for the regression this check prevents." >&2
70+
exit 1
71+
fi
72+
73+
echo "All ${#POMS[@]} POMs look good."

.github/workflows/verify-poms.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Verify published POMs
2+
3+
on: [push, pull_request]
4+
5+
concurrency:
6+
group: ${{ github.workflow }}-${{ github.ref }}
7+
cancel-in-progress: true
8+
9+
jobs:
10+
verify-poms:
11+
name: Publish to Maven local and validate POM coordinates
12+
runs-on: ubuntu-latest
13+
timeout-minutes: 45
14+
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v6
18+
19+
- name: Copy CI gradle.properties
20+
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
21+
22+
- name: Set up JDK 25
23+
uses: actions/setup-java@v5
24+
with:
25+
distribution: 'zulu'
26+
java-version: 25
27+
28+
- name: Publish to Maven local
29+
env:
30+
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx4g -Dfile.encoding=UTF-8"
31+
run: |
32+
./gradlew --no-daemon --stacktrace --no-configuration-cache \
33+
-PRELEASE_SIGNING_ENABLED=false \
34+
-PsignAllPublications=false \
35+
publishToMavenLocal
36+
37+
- name: Validate POM coordinates
38+
run: ./.github/scripts/validate-published-poms.sh

0 commit comments

Comments
 (0)