Skip to content

chore(build): build release binaries in ci#36

Draft
sklarsa wants to merge 11 commits into
mainfrom
build-binaries-in-ci
Draft

chore(build): build release binaries in ci#36
sklarsa wants to merge 11 commits into
mainfrom
build-binaries-in-ci

Conversation

@sklarsa
Copy link
Copy Markdown
Contributor

@sklarsa sklarsa commented May 28, 2026

What this does

Reworks the Maven Central release into a single manually-triggered workflow that proves the release is good before doing anything irreversible. Native libraries are built and tested in CI (not committed by hand), and the git tag / Central publish only happen after the full test suite and the Central Portal validation have passed.

Release flow (abridged)

Trigger Release to Maven Central from the Actions tab, then approve the gated publish step when prompted:

resolve → build ×5 → verify → publish (gated) → open-bump-pr
  1. resolve — infers the release version from the current -SNAPSHOT POM; fails fast if the tag or Central version already exists.
  2. build ×5 — builds + smoke-loads the native lib for each platform (darwin-aarch64/x86-64, linux-x86-64/aarch64, windows-x86-64).
  3. verify — bundles all five libs and runs the full test suite. No credentials. This is the quality gate. (The suite runs on Linux, so it exercises the linux-x86-64 lib directly; the other four are smoke-loaded on their own platform in the build step.)
  4. publish (gated by the maven-release environment) — after approval: signs and uploads a droppable VALIDATED deployment, pushes the release tag, then performs the single irreversible step of publishing the deployment via the Central Portal API.
  5. open-bump-pr — opens the next-development-version bump PR (post-release; merge it before the next release).

Key properties: validation happens before the tag is pushed, and the Central publish is the single irreversible step and runs last — so a tag-push failure leaves nothing published and a clean rerun. The tag pins the exact verified tree. We never push commits to main (the snapshot bump is a PR, so main keeps its PR-only protection). The run does not block on Maven Central's asynchronous propagation (which can take minutes to an hour+).

Required one-time setup

  • Tag ruleset bypass: add github-actions[bot] as a bypass actor on the org-wide restrict-tag-pushing ruleset, so the publish job can push the release tag. (Do not bypass the main branch ruleset — the snapshot bump goes through a PR.)
  • maven-release environment: configure required reviewers (the human approval gate before any credentials are used).
  • AWS release secret (MAVEN_RELEASE_AWS_SECRET_ARN) must define: MAVEN_GPG_PRIVATE_KEY, MAVEN_CENTRAL_USERNAME, MAVEN_CENTRAL_PASSWORD, and optionally MAVEN_GPG_PASSPHRASE (empty/absent for a passphrase-less key).

Full procedure: artifacts/release/README.md.

Follow-ups (not blocking)

  • Pin the GraalVM JDK 25 download (currently /25/latest/) and the Windows jni_md.h (currently jdk25u@master) to exact builds + checksums — marked with TODO(pin) in the workflow.
  • Confirm the central-publishing-maven-plugin 0.9.0 log line matches the deploymentId: <uuid> capture on the first real run.

Evidence

Verified that the include-native-artifacts profile bundles staged binaries into the jar by mocking libquestdb.so with a test string, packaging, and confirming the jar contains the mocked version:

mvn -B -ntp -pl core clean
mkdir -p core/target/native-libs/io/questdb/client/bin/linux-x86-64
printf 'test-linux-x86-64\n' \
    > core/target/native-libs/io/questdb/client/bin/linux-x86-64/libquestdb.so
mvn -B -ntp -pl core package -Pinclude-native-artifacts -DskipTests
$ unzip -p core/target/questdb-client-1.3.2-SNAPSHOT.jar io/questdb/client/bin/linux-x86-64/libquestdb.so
test-linux-x86-64

sklarsa and others added 11 commits May 27, 2026 11:13
Restructure the Maven Central release workflow into a pipeline that
proves the release good before doing anything irreversible: resolve
versions, build the five native libraries, run the full test suite
against them, and validate the signed bundle with the Central Portal
before pushing the tag or publishing.

Push only the release tag (never a commit to main); land the next
snapshot bump as a follow-up PR. Upload as a droppable VALIDATED
deployment, publish it through the Portal API, and do not block on the
asynchronous propagation to Maven Central. Add a shared native-artifact
staging script, harden the shell (pipefail, guarded objdump), pin the
versions-set plugin, and flip central-publishing to autoPublish=false.

Rewrite the release docs for the new flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address self-review findings on the release workflow:

- Push the release tag before the irreversible Central publish POST, not
  after. Validation already proved the bundle good; a tag is deletable, a
  publish is not, so a tag-push failure (e.g. missing bot bypass) now
  leaves nothing published and a clean rerun.
- Guard deployment-id capture and the status peek with || true so a
  no-match or transient curl/jq error cannot abort the step under
  errexit; the status peek timeout stays non-fatal.
- Only commit the version bump when versions:set actually changed the
  poms, so a no-op override does not abort after upload.
- Make open-bump-pr idempotent: force-with-lease the branch and skip PR
  creation when one already exists.
- Re-check the Central version (not just the tag) in publish after the
  environment gate.
- Read the release version from core/pom.xml, the shipped artifact.
- Build both macOS targets to completion (fail-fast: false).
- Fix the README Maven coordinate (org.questdb:questdb-client) and align
  the release docs with the tag-before-publish order and test coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant