Compare commits

..
37 Commits
Author SHA1 Message Date
james.maes 821632586e Merge pull request 'ci: pin shared workflow to v1' (#27) from ci/pin-v1-main into main
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (push) Skipped
QRun-IO/ci-policy: ci / source-config-14 (push) Skipped
QRun-IO/ci-policy: ci / original-voyage (push) Skipped
QRun-IO/ci-policy: ci / original-cli (push) Skipped
QRun-IO/ci-policy: ci / ci-result (push) Successful in 15s
build / maven (push) Successful in 2m15s
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (push) Successful in 18s
QRun-IO/ci-policy: native / native-result (push) Successful in 10s
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: ci / repository-policy (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (push) Skipped
QRun-IO/ci-policy: ci / node-8 (push) Skipped
QRun-IO/ci-policy: ci / node-9 (push) Skipped
QRun-IO/ci-policy: ci / node-10 (push) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (push) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (push) Skipped
QRun-IO/ci-policy: ci / source-config-13 (push) Skipped
QRun-IO/ci-policy: ci / original-business (push) Skipped
QRun-IO/ci-policy: ci / gradle-1 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (push) Skipped
QRun-IO/ci-policy: ci / android-0 (push) Skipped
QRun-IO/ci-policy: ci / original-mcp (push) Skipped
QRun-IO/ci-policy: ci / not-enrolled (push) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (push) Skipped
maven / build (push) Successful in 2m15s
2026-11-06 16:07:58 +00:00
james.maes 1da0afa587 Merge pull request 'chore(release): prepare 0.2.0 (QQQ 4.1, Forge sync fix)' (#29) from chore/release-0.2.0-20261106 into main
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (push) Skipped
QRun-IO/ci-policy: ci / source-config-14 (push) Skipped
QRun-IO/ci-policy: ci / original-voyage (push) Skipped
QRun-IO/ci-policy: ci / original-cli (push) Skipped
QRun-IO/ci-policy: ci / ci-result (push) Successful in 9s
build / maven (push) Failing after 14m33s
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (push) Successful in 11s
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: native / native-result (push) Successful in 12s
QRun-IO/ci-policy: ci / repository-policy (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (push) Skipped
QRun-IO/ci-policy: ci / node-8 (push) Skipped
QRun-IO/ci-policy: ci / node-9 (push) Skipped
QRun-IO/ci-policy: ci / node-10 (push) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (push) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (push) Skipped
QRun-IO/ci-policy: ci / source-config-13 (push) Skipped
QRun-IO/ci-policy: ci / original-business (push) Skipped
QRun-IO/ci-policy: ci / gradle-1 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (push) Skipped
QRun-IO/ci-policy: ci / android-0 (push) Skipped
QRun-IO/ci-policy: ci / original-mcp (push) Skipped
QRun-IO/ci-policy: ci / not-enrolled (push) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (push) Skipped
maven / build (push) Failing after 14m33s
2026-11-06 15:32:33 +00:00
james.maesandClaude Fable 5.1 b50515a8e8 build(pom): flatten the CI-friendly revision in published POMs
build / maven (push) Successful in 1m48s
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 539bec410f7926fec3ef7fabe51934a91e0248be] (pull_request) Successful in 11s
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (pull_request) Successful in 9s
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 12s
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 12s
maven / build (push) Successful in 1m48s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
The root pom keeps its version in the CI-friendly ${revision} property and
the shared ci-workflows Maven workflow deploys with a plain mvn deploy, so
the installed and deployed module POMs carried an unresolved
<parent><version>${revision}</version> that a consuming build cannot resolve
(the retired CircleCI orb path published resolved POMs, 68e85e6). Add
flatten-maven-plugin 1.7.3 in resolveCiFriendliesOnly mode so the published
POMs carry the literal version; ignore the generated .flattened-pom.xml.

Verified with Maven 3.9.11: clean verify passes (29 tests), the installed
qbit-geo-data-0.2.0.pom declares parent version 0.2.0, and a throwaway
consumer resolves com.kingsrook.qbits:qbit-geo-data:0.2.0 through the full
parent chain.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-06 08:51:21 -06:00
james.maesandClaude Fable 5.1 401e7ca471 chore(release): prepare 0.2.0
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
build / maven (push) Successful in 2m11s
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 5s
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (pull_request) Successful in 8s
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 7s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
maven / build (push) Successful in 2m11s
Set the revision to 0.2.0: main already started the 0.2.0 line (6337bfe)
because the QQQ dependency moved from 0.35.0 to 4.1.0-RC.21, a minor
change, not a patch. Align GeoDataQBitProducer.VERSION and its test with
the pom. Add the 0.2.0 changelog entry, move the already-shipped 0.1.0
bullets out of Unreleased, and correct the README coordinates
(artifactId qbit-geo-data, version 0.2.0, Gitea registry, Java 21 / QQQ 4.1).

No tag, release or publish: a push to main only verifies; the v0.2.0 tag
publishes through the shared ci-workflows Maven workflow.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-06 08:46:06 -06:00
james.maesandClaude Fable 5.1 2fd63e734b fix(sync): resolve country and state foreign keys and fail on rejected rows
Port the sync-step half of GG Forge's qualified geo-data-sync.patch (its
entity/producer half landed in b5787bb). The 0.1.0 step matched states on
countryAlpha2 + code and cities on countryAlpha2 + stateCode + name, columns
that do not exist in the schema, so it reported success after persisting 250
countries and zero states or cities.

Resolve the bundled source codes to the persisted countryId and
stateProvinceId before matching; match cities on stateProvinceId, name,
latitude and longitude at the schema's seven-decimal precision; compare
numbers by BigDecimal value so a second run is a no-op; reactivate an
inactive row whose source entry returns; and check insert/update results so
a row the backend rejects fails the sync with a QException.

Same change as the Forge pin 0.1.0-forge.6ac6a0366c34-sync1, with the inline
java.math qualifications turned into imports and the class Javadoc updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-06 08:46:05 -06:00
james.maesandClaude Opus 5.5 afa9166f9c ci: pin shared workflow to v1
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
build / maven (push) Successful in 2m56s
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (pull_request) Successful in 10s
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 5s
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 6s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
maven / build (push) Successful in 2m55s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:10:00 +00:00
james.maes 9c42b3d913 Merge pull request 'ci: use shared ci-workflows Maven workflow' (#25) from ci/ci-workflows into main
build / maven (push) Successful in 1m19s
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (push) Skipped
QRun-IO/ci-policy: ci / source-config-14 (push) Skipped
QRun-IO/ci-policy: ci / original-voyage (push) Skipped
QRun-IO/ci-policy: ci / original-cli (push) Skipped
QRun-IO/ci-policy: ci / ci-result (push) Successful in 5s
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (push) Successful in 5s
QRun-IO/ci-policy: native / native-result (push) Successful in 5s
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: ci / repository-policy (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (push) Skipped
QRun-IO/ci-policy: ci / node-8 (push) Skipped
QRun-IO/ci-policy: ci / node-9 (push) Skipped
QRun-IO/ci-policy: ci / node-10 (push) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (push) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (push) Skipped
QRun-IO/ci-policy: ci / source-config-13 (push) Skipped
QRun-IO/ci-policy: ci / original-business (push) Skipped
maven / build (push) Successful in 1m19s
QRun-IO/ci-policy: ci / gradle-1 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (push) Skipped
QRun-IO/ci-policy: ci / android-0 (push) Skipped
QRun-IO/ci-policy: ci / original-mcp (push) Skipped
QRun-IO/ci-policy: ci / not-enrolled (push) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (push) Skipped
2026-11-06 13:18:44 +00:00
CI 2cb2646fe1 ci: rerun checks after dispatcher retirement
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow d20a578c7d818bc7ca32a2ac2c675da4e4f27385] (pull_request) Successful in 6s
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
build / maven (push) Successful in 1m28s
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 7s
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 5s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
maven / build (push) Successful in 1m28s
2026-11-05 17:22:50 -06:00
james.maesandClaude Opus 5.5 006ae730d7 ci: use shared ci-workflows Maven workflow
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
build / maven (push) Successful in 1m25s
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1b3648d9421543350067e95e54959dfb471b26d5] (pull_request) Successful in 7s
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Successful in 56s
QRun-IO/ci-policy: Shared Java Maven CI / secrets (pull_request) Failing after 1s
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Failing after 13s
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Failing after 8m52s
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 10s
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Failing after 1s
maven / build (push) Successful in 1m24s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
Replace the platform-ci release callers with one caller of
KofTwentyTwo/ci-workflows maven.yaml (qqq-orb port).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 22:05:34 +00:00
james.maes 55edcf4070 Merge pull request 'Align with published QQQ 4.1 and preserve KOF22 integration' (#24) from feature/kof22-geo-data-canonical into main
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
Shared Java Maven CI / verify (push) Successful in 1m55s
Shared Java Maven CI / secrets (push) Successful in 35s
QRun-IO/ci-policy: ci / java-core-2-head (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (push) Skipped
QRun-IO/ci-policy: ci / source-config-14 (push) Skipped
QRun-IO/ci-policy: ci / original-voyage (push) Skipped
QRun-IO/ci-policy: ci / original-cli (push) Skipped
QRun-IO/ci-policy: ci / ci-result (push) Successful in 6s
qrun-release / postpublish (push) Failing after 33m59s
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: native / native-result (push) Successful in 7s
QRun-IO/ci-policy: Shared Java Maven CI / verify (push) Successful in 55s
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: ci / repository-policy (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (push) Skipped
QRun-IO/ci-policy: ci / node-8 (push) Skipped
QRun-IO/ci-policy: ci / node-9 (push) Skipped
QRun-IO/ci-policy: ci / node-10 (push) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (push) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (push) Skipped
QRun-IO/ci-policy: ci / source-config-13 (push) Skipped
QRun-IO/ci-policy: ci / original-business (push) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 5e6bfd71ee8a5674882f7680c695a0ada599622f] (push) Successful in 9s
QRun-IO/ci-policy: Shared Java Maven CI / secrets (push) Successful in 42s
Shared Java Maven CI / gate (push) Successful in 13s
qrun-release / release (push) Successful in 4m20s
QRun-IO/ci-policy: ci / gradle-1 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (push) Skipped
QRun-IO/ci-policy: ci / android-0 (push) Skipped
QRun-IO/ci-policy: ci / original-mcp (push) Skipped
QRun-IO/ci-policy: ci / not-enrolled (push) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (push) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / gate (push) Successful in 12s
QRun-IO/ci-policy: ci / java-maven-6 (push) Successful in 4m14s
Shared QRun source version / version (push) Failing after 33m59s
2026-11-05 16:16:32 +00:00
james.maesandClaude Sonnet 5.5 5802fc4adc build: converge JUnit on 5.10.0 so tests are discovered with the QQQ 4.1 BOM
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
Shared Java Maven CI / verify (push) Successful in 1m10s
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
Shared Java Maven CI / secrets (push) Successful in 37s
qrun-release / postpublish (push) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / secrets (pull_request) Successful in 49s
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Successful in 1m10s
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Successful in 14s
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Successful in 2m43s
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 7s
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 5s
QRun-IO/ci-policy: ci / Scoped workflow [workflow 3d75c629c2706be133505268b6696fe9b1ae420c] (pull_request) Successful in 7s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
Shared Java Maven CI / gate (push) Successful in 15s
qrun-release / release (push) Successful in 2m50s
CI 4834 (verify 77965) failed with "TestEngine with ID 'junit-jupiter' failed to
discover tests" and ran no test. The published qqq-bom-pom 4.1.0-RC.21 inherits
junit-jupiter-engine and junit-jupiter-params at 6.0.2 from its parent
qqq-parent-project. The project imported that BOM before its own junit-bom 5.10.0,
so the engine and params resolved to 6.0.2 while junit-jupiter, the API and the
platform stayed at 5.10.0; the mixed engine cannot start under Surefire 3.1.2.

Import the pom's existing junit-bom 5.10.0 first (first import wins) so every JUnit
artifact converges on 5.10.0. No version is added or upgraded; the parent and the
QQQ BOM are unchanged. The module and revision relationships are unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 08:37:17 -06:00
James MaesandClaude Sonnet 5.5 6337bfe838 build: start the 0.2.0 development line
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / secrets (pull_request) Successful in 51s
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
Shared Java Maven CI / secrets (push) Successful in 50s
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
Shared Java Maven CI / verify (push) Canceled after 0s
qrun-release / postpublish (push) Canceled after 0s
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Failing after 50s
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Failing after 13s
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Failing after 46m31s
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 16s
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Failing after 5s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
Shared Java Maven CI / gate (push) Canceled after 0s
qrun-release / release (push) Canceled after 1m1s
QRun-IO/ci-policy: ci / Scoped workflow [workflow cf802461ca4ebfcf5c500440715cb333d92ea606] (pull_request) Successful in 17s
The published 0.1.0 release stays immutable, so the QQQ 4.1 alignment and
the field-discovery fixes move the development revision to the next
unpublished minor, 0.2.0-SNAPSHOT.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 07:16:52 -06:00
James MaesandClaude Sonnet 5.5 b5787bbe6b fix: align the geo data QBit with QQQ 4.1
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
Shared Java Maven CI / verify (push) Canceled after 0s
qrun-release / postpublish (push) Canceled after 0s
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Canceled after 0s
Shared Java Maven CI / secrets (push) Successful in 56s
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Canceled after 0s
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Canceled after 31m29s
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / secrets (pull_request) Successful in 1m0s
QRun-IO/ci-policy: ci / Scoped workflow [workflow 60e5a80ed7a5a67877bfb3e129b1929c83464b6e] (pull_request) Successful in 12s
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 9s
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Canceled after 0s
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
Shared Java Maven CI / gate (push) Canceled after 0s
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
qrun-release / release (push) Canceled after 6m20s
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
Build against the published QQQ 4.1 core (qqq-bom-pom 4.1.0-RC.21). Mark
City, Country and StateProvince with produceTableMetaData and add the
setters QRecordEntity needs to discover their fields, and make the
producer tolerate a table without fields. Update the producer test.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 05:44:20 -06:00
forge-recovery 6ac6a0366c ci: enroll shared Gitea lifecycle
qrun-release / postpublish (push) Skipped
Shared Java Maven CI / verify (push) Successful in 1m6s
QRun-IO/ci-policy: ci / ci-result (push) Successful in 5s
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (push) Skipped
QRun-IO/ci-policy: ci / source-config-14 (push) Skipped
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
Shared Java Maven CI / secrets (push) Successful in 48s
QRun-IO/ci-policy: ci / java-core-2-head (push) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / verify (push) Successful in 1m1s
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / node-8 (push) Skipped
QRun-IO/ci-policy: ci / node-9 (push) Skipped
QRun-IO/ci-policy: ci / node-10 (push) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (push) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (push) Skipped
QRun-IO/ci-policy: ci / source-config-13 (push) Skipped
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: native / native-result (push) Successful in 8s
QRun-IO/ci-policy: Shared Java Maven CI / secrets (push) Successful in 50s
QRun-IO/ci-policy: ci / repository-policy (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (push) Skipped
Shared Java Maven CI / gate (push) Successful in 13s
qrun-release / release (push) Successful in 46m59s
QRun-IO/ci-policy: Shared Java Maven CI / gate (push) Successful in 15s
QRun-IO/ci-policy: ci / java-maven-6 (push) Successful in 46m59s
QRun-IO/ci-policy: ci / gradle-1 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (push) Skipped
QRun-IO/ci-policy: ci / android-0 (push) Skipped
QRun-IO/ci-policy: ci / original-mcp (push) Skipped
QRun-IO/ci-policy: ci / not-enrolled (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (push) Skipped
2026-11-02 22:16:46 +00:00
ea506f6de6 ci: add the isolated postpublish job to the QRun release caller
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
Shared Java Maven CI / secrets (push) Successful in 28s
QRun-IO/ci-policy: Shared Java Maven CI / secrets (pull_request) Successful in 29s
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
Shared Java Maven CI / verify (push) Canceled after 0s
qrun-release / postpublish (push) Canceled after 0s
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Successful in 54s
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Successful in 9s
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Successful in 2h59m12s
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 6s
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 4s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
Shared Java Maven CI / gate (push) Canceled after 0s
qrun-release / release (push) Canceled after 2h37m1s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 15:49:41 +00:00
5574af58ed ci: move the QRun release caller to the thin v2 contract
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Canceled after 0s
Shared Java Maven CI / verify (push) Canceled after 0s
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-8 (pull_request) Skipped
Shared Java Maven CI / secrets (push) Successful in 38s
QRun-IO/ci-policy: Shared Java Maven CI / secrets (pull_request) Successful in 38s
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Successful in 1m17s
QRun-IO/ci-policy: ci / java-docker-2 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Failing after 4s
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 9s
QRun-IO/ci-policy: ci / java-maven-4 (pull_request) Canceled after 55m54s
Shared Java Maven CI / gate (push) Canceled after 0s
qrun-release / release (push) Canceled after 56m11s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-7 (pull_request) Skipped
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 06:18:30 +00:00
forge-recoveryandCodex f0dbd484d6 ci: add the identical QRun release caller
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-7 (pull_request) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / secrets (pull_request) Failing after 1s
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Successful in 1m23s
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Failing after 1s
QRun-IO/ci-policy: ci / ci-result (pull_request) Failing after 0s
QRun-IO/ci-policy: ci / java-docker-2 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-4 (pull_request) Failing after 3m23s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 04:11:48 +00:00
forge-recovery d0052ea879 Merge pull request 'Qualify central Gitea Java CI' (#21) from qualification/central-actions-20261031 into main
QRun-IO/ci-policy: ci / java-docker-0 (push) Skipped
QRun-IO/ci-policy: ci / node-2 (push) Skipped
QRun-IO/ci-policy: ci / ci-result (push) Successful in 5s
QRun-IO/ci-policy: Shared Java Maven CI / verify (push) Successful in 53s
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / secrets (push) Successful in 25s
QRun-IO/ci-policy: ci / java-maven-1 (push) Successful in 2m49s
QBit CodeQL / Analyze branch source (push) Canceled after 0s
CodeQL / analyze (push) Canceled after 0s
QRun-IO/ci-policy: ci / not-enrolled (push) Skipped
QRun-IO/ci-policy: ci / source-config-3 (push) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / gate (push) Successful in 10s
2026-10-31 20:08:05 +00:00
forge-recoveryandGPT-6.1 79f04c373d test(ci): qualify organization-wide Gitea Java workflow
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Successful in 51s
QRun-IO/ci-policy: Shared Java Maven CI / secrets (pull_request) Successful in 22s
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Successful in 7s
QRun-IO/ci-policy: ci / java-maven-0 (pull_request) Successful in 20m30s
QRun-IO/ci-policy: ci / node-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
CodeQL / analyze (pull_request) Canceled after 0s
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 3s
QRun-IO/ci-policy: ci / source-config-2 (pull_request) Skipped
QBit CodeQL / Analyze branch source (pull_request) Canceled after 0s
Co-Authored-By: GPT-6.1 <noreply@openai.com>
2026-10-31 12:41:23 +00:00
james.maesandCodex 174de92ca5 ci: enroll in the shared QQQ orb (#18)
Co-authored-by: Codex <noreply@openai.com>
2026-10-29 10:47:46 -05:00
james.maesandCodex d1243e4526 ci: adopt current shared orb standard (#17)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 14:51:17 -05:00
james.maesandCodex 845c92bfe2 ci: adopt central orb 0.7.12 and stable gates (#16)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 08:57:16 -05:00
james.maesandCodex b253e9990e ci: publish GA artifacts only from stable tags (#15)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 01:09:07 -05:00
james.maesandCodex 4f27fd1db3 ci: adopt shared orb 0.7.11 (#14)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 00:59:38 -05:00
james.maes 20e38e05d3 Merge pull request #13 from QRun-IO/feature/resolved-publication
fix: resolve published Maven POM coordinates through shared orb
2026-10-20 18:45:06 -05:00
james.maesandCodex 68e85e6ed3 fix: use shared resolved Maven publication POMs
Co-Authored-By: Codex <noreply@openai.com>
2026-10-20 18:43:18 -05:00
james.maes 8a6f345cb5 Merge pull request #12 from QRun-IO/feature/central-ci
ci: adopt verified shared orb 0.7.0
2026-10-20 07:27:43 -05:00
james.maesandCodex 4cf841dfea ci: adopt verified shared orb 0.7.0
Co-Authored-By: Codex <noreply@openai.com>
2026-10-20 07:23:20 -05:00
james.maesandOpenAI Codex 811b079b8a fix: use compressed shared pipeline generator
Keep the orb's Python invocation below CircleCI's argument-size limit; publication policy remains unchanged.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>
2026-10-20 07:03:03 -05:00
james.maesandOpenAI Codex 5f47b112ab ci: adopt central QBit pipeline with preserved release policy
Use the canonical orb caller and explicit audited branch/tag publication policy. Development-orb canary; replace with verified stable version before merge.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>
2026-10-20 06:54:43 -05:00
james.maes 5bda16c6f2 Merge pull request #11 from QRun-IO/feature/release-rc-automation
ci: hotfix/* pushes no longer publish
2026-10-13 15:01:56 -05:00
james.maesandClaude Opus 5.5 a74dd21fa0 ci: keep apt unattended (configure-package-install pre-step)
Every job hung in "Install Java 21" on the needrestart dialog until the
10m no-output timeout. Adds the standard's configure-package-install
command (QRUN-QBIT-REPO-STANDARD C1) as a pre-step to each orb job.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:59:53 -05:00
james.maesandClaude Opus 5.5 2d2eef54c4 ci: hotfix/* pushes no longer publish
Removes publish_hotfix_release: a hotfix/* branch push published a GA
release to Maven Central with no tag or review (QRun-IO/qbit-cdn#12,
QRun-IO/qqq#1121). hotfix/* branches now run test_only; a hotfix
release publishes from a reviewed vX.Y.Z tag through publish_release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:38:23 -05:00
James MaesandClaude Opus 4.8 ebb950f560 docs: add CLAUDE.md pointer to QQQ knowledge-base dossier + hub
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 05:31:09 -05:00
james.maesandClaude Opus 4.7 f7889fdf74 chore: add CODEOWNERS pointing to sole maintainer
Architecture audit pass 2026-05-21. Minimal CODEOWNERS file
making the implicit ownership explicit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 17:14:10 -05:00
james.maes d9f902e956 chore: migrate license from AGPL-3.0 to Apache-2.0 2026-01-05 10:14:24 -06:00
CircleCI 242a9fd4a3 Bump version to 0.1.0 [skip ci] 2025-12-28 23:10:11 +00:00
19 changed files with 741 additions and 79 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
Central Java verification, tests and secret scan are supplied by the organization-scoped workflow.
+10 -53
View File
@@ -1,57 +1,14 @@
version: 2.1
setup: true
orbs:
qqq-orb: kingsrook/qqq-orb@0.5.0
qqq-orb: kingsrook/qqq-orb@0.8
workflows:
test_only:
setup:
jobs:
- qqq-orb/mvn_test_only:
context: [ qqq-maven-registry-credentials ]
filters:
branches:
ignore: /(develop|main|release/.*|hotfix/.*|integration.*)/
tags:
only: []
publish_snapshot:
jobs:
- qqq-orb/mvn_publish:
context: [ qqq-maven-registry-credentials ]
branch_type: snapshot
filters:
branches:
only:
- develop
publish_release_candidate:
jobs:
- qqq-orb/mvn_publish:
context: [ qqq-maven-registry-credentials ]
branch_type: release_candidate
filters:
branches:
only:
- /release\/.*/
publish_release:
jobs:
- qqq-orb/mvn_publish:
context: [ qqq-maven-registry-credentials ]
branch_type: release
filters:
branches:
only: [ main ]
tags:
only: [ /v.*/ ]
publish_hotfix_release:
jobs:
- qqq-orb/mvn_publish:
context: [ qqq-maven-registry-credentials ]
branch_type: hotfix
filters:
branches:
only:
- /hotfix\/.*/
- qqq-orb/generate_pipeline:
orb_version: '0.8'
filters:
branches:
ignore: automation/qbit-rc-pending
tags:
only: /^v\d+\.\d+\.\d+$/
+7
View File
@@ -0,0 +1,7 @@
name: build
on:
push:
jobs:
maven:
uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/maven.yaml@v1
secrets: inherit
+1
View File
@@ -0,0 +1 @@
* @KofTwentyTwo
+23
View File
@@ -0,0 +1,23 @@
name: CodeQL
'on':
push:
branches:
- main
- develop
- release/**
- hotfix/**
pull_request: {}
schedule:
- cron: 41 16 * * 0
workflow_dispatch: {}
permissions:
contents: read
actions: read
security-events: write
packages: read
concurrency:
group: codeql-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
analyze:
uses: QRun-IO/qqq-orb/.github/workflows/qbit-codeql.yml@c288a8864fe9054f68410e1d78f5863aea4c4d22
+1
View File
@@ -1,5 +1,6 @@
# Maven
target/
.flattened-pom.xml
*.jar
*.war
*.ear
+16
View File
@@ -0,0 +1,16 @@
profile: qbit
orb_version: '0.8'
default_branch: main
java_version: '21'
browsers: true
api_checks: false
docs_only: false
release_on_main: false
release_tag_policy: stable
test_branch_policy: non-release
publish:
snapshot: true
release_candidate: true
release: true
asciidoc: false
release_completion: false
+33
View File
@@ -7,6 +7,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.2.0] - 2026-11-06
Published as `com.kingsrook.qbits:qbit-geo-data:0.2.0` on the QRun-IO Gitea Maven
registry. Requires Java 21 and QQQ 4.1 (built against `qqq-bom-pom` 4.1.0-RC.21).
This is the first release that works on QQQ 4.1; 0.1.0 was built against QQQ 0.35.0.
### Changed
- Build against the published QQQ 4.1 core (`qqq-bom-pom` 4.1.0-RC.21) instead of 0.35.0.
- `GeoDataQBitProducer.VERSION` is `0.2.0`.
- Import the project's `junit-bom` 5.10.0 ahead of the QQQ BOM so every JUnit artifact
converges on 5.10.0 and Surefire discovers the tests.
- CI runs on Gitea through the shared `KofTwentyTwo/ci-workflows` Maven workflow
(`main` verifies; a `vX.Y.Z` tag publishes to the Gitea registry).
### Fixed
- `Country`, `StateProvince` and `City` ask for their tables (`produceTableMetaData`)
and expose the setters `QRecordEntity` needs to discover fields, so the producer
creates `<prefix>_country`, `<prefix>_stateProvince` and `<prefix>_city` on core 4.1
instead of zero tables. The producer tolerates a table without fields.
- `GeoDataSyncStep` resolves the bundled `countryAlpha2` / `stateCode` source codes to
the persisted `countryId` / `stateProvinceId` before matching, so states and cities
are persisted (0.1.0 reported success after writing 250 countries and zero states or
cities because those source columns do not exist in the schema).
- Cities match on `stateProvinceId`, `name`, `latitude` and `longitude` at the schema's
seven-decimal precision; city names are not unique within a subdivision.
- Numeric comparisons use `BigDecimal` value equality, so a second run reports zero
inserts, updates or deactivations.
- An inactive existing row whose source entry returns is reactivated.
- Insert and update results are checked; a row rejected by the backend fails the sync
with a `QException` instead of reporting success.
## [0.1.0] - 2025-12-28
### Added
- Multi-module structure (qbit-geo-data-core + tools)
- Country, StateProvince, City entities with sync process
+12
View File
@@ -0,0 +1,12 @@
# qbit-geo-data
## Knowledge base
Reviewed knowledge for this repo and the wider QQQ platform lives in the second-brain vault:
- Platform hub: `R:/Git.Local/KofTwentyTwo/second-brain/knowledge/qqq/qqq-hub.md`
- This repo's dossier: `R:/Git.Local/KofTwentyTwo/second-brain/knowledge/qqq/repos/qbit-geo-data.md`
(reviewed commit `f7889fdf7495` on `main`, 2026-07-04)
- QBit mechanics refresher: `R:/Git.Local/KofTwentyTwo/second-brain/knowledge/qqq/architecture/metadata-model.md`
Key cautions from the review: entities produce PossibleValueSources only (`produceTableMetaData` defaults false — no tables are registered); the sync step's natural keys (`countryAlpha2`/`stateCode`) don't exist in the schema; the `geoDataSync` process name collides on multi-instance registration; pom/README still declare AGPL-3.0 while LICENSE/NOTICE are Apache-2.0; main and develop have diverged.
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright
owner or by an individual or Legal Entity authorized to submit on
behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written
communication sent to the Licensor or its representatives, including
but not limited to communication on electronic mailing lists, source
code control systems, and issue tracking systems that are managed by,
or on behalf of, the Licensor for the purpose of discussing and
improving the Work, but excluding communication that is conspicuously
marked or otherwise designated in writing by the copyright owner as
"Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2022-2025 QRunIO, LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+15
View File
@@ -0,0 +1,15 @@
qBit: Geo Data
Copyright 2022-2025 QRunIO, LLC
This product includes software developed at QRunIO, LLC (https://qrun.io/).
Licensed under the Apache License, Version 2.0.
================================================================================
Trademarks:
QQQ, qBits, qRun, qStudio, and the QRunIO logo are trademarks of QRunIO, LLC.
Use of these trademarks must comply with QRunIO's Trademark Guidelines.
================================================================================
+19 -2
View File
@@ -7,16 +7,33 @@ Geographic reference data QBit providing countries, states/provinces, and cities
## Quick Start
The current release is **0.2.0**. It requires Java 21 and QQQ 4.1 (built against
`qqq-bom-pom` 4.1.0-RC.21). See [CHANGELOG.md](CHANGELOG.md).
Add the dependency to your `pom.xml`:
```xml
<dependency>
<groupId>com.kingsrook.qbits</groupId>
<artifactId>qbit-geo-data-core</artifactId>
<version>${qbit-geo-data.version}</version>
<artifactId>qbit-geo-data</artifactId>
<version>0.2.0</version>
</dependency>
```
Releases are published to the QRun-IO Gitea Maven registry, which requires
authentication for reads as well as writes. Add the repository and a matching
`<server>` entry (with your own Gitea username and token) in your private Maven
`settings.xml`:
```xml
<repository>
<id>qrun-io</id>
<url>https://git.kof22.com/api/packages/QRun-IO/maven</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
```
## What You Get
This QBit provides three entities with pre-populated reference data:
+48 -6
View File
@@ -50,7 +50,8 @@
</modules>
<properties>
<revision>0.1.0-SNAPSHOT</revision>
<revision>0.2.0</revision>
<qqq.version>4.1.0-RC.21</qqq.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -58,11 +59,10 @@
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
<!-- One JUnit line. The QQQ 4.1 BOM inherits junit-jupiter-engine/params at 6.0.2 from qqq-parent-project, while this pom's JUnit BOM
manages junit-jupiter, the API and the platform at 5.10.0; the mixed engine fails discovery ("TestEngine with ID 'junit-jupiter'
failed to discover tests") and no test runs. Import this pom's own JUnit version first (first import wins) so every JUnit
artifact converges on 5.10.0. -->
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
@@ -70,6 +70,19 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Published QQQ 4.1 core (minimum QQQ 4.1), imported ahead of the parent's BOM. -->
<dependency>
<groupId>com.kingsrook.qqq</groupId>
<artifactId>qqq-bom-pom</artifactId>
<version>${qqq.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
@@ -79,6 +92,35 @@
</dependencyManagement>
<build>
<plugins>
<!-- Resolve the CI-friendly ${revision} in the installed and deployed POMs so -->
<!-- consumers of the published artifacts can resolve the parent chain. -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.7.3</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten-clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
@@ -28,7 +28,7 @@ public class GeoDataQBitProducer implements QBitProducer
{
public static final String GROUP_ID = "com.kingsrook.qbits";
public static final String ARTIFACT_ID = "qbit-geo-data";
public static final String VERSION = "0.1.0";
public static final String VERSION = "0.2.0";
private GeoDataQBitConfig config;
@@ -126,6 +126,10 @@ public class GeoDataQBitProducer implements QBitProducer
*******************************************************************************/
private void updateForeignKeyReferences(QTableMetaData table)
{
if(table.getFields() == null)
{
return;
}
table.getFields().values().forEach(field ->
{
if(field.getPossibleValueSourceName() != null)
@@ -14,7 +14,7 @@ import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity;
@QMetaDataProducingEntity(producePossibleValueSource = true)
@QMetaDataProducingEntity(produceTableMetaData = true, producePossibleValueSource = true)
public class City extends QRecordEntity
{
public static final String TABLE_NAME = "city";
@@ -204,4 +204,103 @@ public class City extends QRecordEntity
{
return modifyDate;
}
/*******************************************************************************
** Setter for id (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setId(Integer id)
{
this.id = id;
}
/*******************************************************************************
** Setter for stateProvinceId (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setStateProvinceId(Integer stateProvinceId)
{
this.stateProvinceId = stateProvinceId;
}
/*******************************************************************************
** Setter for name (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setName(String name)
{
this.name = name;
}
/*******************************************************************************
** Setter for asciiName (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setAsciiName(String asciiName)
{
this.asciiName = asciiName;
}
/*******************************************************************************
** Setter for population (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setPopulation(Integer population)
{
this.population = population;
}
/*******************************************************************************
** Setter for latitude (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setLatitude(BigDecimal latitude)
{
this.latitude = latitude;
}
/*******************************************************************************
** Setter for longitude (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setLongitude(BigDecimal longitude)
{
this.longitude = longitude;
}
/*******************************************************************************
** Setter for timezone (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setTimezone(String timezone)
{
this.timezone = timezone;
}
/*******************************************************************************
** Setter for isActive (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setIsActive(Boolean isActive)
{
this.isActive = isActive;
}
/*******************************************************************************
** Setter for createDate (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setCreateDate(Instant createDate)
{
this.createDate = createDate;
}
/*******************************************************************************
** Setter for modifyDate (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setModifyDate(Instant modifyDate)
{
this.modifyDate = modifyDate;
}
}
@@ -13,7 +13,7 @@ import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity;
@QMetaDataProducingEntity(producePossibleValueSource = true)
@QMetaDataProducingEntity(produceTableMetaData = true, producePossibleValueSource = true)
public class Country extends QRecordEntity
{
public static final String TABLE_NAME = "country";
@@ -171,4 +171,85 @@ public class Country extends QRecordEntity
{
return modifyDate;
}
/*******************************************************************************
** Setter for id (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setId(Integer id)
{
this.id = id;
}
/*******************************************************************************
** Setter for alpha2Code (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setAlpha2Code(String alpha2Code)
{
this.alpha2Code = alpha2Code;
}
/*******************************************************************************
** Setter for alpha3Code (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setAlpha3Code(String alpha3Code)
{
this.alpha3Code = alpha3Code;
}
/*******************************************************************************
** Setter for numericCode (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setNumericCode(Integer numericCode)
{
this.numericCode = numericCode;
}
/*******************************************************************************
** Setter for name (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setName(String name)
{
this.name = name;
}
/*******************************************************************************
** Setter for officialName (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setOfficialName(String officialName)
{
this.officialName = officialName;
}
/*******************************************************************************
** Setter for isActive (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setIsActive(Boolean isActive)
{
this.isActive = isActive;
}
/*******************************************************************************
** Setter for createDate (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setCreateDate(Instant createDate)
{
this.createDate = createDate;
}
/*******************************************************************************
** Setter for modifyDate (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setModifyDate(Instant modifyDate)
{
this.modifyDate = modifyDate;
}
}
@@ -13,7 +13,7 @@ import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity;
@QMetaDataProducingEntity(producePossibleValueSource = true)
@QMetaDataProducingEntity(produceTableMetaData = true, producePossibleValueSource = true)
public class StateProvince extends QRecordEntity
{
public static final String TABLE_NAME = "stateProvince";
@@ -155,4 +155,76 @@ public class StateProvince extends QRecordEntity
{
return modifyDate;
}
/*******************************************************************************
** Setter for id (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setId(Integer id)
{
this.id = id;
}
/*******************************************************************************
** Setter for countryId (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setCountryId(Integer countryId)
{
this.countryId = countryId;
}
/*******************************************************************************
** Setter for code (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setCode(String code)
{
this.code = code;
}
/*******************************************************************************
** Setter for name (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setName(String name)
{
this.name = name;
}
/*******************************************************************************
** Setter for subdivisionType (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setSubdivisionType(String subdivisionType)
{
this.subdivisionType = subdivisionType;
}
/*******************************************************************************
** Setter for isActive (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setIsActive(Boolean isActive)
{
this.isActive = isActive;
}
/*******************************************************************************
** Setter for createDate (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setCreateDate(Instant createDate)
{
this.createDate = createDate;
}
/*******************************************************************************
** Setter for modifyDate (QRecordEntity discovers a field only from a getter and setter pair).
*******************************************************************************/
public void setModifyDate(Instant modifyDate)
{
this.modifyDate = modifyDate;
}
}
@@ -4,13 +4,15 @@
** Syncs all three entity types (Country, StateProvince, City) from bundled
** JSON files into database tables. Performs natural key upsert:
** - Country: by alpha2Code
** - StateProvince: by countryAlpha2 + code
** - City: by countryAlpha2 + stateCode + name
** - StateProvince: by countryId + code (countryAlpha2 resolved to the persisted country)
** - City: by stateProvinceId + name + latitude + longitude (codes resolved to the persisted state)
*******************************************************************************/
package com.kingsrook.qbits.geodata.sync;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
@@ -62,9 +64,39 @@ public class GeoDataSyncStep implements BackendStep
// Sync in order: countries first (no dependencies), then states, then //
// cities (which may reference states) //
//////////////////////////////////////////////////////////////////////////
int countriesInserted = syncTable(prefix + "_country", "/data/countries.json", List.of("alpha2Code"));
int statesInserted = syncTable(prefix + "_stateProvince", "/data/states.json", List.of("countryAlpha2", "code"));
int citiesInserted = syncTable(prefix + "_city", "/data/cities.json", List.of("countryAlpha2", "stateCode", "name"));
int countriesInserted = syncTable(prefix + "_country", loadJsonData("/data/countries.json"), List.of("alpha2Code"));
Map<String, QRecord> countries = queryExisting(prefix + "_country", List.of("alpha2Code"));
List<QRecord> states = loadJsonData("/data/states.json");
for(QRecord state : states)
{
QRecord country = countries.get(state.getValueString("countryAlpha2"));
if(country == null)
{
throw new QException("Geo Data state references an unavailable country");
}
state.setValue("countryId", country.getValue("id"));
state.getValues().remove("countryAlpha2");
}
int statesInserted = syncTable(prefix + "_stateProvince", states, List.of("countryId", "code"));
Map<String, QRecord> persistedStates = queryExisting(prefix + "_stateProvince", List.of("countryId", "code"));
List<QRecord> cities = loadJsonData("/data/cities.json");
for(QRecord city : cities)
{
QRecord country = countries.get(city.getValueString("countryAlpha2"));
QRecord state = country == null ? null : persistedStates.get(country.getValue("id") + "|" + city.getValueString("stateCode"));
if(state == null)
{
throw new QException("Geo Data city references an unavailable state");
}
city.setValue("stateProvinceId", state.getValue("id"));
for(String coordinate : List.of("latitude", "longitude"))
{
city.setValue(coordinate, new BigDecimal(city.getValue(coordinate).toString()).setScale(7, RoundingMode.HALF_UP));
}
city.getValues().remove("countryAlpha2");
city.getValues().remove("stateCode");
}
int citiesInserted = syncTable(prefix + "_city", cities, List.of("stateProvinceId", "name", "latitude", "longitude"));
LOG.info("Geo data sync complete",
logPair("prefix", prefix),
@@ -83,17 +115,15 @@ public class GeoDataSyncStep implements BackendStep
** Sync a single table from JSON resource.
** Returns count of records processed.
*******************************************************************************/
private int syncTable(String tableName, String resourcePath, List<String> naturalKeyFields) throws QException
private int syncTable(String tableName, List<QRecord> sourceRecords, List<String> naturalKeyFields) throws QException
{
LOG.info("Syncing table",
logPair("table", tableName),
logPair("resource", resourcePath),
logPair("naturalKey", naturalKeyFields));
/////////////////////////////////////////////////////////////////////////
// 1. Load source data from classpath JSON //
/////////////////////////////////////////////////////////////////////////
List<QRecord> sourceRecords = loadJsonData(resourcePath);
LOG.info("Loaded source data", logPair("count", sourceRecords.size()));
/////////////////////////////////////////////////////////////////////////
@@ -119,7 +149,7 @@ public class GeoDataSyncStep implements BackendStep
source.setValue("isActive", true);
toInsert.add(source);
}
else if(hasChanges(source, existing))
else if(hasChanges(source, existing) || !Boolean.TRUE.equals(existing.getValueBoolean("isActive")))
{
source.setValue("id", existing.getValue("id"));
source.setValue("isActive", true);
@@ -182,7 +212,7 @@ public class GeoDataSyncStep implements BackendStep
key.append("|");
}
Object value = record.getValue(field);
key.append(value != null ? value.toString() : "");
key.append(value instanceof Number ? new BigDecimal(value.toString()).stripTrailingZeros().toPlainString() : value != null ? value.toString() : "");
}
return key.toString();
}
@@ -265,7 +295,14 @@ public class GeoDataSyncStep implements BackendStep
}
Object sourceValue = source.getValue(fieldName);
Object existingValue = existing.getValue(fieldName);
if(!Objects.equals(sourceValue, existingValue))
if(sourceValue instanceof Number && existingValue instanceof Number)
{
if(new BigDecimal(sourceValue.toString()).compareTo(new BigDecimal(existingValue.toString())) != 0)
{
return true;
}
}
else if(!Objects.equals(sourceValue, existingValue))
{
return true;
}
@@ -283,7 +320,7 @@ public class GeoDataSyncStep implements BackendStep
InsertInput insertInput = new InsertInput();
insertInput.setTableName(tableName);
insertInput.setRecords(records);
new InsertAction().execute(insertInput);
requireSuccess(tableName, records.size(), new InsertAction().execute(insertInput).getRecords());
}
@@ -296,6 +333,16 @@ public class GeoDataSyncStep implements BackendStep
UpdateInput updateInput = new UpdateInput();
updateInput.setTableName(tableName);
updateInput.setRecords(records);
new UpdateAction().execute(updateInput);
requireSuccess(tableName, records.size(), new UpdateAction().execute(updateInput).getRecords());
}
/*******************************************************************************
** Do not report a successful sync when a native action rejected rows.
*******************************************************************************/
private void requireSuccess(String tableName, int expected, List<QRecord> records) throws QException
{
if(records == null || records.size() != expected || records.stream().anyMatch(record -> !record.getErrors().isEmpty()))
{
throw new QException("Geo Data persistence failed for table " + tableName);
}
}
}
@@ -78,6 +78,38 @@ class GeoDataQBitProducerTest
/*******************************************************************************
** The enabled entities produce their tables, on the configured backend, with the
** prefix; the possible value sources point at tables that exist. (On core 4.1 an
** entity annotation only produces a table when it asks for it.)
*******************************************************************************/
@Test
void testProduce_createsTablesAndPossibleValueSourcesPointAtThem() throws QException
{
QInstance qInstance = new QInstance();
qInstance.addBackend(new QBackendMetaData().withName("rdbms"));
new GeoDataQBitProducer()
.withConfig(new GeoDataQBitConfig().withBackendName("rdbms").withTableNamePrefix("geo")
.withEnableCountries(true).withEnableStateProvinces(true).withEnableCities(true))
.produce(qInstance, "geo");
assertThat(qInstance.getTables().keySet()).contains("geo_country", "geo_stateProvince", "geo_city");
assertThat(qInstance.getTable("geo_city").getBackendName()).isEqualTo("rdbms");
assertThat(qInstance.getTable("geo_country").getPrimaryKeyField()).isEqualTo("id");
assertThat(qInstance.getTable("geo_country").getFields().keySet()).contains("alpha2Code", "name", "isActive");
assertThat(qInstance.getTable("geo_city").getFields().keySet()).contains("name");
for(var pvs : qInstance.getPossibleValueSources().values())
{
if(pvs.getTableName() != null)
{
assertThat(qInstance.getTable(pvs.getTableName())).as(pvs.getName()).isNotNull();
}
}
}
/*******************************************************************************
** Test that producer stores config in QBit metadata.
*******************************************************************************/
@@ -133,6 +165,6 @@ class GeoDataQBitProducerTest
{
assertThat(GeoDataQBitProducer.GROUP_ID).isEqualTo("com.kingsrook.qbits");
assertThat(GeoDataQBitProducer.ARTIFACT_ID).isEqualTo("qbit-geo-data");
assertThat(GeoDataQBitProducer.VERSION).isEqualTo("0.1.0");
assertThat(GeoDataQBitProducer.VERSION).isEqualTo("0.2.0");
}
}