# 4.1.0 release preparation 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 The same workflow accepts only `4.1.0` (default GA path) or exact `4.1.0-RC.1`. For the [coordinated RC chain](https://github.com/QRun-IO/qqq/issues/921), first publish and verify the accepted Next candidate, QQQ `v4.1.0-RC.1`, and the corresponding build parent/eight QBits. Then review actual source pins: root `revision` and BOM `qqq.version` both `4.1.0-RC.1`, explicit accepted Next version, and immutable published QBit versions. No command-line version overrides substitute for source edits. The current RC8/snapshot pins are intentionally unchanged and cannot pass release validation. Acceptance limitations belong to the exact accepted pair; the RC8 notes below are historical evidence, not automatic approval for a newer pair. Use the existing `release-central` profile and the parent/BOM-only command below to stage the exact RC POMs for **manual** Central review (`autoPublish=false`). Its enforcers accept only GA or exact RC1, require the QQQ pin to equal the source revision, and reject snapshot/range/LATEST dependency pins. After both POMs are public and the reviewed source is merged, require a successful CircleCI `verify-and-smoke` workflow with `build-and-test`, `core` and `full` on that exact develop SHA and an annotated signed tag named `4.1.0-RC.1` at it. The workflow requires GitHub's tag verification to report `verified=true`, `reason=valid`, and checks the exact local/remote tag object and commit. Public QQQ/Next release tags must match their pins and prerelease state; first-party BOM inputs (including recursive public parents) must resolve anonymously, with qbit-build-parent importing this QQQ version. The full reactor also rejects transitive snapshot dependencies. Public POM comparison includes the explicit Next pin. Existing GHCR visibility, protected environment, license/enable controls, destination-absence checks and live ref rechecks remain required. When those gates and owner authorization are satisfied, dispatch **Release 4.1.0** on develop with `version=4.1.0-RC.1`, the full `release_sha`, `smoke_evidence=circle`, and its successful `circle_workflow_id`. RC publication uses `--prerelease --latest=false`; it never becomes the latest GA release. The default `version=4.1.0` still requires upstream non-prerelease GA and follows the separate GA requirements below. Do not dispatch while any pin or external prerequisite is pending. ## Image Compose bundle The workflow attaches `qqq-all-.tar.gz` and its rendered `compose.yaml`. Download/extract the **whole bundle**, retain the `infra` directory beside Compose, and follow its README. Both app profiles use the exact pushed GHCR digest and have no app build context. The bundle includes the tracked PostgreSQL/MySQL/Mongo initialization, Keycloak realm, MinIO Dockerfile, `.env.example`, LICENSE/NOTICE and `release.json` source/image identity. It excludes local `.env`, application source and Maven outputs. Full-profile MinIO still builds locally and needs network access; other service images are unchanged. The standalone Compose asset alone is insufficient for full-profile operation. Configure a unique Compose project and demo credentials, build only MinIO for full, then start with `--no-build`. Verify anonymous image pull and real core/full startup from the extracted bundle after publication; config-rendering tests are not runtime acceptance. ## Next RC8 integration The stack BOM explicitly pins public `com.kingsrook.qqq:qqq-frontend-next:1.0.0-RC.8`, independently of the framework snapshot's dashboard pin. Its [release source](https://github.com/QRun-IO/qqq-frontend-next/commit/cd3d4731d1910e68e994da9c74a8c28a2f1b7c1c) is `cd3d4731d1910e68e994da9c74a8c28a2f1b7c1c`; the public JAR SHA-256 is `238c9ae80beea336717be759219f0d65a1d614e8e7d6a145a16374cc392a73a1`. The owner [approved a QQQ RC with these documented limitations](https://github.com/QRun-IO/qqq/issues/798#issuecomment-5930629521): Firefox/WebKit/tablet failures, incomplete report/query and input parity, sub-path hosting, real Google Drive verification, and visual approval. See the [RC8 release notes](https://github.com/QRun-IO/qqq-frontend-next/releases/tag/v1.0.0-RC.8) for the retained failures and incomplete runs. This approval applies to exact RC8 and does not turn those limitations into passing acceptance. The successor contracts `core.widget.data_bag_viewer`, `core.widget.pivot_table_setup`, `core.widget.filter_and_columns_setup`, `core.widget.row_builder`, `core.widget.script_viewer`, `core.widget.blocks`, and `dashboard.acceptance` remain pending and excluded from verified counts, with Next 1.0 final / QQQ 4.1 GA as the follow-up target. qqq-all's package and HTTP smoke checks verify integration and asset delivery, not browser parity. This repository remains a snapshot integration build; the separate GA procedure below and other release/security/public-consumer gates remain in force. ## Prerequisites and Maven artifacts 1. QQQ must publish a non-draft, non-prerelease `v4.1.0` GitHub release with ESB and the Next dashboard included. Release `qbit-build-parent` against the 4.1 BOM, then publish all eight qbits against that parent. This work occurs in their own repositories. 2. In a separate reviewed change to this repository, set root `revision` and the BOM's `qqq.version` to `4.1.0`; replace the explicit Next RC8 pin with the accepted Next 1.0 final version and pin each qbit to a published non-snapshot version. Run `mvn -B -ntp verify`, the core and full smoke checks, and review the resolved dependencies and effective POMs. Do not use `-Drevision=4.1.0` against a snapshot source tree as a substitute for reviewed pins. 3. Stage **both** `com.kingsrook.qqq:qqq-all-parent:4.1.0` and `com.kingsrook.qqq:qqq-all-bom:4.1.0` using the opt-in `release-central` Maven profile. The profile runs the release-version/dependency checks, signs the POMs with GPG, and uses the Central Publishing Maven plugin with `autoPublish=false`. It is only for the parent and BOM reactor; the app and BOM test JAR are excluded. POM packaging needs no source or Javadoc JARs. Configure the owner's `central` Portal user token in a private Maven `settings.xml` and a trusted GPG key outside the repository. Do not place credentials in this project or CI. ```bash mvn -B -ntp -pl qqq-all-bom -am -Prelease-central deploy ``` The command uploads a deployment for **manual** Central Portal review; it does not auto-publish. Check the staged parent and BOM POM coordinates, signatures, license/SCM metadata, 4.1 QQQ import, and all eight qbit pins. Publish in the Portal only after the required reviews and release gates pass; the owner has already authorized this gated publication. The profile fails validation while any current snapshot version remains. `mvn deploy` without the profile is not a release path. 4. Wait until both release POMs resolve anonymously from Maven Central. The release workflow fetches them from `repo.maven.apache.org` and compares their coordinates and BOM pins with its exact source commit. If either artifact is absent or differs, it stops before image publication. The owner selected Apache-2.0 for first-party code in [QQQ #923](https://github.com/QRun-IO/qqq/issues/923). Complete its reviewed alignment and verify the published artifacts before enabling release, preserving third-party terms. Existing Apache-2.0 metadata alone does not prove that all first-party headers and artifacts are aligned. The owner must also bootstrap the `qqq-all` GHCR package and make it **Public** in package settings; first publication defaults private. The workflow checks public visibility and refuses to push a private release image. ## Exact commit and manual dispatch After the release POMs are public, merge the version-pin change to `develop`. Require a successful webhook-triggered CircleCI `verify-and-smoke` workflow on the exact intended commit; `build-and-test`, `core` and `full` must all pass. Record its full SHA and workflow UUID. The shared verifier checks public Circle records against the latest trusted GitHub CircleCI check; it needs no exported Circle token for this public repository. Create an **annotated**, signed `4.1.0` tag at that exact `develop` commit. The workflow checks GitHub's valid signature verification, the tag object and its exact commit, including live remote refs. Do not move the tag or advance `develop` before dispatch. Configure a protected `qqq-all-release` GitHub environment with no required human reviewers and branch restriction to `develop`. After Apache alignment and the publication preconditions pass, set environment variables `QQQ_ALL_RELEASE_LICENSE_APPROVED=true` and `QQQ_ALL_RELEASE_ENABLED=true`. Unset them to close the gate. These variables are automated release controls; enable them only after the documented artifact and license prerequisites are established. Dispatch **Release 4.1.0** on `develop` with `version=4.1.0` (default), `release_sha` (the full 40-character commit SHA) `smoke_evidence=circle`, and `circle_workflow_id` (the successful Circle workflow UUID). The job requires that checkout, `develop`, the annotated signed tag, and the smoke run all refer to that SHA. It checks upstream GA, both public Central POMs and immutable upstream inputs, public GHCR visibility, and destination absence; verifies the reactor with a fresh public-only cache and rejects transitive snapshots; then rechecks the live `develop` and remote tag refs before publication. Only then does it build and push `ghcr.io/qrun-io/qqq-all:4.1.0` and create the GitHub `4.1.0` release with the Compose bundle and rendered `compose.yaml` attached. The image push and GitHub release creation are separate API operations, not an atomic transaction. If the release step fails after the image push, inspect the image digest and workflow logs before recovery; never reuse or overwrite the version tag blindly. Verify the public image pull, release asset, and both Maven POMs from an unauthenticated environment after publication. No workflow in this preparation branch publishes or tags anything by itself.