chore(build): build release binaries in ci#36
Draft
sklarsa wants to merge 15 commits into
Draft
Conversation
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>
Second self-review pass:
- open-bump-pr pushed the bump branch with --force-with-lease, but the
job never fetches that branch, so there is no lease reference and the
push is rejected ("stale info") whenever the branch already exists (and
on first creation). Use plain --force; the branch is a throwaway owned
solely by this workflow.
- Tag is now pushed before the publish POST, so a POST failure used to
leave a tag that blocks reruns while nothing was published. Add an
if: failure() step that deletes the tag; the publish job fails only
when nothing reached Central, so this never drops a real release's tag.
- Correct the release doc: the Windows DLL is cross-compiled on Linux and
only objdump-checked, not load-tested like the macOS/Linux libraries.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The tag-rollback step was gated only on if: failure(), which can fire after the publish POST already returned 2xx (the deployment is then irreversibly Sonatype's) -- via the status peek exiting on FAILED or a job timeout mid-peek -- deleting the tag of a release that will publish. Set a published=true step output immediately after the 2xx accept and gate the rollback on `failure() && steps.central-publish.outputs.published != 'true'`. Outputs persist even if the step later fails, so the tag can never be rolled back once the publish was accepted. Rollback now runs only for failures before the POST, where nothing reached Central. Also warn, instead of silently swallowing, when the tag deletion itself fails. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- open-bump-pr opened the PR with --base "${SOURCE_REF}", which fails for
a tag or SHA ref and would redden a run whose release already
succeeded. Skip the bump with a notice when source_ref is not a branch;
the bump is post-release housekeeping and can be done manually.
- Document that MAVEN_GPG_PRIVATE_KEY must be the ASCII-armored key as a
JSON-escaped string (newlines as \n) so parse-json-secrets restores
real newlines for gpg --import -- the most common Central release
failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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, and the git tag / Central publish only happen after the full test suite and the Central Portal validation have passed.
This update also fixes the tag-ruleset bypass model: GitHub does not expose the built-in
GITHUB_TOKENidentity (github-actions[bot]) as a usable ruleset bypass actor. The publish job now mints a token from a dedicated Maven release GitHub App, and that app is the actor that must be added to the org-widerestrict-tag-pushingbypass list.Release flow (abridged)
Trigger
Release to Maven Centralfrom the Actions tab, then approve the gatedpublishstep when prompted:-SNAPSHOTPOM; fails fast if the tag or Central version already exists.objdump-checked for a clean runtime-dependency list.maven-releaseenvironment. After approval, it signs and uploads a droppableVALIDATEDdeployment, pushes the release tag using the Maven release GitHub App token, then performs the single irreversible Central Portal publish step. If anything fails before publish is accepted, the tag is rolled back so reruns stay clean.Key properties: validation happens before the tag is pushed, and the Central publish is the single irreversible step and runs last. 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, somainkeeps its PR-only protection. The run does not block on Maven Central asynchronous propagation.Required one-time setup
restrict-tag-pushingruleset. Do not try to addgithub-actions[bot]; GitHub does not offer it as a usable bypass actor here.MAVEN_RELEASE_GITHUB_APP_CLIENT_IDto the app client ID, and setMAVEN_RELEASE_GITHUB_APP_PRIVATE_KEYas amaven-releaseenvironment secret.maven-releaseenvironment: configure required reviewers. This is the human approval gate before any release credentials are used.MAVEN_RELEASE_AWS_SECRET_ARN) must defineMAVEN_GPG_PRIVATE_KEY,MAVEN_CENTRAL_USERNAME,MAVEN_CENTRAL_PASSWORD, and optionallyMAVEN_GPG_PASSPHRASE.Full procedure:
artifacts/release/README.md.Follow-ups (not blocking)
jni_md.hto exact builds + checksums. Both are marked withTODO(pin)in the workflow.central-publishing-maven-plugin0.9.0 log line still matches thedeploymentId: <uuid>capture, and that the GPG key imports cleanly from the AWS secret.Evidence
Verified that the
include-native-artifactsprofile bundles staged binaries into the jar by mockinglibquestdb.sowith a test string, packaging, and confirming the jar contains the mocked version: