From 2b04d936cf73d25be073aa72edf2069502718db0 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sat, 7 Nov 2026 14:01:29 -0600 Subject: [PATCH 1/5] ci: build on the shared ci-workflows container workflow Replace the retired CircleCI qqq-orb pipeline and the GitHub release workflow (qqq-orb caller) with KofTwentyTwo/ci-workflows container.yaml@v1. Every push runs the script unit tests, mvn verify and the packaged core HTTP smoke check, then builds and Trivy-scans the image; develop pushes git.kof22.com/qrun-io/qqq-all (ci--run- and develop). Co-Authored-By: Claude Opus 5.5 --- .circleci/config.yml | 14 --------- .gitea/workflows/build.yaml | 22 +++++++++++++++ .github/workflows/release.yml | 53 ----------------------------------- .qqq-ci.yml | 6 ---- README.md | 4 +-- docs/release.md | 2 +- 6 files changed, 25 insertions(+), 76 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .gitea/workflows/build.yaml delete mode 100644 .github/workflows/release.yml delete mode 100644 .qqq-ci.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 18fd9f1..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2.1 -setup: true -orbs: - qqq-orb: kingsrook/qqq-orb@0.8 -workflows: - setup: - jobs: - - qqq-orb/generate_pipeline: - orb_version: '0.8' - filters: - branches: - ignore: automation/qbit-rc-pending - tags: - only: /.*/ diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..5dfe6b2 --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,22 @@ +name: build +on: + push: +jobs: + container: + uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/container.yaml@v1 + secrets: inherit + with: + # Same gates as the old orb build-and-test + core smoke: script unit tests, + # the full reactor (BOM tests, packaged integration tests), then the packaged + # core jar smoked over HTTP. The Dockerfile copies that verified jar. + prebuild: | + set -euo pipefail + apt-get update -qq && apt-get install -y -qq --no-install-recommends python3 > /dev/null + python3 -m unittest discover -s scripts -p 'test_*.py' -v + mvn verify + python3 scripts/run_core_smoke.py qqq-all-app/target/qqq-all-app.jar + images: | + qqq-all|Dockerfile|. + # develop pushes git.kof22.com/qrun-io/qqq-all:ci--run- plus the moving develop tag. + publish-branch: develop + extra-tags: develop diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 138db2e..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Release 4.1.0 -'on': - workflow_dispatch: - inputs: - version: - description: Reviewed source version (GA or exact coordinated RC) - required: true - type: choice - default: 4.1.0 - options: - - 4.1.0 - - 4.1.0-RC.1 - release_sha: - description: Full develop commit SHA already signed and tagged with the selected - version - required: true - type: string - smoke_run_id: - description: Successful Smoke workflow run ID for that exact develop SHA - required: false - type: string - default: '' - smoke_evidence: - description: Evidence provider; github preserves the original Smoke workflow - validation - type: choice - default: circle - options: - - github - - circle - required: true - circle_workflow_id: - description: Exact successful Circle workflow UUID when circle evidence is - selected - type: string - required: false - default: '' -permissions: - actions: read - contents: write - packages: write - checks: read -jobs: - release: - uses: QRun-IO/qqq-orb/.github/workflows/qqq-all-release.yml@0f33ddadf88b9a1b940b8883782fe2000ee1d2bd - with: - version: ${{ inputs.version }} - release_sha: ${{ inputs.release_sha }} - smoke_run_id: ${{ inputs.smoke_run_id }} - smoke_evidence: ${{ inputs.smoke_evidence }} - circle_workflow_id: ${{ inputs.circle_workflow_id }} - secrets: - CIRCLECI_TOKEN: ${{ secrets.CIRCLECI_TOKEN }} diff --git a/.qqq-ci.yml b/.qqq-ci.yml deleted file mode 100644 index 8617bfa..0000000 --- a/.qqq-ci.yml +++ /dev/null @@ -1,6 +0,0 @@ -profile: all -orb_version: '0.8' -default_branch: develop -publish: - snapshot: true -publish_context: qqq-maven-registry-credentials diff --git a/README.md b/README.md index 2513d1b..c3f714c 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,9 @@ Full adds sample tables on PostgreSQL, MySQL, MongoDB, MinIO S3, and SFTP. It in To stop the full stack, run `docker compose --profile full down`. Add `--volumes` only when you intend to erase demo data. For a fresh Artemis volume, the configured login is required; old volumes created for anonymous access should be recreated. This reference stack uses demo credentials and is not a production deployment. -The [canonical QQQ pipeline](.circleci/config.yml), configured by [.qqq-ci.yml](.qqq-ci.yml), builds once and runs core/full smoke checks through the shared orb. Its develop-image job publishes to GHCR only after the container package exists and its visibility is public. Until then, image publication is skipped and local Compose remains available. +CI runs [.gitea/workflows/build.yaml](.gitea/workflows/build.yaml) through the shared `KofTwentyTwo/ci-workflows` container workflow: script unit tests, `mvn verify`, and the packaged core HTTP smoke check on every push, then the image build and Trivy scan. Pushes to `develop` publish `git.kof22.com/qrun-io/qqq-all` (`ci--run-` and `develop`). The full Compose smoke check runs locally with `python3 scripts/run_full_smoke.py`. -The [4.1.0 release procedure](docs/release.md) describes the separate Maven parent/BOM publication path and the manually gated, exact-commit [release workflow](.github/workflows/release.yml). The workflow will not release the current snapshot build. +The [4.1.0 release procedure](docs/release.md) describes the separate Maven parent/BOM publication path. The GitHub release workflow that called the retired qqq-orb was removed; a versioned release path on Gitea is not defined yet. ## Contributing and license diff --git a/docs/release.md b/docs/release.md index c534f22..38aea33 100644 --- a/docs/release.md +++ b/docs/release.md @@ -1,6 +1,6 @@ # 4.1.0 release preparation -This procedure prepares a release; this repository currently remains on `4.1.0-SNAPSHOT`. The [manual release workflow](../.github/workflows/release.yml) publishes the versioned GHCR image and a GitHub release containing an image-based Compose bundle plus `compose.yaml`. It does **not** deploy Maven artifacts or create a tag. Publication is authorized once the release gates pass. Keep the workflow disabled until Apache-2.0 alignment, public artifact verification and GHCR visibility are complete. +This procedure prepares a release; this repository currently remains on `4.1.0-SNAPSHOT`. The GitHub manual release workflow (GHCR image plus Compose bundle, via the retired qqq-orb) was removed with the move to Gitea CI; `develop` images now publish to `git.kof22.com/qrun-io/qqq-all`. A versioned release path on Gitea is not defined yet. ## Exact coordinated RC under QQQ #921 -- 2.54.0 From 0e80a5e7367d22fddb4a31c577dcbae478e93af5 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sat, 7 Nov 2026 14:03:07 -0600 Subject: [PATCH 2/5] ci: install checksum-pinned Python for the smoke scripts The job image runs unprivileged without python3, so apt is unavailable. Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 5dfe6b2..4806834 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -11,7 +11,9 @@ jobs: # core jar smoked over HTTP. The Dockerfile copies that verified jar. prebuild: | set -euo pipefail - apt-get update -qq && apt-get install -y -qq --no-install-recommends python3 > /dev/null + # The smoke scripts need Python 3 (stdlib only); the job image has none and no root for apt. + (mkdir -p /tmp/python && cd /tmp/python && curl -fsSLo python.tgz https://github.com/astral-sh/python-build-standalone/releases/download/20261013/cpython-3.12.15%2B20261013-x86_64-unknown-linux-gnu-install_only.tar.gz && echo "5d546fc004fc2435fa142eb8f42ed8de5eb4725963dc22f7e6671014a80eb560 python.tgz" | sha256sum -c - && tar -xzf python.tgz --strip-components=1 && rm python.tgz) + export PATH=/tmp/python/bin:$PATH python3 -m unittest discover -s scripts -p 'test_*.py' -v mvn verify python3 scripts/run_core_smoke.py qqq-all-app/target/qqq-all-app.jar -- 2.54.0 From 22bb23613fe9f90d27892622fa0501cd3836089d Mon Sep 17 00:00:00 2001 From: James Maes Date: Sat, 7 Nov 2026 14:03:38 -0600 Subject: [PATCH 3/5] ci: one command per line for the Python install Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 4806834..6ba6a88 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -12,7 +12,10 @@ jobs: prebuild: | set -euo pipefail # The smoke scripts need Python 3 (stdlib only); the job image has none and no root for apt. - (mkdir -p /tmp/python && cd /tmp/python && curl -fsSLo python.tgz https://github.com/astral-sh/python-build-standalone/releases/download/20261013/cpython-3.12.15%2B20261013-x86_64-unknown-linux-gnu-install_only.tar.gz && echo "5d546fc004fc2435fa142eb8f42ed8de5eb4725963dc22f7e6671014a80eb560 python.tgz" | sha256sum -c - && tar -xzf python.tgz --strip-components=1 && rm python.tgz) + mkdir -p /tmp/python + curl -fsSLo /tmp/python.tgz https://github.com/astral-sh/python-build-standalone/releases/download/20261013/cpython-3.12.15%2B20261013-x86_64-unknown-linux-gnu-install_only.tar.gz + echo "5d546fc004fc2435fa142eb8f42ed8de5eb4725963dc22f7e6671014a80eb560 /tmp/python.tgz" | sha256sum -c - + tar -xzf /tmp/python.tgz -C /tmp/python --strip-components=1 && rm /tmp/python.tgz export PATH=/tmp/python/bin:$PATH python3 -m unittest discover -s scripts -p 'test_*.py' -v mvn verify -- 2.54.0 From 30820a6d4fdac9fd7d0ad86c1d2b130c13635c37 Mon Sep 17 00:00:00 2001 From: James Maes Date: Sat, 7 Nov 2026 14:05:00 -0600 Subject: [PATCH 4/5] ci: keep the script tests green on Gitea CI The CI-contract test now checks the Gitea workflow smokes the Maven final jar (the orb .qqq-ci.yml is gone). The release-bundle test renders compose.yaml with docker compose config, so CI installs a checksum-pinned Compose binary behind a docker compose-only shim. Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 6 ++++++ scripts/test_smoke.py | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 6ba6a88..b39d46a 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -16,6 +16,12 @@ jobs: curl -fsSLo /tmp/python.tgz https://github.com/astral-sh/python-build-standalone/releases/download/20261013/cpython-3.12.15%2B20261013-x86_64-unknown-linux-gnu-install_only.tar.gz echo "5d546fc004fc2435fa142eb8f42ed8de5eb4725963dc22f7e6671014a80eb560 /tmp/python.tgz" | sha256sum -c - tar -xzf /tmp/python.tgz -C /tmp/python --strip-components=1 && rm /tmp/python.tgz + # The release-bundle and full-smoke config tests render compose.yaml with `docker compose config` + # (no daemon). Provide the Compose binary behind a `docker compose`-only shim. + curl -fsSLo /tmp/python/bin/docker-compose https://github.com/docker/compose/releases/download/v5.6.1/docker-compose-linux-x86_64 + echo "47737f4236e6d3ccea7291995203f8f018058783b4c3a9469119811a0b5db8c0 /tmp/python/bin/docker-compose" | sha256sum -c - + printf '%s\n' '#!/bin/sh' '[ "$1" = compose ] || { echo "only docker compose is installed" >&2; exit 1; }' 'shift' 'exec docker-compose "$@"' > /tmp/python/bin/docker + chmod +x /tmp/python/bin/docker-compose /tmp/python/bin/docker export PATH=/tmp/python/bin:$PATH python3 -m unittest discover -s scripts -p 'test_*.py' -v mvn verify diff --git a/scripts/test_smoke.py b/scripts/test_smoke.py index 71fe043..42585fa 100644 --- a/scripts/test_smoke.py +++ b/scripts/test_smoke.py @@ -148,11 +148,11 @@ class SmokeTest(unittest.TestCase): pom = ET.parse(ROOT / "qqq-all-app" / "pom.xml") final_name = pom.findtext(".//{http://maven.apache.org/POM/4.0.0}build/" "{http://maven.apache.org/POM/4.0.0}finalName") - # The shared all profile owns the smoke command; this repository owns - # the Maven artifact it consumes. Keep that cross-repository contract. + # CI smokes the exact jar Maven builds; keep the build output and the + # CI smoke command on the same artifact path. self.assertEqual("qqq-all-app", final_name) - manifest = (ROOT / ".qqq-ci.yml").read_text() - self.assertRegex(manifest, r"(?m)^profile: all$") + workflow = (ROOT / ".gitea" / "workflows" / "build.yaml").read_text() + self.assertIn("python3 scripts/run_core_smoke.py qqq-all-app/target/qqq-all-app.jar", workflow) def test_standalone_full_smoke_requires_explicit_search_endpoint(self): -- 2.54.0 From 0740fab02701fd79edbe5f0477eee38eaf01958f Mon Sep 17 00:00:00 2001 From: James Maes Date: Sat, 7 Nov 2026 14:13:31 -0600 Subject: [PATCH 5/5] build(image): apply Ubuntu security updates in the runtime image The eclipse-temurin:21-jre-jammy base ships apt 2.4.14 (HIGH CVE-2026-109518, fixed in 2.4.15ubuntu0.1), which the CI Trivy gate blocks. Upgrade installed packages when building the image. Co-Authored-By: Claude Opus 5.5 --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 4368c91..412bec4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ FROM eclipse-temurin:21-jre-jammy RUN apt-get update \ + && apt-get upgrade -y --no-install-recommends \ && apt-get install -y --no-install-recommends curl \ && rm -rf /var/lib/apt/lists/* \ && groupadd --system --gid 10001 qqq \ -- 2.54.0