From 572b35499fdfc14fd79094001ed5180050fa900b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sabri=20Onur=20T=C3=BCz=C3=BCn?= Date: Mon, 19 Oct 2026 13:58:08 +0300 Subject: [PATCH] Release with a manually run workflow --- .github/scripts/prepare-release.sh | 34 ++++++++++++++ .github/scripts/resolve-version.sh | 5 -- .github/workflows/craftgate-build.yml | 8 ++-- .github/workflows/craftgate-release.yml | 61 +++++++++++++++++++------ 4 files changed, 86 insertions(+), 22 deletions(-) create mode 100755 .github/scripts/prepare-release.sh delete mode 100755 .github/scripts/resolve-version.sh diff --git a/.github/scripts/prepare-release.sh b/.github/scripts/prepare-release.sh new file mode 100755 index 0000000..74a3a08 --- /dev/null +++ b/.github/scripts/prepare-release.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Validates the version requested from the release workflow and writes VERSION and TAG to GITHUB_ENV +# (and as "version" and "tag" step outputs). +# "1.0.84" and "v1.0.84" are both accepted; the tag is created as "1.0.84". +# Fails if the version is not X.Y.Z, is already tagged (with or without "v") or is not above the latest release. +set -euo pipefail +input="${1:?usage: prepare-release.sh [tag-prefix]}" +prefix="${2:-}" +version="${input#v}" + +if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Version must be in the form X.Y.Z, got '$input'" + exit 1 +fi + +for existing in "$version" "v$version"; do + if git rev-parse -q --verify "refs/tags/$existing" >/dev/null; then + echo "::error::Version $version is already released as tag '$existing'" + exit 1 + fi +done + +latest="$(git tag --list | sed -nE 's/^v?([0-9]+\.[0-9]+\.[0-9]+)$/\1/p' | sort -V | tail -n 1)" +if [[ -n "$latest" && "$(printf '%s\n%s\n' "$latest" "$version" | sort -V | tail -n 1)" != "$version" ]]; then + echo "::error::Version $version must be greater than the latest release $latest" + exit 1 +fi + +echo "Releasing $version as tag $prefix$version (latest release: ${latest:-none})" +echo "VERSION=$version" >> "$GITHUB_ENV" +echo "TAG=$prefix$version" >> "$GITHUB_ENV" +if [[ -n "${GITHUB_OUTPUT:-}" ]]; then + printf 'version=%s\ntag=%s\n' "$version" "$prefix$version" >> "$GITHUB_OUTPUT" +fi diff --git a/.github/scripts/resolve-version.sh b/.github/scripts/resolve-version.sh deleted file mode 100755 index 5fdde57..0000000 --- a/.github/scripts/resolve-version.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# Resolves the library version from a release tag: "v1.0.83" and "1.0.83" both become "1.0.83". -set -euo pipefail -tag="${1:?usage: resolve-version.sh }" -echo "VERSION=${tag#v}" >> "$GITHUB_ENV" diff --git a/.github/workflows/craftgate-build.yml b/.github/workflows/craftgate-build.yml index 561fbd0..35952e3 100644 --- a/.github/workflows/craftgate-build.yml +++ b/.github/workflows/craftgate-build.yml @@ -50,13 +50,13 @@ jobs: distribution: 'zulu' java-version: '8' - # Same version resolution as the release workflow, with a fake "v" prefixed tag. - - name: Resolve version from tag - run: .github/scripts/resolve-version.sh v0.0.0-dryrun + # Same version validation as the release workflow, with a fake "v" prefixed version. + - name: Validate version + run: .github/scripts/prepare-release.sh v9.9.9 - name: Build release artifacts without signing or publishing run: | - test "$VERSION" = "0.0.0-dryrun" + test "$VERSION" = "9.9.9" ./gradlew clean test publishToMavenLocal -Pversion="$VERSION" -x signMavenJavaPublication - name: Verify the version in the artifacts diff --git a/.github/workflows/craftgate-release.yml b/.github/workflows/craftgate-release.yml index 7f39879..4521299 100644 --- a/.github/workflows/craftgate-release.yml +++ b/.github/workflows/craftgate-release.yml @@ -1,16 +1,39 @@ -name: Craftgate Java CI +name: Craftgate Java Release on: - release: - types: [ published ] + workflow_dispatch: + inputs: + version: + description: "Release version (format: 1.2.3)" + required: true + publish_to_maven_central: + description: "Publish artifacts to Maven Central" + type: boolean + default: true jobs: - build-artifact: - name: Publish Library + release: + name: Release runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Ensure branch context + run: | + if [[ "${GITHUB_REF}" != refs/heads/* ]]; then + echo "::error::Release workflow must run against a branch ref." + exit 1 + fi + + - name: Validate version + env: + INPUT_VERSION: ${{ inputs.version }} + run: .github/scripts/prepare-release.sh "$INPUT_VERSION" - name: Set up JDK 1.8 uses: actions/setup-java@v6 @@ -25,18 +48,30 @@ jobs: key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} restore-keys: ${{ runner.os }}-gradle - - name: Resolve version from tag - env: - TAG_NAME: ${{ github.event.release.tag_name }} - run: .github/scripts/resolve-version.sh "$TAG_NAME" + - name: Build and test + run: ./gradlew clean build -Pversion="$VERSION" - - name: Build and Publish with Gradle + - name: Create tag + run: | + git tag "$TAG" + git push origin "refs/tags/$TAG" + + - name: Publish to Maven Central + if: inputs.publish_to_maven_central == true run: openssl enc -aes-256-cbc -md sha256 -pass pass:${{secrets.ENC_KEY}} -d -A -in craftgate.gpg.enc -out craftgate.gpg && - ./gradlew clean && - ./gradlew publish -Dorg.gradle.internal.http.socketTimeout=120000 -Dorg.gradle.internal.http.connectionTimeout=120000 -Pversion=${VERSION} -PrepoUser=${{secrets.CP_TOKEN_USERNAME}} -PrepoPassword=${{secrets.CP_TOKEN_PASSWORD}} -Psigning.keyId=${{secrets.SIGNING_KEY_ID}} -Psigning.password=${{secrets.SIGNING_PASSWORD}} + ./gradlew publish -Dorg.gradle.internal.http.socketTimeout=120000 -Dorg.gradle.internal.http.connectionTimeout=120000 -Pversion="$VERSION" -PrepoUser=${{secrets.CP_TOKEN_USERNAME}} -PrepoPassword=${{secrets.CP_TOKEN_PASSWORD}} -Psigning.keyId=${{secrets.SIGNING_KEY_ID}} -Psigning.password=${{secrets.SIGNING_PASSWORD}} - name: Trigger deployment visibility - run: | + if: inputs.publish_to_maven_central == true + run: | curl -i -X POST https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/io.craftgate \ -H "Authorization: Bearer $(echo -n "${{secrets.CP_TOKEN_USERNAME}}:${{secrets.CP_TOKEN_PASSWORD}}" | base64)" + - name: Create GitHub release + uses: softprops/action-gh-release@v3 + with: + tag_name: ${{ env.TAG }} + name: ${{ env.TAG }} + generate_release_notes: true + files: | + build/libs/*.jar