Compare commits

..
35 Commits
Author SHA1 Message Date
james.maes aa9e6c5563 Merge pull request 'build(deps): align with Gitea registry (parent 2.2.1, QQQ 4.1.0-RC.26)' (#32) from deps/align-gitea into develop
build / maven (push) Successful in 5m24s
maven / build (push) Successful in 5m23s
2026-11-07 18:08:21 +00:00
james.maesandClaude Opus 5.5 03127c17a3 build(deps): align with Gitea registry (parent 2.2.1, QQQ 4.1.0-RC.26)
build / maven (push) Successful in 1m56s
maven / build (push) Successful in 1m55s
pom.xml: parent -> 2.2.1
pom.xml: qqq.snapshot.version: 4.1.0-SNAPSHOT -> 4.1.0-RC.26
pom.xml: removed Central snapshot repository
pom.xml: added qqq.version=4.1.0-RC.26 (parent BOM import)
pom.xml: revision -> 0.3.0-SNAPSHOT

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 18:03:19 +00:00
james.maes e4d4b9277b Merge pull request 'ci: pin shared workflow to v1' (#28) from ci/pin-v1-develop into develop
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (push) Successful in 14s
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: ci / repository-policy (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-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (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 / 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 14s
QRun-IO/ci-policy: native / native-result (push) Successful in 13s
build / maven (push) Successful in 3m45s
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (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-business (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 3m45s
2026-11-06 16:07:46 +00:00
james.maesandClaude Opus 5.5 d37fc6c51f ci: pin shared workflow to v1
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (pull_request) Successful in 7s
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 / 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-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 / java-maven-7-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-mcp (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: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 5s
build / maven (push) Successful in 2m49s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 5s
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-10 (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 / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
maven / build (push) Successful in 2m49s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:10:21 +00:00
james.maes 1dc87efceb Merge pull request 'ci: use shared ci-workflows Maven workflow' (#26) from ci/ci-workflows-develop into develop
build / maven (push) Successful in 1m55s
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: native / dotnet-0 (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 / java-core-2-head (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (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 / 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) Waiting to run
maven / build (push) Successful in 1m55s
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (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-business (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:41 +00:00
CI 6918b1643a ci: rerun checks after dispatcher retirement
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 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-core-2-head (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 / java-maven-7-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-mcp (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: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 5s
build / maven (push) Successful in 1m37s
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-10 (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 / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 5s
maven / build (push) Successful in 1m37s
2026-11-05 17:18:39 -06:00
CI 0e361584dc ci: rerun shared workflow
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 1b3648d9421543350067e95e54959dfb471b26d5] (pull_request) Successful in 10s
build / maven (push) Successful in 1m28s
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-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-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-mcp (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: ci / not-enrolled (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 49s
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Failing after 10s
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Failing after 11m31s
QRun-IO/ci-policy: ci / ci-result (pull_request) Failing after 6s
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 7s
maven / build (push) Successful in 1m27s
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-docker-3-head (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-10 (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 / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
2026-11-05 16:25:26 -06:00
james.maesandClaude Opus 5.5 6995077319 ci: use shared ci-workflows Maven workflow
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
build / maven (push) Failing after 2s
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1b3648d9421543350067e95e54959dfb471b26d5] (pull_request) Failing after 2s
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-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 / java-maven-7-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-mcp (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: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / ci-result (pull_request) Canceled after 0s
maven / build (push) Failing after 2s
QRun-IO/ci-policy: native / native-result (pull_request) Failing after 1s
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-10 (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 / android-0 (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:12:52 +00:00
forge-recovery 5db6927c8e ci: enroll shared Gitea lifecycle
QRun-IO/ci-policy: Shared Java Maven CI / verify (push) Successful in 56s
Shared Java Maven CI / verify (push) Successful in 1m28s
qrun-release / postpublish (push) Successful in 12m22s
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (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 / source-config-14 (push) Skipped
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
Shared Java Maven CI / secrets (push) Successful in 47s
QRun-IO/ci-policy: Shared Java Maven CI / secrets (push) Successful in 48s
QRun-IO/ci-policy: ci / repository-policy (push) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (push) Skipped
QRun-IO/ci-policy: native / native-result (push) Successful in 7s
QRun-IO/ci-policy: ci / ci-result (push) Successful in 7s
QRun-IO/ci-policy: Shared Java Maven CI / gate (push) Successful in 17s
QRun-IO/ci-policy: ci / java-maven-6 (push) Successful in 46m52s
Shared Java Maven CI / gate (push) Successful in 14s
qrun-release / release (push) Successful in 47m5s
Shared QRun source version / version (push) Successful in 12m22s
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (push) Skipped
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:41 +00:00
fba6f7f903 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
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (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 28s
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-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 51s
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Successful in 11s
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Successful in 2h58m58s
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-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-10 (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 / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 5s
Shared Java Maven CI / gate (push) Canceled after 0s
qrun-release / release (push) Canceled after 2h37m15s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 15:49:36 +00:00
139927057a 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 / java-docker-2 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-3 (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
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 3s
Shared Java Maven CI / secrets (push) Successful in 37s
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 1m22s
QRun-IO/ci-policy: ci / java-maven-4 (pull_request) Canceled after 57m20s
Shared Java Maven CI / gate (push) Canceled after 0s
qrun-release / release (push) Canceled after 57m59s
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-7 (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 6s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 06:18:26 +00:00
forge-recoveryandCodex 587b1fef3f 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 / java-docker-2 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-3 (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: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Failing after 2s
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 0s
QRun-IO/ci-policy: ci / ci-result (pull_request) Failing after 1s
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 2m18s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 04:11:57 +00:00
james.maes cef870f46e Merge pull request #20 from QRun-IO/fix/develop-codeql-20261029
ci: restore develop CodeQL scanning
2026-10-29 12:33:37 -05:00
James MaesandCodex adefa969c8 ci: scan develop with the shared CodeQL workflow
Co-Authored-By: Codex (GPT-6) <noreply@openai.com>
2026-10-29 12:30:09 -05:00
james.maesandCodex 2ae5150012 ci: enroll in the shared QQQ orb (#19)
Co-authored-by: Codex <noreply@openai.com>
2026-10-21 21:08:52 -05:00
james.maes 1383d92f0a Merge pull request #10 from QRun-IO/feature/ga-only-release-tags
ci: publish only GA tags (vX.Y.Z), never RC tags
2026-10-12 16:02:43 -05:00
james.maesandClaude Opus 5.5 d9c313ffca ci: publish only GA tags (vX.Y.Z), never RC tags
An RC tag matched /v.*/ and the orb republished it as the next RC.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:00:28 -05:00
james.maes 45facd1b31 Merge pull request #8 from QRun-IO/feature/GH-945-assertj-3277
fix(deps): update test AssertJ to 3.27.7 (QQQ #945)
2026-10-01 00:06:22 -05:00
james.maes 253e15b77c fix(deps): update test AssertJ to 3.27.7 2026-10-01 00:04:06 -05:00
james.maes fa731308f1 Merge pull request #7 from QRun-IO/feature/GH-944-packaged-notices
fix(#944): locate root notices for geo modules
2026-09-30 23:46:23 -05:00
james.maes 93ebe812fc Merge develop into packaged-notices branch (#944) 2026-09-30 23:44:36 -05:00
james.maes 2c403b77c8 fix(#944): locate root notices for geo modules 2026-09-30 23:40:11 -05:00
james.maes e96b49beb6 fix: align first-party Apache-2.0 declarations (#6)
Refs QRun-IO/qqq#923.
2026-09-30 20:21:30 -05:00
james.maes 64723faa2a fix: align first-party Apache-2.0 declarations
Refs QRun-IO/qqq#923.
2026-09-30 20:17:46 -05:00
james.maes d745a3753a ci: require release tags and pin QQQ orb 0.6.8 (#5)
* ci: retain main tests and gate GA publication on tags

Refs QRun-IO/qqq-all#10. Preserve reviewed selectors; version pins remain separate and publication remains gated.

* ci: pin settings-safe QQQ orb 0.6.8

Use the reviewed immutable release tooling for QRun-IO/qqq-all#10.
2026-09-30 10:50:03 -05:00
james.maes 68f6a6309b build: flatten published poms (#4)
Refs QRun-IO/qqq#785. Part of QRun-IO/qqq-all#1.
2026-09-26 02:12:28 -05:00
james.maes 3cf53b5f1a build: re-pin to qbit-build-parent 2.0.0 (#3)
Closes QRun-IO/qqq#769. Part of QRun-IO/qqq-all#1.
2026-09-26 01:09:18 -05:00
james.maes a73162babb docs: note qqq 4.0.0 re-pin and Java 21 prerequisite
Part of QRun-IO/qqq-all#1
2026-09-25 20:43:14 -05:00
james.maes 4e9c047fdb ci: keep apt unattended on CircleCI machine images
Adds the configure-package-install pre-step from qbit-quick-search so needrestart cannot stall install_java (QRun-IO/qqq-orb#11).

Part of QRun-IO/qqq-all#1
2026-09-25 20:42:59 -05:00
james.maes 6ae6f3dfdd build: add opt-in qqq-snapshot profile
Imports qqq-bom-pom ${qqq.snapshot.version} (default 4.1.0-SNAPSHOT) ahead of the parent's BOM, from Central snapshots.

Part of QRun-IO/qqq-all#1
2026-09-25 20:42:17 -05:00
james.maes 2f87fbb31a build: re-pin to qbit-build-parent 2.0.0 (qqq 4.0.0)
The parent imports qqq-bom-pom 4.0.0; qqq modules keep taking their versions from it.

Part of QRun-IO/qqq-all#1
2026-09-25 20:41:32 -05:00
james.maes 819b3da7d7 chore: merge main into develop
Part of QRun-IO/qqq-all#1
2026-09-25 20:39:25 -05:00
CircleCI b9eaa6cf48 Bump version to 0.2.0-SNAPSHOT [skip ci] 2025-12-29 12:42:41 +00:00
james.maes e6a2ce7f58 fix(claude): removed settings 2025-12-29 06:40:40 -06:00
james.maes 3ae9356462 build(gitignore): added claude settings 2025-12-29 06:40:03 -06:00
18 changed files with 101 additions and 476 deletions

No files matched your search

-1
View File
@@ -1 +0,0 @@
Central Java verification, tests and secret scan are supplied by the organization-scoped workflow.
-22
View File
@@ -1,22 +0,0 @@
{
"permissions": {
"allow": [
"Bash(wc:*)",
"Bash(mvn clean compile:*)",
"Bash(mvn compile:*)",
"Bash(find:*)",
"Bash(mvn test:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(git push:*)",
"Bash(mvn clean test:*)",
"Bash(gh pr create:*)",
"Bash(gh pr merge:*)",
"Bash(git checkout:*)",
"Bash(git pull:*)",
"Bash(git merge:*)",
"mcp__circleci-mcp-server__get_latest_pipeline_status",
"mcp__circleci-mcp-server__get_build_failure_logs"
]
}
}
+1 -1
View File
@@ -3,5 +3,5 @@ on:
push:
jobs:
maven:
uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/maven.yaml@main
uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/maven.yaml@v1
secrets: inherit
+5 -1
View File
@@ -1,6 +1,5 @@
# Maven
target/
.flattened-pom.xml
*.jar
*.war
*.ear
@@ -22,3 +21,8 @@ Thumbs.db
# Generated
generated/
.claude/
# flatten-maven-plugin output
.flattened-pom.xml
+2 -2
View File
@@ -7,10 +7,10 @@ api_checks: false
docs_only: false
release_on_main: false
release_tag_policy: stable
test_branch_policy: non-release
test_branch_policy: non-release-no-hotfix-integration
publish:
snapshot: true
release_candidate: true
release: true
hotfix: true
asciidoc: false
release_completion: false
+4 -33
View File
@@ -7,39 +7,6 @@ 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
@@ -52,6 +19,10 @@ This is the first release that works on QQQ 4.1; 0.1.0 was built against QQQ 0.3
### Changed
- Upgraded to QQQ 0.35.0 with Java 21 support
- Re-pinned to qbit-build-parent 2.0.0 (QQQ 4.0.0); opt-in `qqq-snapshot` Maven profile builds against QQQ 4.1.0-SNAPSHOT
### Fixed
- Published module poms name their parent by its real version instead of `${revision}` (flatten-maven-plugin)
## [0.1.0-alpha] - 2024-12-28
+1 -1
View File
@@ -9,4 +9,4 @@ Reviewed knowledge for this repo and the wider QQQ platform lives in the second-
(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.
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; current first-party pom/README declarations align with Apache-2.0 LICENSE/NOTICE; main and develop have diverged.
+10 -20
View File
@@ -7,33 +7,16 @@ 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</artifactId>
<version>0.2.0</version>
<artifactId>qbit-geo-data-core</artifactId>
<version>${qbit-geo-data.version}</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:
@@ -179,4 +162,11 @@ The generator creates a changelog with your prefix substituted and only includes
## License
AGPL-3.0 - See [LICENSE](LICENSE)
Both Maven child modules set `qbit.noticesDirectory` to their parent directory,
where this repository's `LICENSE` and `NOTICE` live. This supports the shared
notice packaging correction in `qbit-build-parent`; it takes effect after adopting
a parent version containing that correction. Existing public parent 2.0.0 is
unchanged. Verify each generated module archive against these root files when
integrating the new parent.
Apache-2.0 - See [LICENSE](LICENSE)
+50 -40
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.kingsrook</groupId>
<artifactId>qbit-build-parent</artifactId>
<version>1.5.1</version>
<version>2.2.1</version>
</parent>
<groupId>com.kingsrook.qbits</groupId>
@@ -21,8 +21,8 @@
<licenses>
<license>
<name>GNU Affero General Public License v3.0</name>
<url>https://www.gnu.org/licenses/agpl-3.0.html</url>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
<distribution>repo</distribution>
</license>
</licenses>
@@ -50,8 +50,8 @@
</modules>
<properties>
<revision>0.2.0</revision>
<qqq.version>4.1.0-RC.21</qqq.version>
<qqq.version>4.1.0-RC.26</qqq.version> <!-- feeds qbit-build-parent's qqq-bom-pom import -->
<revision>0.3.0-SNAPSHOT</revision>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -59,10 +59,11 @@
<dependencyManagement>
<dependencies>
<!-- 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.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
@@ -70,31 +71,31 @@
<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>
<version>3.27.3</version>
<version>3.27.7</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- Resolve the CI-friendly ${revision} in the installed and deployed POMs so -->
<!-- consumers of the published artifacts can resolve the parent chain. -->
<!-- Replace ${revision} with its value in the poms that get installed and published. -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
@@ -112,7 +113,7 @@
</goals>
</execution>
<execution>
<id>flatten-clean</id>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
@@ -121,19 +122,28 @@
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<!-- Opt-in check against the next qqq line: mvn -B verify -Pqqq-snapshot -->
<!-- (override the version with -Dqqq.snapshot.version=...). Default builds -->
<!-- take the qqq version only from qbit-build-parent. -->
<profile>
<id>qqq-snapshot</id>
<properties>
<qqq.snapshot.version>4.1.0-RC.26</qqq.snapshot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.kingsrook.qqq</groupId>
<artifactId>qqq-bom-pom</artifactId>
<version>${qqq.snapshot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</profile>
</profiles>
</project>
@@ -2,9 +2,9 @@
## Prerequisites
- Java 17+
- Java 21+
- Maven 3.8+
- QQQ 0.23.0+
- QQQ 4.0.0+
## Creating Your Data QBit
+4
View File
@@ -13,6 +13,10 @@
<artifactId>qbit-geo-data</artifactId>
<packaging>jar</packaging>
<properties>
<qbit.noticesDirectory>${project.basedir}/..</qbit.noticesDirectory>
</properties>
<name>QBit Geographic Data</name>
<description>Geographic reference data for QQQ applications - countries, states/provinces, and cities</description>
@@ -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.2.0";
public static final String VERSION = "0.1.0";
private GeoDataQBitConfig config;
@@ -126,10 +126,6 @@ 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(produceTableMetaData = true, producePossibleValueSource = true)
@QMetaDataProducingEntity(producePossibleValueSource = true)
public class City extends QRecordEntity
{
public static final String TABLE_NAME = "city";
@@ -204,103 +204,4 @@ 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(produceTableMetaData = true, producePossibleValueSource = true)
@QMetaDataProducingEntity(producePossibleValueSource = true)
public class Country extends QRecordEntity
{
public static final String TABLE_NAME = "country";
@@ -171,85 +171,4 @@ 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(produceTableMetaData = true, producePossibleValueSource = true)
@QMetaDataProducingEntity(producePossibleValueSource = true)
public class StateProvince extends QRecordEntity
{
public static final String TABLE_NAME = "stateProvince";
@@ -155,76 +155,4 @@ 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,15 +4,13 @@
** Syncs all three entity types (Country, StateProvince, City) from bundled
** JSON files into database tables. Performs natural key upsert:
** - Country: by alpha2Code
** - StateProvince: by countryId + code (countryAlpha2 resolved to the persisted country)
** - City: by stateProvinceId + name + latitude + longitude (codes resolved to the persisted state)
** - StateProvince: by countryAlpha2 + code
** - City: by countryAlpha2 + stateCode + name
*******************************************************************************/
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;
@@ -64,39 +62,9 @@ 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", 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"));
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"));
LOG.info("Geo data sync complete",
logPair("prefix", prefix),
@@ -115,15 +83,17 @@ public class GeoDataSyncStep implements BackendStep
** Sync a single table from JSON resource.
** Returns count of records processed.
*******************************************************************************/
private int syncTable(String tableName, List<QRecord> sourceRecords, List<String> naturalKeyFields) throws QException
private int syncTable(String tableName, String resourcePath, 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()));
/////////////////////////////////////////////////////////////////////////
@@ -149,7 +119,7 @@ public class GeoDataSyncStep implements BackendStep
source.setValue("isActive", true);
toInsert.add(source);
}
else if(hasChanges(source, existing) || !Boolean.TRUE.equals(existing.getValueBoolean("isActive")))
else if(hasChanges(source, existing))
{
source.setValue("id", existing.getValue("id"));
source.setValue("isActive", true);
@@ -212,7 +182,7 @@ public class GeoDataSyncStep implements BackendStep
key.append("|");
}
Object value = record.getValue(field);
key.append(value instanceof Number ? new BigDecimal(value.toString()).stripTrailingZeros().toPlainString() : value != null ? value.toString() : "");
key.append(value != null ? value.toString() : "");
}
return key.toString();
}
@@ -295,14 +265,7 @@ public class GeoDataSyncStep implements BackendStep
}
Object sourceValue = source.getValue(fieldName);
Object existingValue = existing.getValue(fieldName);
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))
if(!Objects.equals(sourceValue, existingValue))
{
return true;
}
@@ -320,7 +283,7 @@ public class GeoDataSyncStep implements BackendStep
InsertInput insertInput = new InsertInput();
insertInput.setTableName(tableName);
insertInput.setRecords(records);
requireSuccess(tableName, records.size(), new InsertAction().execute(insertInput).getRecords());
new InsertAction().execute(insertInput);
}
@@ -333,16 +296,6 @@ public class GeoDataSyncStep implements BackendStep
UpdateInput updateInput = new UpdateInput();
updateInput.setTableName(tableName);
updateInput.setRecords(records);
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);
}
new UpdateAction().execute(updateInput);
}
}
@@ -78,38 +78,6 @@ 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.
*******************************************************************************/
@@ -165,6 +133,6 @@ class GeoDataQBitProducerTest
{
assertThat(GeoDataQBitProducer.GROUP_ID).isEqualTo("com.kingsrook.qbits");
assertThat(GeoDataQBitProducer.ARTIFACT_ID).isEqualTo("qbit-geo-data");
assertThat(GeoDataQBitProducer.VERSION).isEqualTo("0.2.0");
assertThat(GeoDataQBitProducer.VERSION).isEqualTo("0.1.0");
}
}
+4
View File
@@ -13,6 +13,10 @@
<artifactId>qbit-geo-data-tools</artifactId>
<packaging>jar</packaging>
<properties>
<qbit.noticesDirectory>${project.basedir}/..</qbit.noticesDirectory>
</properties>
<name>QBit Geographic Data - Tools</name>
<description>Data acquisition and formatting utilities for geo-data</description>