From eedc845432b2c42140add5e2e3e802e19c93b281 Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Wed, 13 May 2026 13:32:58 -0400 Subject: [PATCH 01/16] automate maven release --- .github/workflows/maven_central_release.yml | 162 ++++++++++++++++++++ RELEASE.md | 133 ++++++++++------ 2 files changed, 245 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/maven_central_release.yml diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml new file mode 100644 index 00000000..841589ed --- /dev/null +++ b/.github/workflows/maven_central_release.yml @@ -0,0 +1,162 @@ +name: Release to Maven Central + +on: + workflow_dispatch: + inputs: + release_version: + description: Release version to publish, for example 1.2.1 + required: true + type: string + next_development_version: + description: Next development version, for example 1.2.2-SNAPSHOT + required: true + type: string + +permissions: + contents: write + id-token: write + +concurrency: + group: maven-central-release + cancel-in-progress: false + +jobs: + release: + runs-on: ubuntu-latest + env: + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + MAVEN_RELEASE_AWS_REGION: ${{ vars.MAVEN_RELEASE_AWS_REGION }} + MAVEN_RELEASE_AWS_ROLE_ARN: ${{ vars.MAVEN_RELEASE_AWS_ROLE_ARN }} + MAVEN_RELEASE_AWS_SECRET_ID: ${{ vars.MAVEN_RELEASE_AWS_SECRET_ID }} + steps: + - name: Validate workflow configuration + run: | + if [[ "${GITHUB_REF_NAME}" != "${DEFAULT_BRANCH}" ]]; then + echo "::error::Run this workflow from ${DEFAULT_BRANCH}." + exit 1 + fi + + if [[ "${{ inputs.release_version }}" == *-SNAPSHOT ]]; then + echo "::error::release-version must not end with -SNAPSHOT." + exit 1 + fi + + if [[ "${{ inputs.next_development_version }}" != *-SNAPSHOT ]]; then + echo "::error::next-development-version must end with -SNAPSHOT." + exit 1 + fi + + required_vars=( + MAVEN_RELEASE_AWS_REGION + MAVEN_RELEASE_AWS_ROLE_ARN + MAVEN_RELEASE_AWS_SECRET_ID + ) + + for var_name in "${required_vars[@]}"; do + if [[ -z "${!var_name:-}" ]]; then + echo "::error::Repository variable ${var_name} is required." + exit 1 + fi + done + + - name: Check out repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.MAVEN_RELEASE_GIT_TOKEN || github.token }} + + - name: Set up Java 11 + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: "11" + cache: maven + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v6.1.0 + with: + aws-region: ${{ env.MAVEN_RELEASE_AWS_REGION }} + role-to-assume: ${{ env.MAVEN_RELEASE_AWS_ROLE_ARN }} + role-session-name: java-questdb-client-release + + - name: Fetch release credentials + uses: aws-actions/aws-secretsmanager-get-secrets@v2 + with: + secret-ids: | + ,${{ env.MAVEN_RELEASE_AWS_SECRET_ID }} + parse-json-secrets: true + + - name: Validate release credentials + run: | + required_vars=( + MAVEN_GPG_PRIVATE_KEY + MAVEN_GPG_PASSPHRASE + MAVEN_CENTRAL_USERNAME + MAVEN_CENTRAL_PASSWORD + ) + + for var_name in "${required_vars[@]}"; do + if [[ -z "${!var_name:-}" ]]; then + echo "::error::AWS secret ${MAVEN_RELEASE_AWS_SECRET_ID} must define ${var_name}." + exit 1 + fi + done + + - name: Configure Git author + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Configure Maven settings.xml + run: | + mkdir -p "$HOME/.m2" + cat > "$HOME/.m2/settings.xml" <<'EOF' + + + + central + ${env.MAVEN_CENTRAL_USERNAME} + ${env.MAVEN_CENTRAL_PASSWORD} + + + gpg.passphrase + ${env.MAVEN_GPG_PASSPHRASE} + + + + EOF + + - name: Import release signing key + run: | + export GNUPGHOME="$(mktemp -d)" + chmod 700 "$GNUPGHOME" + printf '%s\n' "$MAVEN_GPG_PRIVATE_KEY" | gpg --batch --import + echo "GNUPGHOME=$GNUPGHOME" >> "$GITHUB_ENV" + + - name: Prepare and publish release + env: + RELEASE_VERSION: ${{ inputs.release_version }} + NEXT_DEVELOPMENT_VERSION: ${{ inputs.next_development_version }} + run: | + mvn -B -ntp \ + release:clean release:prepare release:perform \ + -DautoVersionSubmodules=true \ + -DpushChanges=false \ + -DlocalCheckout=true \ + -DreleaseVersion="${RELEASE_VERSION}" \ + -DdevelopmentVersion="${NEXT_DEVELOPMENT_VERSION}" \ + -Dtag="${RELEASE_VERSION}" + + - name: Push release commits and tag + run: | + git push origin HEAD:${GITHUB_REF_NAME} + git push origin --tags + + - name: Remove imported signing key + if: always() + run: | + if [[ -n "${GNUPGHOME:-}" && -d "${GNUPGHOME}" ]]; then + rm -rf "$GNUPGHOME" + fi diff --git a/RELEASE.md b/RELEASE.md index 38fa0356..2161cc5b 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -4,11 +4,82 @@ This document describes how to release `org.questdb:client` to Maven Central. ## Overview -Releases are performed using the [Maven Release Plugin](https://maven.apache.org/maven-release/maven-release-plugin/) combined with the [Sonatype Central Publishing Plugin](https://central.sonatype.org/publish/publish-portal-maven/). The `maven-central-release` profile handles signing, Javadoc generation, source attachment, and publishing. +Releases use the [Maven Release Plugin](https://maven.apache.org/maven-release/maven-release-plugin/) together with the [Sonatype Central Publishing Plugin](https://central.sonatype.org/publish/publish-portal-maven/). The `maven-central-release` profile handles signing, Javadoc generation, source attachment, and publishing. -## Prerequisites +The repo now includes a GitHub Actions workflow at `.github/workflows/maven_central_release.yml` that: -### 1. GPG Key +- assumes an AWS IAM role via GitHub OIDC +- reads the release credentials from AWS Secrets Manager +- imports the GPG key at runtime +- runs `mvn release:prepare release:perform` +- pushes the release commits and tag only after Central publication succeeds + +## Automated GitHub Release + +### AWS secret payload + +Store a single JSON secret in AWS Secrets Manager with these keys: + +```json +{ + "MAVEN_GPG_PRIVATE_KEY": "-----BEGIN PGP PRIVATE KEY BLOCK-----\n...\n-----END PGP PRIVATE KEY BLOCK-----", + "MAVEN_GPG_PASSPHRASE": "your-passphrase", + "MAVEN_CENTRAL_USERNAME": "your-central-username", + "MAVEN_CENTRAL_PASSWORD": "your-central-password-or-token" +} +``` + +Export the private key in ASCII armor form: + +```bash +gpg --armor --export-secret-keys +``` + +### Repository configuration + +Create these GitHub repository variables: + +- `MAVEN_RELEASE_AWS_REGION` +- `MAVEN_RELEASE_AWS_ROLE_ARN` +- `MAVEN_RELEASE_AWS_SECRET_ID` + +Optional GitHub repository secret: + +- `MAVEN_RELEASE_GIT_TOKEN` + +Use `MAVEN_RELEASE_GIT_TOKEN` only if the default `GITHUB_TOKEN` cannot push the release commits and tag to the default branch because of branch protection. + +### AWS permissions + +The IAM role assumed by the workflow needs: + +- `secretsmanager:GetSecretValue` on the release secret +- `secretsmanager:ListSecrets` +- `kms:Decrypt` if the secret uses a customer-managed KMS key + +Its trust policy must allow GitHub Actions to assume the role through the GitHub OIDC provider. + +### Trigger the release + +Run the `Release to Maven Central` workflow from the default branch and provide: + +- `release_version`, for example `1.2.1` +- `next_development_version`, for example `1.2.2-SNAPSHOT` + +The workflow creates the standard Maven release commits: + +1. `[maven-release-plugin] prepare release ` +2. `[maven-release-plugin] prepare for next development iteration` + +It also creates a Git tag named after the release version. + +## Manual Fallback + +If the workflow is unavailable, the release can still be performed locally. + +### Prerequisites + +#### 1. GPG key A GPG key is required to sign the release artifacts. If you don't have one: @@ -19,11 +90,11 @@ gpg --keyserver keyserver.ubuntu.com --send-keys More details on GPG key generation can be found in the [Sonatype guide](https://central.sonatype.org/publish/requirements/gpg/). -### 2. Sonatype Credentials +#### 2. Sonatype credentials You need credentials for the Sonatype Central Portal (https://central.sonatype.com/). -### 3. Maven `settings.xml` +#### 3. Maven `settings.xml` Configure your `~/.m2/settings.xml` with the Sonatype server credentials: @@ -39,55 +110,25 @@ Configure your `~/.m2/settings.xml` with the Sonatype server credentials: ``` -More details can be found in the [Sonatype guide](https://central.sonatype.org/publish/publish-portal-maven/). - -### 4. Repository Access +#### 4. Repository access You need push access to the `questdb/java-questdb-client` repository on GitHub. -## Release Process +### Release commands -### Step 1: Prepare the Release - -This bumps the version, creates a tag, and commits the changes: +Prepare the release: ```bash mvn release:prepare ``` -The plugin will prompt for: - -- **Release version** (e.g., `9.3.1`) — the version to release -- **SCM tag** (e.g., `9.3.1`) — the Git tag name (uses the `tagNameFormat` of `@{project.version}`) -- **Next development version** (e.g., `9.3.2-SNAPSHOT`) — the next snapshot version - -This creates two commits: - -1. `[maven-release-plugin] prepare release 9.3.1` — sets the release version -2. `[maven-release-plugin] prepare for next development iteration` — sets the next snapshot version - -And a Git tag (e.g., `9.3.1`). - -### Step 2: Perform the Release - -This builds, signs, and publishes the artifacts to Maven Central: +Perform the release: ```bash mvn release:perform ``` -The `maven-central-release` profile is activated automatically. It: - -- Compiles the source -- Generates Javadoc -- Attaches sources JAR -- Signs all artifacts with GPG -- Publishes to Maven Central via the Sonatype Central Publishing Plugin -- Waits until the artifacts are published (`waitUntil=published`) - -### Step 3: Push Tags - -If not pushed automatically: +If required, push the resulting commits and tags: ```bash git push origin main --tags @@ -95,14 +136,6 @@ git push origin main --tags ## Post-Release -### Verify on Maven Central - -Check that the new version appears on [Maven Central](https://central.sonatype.com/artifact/org.questdb/client). Propagation may take some time after publishing. - -### Create a GitHub Release +Verify that the new version appears on [Maven Central](https://central.sonatype.com/artifact/org.questdb/client). Propagation may take some time after publishing. -1. Go to [GitHub Releases](https://github.com/questdb/java-questdb-client/releases). -2. Click **Draft a new release**. -3. Select the tag created by the release plugin. -4. Add release notes describing the changes. -5. Publish the release. +If you also want a GitHub release entry, draft one from the tag created by the Maven release plugin and add release notes for the version. From 3707a33e701be40b6840a6d13267a81ccb9a126c Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Wed, 13 May 2026 14:06:19 -0400 Subject: [PATCH 02/16] workflow fixes --- .github/workflows/maven_central_release.yml | 9 +++-- RELEASE.md | 43 --------------------- 2 files changed, 5 insertions(+), 47 deletions(-) diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml index 841589ed..b6f0d401 100644 --- a/.github/workflows/maven_central_release.yml +++ b/.github/workflows/maven_central_release.yml @@ -23,11 +23,12 @@ concurrency: jobs: release: runs-on: ubuntu-latest + environment: maven-release env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} MAVEN_RELEASE_AWS_REGION: ${{ vars.MAVEN_RELEASE_AWS_REGION }} MAVEN_RELEASE_AWS_ROLE_ARN: ${{ vars.MAVEN_RELEASE_AWS_ROLE_ARN }} - MAVEN_RELEASE_AWS_SECRET_ID: ${{ vars.MAVEN_RELEASE_AWS_SECRET_ID }} + MAVEN_RELEASE_AWS_SECRET_ARN: ${{ vars.MAVEN_RELEASE_AWS_SECRET_ARN }} steps: - name: Validate workflow configuration run: | @@ -49,7 +50,7 @@ jobs: required_vars=( MAVEN_RELEASE_AWS_REGION MAVEN_RELEASE_AWS_ROLE_ARN - MAVEN_RELEASE_AWS_SECRET_ID + MAVEN_RELEASE_AWS_SECRET_ARN ) for var_name in "${required_vars[@]}"; do @@ -83,7 +84,7 @@ jobs: uses: aws-actions/aws-secretsmanager-get-secrets@v2 with: secret-ids: | - ,${{ env.MAVEN_RELEASE_AWS_SECRET_ID }} + ,${{ env.MAVEN_RELEASE_AWS_SECRET_ARN }} parse-json-secrets: true - name: Validate release credentials @@ -97,7 +98,7 @@ jobs: for var_name in "${required_vars[@]}"; do if [[ -z "${!var_name:-}" ]]; then - echo "::error::AWS secret ${MAVEN_RELEASE_AWS_SECRET_ID} must define ${var_name}." + echo "::error::AWS secret ${MAVEN_RELEASE_AWS_SECRET_ARN} must define ${var_name}." exit 1 fi done diff --git a/RELEASE.md b/RELEASE.md index 2161cc5b..95e50242 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -16,49 +16,6 @@ The repo now includes a GitHub Actions workflow at `.github/workflows/maven_cent ## Automated GitHub Release -### AWS secret payload - -Store a single JSON secret in AWS Secrets Manager with these keys: - -```json -{ - "MAVEN_GPG_PRIVATE_KEY": "-----BEGIN PGP PRIVATE KEY BLOCK-----\n...\n-----END PGP PRIVATE KEY BLOCK-----", - "MAVEN_GPG_PASSPHRASE": "your-passphrase", - "MAVEN_CENTRAL_USERNAME": "your-central-username", - "MAVEN_CENTRAL_PASSWORD": "your-central-password-or-token" -} -``` - -Export the private key in ASCII armor form: - -```bash -gpg --armor --export-secret-keys -``` - -### Repository configuration - -Create these GitHub repository variables: - -- `MAVEN_RELEASE_AWS_REGION` -- `MAVEN_RELEASE_AWS_ROLE_ARN` -- `MAVEN_RELEASE_AWS_SECRET_ID` - -Optional GitHub repository secret: - -- `MAVEN_RELEASE_GIT_TOKEN` - -Use `MAVEN_RELEASE_GIT_TOKEN` only if the default `GITHUB_TOKEN` cannot push the release commits and tag to the default branch because of branch protection. - -### AWS permissions - -The IAM role assumed by the workflow needs: - -- `secretsmanager:GetSecretValue` on the release secret -- `secretsmanager:ListSecrets` -- `kms:Decrypt` if the secret uses a customer-managed KMS key - -Its trust policy must allow GitHub Actions to assume the role through the GitHub OIDC provider. - ### Trigger the release Run the `Release to Maven Central` workflow from the default branch and provide: From 0aca3f5abe918ba9e317980f5b244314336efd80 Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Wed, 13 May 2026 14:10:40 -0400 Subject: [PATCH 03/16] move to secrets... --- .github/workflows/maven_central_release.yml | 18 ++++++++++++++---- RELEASE.md | 6 ++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml index b6f0d401..443ccf44 100644 --- a/.github/workflows/maven_central_release.yml +++ b/.github/workflows/maven_central_release.yml @@ -27,8 +27,8 @@ jobs: env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} MAVEN_RELEASE_AWS_REGION: ${{ vars.MAVEN_RELEASE_AWS_REGION }} - MAVEN_RELEASE_AWS_ROLE_ARN: ${{ vars.MAVEN_RELEASE_AWS_ROLE_ARN }} - MAVEN_RELEASE_AWS_SECRET_ARN: ${{ vars.MAVEN_RELEASE_AWS_SECRET_ARN }} + MAVEN_RELEASE_AWS_ROLE_ARN: ${{ secrets.MAVEN_RELEASE_AWS_ROLE_ARN }} + MAVEN_RELEASE_AWS_SECRET_ARN: ${{ secrets.MAVEN_RELEASE_AWS_SECRET_ARN }} steps: - name: Validate workflow configuration run: | @@ -49,8 +49,6 @@ jobs: required_vars=( MAVEN_RELEASE_AWS_REGION - MAVEN_RELEASE_AWS_ROLE_ARN - MAVEN_RELEASE_AWS_SECRET_ARN ) for var_name in "${required_vars[@]}"; do @@ -60,6 +58,18 @@ jobs: fi done + required_secrets=( + MAVEN_RELEASE_AWS_ROLE_ARN + MAVEN_RELEASE_AWS_SECRET_ARN + ) + + for secret_name in "${required_secrets[@]}"; do + if [[ -z "${!secret_name:-}" ]]; then + echo "::error::GitHub secret ${secret_name} is required." + exit 1 + fi + done + - name: Check out repository uses: actions/checkout@v4 with: diff --git a/RELEASE.md b/RELEASE.md index 95e50242..5a9bac0b 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -14,6 +14,12 @@ The repo now includes a GitHub Actions workflow at `.github/workflows/maven_cent - runs `mvn release:prepare release:perform` - pushes the release commits and tag only after Central publication succeeds +Workflow configuration: + +- repository variable `MAVEN_RELEASE_AWS_REGION` +- GitHub secret `MAVEN_RELEASE_AWS_ROLE_ARN` +- GitHub secret `MAVEN_RELEASE_AWS_SECRET_ARN` + ## Automated GitHub Release ### Trigger the release From 96b420178c88e7f5473a16abda98a7e7f368c804 Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Thu, 14 May 2026 10:09:48 -0400 Subject: [PATCH 04/16] add testing target --- core/pom.xml | 10 ++++++---- examples/pom.xml | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index e82fdfcd..b4aaafef 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -40,8 +40,9 @@ 1.2.1-SNAPSHOT - org.questdb - questdb-client + + io.github.sklarsa + questdb-client-central-e2e jar https://questdb.io/ @@ -61,8 +62,9 @@ - scm:git:https://github.com/questdb/java-questdb-client.git + https://github.com/questdb/java-questdb-client scm:git:https://github.com/questdb/java-questdb-client.git + scm:git:https://github.com/questdb/java-questdb-client.git HEAD @@ -352,7 +354,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.8.0 + 0.9.0 true central diff --git a/examples/pom.xml b/examples/pom.xml index 804e8bae..60a5cc83 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -32,8 +32,9 @@ - org.questdb - questdb-client + + io.github.sklarsa + questdb-client-central-e2e ${project.version} From 3cd19f59b0a11e1d4d813e4e3da8942388881ecd Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Thu, 14 May 2026 10:12:14 -0400 Subject: [PATCH 05/16] another test thing --- .github/workflows/maven_central_release.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml index 443ccf44..8273c5da 100644 --- a/.github/workflows/maven_central_release.yml +++ b/.github/workflows/maven_central_release.yml @@ -32,9 +32,10 @@ jobs: steps: - name: Validate workflow configuration run: | + # Temporary Maven Central E2E test override: allow release runs from a non-default branch. + # Production behavior should fail here unless running from the default branch. Revert before merge. if [[ "${GITHUB_REF_NAME}" != "${DEFAULT_BRANCH}" ]]; then - echo "::error::Run this workflow from ${DEFAULT_BRANCH}." - exit 1 + echo "::warning::Running from non-default branch ${GITHUB_REF_NAME}; production workflow should normally run from ${DEFAULT_BRANCH}." fi if [[ "${{ inputs.release_version }}" == *-SNAPSHOT ]]; then From 58096bcb9e3c26d693917f994e83c7458bde1d64 Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Thu, 14 May 2026 14:51:36 -0400 Subject: [PATCH 06/16] chore: revert maven central e2e test overrides --- .github/workflows/maven_central_release.yml | 5 ++--- core/pom.xml | 5 ++--- examples/pom.xml | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml index 8273c5da..443ccf44 100644 --- a/.github/workflows/maven_central_release.yml +++ b/.github/workflows/maven_central_release.yml @@ -32,10 +32,9 @@ jobs: steps: - name: Validate workflow configuration run: | - # Temporary Maven Central E2E test override: allow release runs from a non-default branch. - # Production behavior should fail here unless running from the default branch. Revert before merge. if [[ "${GITHUB_REF_NAME}" != "${DEFAULT_BRANCH}" ]]; then - echo "::warning::Running from non-default branch ${GITHUB_REF_NAME}; production workflow should normally run from ${DEFAULT_BRANCH}." + echo "::error::Run this workflow from ${DEFAULT_BRANCH}." + exit 1 fi if [[ "${{ inputs.release_version }}" == *-SNAPSHOT ]]; then diff --git a/core/pom.xml b/core/pom.xml index b4aaafef..efe09fe6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -40,9 +40,8 @@ 1.2.1-SNAPSHOT - - io.github.sklarsa - questdb-client-central-e2e + org.questdb + questdb-client jar https://questdb.io/ diff --git a/examples/pom.xml b/examples/pom.xml index 60a5cc83..804e8bae 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -32,9 +32,8 @@ - - io.github.sklarsa - questdb-client-central-e2e + org.questdb + questdb-client ${project.version} From 6a2ad98be231a7ece9a9cdd9e28dec2ad72dc832 Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Fri, 15 May 2026 16:14:24 +0100 Subject: [PATCH 07/16] [maven-release-plugin] prepare release 1.2.2 --- core/pom.xml | 4 ++-- examples/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index efe09fe6..a47e7e95 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -39,7 +39,7 @@ 1.37 - 1.2.1-SNAPSHOT + 1.2.2 org.questdb questdb-client jar @@ -64,7 +64,7 @@ https://github.com/questdb/java-questdb-client scm:git:https://github.com/questdb/java-questdb-client.git scm:git:https://github.com/questdb/java-questdb-client.git - HEAD + 1.2.2 diff --git a/examples/pom.xml b/examples/pom.xml index 804e8bae..fa5a2a80 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -27,7 +27,7 @@ org.questdb client-examples - 1.2.1-SNAPSHOT + 1.2.2 Examples for QuestDB diff --git a/pom.xml b/pom.xml index 8df674cf..cbd24f2d 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 4.0.0 - 1.2.1-SNAPSHOT + 1.2.2 org.questdb client-parent pom @@ -35,7 +35,7 @@ scm:git:https://github.com/questdb/java-questdb-client.git scm:git:https://github.com/questdb/java-questdb-client.git https://github.com/questdb/java-questdb-client - HEAD + 1.2.2 From 46c4df884e8874f90372c67d4779906ae77793b7 Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Fri, 15 May 2026 16:14:24 +0100 Subject: [PATCH 08/16] [maven-release-plugin] prepare for next development iteration --- core/pom.xml | 4 ++-- examples/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index a47e7e95..cf48384d 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -39,7 +39,7 @@ 1.37 - 1.2.2 + 1.2.3-SNAPSHOT org.questdb questdb-client jar @@ -64,7 +64,7 @@ https://github.com/questdb/java-questdb-client scm:git:https://github.com/questdb/java-questdb-client.git scm:git:https://github.com/questdb/java-questdb-client.git - 1.2.2 + HEAD diff --git a/examples/pom.xml b/examples/pom.xml index fa5a2a80..19293e81 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -27,7 +27,7 @@ org.questdb client-examples - 1.2.2 + 1.2.3-SNAPSHOT Examples for QuestDB diff --git a/pom.xml b/pom.xml index cbd24f2d..43655dd0 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 4.0.0 - 1.2.2 + 1.2.3-SNAPSHOT org.questdb client-parent pom @@ -35,7 +35,7 @@ scm:git:https://github.com/questdb/java-questdb-client.git scm:git:https://github.com/questdb/java-questdb-client.git https://github.com/questdb/java-questdb-client - 1.2.2 + HEAD From 9986e1911ff345de0134ee0e4854e1332986584f Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Fri, 15 May 2026 16:30:14 +0100 Subject: [PATCH 09/16] split release to maven prepare and building the tag --- .github/workflows/maven_central_release.yml | 72 ++++--------- RELEASE.md | 104 ------------------ artifacts/release/README.md | 113 ++++++++++++++++++++ 3 files changed, 133 insertions(+), 156 deletions(-) delete mode 100644 RELEASE.md create mode 100644 artifacts/release/README.md diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml index 443ccf44..ffc37702 100644 --- a/.github/workflows/maven_central_release.yml +++ b/.github/workflows/maven_central_release.yml @@ -1,19 +1,12 @@ name: Release to Maven Central on: - workflow_dispatch: - inputs: - release_version: - description: Release version to publish, for example 1.2.1 - required: true - type: string - next_development_version: - description: Next development version, for example 1.2.2-SNAPSHOT - required: true - type: string + push: + tags: + - '*.*.*' permissions: - contents: write + contents: read id-token: write concurrency: @@ -25,28 +18,12 @@ jobs: runs-on: ubuntu-latest environment: maven-release env: - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} MAVEN_RELEASE_AWS_REGION: ${{ vars.MAVEN_RELEASE_AWS_REGION }} MAVEN_RELEASE_AWS_ROLE_ARN: ${{ secrets.MAVEN_RELEASE_AWS_ROLE_ARN }} MAVEN_RELEASE_AWS_SECRET_ARN: ${{ secrets.MAVEN_RELEASE_AWS_SECRET_ARN }} steps: - name: Validate workflow configuration run: | - if [[ "${GITHUB_REF_NAME}" != "${DEFAULT_BRANCH}" ]]; then - echo "::error::Run this workflow from ${DEFAULT_BRANCH}." - exit 1 - fi - - if [[ "${{ inputs.release_version }}" == *-SNAPSHOT ]]; then - echo "::error::release-version must not end with -SNAPSHOT." - exit 1 - fi - - if [[ "${{ inputs.next_development_version }}" != *-SNAPSHOT ]]; then - echo "::error::next-development-version must end with -SNAPSHOT." - exit 1 - fi - required_vars=( MAVEN_RELEASE_AWS_REGION ) @@ -70,11 +47,10 @@ jobs: fi done - - name: Check out repository + - name: Check out tag uses: actions/checkout@v4 with: - fetch-depth: 0 - token: ${{ secrets.MAVEN_RELEASE_GIT_TOKEN || github.token }} + ref: ${{ github.ref }} - name: Set up Java 11 uses: actions/setup-java@v5 @@ -113,11 +89,6 @@ jobs: fi done - - name: Configure Git author - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - name: Configure Maven settings.xml run: | mkdir -p "$HOME/.m2" @@ -146,28 +117,25 @@ jobs: printf '%s\n' "$MAVEN_GPG_PRIVATE_KEY" | gpg --batch --import echo "GNUPGHOME=$GNUPGHOME" >> "$GITHUB_ENV" - - name: Prepare and publish release - env: - RELEASE_VERSION: ${{ inputs.release_version }} - NEXT_DEVELOPMENT_VERSION: ${{ inputs.next_development_version }} + - name: Verify tag matches POM version run: | - mvn -B -ntp \ - release:clean release:prepare release:perform \ - -DautoVersionSubmodules=true \ - -DpushChanges=false \ - -DlocalCheckout=true \ - -DreleaseVersion="${RELEASE_VERSION}" \ - -DdevelopmentVersion="${NEXT_DEVELOPMENT_VERSION}" \ - -Dtag="${RELEASE_VERSION}" - - - name: Push release commits and tag + POM_VERSION=$(mvn -B -q -DforceStdout help:evaluate -Dexpression=project.version) + if [[ "${POM_VERSION}" == *-SNAPSHOT ]]; then + echo "::error::Refusing to release SNAPSHOT version ${POM_VERSION}." + exit 1 + fi + if [[ "${GITHUB_REF_NAME}" != "${POM_VERSION}" ]]; then + echo "::error::Tag ${GITHUB_REF_NAME} does not match POM version ${POM_VERSION}." + exit 1 + fi + + - name: Publish release to Maven Central run: | - git push origin HEAD:${GITHUB_REF_NAME} - git push origin --tags + mvn -B -ntp deploy -P maven-central-release -DskipTests - name: Remove imported signing key if: always() run: | if [[ -n "${GNUPGHOME:-}" && -d "${GNUPGHOME}" ]]; then rm -rf "$GNUPGHOME" - fi + fi \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md deleted file mode 100644 index 5a9bac0b..00000000 --- a/RELEASE.md +++ /dev/null @@ -1,104 +0,0 @@ -# Release Guide - -This document describes how to release `org.questdb:client` to Maven Central. - -## Overview - -Releases use the [Maven Release Plugin](https://maven.apache.org/maven-release/maven-release-plugin/) together with the [Sonatype Central Publishing Plugin](https://central.sonatype.org/publish/publish-portal-maven/). The `maven-central-release` profile handles signing, Javadoc generation, source attachment, and publishing. - -The repo now includes a GitHub Actions workflow at `.github/workflows/maven_central_release.yml` that: - -- assumes an AWS IAM role via GitHub OIDC -- reads the release credentials from AWS Secrets Manager -- imports the GPG key at runtime -- runs `mvn release:prepare release:perform` -- pushes the release commits and tag only after Central publication succeeds - -Workflow configuration: - -- repository variable `MAVEN_RELEASE_AWS_REGION` -- GitHub secret `MAVEN_RELEASE_AWS_ROLE_ARN` -- GitHub secret `MAVEN_RELEASE_AWS_SECRET_ARN` - -## Automated GitHub Release - -### Trigger the release - -Run the `Release to Maven Central` workflow from the default branch and provide: - -- `release_version`, for example `1.2.1` -- `next_development_version`, for example `1.2.2-SNAPSHOT` - -The workflow creates the standard Maven release commits: - -1. `[maven-release-plugin] prepare release ` -2. `[maven-release-plugin] prepare for next development iteration` - -It also creates a Git tag named after the release version. - -## Manual Fallback - -If the workflow is unavailable, the release can still be performed locally. - -### Prerequisites - -#### 1. GPG key - -A GPG key is required to sign the release artifacts. If you don't have one: - -```bash -gpg --gen-key -gpg --keyserver keyserver.ubuntu.com --send-keys -``` - -More details on GPG key generation can be found in the [Sonatype guide](https://central.sonatype.org/publish/requirements/gpg/). - -#### 2. Sonatype credentials - -You need credentials for the Sonatype Central Portal (https://central.sonatype.com/). - -#### 3. Maven `settings.xml` - -Configure your `~/.m2/settings.xml` with the Sonatype server credentials: - -```xml - - - - central - YOUR_SONATYPE_USERNAME - YOUR_SONATYPE_PASSWORD - - - -``` - -#### 4. Repository access - -You need push access to the `questdb/java-questdb-client` repository on GitHub. - -### Release commands - -Prepare the release: - -```bash -mvn release:prepare -``` - -Perform the release: - -```bash -mvn release:perform -``` - -If required, push the resulting commits and tags: - -```bash -git push origin main --tags -``` - -## Post-Release - -Verify that the new version appears on [Maven Central](https://central.sonatype.com/artifact/org.questdb/client). Propagation may take some time after publishing. - -If you also want a GitHub release entry, draft one from the tag created by the Maven release plugin and add release notes for the version. diff --git a/artifacts/release/README.md b/artifacts/release/README.md new file mode 100644 index 00000000..5ebad831 --- /dev/null +++ b/artifacts/release/README.md @@ -0,0 +1,113 @@ +# Release steps + +This is a short guide to outline the steps involved in releasing `org.questdb:questdb-client` to Maven Central. + +## Edit release notes + +First step is to create a draft release with the intended release version number and release notes. The git tag should +not be created up front — choose the intended tag name in the draft and let GitHub create it when the release is +published. When crafting new release notes, please use previous release notes as style guidelines. Releases should not +look too dissimilar. + +## Switch to `main` + +```bash +git fetch +git checkout main +git pull +``` + +Releases must be cut from the latest `main`. Make sure your working tree is clean. + +## Clear previous release "memory" + +```bash +mvn release:clean +``` + +This removes any `release.properties` and `*.releaseBackup` files left over from a previous attempt. + +## Roll versions and create the tag + +This step will do the following: + +- roll the parent and module versions from snapshot to release, e.g. from `1.2.2-SNAPSHOT` to `1.2.2` +- commit the release POMs +- create the release tag in the local git repo +- roll the versions to the next snapshot, e.g. `1.2.3-SNAPSHOT` +- commit the next-snapshot POMs + +```bash +mvn -B release:prepare \ + -DautoVersionSubmodules=true \ + -DpushChanges=false \ + -DreleaseVersion= \ + -DdevelopmentVersion= \ + -Dtag= +``` + +For example, when releasing `1.2.2`: + +```bash +mvn -B release:prepare \ + -DautoVersionSubmodules=true \ + -DpushChanges=false \ + -DreleaseVersion=1.2.2 \ + -DdevelopmentVersion=1.2.3-SNAPSHOT \ + -Dtag=1.2.2 +``` + +The `-B` flag will make assumptions about the release version. Use it for routine releases. For a special version (for +example a new major like `2.0`), drop `-B` and answer the interactive prompts. + +`-DpushChanges=false` keeps both commits and the tag local until you have verified they look right. + +If `release:prepare` fails partway through, recover with: + +```bash +mvn release:rollback +``` + +This reverts the prepare commits and removes the backup files. If `release.properties` has already been cleaned up, you +can reset the unwanted commits manually with `git reset --hard ` instead. + +## Push the branch and tag + +Once the local commits and tag look correct, publish them: + +```bash +git push origin main +git push origin +``` + +For example: + +```bash +git push origin main +git push origin 1.2.2 +``` + +## Publish to Maven Central + +The jar publication to Maven Central is performed by the +[`Release to Maven Central`](../../.github/workflows/maven_central_release.yml) GitHub Actions workflow added in this PR. + +Trigger the workflow manually (`workflow_dispatch`) from the default branch and provide: + +- `release_version`, for example `1.2.2` +- `next_development_version`, for example `1.2.3-SNAPSHOT` + +The workflow assumes an AWS IAM role via OIDC, reads the GPG key and Sonatype credentials from AWS Secrets Manager, +signs the artifacts, publishes them through the Sonatype Central Portal, and pushes the release commits and tag only +after publication succeeds. + +You will need write access to the repository and to the configured AWS secret to trigger the workflow. + +## Post-release + +Verify that the new version appears on +[Maven Central](https://central.sonatype.com/artifact/org.questdb/questdb-client). Propagation may take some time after +publishing. + +Finalize the GitHub release draft from the tag created by the release process and add the release notes for the +version. From 0891295c5ac91fa3136dc05a1033a3697e91fdf9 Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Fri, 15 May 2026 17:18:19 +0100 Subject: [PATCH 10/16] Revert release-plugin test commits Revert "[maven-release-plugin] prepare for next development iteration" and "[maven-release-plugin] prepare release 1.2.2", which were created by a local mvn release:prepare dry-run while validating the new workflow. The 1.2.2 tag was never pushed and no 1.2.2 artifact was published, so keeping the version-bump commits on the branch would leave main claiming a 1.2.2 release that did not happen. --- core/pom.xml | 2 +- examples/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index cf48384d..efe09fe6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -39,7 +39,7 @@ 1.37 - 1.2.3-SNAPSHOT + 1.2.1-SNAPSHOT org.questdb questdb-client jar diff --git a/examples/pom.xml b/examples/pom.xml index 19293e81..804e8bae 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -27,7 +27,7 @@ org.questdb client-examples - 1.2.3-SNAPSHOT + 1.2.1-SNAPSHOT Examples for QuestDB diff --git a/pom.xml b/pom.xml index 43655dd0..8df674cf 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 4.0.0 - 1.2.3-SNAPSHOT + 1.2.1-SNAPSHOT org.questdb client-parent pom From b03be22c98e489dc5a3428fc50a7e479b16ae0fc Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Fri, 15 May 2026 17:19:46 +0100 Subject: [PATCH 11/16] Fix help:evaluate output and align README with tag-push flow - Add -N to mvn help:evaluate so it runs only against the parent POM. Without it, Maven recurses into core and examples and forceStdout prints the version once per module, producing multi-line output that fails both the SNAPSHOT check and the tag-equality check. - Rewrite the "Publish to Maven Central" section in the release README. The workflow no longer uses workflow_dispatch with inputs; it triggers on a *.*.* tag push and does not push commits or tags. --- .github/workflows/maven_central_release.yml | 2 +- artifacts/release/README.md | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml index ffc37702..8378ca62 100644 --- a/.github/workflows/maven_central_release.yml +++ b/.github/workflows/maven_central_release.yml @@ -119,7 +119,7 @@ jobs: - name: Verify tag matches POM version run: | - POM_VERSION=$(mvn -B -q -DforceStdout help:evaluate -Dexpression=project.version) + POM_VERSION=$(mvn -B -q -N -DforceStdout help:evaluate -Dexpression=project.version) if [[ "${POM_VERSION}" == *-SNAPSHOT ]]; then echo "::error::Refusing to release SNAPSHOT version ${POM_VERSION}." exit 1 diff --git a/artifacts/release/README.md b/artifacts/release/README.md index 5ebad831..c936c436 100644 --- a/artifacts/release/README.md +++ b/artifacts/release/README.md @@ -92,16 +92,15 @@ git push origin 1.2.2 The jar publication to Maven Central is performed by the [`Release to Maven Central`](../../.github/workflows/maven_central_release.yml) GitHub Actions workflow added in this PR. -Trigger the workflow manually (`workflow_dispatch`) from the default branch and provide: +The workflow is triggered automatically when a release tag (matching `*.*.*`) is pushed in the previous step. No manual +dispatch is required. The workflow: -- `release_version`, for example `1.2.2` -- `next_development_version`, for example `1.2.3-SNAPSHOT` +- checks out the pushed tag +- assumes an AWS IAM role via OIDC and reads the GPG key and Sonatype credentials from AWS Secrets Manager +- verifies that the tag name matches the parent POM version and that the version is not a snapshot +- signs the artifacts and publishes them through the Sonatype Central Portal -The workflow assumes an AWS IAM role via OIDC, reads the GPG key and Sonatype credentials from AWS Secrets Manager, -signs the artifacts, publishes them through the Sonatype Central Portal, and pushes the release commits and tag only -after publication succeeds. - -You will need write access to the repository and to the configured AWS secret to trigger the workflow. +You need push access to the repository to push the release tag, which is what triggers the workflow. ## Post-release From 4254b752554d06be3c5c42b2c639a0f1199ec118 Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Fri, 15 May 2026 17:29:11 +0100 Subject: [PATCH 12/16] nits --- .github/workflows/maven_central_release.yml | 4 ++-- artifacts/release/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml index 8378ca62..58cd38d9 100644 --- a/.github/workflows/maven_central_release.yml +++ b/.github/workflows/maven_central_release.yml @@ -3,7 +3,7 @@ name: Release to Maven Central on: push: tags: - - '*.*.*' + - '[0-9]+.[0-9]+.[0-9]+' permissions: contents: read @@ -131,7 +131,7 @@ jobs: - name: Publish release to Maven Central run: | - mvn -B -ntp deploy -P maven-central-release -DskipTests + mvn -B -ntp deploy -P maven-central-release -DskipTests -Dgpg.passphrase="${MAVEN_GPG_PASSPHRASE}" - name: Remove imported signing key if: always() diff --git a/artifacts/release/README.md b/artifacts/release/README.md index c936c436..70483fba 100644 --- a/artifacts/release/README.md +++ b/artifacts/release/README.md @@ -92,7 +92,7 @@ git push origin 1.2.2 The jar publication to Maven Central is performed by the [`Release to Maven Central`](../../.github/workflows/maven_central_release.yml) GitHub Actions workflow added in this PR. -The workflow is triggered automatically when a release tag (matching `*.*.*`) is pushed in the previous step. No manual +The workflow is triggered automatically when a release tag matching `X.Y.Z` (three numeric segments) is pushed in the previous step. No manual dispatch is required. The workflow: - checks out the pushed tag From 4f06526cc6573ba22a25b011ca9b83c45647ea7c Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Fri, 15 May 2026 18:00:23 +0100 Subject: [PATCH 13/16] more nits --- .github/workflows/maven_central_release.yml | 11 +-- artifacts/release/README.md | 97 +++++++++------------ 2 files changed, 49 insertions(+), 59 deletions(-) diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml index 58cd38d9..ee06a149 100644 --- a/.github/workflows/maven_central_release.yml +++ b/.github/workflows/maven_central_release.yml @@ -17,6 +17,7 @@ jobs: release: runs-on: ubuntu-latest environment: maven-release + timeout-minutes: 15 env: MAVEN_RELEASE_AWS_REGION: ${{ vars.MAVEN_RELEASE_AWS_REGION }} MAVEN_RELEASE_AWS_ROLE_ARN: ${{ secrets.MAVEN_RELEASE_AWS_ROLE_ARN }} @@ -48,26 +49,26 @@ jobs: done - name: Check out tag - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: ref: ${{ github.ref }} - name: Set up Java 11 - uses: actions/setup-java@v5 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: distribution: temurin java-version: "11" cache: maven - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v6.1.0 + uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885 # v6.1.1 with: aws-region: ${{ env.MAVEN_RELEASE_AWS_REGION }} role-to-assume: ${{ env.MAVEN_RELEASE_AWS_ROLE_ARN }} role-session-name: java-questdb-client-release - name: Fetch release credentials - uses: aws-actions/aws-secretsmanager-get-secrets@v2 + uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802 # v2.0.10 with: secret-ids: | ,${{ env.MAVEN_RELEASE_AWS_SECRET_ARN }} @@ -131,7 +132,7 @@ jobs: - name: Publish release to Maven Central run: | - mvn -B -ntp deploy -P maven-central-release -DskipTests -Dgpg.passphrase="${MAVEN_GPG_PASSPHRASE}" + mvn -B -ntp deploy -P maven-central-release -DskipTests - name: Remove imported signing key if: always() diff --git a/artifacts/release/README.md b/artifacts/release/README.md index 70483fba..9b5c5e85 100644 --- a/artifacts/release/README.md +++ b/artifacts/release/README.md @@ -1,23 +1,26 @@ # Release steps -This is a short guide to outline the steps involved in releasing `org.questdb:questdb-client` to Maven Central. +Steps to release `org.questdb:questdb-client` to Maven Central. Examples below use `1.2.2` (release) and +`1.2.3-SNAPSHOT` (next snapshot); substitute the actual versions when running. ## Edit release notes -First step is to create a draft release with the intended release version number and release notes. The git tag should -not be created up front — choose the intended tag name in the draft and let GitHub create it when the release is -published. When crafting new release notes, please use previous release notes as style guidelines. Releases should not -look too dissimilar. +Create a draft release with the intended version and notes. Do not create the git tag up front -- pick the tag name +in the draft and let GitHub create it when the release is published. Match the style of previous release notes. -## Switch to `main` +## Create a release branch + +Direct pushes to `main` are blocked by the org ruleset (one-approval squash-merged PR is the only path), so release +commits live on a dedicated branch. ```bash git fetch git checkout main git pull +git checkout -b release/1.2.2 ``` -Releases must be cut from the latest `main`. Make sure your working tree is clean. +Make sure your working tree is clean. ## Clear previous release "memory" @@ -25,29 +28,18 @@ Releases must be cut from the latest `main`. Make sure your working tree is clea mvn release:clean ``` -This removes any `release.properties` and `*.releaseBackup` files left over from a previous attempt. +Removes any `release.properties` and `*.releaseBackup` files left over from a previous attempt. ## Roll versions and create the tag -This step will do the following: +`release:prepare` will: -- roll the parent and module versions from snapshot to release, e.g. from `1.2.2-SNAPSHOT` to `1.2.2` +- roll parent and module versions from snapshot to release (`1.2.2-SNAPSHOT` -> `1.2.2`) - commit the release POMs -- create the release tag in the local git repo -- roll the versions to the next snapshot, e.g. `1.2.3-SNAPSHOT` +- create the release tag locally +- roll the versions to the next snapshot (`1.2.3-SNAPSHOT`) - commit the next-snapshot POMs -```bash -mvn -B release:prepare \ - -DautoVersionSubmodules=true \ - -DpushChanges=false \ - -DreleaseVersion= \ - -DdevelopmentVersion= \ - -Dtag= -``` - -For example, when releasing `1.2.2`: - ```bash mvn -B release:prepare \ -DautoVersionSubmodules=true \ @@ -57,56 +49,53 @@ mvn -B release:prepare \ -Dtag=1.2.2 ``` -The `-B` flag will make assumptions about the release version. Use it for routine releases. For a special version (for -example a new major like `2.0`), drop `-B` and answer the interactive prompts. +`-B` runs non-interactively; drop it for special versions (e.g. a new major) to get the prompts. `-DpushChanges=false` +keeps the commits and tag local until you have verified them. -`-DpushChanges=false` keeps both commits and the tag local until you have verified they look right. - -If `release:prepare` fails partway through, recover with: +If `release:prepare` fails partway through: ```bash mvn release:rollback +git tag -d 1.2.2 ``` -This reverts the prepare commits and removes the backup files. If `release.properties` has already been cleaned up, you -can reset the unwanted commits manually with `git reset --hard ` instead. - -## Push the branch and tag +`release:rollback` reverts the prepare commits and removes the backup files but does **not** delete the tag -- drop +it manually or the next attempt at the same version fails. If `release.properties` is already gone, use +`git reset --hard ` instead (and still drop the tag). -Once the local commits and tag look correct, publish them: +## Push the release branch and tag ```bash -git push origin main -git push origin -``` - -For example: - -```bash -git push origin main +git push origin release/1.2.2 git push origin 1.2.2 ``` -## Publish to Maven Central +The tag push triggers the Maven Central workflow (see below). The branch is merged to `main` afterwards -- see +[Merge the release branch to `main`](#merge-the-release-branch-to-main). -The jar publication to Maven Central is performed by the -[`Release to Maven Central`](../../.github/workflows/maven_central_release.yml) GitHub Actions workflow added in this PR. +## Publish to Maven Central -The workflow is triggered automatically when a release tag matching `X.Y.Z` (three numeric segments) is pushed in the previous step. No manual -dispatch is required. The workflow: +The [`Release to Maven Central`](../../.github/workflows/maven_central_release.yml) workflow fires automatically when +a tag matching `X.Y.Z` is pushed. No manual dispatch. It: - checks out the pushed tag - assumes an AWS IAM role via OIDC and reads the GPG key and Sonatype credentials from AWS Secrets Manager -- verifies that the tag name matches the parent POM version and that the version is not a snapshot +- verifies the tag matches the parent POM version and is not a snapshot - signs the artifacts and publishes them through the Sonatype Central Portal -You need push access to the repository to push the release tag, which is what triggers the workflow. +Push access to the repository is required to push the release tag. -## Post-release +## Merge the release branch to `main` + +Once the workflow finishes and the artifacts appear on Maven Central, open a PR from `release/1.2.2` to `main` and +squash-merge it after approval. Delete the release branch afterwards. -Verify that the new version appears on -[Maven Central](https://central.sonatype.com/artifact/org.questdb/questdb-client). Propagation may take some time after -publishing. +Squash-merge is the only merge method allowed by the org ruleset on `main`, so the original `[maven-release-plugin]` +commits will not appear in `main`'s history. The tag remains the canonical pointer to the released code; `main` +carries a single squashed commit that bumps the snapshot version. + +## Post-release -Finalize the GitHub release draft from the tag created by the release process and add the release notes for the -version. +Verify the version appears on +[Maven Central](https://central.sonatype.com/artifact/org.questdb/questdb-client) (propagation can take a few +minutes). Finalize the GitHub release draft against the new tag and add the release notes. From aedf4c7dbac99a26058463ad3968a7dd048d54fc Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Fri, 15 May 2026 18:31:16 +0100 Subject: [PATCH 14/16] team description for releases --- artifacts/release/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/artifacts/release/README.md b/artifacts/release/README.md index 9b5c5e85..0ad8ef2f 100644 --- a/artifacts/release/README.md +++ b/artifacts/release/README.md @@ -3,6 +3,9 @@ Steps to release `org.questdb:questdb-client` to Maven Central. Examples below use `1.2.2` (release) and `1.2.3-SNAPSHOT` (next snapshot); substitute the actual versions when running. +**Prerequisite:** tag creation is restricted by an org-wide ruleset, so you must be a member of the `questdb/release` +team to push the release tag. Confirm membership before starting. + ## Edit release notes Create a draft release with the intended version and notes. Do not create the git tag up front -- pick the tag name @@ -83,8 +86,6 @@ a tag matching `X.Y.Z` is pushed. No manual dispatch. It: - verifies the tag matches the parent POM version and is not a snapshot - signs the artifacts and publishes them through the Sonatype Central Portal -Push access to the repository is required to push the release tag. - ## Merge the release branch to `main` Once the workflow finishes and the artifacts appear on Maven Central, open a PR from `release/1.2.2` to `main` and From eb1a0815fbb026f46cafa5064b2d8efaf1cd40d6 Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Fri, 15 May 2026 19:13:34 +0100 Subject: [PATCH 15/16] relax maven publishing --- artifacts/release/README.md | 19 +++++++++++++------ core/pom.xml | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/artifacts/release/README.md b/artifacts/release/README.md index 0ad8ef2f..918fab65 100644 --- a/artifacts/release/README.md +++ b/artifacts/release/README.md @@ -84,12 +84,18 @@ a tag matching `X.Y.Z` is pushed. No manual dispatch. It: - checks out the pushed tag - assumes an AWS IAM role via OIDC and reads the GPG key and Sonatype credentials from AWS Secrets Manager - verifies the tag matches the parent POM version and is not a snapshot -- signs the artifacts and publishes them through the Sonatype Central Portal +- signs the artifacts and uploads them through the Sonatype Central Portal + +The workflow returns once Sonatype has validated the upload and taken ownership of the artifacts. Physical +propagation to Maven Central happens asynchronously after the workflow finishes, so a green run does **not** mean the +artifacts are visible on `central.sonatype.com` yet -- that step is covered under [Post-release](#post-release). ## Merge the release branch to `main` -Once the workflow finishes and the artifacts appear on Maven Central, open a PR from `release/1.2.2` to `main` and -squash-merge it after approval. Delete the release branch afterwards. +Once the workflow finishes, open a PR from `release/1.2.2` to `main` and squash-merge it after approval. Delete the +release branch afterwards. You do not need to wait for Maven Central propagation before merging -- once the workflow +is green, Sonatype owns the artifacts and the next snapshot version on `main` is the source of truth for ongoing +development. Squash-merge is the only merge method allowed by the org ruleset on `main`, so the original `[maven-release-plugin]` commits will not appear in `main`'s history. The tag remains the canonical pointer to the released code; `main` @@ -97,6 +103,7 @@ carries a single squashed commit that bumps the snapshot version. ## Post-release -Verify the version appears on -[Maven Central](https://central.sonatype.com/artifact/org.questdb/questdb-client) (propagation can take a few -minutes). Finalize the GitHub release draft against the new tag and add the release notes. +After the workflow completes, Sonatype still has to propagate the artifacts to Maven Central. This typically takes a +few minutes but can occasionally run longer. Check +[Maven Central](https://central.sonatype.com/artifact/org.questdb/questdb-client) until the new version is listed, +then finalize the GitHub release draft against the new tag and add the release notes. diff --git a/core/pom.xml b/core/pom.xml index d71223ba..addab542 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -358,7 +358,7 @@ central true - published + validated From c4b3bd78c182a418f05a0f26bb26ff5545bddda3 Mon Sep 17 00:00:00 2001 From: ideoma <2159629+ideoma@users.noreply.github.com> Date: Mon, 18 May 2026 14:14:46 +0100 Subject: [PATCH 16/16] few nits fixes in the new job --- .github/workflows/maven_central_release.yml | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/maven_central_release.yml b/.github/workflows/maven_central_release.yml index ee06a149..174b018e 100644 --- a/.github/workflows/maven_central_release.yml +++ b/.github/workflows/maven_central_release.yml @@ -17,7 +17,7 @@ jobs: release: runs-on: ubuntu-latest environment: maven-release - timeout-minutes: 15 + timeout-minutes: 30 env: MAVEN_RELEASE_AWS_REGION: ${{ vars.MAVEN_RELEASE_AWS_REGION }} MAVEN_RELEASE_AWS_ROLE_ARN: ${{ secrets.MAVEN_RELEASE_AWS_ROLE_ARN }} @@ -60,6 +60,18 @@ jobs: java-version: "11" cache: maven + - name: Verify tag matches POM version + run: | + POM_VERSION=$(mvn -B -q -N -DforceStdout help:evaluate -Dexpression=project.version) + if [[ "${POM_VERSION}" == *-SNAPSHOT ]]; then + echo "::error::Refusing to release SNAPSHOT version ${POM_VERSION}." + exit 1 + fi + if [[ "${GITHUB_REF_NAME}" != "${POM_VERSION}" ]]; then + echo "::error::Tag ${GITHUB_REF_NAME} does not match POM version ${POM_VERSION}." + exit 1 + fi + - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885 # v6.1.1 with: @@ -118,18 +130,6 @@ jobs: printf '%s\n' "$MAVEN_GPG_PRIVATE_KEY" | gpg --batch --import echo "GNUPGHOME=$GNUPGHOME" >> "$GITHUB_ENV" - - name: Verify tag matches POM version - run: | - POM_VERSION=$(mvn -B -q -N -DforceStdout help:evaluate -Dexpression=project.version) - if [[ "${POM_VERSION}" == *-SNAPSHOT ]]; then - echo "::error::Refusing to release SNAPSHOT version ${POM_VERSION}." - exit 1 - fi - if [[ "${GITHUB_REF_NAME}" != "${POM_VERSION}" ]]; then - echo "::error::Tag ${GITHUB_REF_NAME} does not match POM version ${POM_VERSION}." - exit 1 - fi - - name: Publish release to Maven Central run: | mvn -B -ntp deploy -P maven-central-release -DskipTests