Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions .github/workflows/maven_central_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: Release to Maven Central

on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+'

permissions:
contents: read
id-token: write

concurrency:
group: maven-central-release
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
environment: maven-release
timeout-minutes: 30
env:
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: |
required_vars=(
MAVEN_RELEASE_AWS_REGION
)

for var_name in "${required_vars[@]}"; do
if [[ -z "${!var_name:-}" ]]; then
echo "::error::Repository variable ${var_name} is required."
exit 1
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 tag
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
ref: ${{ github.ref }}

- name: Set up Java 11
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
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:
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@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802 # v2.0.10
with:
secret-ids: |
,${{ env.MAVEN_RELEASE_AWS_SECRET_ARN }}
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_ARN} must define ${var_name}."
exit 1
fi
done

- name: Configure Maven settings.xml
run: |
mkdir -p "$HOME/.m2"
cat > "$HOME/.m2/settings.xml" <<'EOF'
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>central</id>
<username>${env.MAVEN_CENTRAL_USERNAME}</username>
<password>${env.MAVEN_CENTRAL_PASSWORD}</password>
</server>
<server>
<id>gpg.passphrase</id>
<passphrase>${env.MAVEN_GPG_PASSPHRASE}</passphrase>
</server>
</servers>
</settings>
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: Publish release to Maven Central
run: |
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
108 changes: 0 additions & 108 deletions RELEASE.md

This file was deleted.

109 changes: 109 additions & 0 deletions artifacts/release/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Release steps

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
in the draft and let GitHub create it when the release is published. Match the style of previous release notes.

## 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
```

Make sure your working tree is clean.

## Clear previous release "memory"

```bash
mvn release:clean
```

Removes any `release.properties` and `*.releaseBackup` files left over from a previous attempt.

## Roll versions and create the tag

`release:prepare` will:

- roll parent and module versions from snapshot to release (`1.2.2-SNAPSHOT` -> `1.2.2`)
- commit the release POMs
- 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=1.2.2 \
-DdevelopmentVersion=1.2.3-SNAPSHOT \
-Dtag=1.2.2
```

`-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.

If `release:prepare` fails partway through:

```bash
mvn release:rollback
git tag -d 1.2.2
```

`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 <previous-HEAD>` instead (and still drop the tag).

## Push the release branch and tag

```bash
git push origin release/1.2.2
git push origin 1.2.2
```

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).

## Publish to Maven Central

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 the tag matches the parent POM version and is not a snapshot
- 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, 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`
carries a single squashed commit that bumps the snapshot version.

## Post-release

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.
7 changes: 4 additions & 3 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@
</developers>

<scm>
<url>scm:git:https://github.com/questdb/java-questdb-client.git</url>
<url>https://github.com/questdb/java-questdb-client</url>
<connection>scm:git:https://github.com/questdb/java-questdb-client.git</connection>
<developerConnection>scm:git:https://github.com/questdb/java-questdb-client.git</developerConnection>
<tag>HEAD</tag>
</scm>

Expand Down Expand Up @@ -352,12 +353,12 @@
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.8.0</version>
<version>0.9.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
<autoPublish>true</autoPublish>
<waitUntil>published</waitUntil>
<waitUntil>validated</waitUntil>
</configuration>
</plugin>
</plugins>
Expand Down
Loading