From 66a5408a632cfe8aa5849e270fd5a7b233cb6dcb Mon Sep 17 00:00:00 2001 From: Martin Todorov Date: Sun, 29 Mar 2026 19:47:10 +0300 Subject: [PATCH 1/3] Set up publishing of SNAPSHOT builds to GitHub Packages * Added workflow for publishing `SNAPSHOT` builds. * Added workflow for removing `SNAPSHOT` builds once a pull request has been merged. --- .github/workflows/build.yml | 58 +++++++++++++++++++++- .github/workflows/cleanup-snapshot.yml | 56 +++++++++++++++++++++ .github/workflows/codeql.yml | 2 +- .github/workflows/deploy-tagged.yml | 4 +- README.md | 68 ++++++++++++++++++++++++++ build.gradle.kts | 14 ++++++ 6 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/cleanup-snapshot.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3735cb5..223de90 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,10 +23,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Setup JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: java-version: ${{ matrix.java }} distribution: 'temurin' @@ -46,3 +46,57 @@ jobs: - name: Build and test run: ./gradlew build --stacktrace + + publish-snapshot: + name: Publish snapshot to GitHub Packages + runs-on: ubuntu-latest + needs: build + if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Get base version + id: get-version + run: | + BASE_VERSION=$(grep -iE "version([ ]*)=" gradle.properties | cut -f 2 -d "=" | tr -d '[:space:]') + # Strip any existing -SNAPSHOT suffix so we can re-apply it cleanly + BASE_VERSION="${BASE_VERSION%-SNAPSHOT}" + echo "base_version=${BASE_VERSION}" >> $GITHUB_OUTPUT + + - name: Determine snapshot version + id: snapshot-version + run: | + if [ "${{ github.event_name }}" == "pull_request" ]; then + SNAPSHOT_VERSION="${{ steps.get-version.outputs.base_version }}-PR-${{ github.event.pull_request.number }}-SNAPSHOT" + else + SNAPSHOT_VERSION="${{ steps.get-version.outputs.base_version }}-SNAPSHOT" + fi + echo "snapshot_version=${SNAPSHOT_VERSION}" >> $GITHUB_OUTPUT + echo "Publishing snapshot version: ${SNAPSHOT_VERSION}" + + - name: Setup JDK + uses: actions/setup-java@v5 + with: + java-version: 8 + distribution: 'temurin' + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + with: + gradle-version: wrapper + gradle-home-cache-cleanup: true + gradle-home-cache-includes: | + caches + notifications + jdks + + - name: Publish snapshot to GitHub Packages + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} + run: ./gradlew publishReleasePublicationToGitHubPackagesRepository -Pversion=${{ steps.snapshot-version.outputs.snapshot_version }} --stacktrace diff --git a/.github/workflows/cleanup-snapshot.yml b/.github/workflows/cleanup-snapshot.yml new file mode 100644 index 0000000..f43a04d --- /dev/null +++ b/.github/workflows/cleanup-snapshot.yml @@ -0,0 +1,56 @@ +name: Clean up PR snapshot + +on: + pull_request: + types: [closed] + +jobs: + cleanup-snapshot: + name: Delete PR snapshot from GitHub Packages + runs-on: ubuntu-latest + # Only run when the PR was actually merged, not just closed. + if: github.event.pull_request.merged == true + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Get base version + id: get-version + run: | + BASE_VERSION=$(grep -iE "version([ ]*)=" gradle.properties | cut -f 2 -d "=" | tr -d '[:space:]') + # Strip any existing -SNAPSHOT suffix so we can re-apply it cleanly + BASE_VERSION="${BASE_VERSION%-SNAPSHOT}" + echo "base_version=${BASE_VERSION}" >> $GITHUB_OUTPUT + + - name: Delete PR snapshot from GitHub Packages + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + SNAPSHOT_VERSION="${{ steps.get-version.outputs.base_version }}-PR-${{ github.event.pull_request.number }}-SNAPSHOT" + echo "Looking for package version: ${SNAPSHOT_VERSION}" + + # Retrieve the numeric ID of any published version matching this snapshot. + # --paginate ensures all pages are scanned; --jq filters on each page. + VERSION_IDS=$(gh api \ + --paginate \ + -H "Accept: application/vnd.github+json" \ + "/orgs/${{ github.repository_owner }}/packages/maven/com.uploadcare.uploadcare/versions" \ + --jq ".[] | select(.name == \"${SNAPSHOT_VERSION}\") | .id" 2>/dev/null || true) + + if [ -z "$VERSION_IDS" ]; then + echo "No published version found for ${SNAPSHOT_VERSION} — nothing to delete." + exit 0 + fi + + while IFS= read -r VERSION_ID; do + echo "Deleting version ID ${VERSION_ID} (${SNAPSHOT_VERSION}) …" + gh api --method DELETE \ + -H "Accept: application/vnd.github+json" \ + "/orgs/${{ github.repository_owner }}/packages/maven/com.uploadcare.uploadcare/versions/${VERSION_ID}" + echo "Deleted version ID ${VERSION_ID}." + done <<< "$VERSION_IDS" + echo "Done cleaning up ${SNAPSHOT_VERSION}." diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8d45a23..b112cfd 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v6 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/deploy-tagged.yml b/.github/workflows/deploy-tagged.yml index 921d68a..cfba8de 100644 --- a/.github/workflows/deploy-tagged.yml +++ b/.github/workflows/deploy-tagged.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 with: ref: ${{ env.TAG }} @@ -37,7 +37,7 @@ jobs: fi - name: Setup JDK and Maven - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: java-version: 8 distribution: "temurin" diff --git a/README.md b/README.md index 26041f1..37e1410 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,74 @@ If you are using the kotlin style `build.gradle.kts`: implementation("com.uploadcare:uploadcare:3.5.1") ``` +## Snapshot Builds (Pre-release) + +Snapshot builds are published to [GitHub Packages](https://github.com/uploadcare/uploadcare-java/packages) automatically: + +- **From pull requests**: version format `{version}-PR-{pr-number}-SNAPSHOT` (e.g. `3.5.3-PR-42-SNAPSHOT`) +- **From the `master` branch**: version format `{version}-SNAPSHOT` (e.g. `3.5.3-SNAPSHOT`) + +To consume a snapshot build, add the GitHub Packages repository and authenticate with a [personal access token](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages) (PAT) that has `read:packages` scope. + +### Maven (snapshot) + +Add to your `~/.m2/settings.xml`: + +```xml + + + + uploadcare-snapshots + YOUR_GITHUB_USERNAME + YOUR_GITHUB_PAT + + + +``` + +Add to your `pom.xml`: + +```xml + + + uploadcare-snapshots + https://maven.pkg.github.com/uploadcare/uploadcare-java + + true + + + + + + + com.uploadcare + uploadcare + 3.5.3-SNAPSHOT + + +``` + +### Gradle (snapshot) + +Add to your `build.gradle` (or `build.gradle.kts`): + +```groovy +repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/uploadcare/uploadcare-java") + credentials { + username = project.findProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR") + password = project.findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") + } + } +} + +dependencies { + implementation("com.uploadcare:uploadcare:3.5.3-SNAPSHOT") +} +``` + ## Examples Get your [API keys](https://uploadcare.com/docs/start/settings/#keys) to proceed with the examples below. diff --git a/build.gradle.kts b/build.gradle.kts index bf62e79..0193b90 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -31,12 +31,26 @@ dependencies { // Setup global publishing repository settings. signing { + setRequired({ isReleaseVersion }) useGpgCmd() sign(publishing.publications) } +// Skip signing entirely for non-release (snapshot) builds. +tasks.withType().configureEach { + onlyIf { isReleaseVersion } +} + publishing { repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/uploadcare/uploadcare-java") + credentials { + username = System.getenv("GITHUB_ACTOR") ?: "" + password = System.getenv("GITHUB_TOKEN") ?: "" + } + } maven { // Dynamically select either Maven Central or na Internal repository depending on the value of uploadcare.publish.type / UPLOADCARE_PUBLISH_TYPE name = "selected" From efeb18322e3a21b737f75825df7aaa459d80cdfc Mon Sep 17 00:00:00 2001 From: Martin Todorov Date: Mon, 30 Mar 2026 00:19:20 +0300 Subject: [PATCH 2/3] Update build.gradle.kts Co-authored-by: Steve Todorov --- build.gradle.kts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0193b90..2b2583a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,8 +37,10 @@ signing { } // Skip signing entirely for non-release (snapshot) builds. -tasks.withType().configureEach { - onlyIf { isReleaseVersion } +tasks { + withType().configureEach { + onlyIf { isReleaseVersion } + } } publishing { From f2f57474e717f03d74113062ecbe1552d79ab265 Mon Sep 17 00:00:00 2001 From: Martin Todorov Date: Sun, 29 Mar 2026 19:47:10 +0300 Subject: [PATCH 3/3] Set up publishing of SNAPSHOT builds to GitHub Packages * Added workflow for publishing `SNAPSHOT` builds. * Added workflow for removing `SNAPSHOT` builds once a pull request has been merged. --- .github/workflows/build.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 223de90..33ba420 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,8 @@ name: Build and test on: # Build PRs and branches. - pull_request: + pull_request_target: + types: [ opened, synchronize, reopened ] paths-ignore: - .github/workflows/deploy-tagged.yml push: @@ -24,7 +25,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 - + with: + ref: ${{ github.event.pull_request.head.sha }} - name: Setup JDK uses: actions/setup-java@v5 with: @@ -51,7 +53,7 @@ jobs: name: Publish snapshot to GitHub Packages runs-on: ubuntu-latest needs: build - if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master') + if: github.event_name == 'pull_request_target' || (github.event_name == 'push' && github.ref == 'refs/heads/master') permissions: contents: read packages: write @@ -59,7 +61,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 - + with: + ref: ${{ github.event.pull_request.head.sha }} - name: Get base version id: get-version run: | @@ -71,7 +74,7 @@ jobs: - name: Determine snapshot version id: snapshot-version run: | - if [ "${{ github.event_name }}" == "pull_request" ]; then + if [ "${{ github.event_name }}" == "pull_request_target" ]; then SNAPSHOT_VERSION="${{ steps.get-version.outputs.base_version }}-PR-${{ github.event.pull_request.number }}-SNAPSHOT" else SNAPSHOT_VERSION="${{ steps.get-version.outputs.base_version }}-SNAPSHOT"