Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
236 changes: 236 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
name: Release to Maven Central

on:
# Manual trigger
workflow_dispatch:
inputs:
release_version:
description: "Version to release (if empty, derive from project version)"
required: false
# Automatic trigger on pushing a version tag (e.g., "v1.2.3")
push:
tags:
- "v*"
# For testing:
# pull_request:
# branches:
# - master

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete?

Suggested change
# For testing:
# pull_request:
# branches:
# - master

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this helpful to have on hand for testing the workflow in a PR, but probably don't want to leave it in after initial tests.


jobs:
# tests and tests-no-docker are from tests.yml and build the actual native libraries that will be used in the release.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that mean that these two also need to have the exact same name or it won't line up correctly? Because having a job called tests in the release yaml file feels kinda weird.

@isaacbrodsky isaacbrodsky May 29, 2025

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could rename them to be clearer that they are just here for building the artifacts, but keeping the same names makes it easier to copy changes back and forth.

edit: I have updated the names to be clearer what they are actually doing

tests:
name: Java ${{ matrix.java-version }} ${{ matrix.os }} ${{ matrix.dockcross-only }}
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest]
java-distribution: [adopt]
java-version: [8]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 is EOL, right? Should we move this higher?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen different things about Java 8. It seems Oracle has very long term support for it, but it does seem practically EOL. I'm not sure how much the open source ecosystem is still supporting it as I haven't done as much Java work recently.

My plan was to leave the baseline at Java 8 for now (since that is what we previously built) and then in a follow up PR re-enable some code quality tools and bump the baseline to a newer LTS release.

dockcross-only:
[
"android-arm",
"android-arm64",
"linux-arm64",
"linux-armv5",
"linux-armv7",
"linux-s390x",
"linux-ppc64le",
"linux-x64",
"linux-x86",
"windows-static-x64",
"windows-static-x86",
Comment thread
isaacbrodsky marked this conversation as resolved.
]

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: actions/setup-java@v2
with:
distribution: "${{ matrix.java-distribution }}"
java-version: "${{ matrix.java-version }}"

- uses: gradle/actions/setup-gradle@v3
with:
gradle-version: wrapper

- uses: actions/cache@v4
id: gradle-cache
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

# - name: Format check
# if: ${{ matrix.java-version != 8 }}
# run: ./gradlew spotlessCheck

- name: Tests
run: ./gradlew clean test -Ph3SystemPrune=true "-Ph3DockcrossOnly=${{ matrix.dockcross-only }}"
env:
OCI_EXE: docker

- name: Format check for C
run: git diff --exit-code

- uses: actions/upload-artifact@v4
name: Upload artifacts
if: ${{ matrix.java-version == 8 }}
with:
name: docker-built-shared-objects-${{ matrix.dockcross-only }}
path: |
src/main/resources/*/*.so
src/main/resources/*/*.dll
if-no-files-found: error

tests-no-docker:
name: Java (No Docker) ${{ matrix.java-version }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [macos-latest]
Comment thread
isaacbrodsky marked this conversation as resolved.
java-distribution: [adopt]
java-version: [8]

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: actions/setup-java@v2
with:
distribution: "${{ matrix.java-distribution }}"
java-version: "${{ matrix.java-version }}"

- uses: gradle/actions/setup-gradle@v3
with:
gradle-version: wrapper

- uses: actions/cache@v4
id: gradle-cache
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Tests
run: ./gradlew clean test

- uses: actions/upload-artifact@v4
name: Upload Mac OS Artifacts
if: ${{ matrix.os == 'macos-latest' && matrix.java-version == 8 }}
with:
name: macos-built-shared-objects
path: src/main/resources/*/*.dylib
if-no-files-found: error

release:
runs-on: ubuntu-latest
permissions:
contents: write # allow pushing commits/tags

needs:
- tests
- tests-no-docker

steps:
- name: Check out code
uses: actions/checkout@v3

- name: Set up JDK
uses: actions/setup-java@v3
with:
distribution: "temurin"
java-version: "21"

- name: Determine release version
id: vars
run: |
# Derive the release version (drop "-SNAPSHOT") from Gradle project or input
VERSION_INPUT="${{ github.event.inputs.release_version || '' }}"
if [ -n "$VERSION_INPUT" ]; then
RELEASE_VERSION="$VERSION_INPUT"
else
# Read version from build.gradle.kts or gradle.properties
RELEASE_VERSION=$(grep -E 'version\s*=' build.gradle.kts | sed -E 's/.*\"(.+)-SNAPSHOT\".*/\1/')
fi
echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_ENV

- name: Remove -SNAPSHOT suffix (prepare release version)
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
sed -i -E "s/${RELEASE_VERSION}-SNAPSHOT/$RELEASE_VERSION/" build.gradle.kts gradle.properties || true
git config user.name "github-actions"
git config user.email "[email protected]"
git commit -am "chore: release $RELEASE_VERSION [skip ci]"

- name: Create Git tag for release
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
git tag -a "v${RELEASE_VERSION}" -m "Release $RELEASE_VERSION"
git push origin HEAD:main --follow-tags

- name: Download Docker binaries
uses: actions/download-artifact@v4.1.7
with:
pattern: docker-built-shared-objects-*
merge-multiple: true
path: src/main/resources/

- name: Download Mac binaries
uses: actions/download-artifact@v4.1.7
with:
name: macos-built-shared-objects
path: src/main/resources/

- name: Download and test
run: |
./gradlew clean test assemble -Ph3GithubArtifactsUse=true -Ph3GithubArtifactsByRun=true

- name: List files in jars
run: |
ls -lh build/libs
for f in build/libs/*.jar; do
echo "File: $f"
unzip -l "$f"
done

- name: Publish to Sonatype OSSRH (Maven Central)
env:
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }}
ORG_GRADLE_PROJECT_signingKeyId: ${{ secrets.SIGNING_KEY_ID }}
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
OSSRH_STAGING_PROFILE_ID: ${{ secrets.OSSRH_STAGING_PROFILE_ID }}
run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository

- name: Create GitHub Release (with changelog notes)
# This uses an action to create a release on GitHub
uses: softprops/action-gh-release@v1
with:
tag_name: "v${{ env.RELEASE_VERSION }}"
release_name: "${{ env.RELEASE_VERSION }}"
body_path: CHANGELOG.md # assumes changelog contains latest release notes at top

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this include the entire changelog per release? Or just the latest release?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the repo https://github.com/softprops/action-gh-release I think it is set up to take the first markdown section, the generated release should be very easy to manually modify after the fact if the detected changelog is not right.

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Bump to next snapshot version
run: |
# Bump minor version (for example) and append -SNAPSHOT for continued development
NEXT_VERSION=$(echo $RELEASE_VERSION | awk -F. '{$NF += 1; OFS="."; print $0}') # increment last segment
NEXT_VERSION="$NEXT_VERSION-SNAPSHOT"
sed -i -E "s/$RELEASE_VERSION/$NEXT_VERSION/" build.gradle.kts gradle.properties || true
git config user.name "github-actions"
git config user.email "[email protected]"
git commit -am "chore: start next development cycle $NEXT_VERSION [skip ci]"
git push origin HEAD:main
Comment thread
isaacbrodsky marked this conversation as resolved.
Outdated
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ plugins {
}

group = 'com.uber'
version = '4.1.3-SNAPSHOT'
description = 'Java bindings for H3, a hierarchical hexagonal geospatial indexing system.'

java {
Expand Down Expand Up @@ -114,6 +113,10 @@ jar {
duplicatesStrategy = DuplicatesStrategy.WARN
}

sourcesJar {
dependsOn buildH3
}

publishing {
publications {
mavenJava(MavenPublication) {
Expand Down
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
# Blocked on https://github.com/nbaztec/coveralls-jacoco-gradle-plugin/issues/66
org.gradle.configuration-cache=false

version=4.1.3-SNAPSHOT