diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9296a76..61fab54 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,6 +10,8 @@ jobs: permissions: contents: read packages: write + env: + GITHUB_VERSION: ${{ github.ref_name }} steps: - name: Checkout uses: actions/checkout@v4 @@ -33,8 +35,7 @@ jobs: vips --version || (sudo apt update && sudo apt install libvips-dev) ./run_samples.sh - - name: Publish + - name: Publish to GitHub Packages run: ./gradlew core:publish env: - GITHUB_VERSION: ${{ github.ref_name }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index ec6fa76..3220d11 100644 --- a/README.md +++ b/README.md @@ -133,4 +133,12 @@ memory: high-water mark 36.55 MB [main] INFO vipsffm.SampleRunner - all samples ran successfully 🎉 ``` +## Releasing + +* GitHub Releases automatically result in a deployment to GitHub Packages +* Maven Central releases happen manually + * This can only be done by @lopcode + * And only after a GitHub Release is made + * Run `./publish_release_to_maven_central.sh ` + [1]: https://docs.oracle.com/en/java/javase/22/core/memory-segments-and-arenas.html \ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 719cc0c..f06434e 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -7,6 +7,7 @@ import java.net.URI plugins { `java-library` `maven-publish` + signing } repositories { @@ -17,6 +18,8 @@ java { toolchain { languageVersion.set(JavaLanguageVersion.of(22)) } + withJavadocJar() + withSourcesJar() } testing { @@ -70,12 +73,16 @@ tasks.withType().configureEach { dependencies {} +val githubVersion = System.getenv("GITHUB_VERSION") ?: null +val mavenVersion = githubVersion?.removePrefix("v") ?: "local" +val releasePath = "repos/release-${githubVersion}" + publishing { publications { create("mavenJava") { groupId = "app.photofox.vips-ffm" artifactId = "vips-ffm-core" - version = System.getenv("GITHUB_VERSION")?.removePrefix("v") + version = mavenVersion from(components["java"]) @@ -83,6 +90,18 @@ publishing { name.set("vips-ffm-core") description.set("libvips bindings for JVM projects, using JDK 22's FFM and Class-File APIs, for performant, safe, and ergonomic image manipulation") url.set("https://github.com/lopcode/vips-ffm") + licenses { + license { + name = "Apache License, Version 2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0" + } + } + developers { + developer { + name = "lopcode" + url = "https://github.com/lopcode" + } + } } } } @@ -95,5 +114,35 @@ publishing { password = System.getenv("GITHUB_TOKEN") } } + maven { + name = "Local" + url = uri(layout.buildDirectory.dir(releasePath)) + } } +} + +val signingKey = System.getenv("SIGNING_KEY_ID") ?: null +val signingKeyPassphrase = System.getenv("SIGNING_KEY_PASSPHRASE") ?: null + +if (!signingKey.isNullOrBlank()) { + project.ext["signing.gnupg.keyName"] = signingKey + project.ext["signing.gnupg.passphrase"] = signingKeyPassphrase + project.ext["signing.gnupg.executable"] = "/usr/local/bin/gpg" + + signing { + useGpgCmd() + sign(publishing.publications) + } +} + +tasks.register("packageMavenCentralRelease") { + dependsOn("publishMavenJavaPublicationToLocalRepository") + + archiveFileName.set("release-${githubVersion}.zip") + destinationDirectory.set(layout.buildDirectory.dir("repos")) + + // exclude hidden files + exclude("*/.*") + + from(layout.buildDirectory.dir(releasePath)) } \ No newline at end of file diff --git a/publish_release_to_maven_central.sh b/publish_release_to_maven_central.sh new file mode 100755 index 0000000..ecd937f --- /dev/null +++ b/publish_release_to_maven_central.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -eou pipefail + +if [ -z "$1" ]; then + echo "Usage: ./publish_release_to_maven_central.sh " + exit 1 +fi + +if [ -n "$(git status --porcelain)" ]; then + echo "there are local changes, not building (check \"git status\")" + exit 1 +fi + +(gh release list --json tagName,isDraft,isPrerelease | jq -e ".[] | select(.tagName == \"$1\" and .isDraft == false and .isPrerelease == false)") || (echo "couldn't find release" && exit 1) +git fetch --tags +git checkout tags/"$1" +git describe --exact-match --tags + +SIGNING_KEY_ID=$(op read "op://Private/Sonatype GPG/key id") \ +SIGNING_KEY_PASSPHRASE=$(op read "op://Private/Sonatype GPG/password") \ +./gradlew clean core:compileJava core:packageMavenCentralRelease + +MAVEN_CENTRAL_USER=$(op read "op://Private/New Maven Central Portal Publish/username") +MAVEN_CENTRAL_TOKEN=$(op read "op://Private/New Maven Central Portal Publish/password") +BEARER_TOKEN=$(echo "$MAVEN_CENTRAL_USER:$MAVEN_CENTRAL_TOKEN" | base64) + +curl --request POST \ + --verbose \ + --header "Authorization: Bearer $BEARER_TOKEN" \ + --form bundle=@core/build/repos/release-"$VERSION".zip \ + https://central.sonatype.com/api/v1/publisher/upload?name="$VERSION"\&publishingType=USER_MANAGED \ No newline at end of file