From e8373571374ef11a0563415d5e7d6ec0eb083815 Mon Sep 17 00:00:00 2001 From: Guian Gumpac Date: Mon, 12 Aug 2024 12:08:41 -0700 Subject: [PATCH] Add Maven automation workflow Signed-off-by: Guian Gumpac --- .github/json_matrices/build-matrix.json | 8 +- .github/workflows/java-cd.yml | 231 +++++++++++++++++------- CHANGELOG.md | 3 + java/benchmarks/build.gradle | 8 +- java/build.gradle | 11 ++ 5 files changed, 190 insertions(+), 71 deletions(-) diff --git a/.github/json_matrices/build-matrix.json b/.github/json_matrices/build-matrix.json index e8589b84f8..45ac7a57f3 100644 --- a/.github/json_matrices/build-matrix.json +++ b/.github/json_matrices/build-matrix.json @@ -5,7 +5,7 @@ "RUNNER": "ubuntu-latest", "ARCH": "x64", "TARGET": "x86_64-unknown-linux-gnu", - "PACKAGE_MANAGERS": ["pypi", "npm"] + "PACKAGE_MANAGERS": ["pypi", "npm", "maven"] }, { "OS": "ubuntu", @@ -13,7 +13,7 @@ "RUNNER": ["self-hosted", "Linux", "ARM64"], "ARCH": "arm64", "TARGET": "aarch64-unknown-linux-gnu", - "PACKAGE_MANAGERS": ["pypi", "npm"], + "PACKAGE_MANAGERS": ["pypi", "npm", "maven"], "CONTAINER": "2_28" }, { @@ -22,7 +22,7 @@ "RUNNER": "macos-12", "ARCH": "x64", "TARGET": "x86_64-apple-darwin", - "PACKAGE_MANAGERS": ["pypi", "npm"] + "PACKAGE_MANAGERS": ["pypi", "npm", "maven"] }, { "OS": "macos", @@ -30,7 +30,7 @@ "RUNNER": "macos-latest", "ARCH": "arm64", "TARGET": "aarch64-apple-darwin", - "PACKAGE_MANAGERS": ["pypi", "npm"] + "PACKAGE_MANAGERS": ["pypi", "npm", "maven"] }, { "OS": "ubuntu", diff --git a/.github/workflows/java-cd.yml b/.github/workflows/java-cd.yml index 0859892b45..2b62c2ff67 100644 --- a/.github/workflows/java-cd.yml +++ b/.github/workflows/java-cd.yml @@ -1,77 +1,78 @@ name: Java Prepare Deployment on: - pull_request: - paths: - - .github/workflows/java-cd.yml - - .github/workflows/install-shared-dependencies/action.yml - - .github/workflows/start-self-hosted-runner/action.yml - - .github/json_matrices/build-matrix.json push: tags: - "v*.*" workflow_dispatch: - inputs: - version: - description: 'The release version of GLIDE, formatted as *.*.* or *.*.*-rc*' - required: true + inputs: + version: + description: "The release version of GLIDE, formatted as *.*.* or *.*.*-rc*" + required: true + maven_publish: + description: "Publish to Maven Central" + required: true + type: boolean concurrency: group: java-cd-${{ github.head_ref || github.ref }} cancel-in-progress: true permissions: - id-token: write + id-token: write jobs: - start-self-hosted-runner: - if: github.repository_owner == 'valkey-io' + load-platform-matrix: runs-on: ubuntu-latest - environment: AWS_ACTIONS +# environment: AWS_ACTIONS + outputs: + PLATFORM_MATRIX: ${{ steps.load-platform-matrix.outputs.PLATFORM_MATRIX }} steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Start self hosted EC2 runner - uses: ./.github/workflows/start-self-hosted-runner - with: - role-to-assume: ${{ secrets.ROLE_TO_ASSUME }} - aws-region: ${{ secrets.AWS_REGION }} - ec2-instance-id: ${{ secrets.AWS_EC2_INSTANCE_ID }} + - name: Checkout + uses: actions/checkout@v4 + + - name: load-platform-matrix + id: load-platform-matrix + shell: bash + run: | + # Get the matrix from the matrix.json file, without the object that has the IMAGE key + export "PLATFORM_MATRIX=$(jq 'map(select(.PACKAGE_MANAGERS | contains(["maven"])))' < .github/json_matrices/build-matrix.json | jq -c .)" + echo "PLATFORM_MATRIX=${PLATFORM_MATRIX}" >> $GITHUB_OUTPUT + + set-release-version: + needs: load-platform-matrix + runs-on: ubuntu-latest + outputs: + RELEASE_VERSION: ${{ steps.release-version.outputs.RELEASE_VERSION }} + steps: + - name: Set the release version + id: release-version + shell: bash + run: | + if ${{ github.event_name == 'workflow_dispatch' }}; then + R_VERSION="${{ env.INPUT_VERSION }}" + else + R_VERSION=${GITHUB_REF:11} + fi + echo "RELEASE_VERSION=${R_VERSION}" >> $GITHUB_ENV + echo "Release version detected: $R_VERSION" + echo "RELEASE_VERSION=$R_VERSION" >> $GITHUB_OUTPUT + env: + EVENT_NAME: ${{ github.event_name }} + INPUT_VERSION: ${{ github.event.inputs.version }} create-binaries-to-publish: - needs: start-self-hosted-runner + needs: [set-release-version, load-platform-matrix] if: github.repository_owner == 'valkey-io' timeout-minutes: 35 env: - JAVA_VERSION: '11' + JAVA_VERSION: "11" + RELEASE_VERSION: ${{ needs.set-release-version.outputs.RELEASE_VERSION }} strategy: # Run all jobs fail-fast: false matrix: - host: - - { - OS: ubuntu, - RUNNER: ubuntu-latest, - TARGET: x86_64-unknown-linux-gnu, - } - - { - OS: ubuntu, - RUNNER: ["self-hosted", "Linux", "ARM64"], - TARGET: aarch64-unknown-linux-gnu, - } - - { - OS: macos, - RUNNER: macos-12, - TARGET: x86_64-apple-darwin, - } - - { - OS: macos, - RUNNER: macos-latest, - TARGET: aarch64-apple-darwin, - } + host: ${{fromJson(needs.load-platform-matrix.outputs.PLATFORM_MATRIX)}} runs-on: ${{ matrix.host.RUNNER }} @@ -86,27 +87,10 @@ jobs: else echo "No cleaning needed" fi - - uses: actions/checkout@v4 with: submodules: recursive - - name: Set the release version - shell: bash - run: | - if ${{ github.event_name == 'pull_request' }}; then - R_VERSION="255.255.255" - elif ${{ github.event_name == 'workflow_dispatch' }}; then - R_VERSION="${{ env.INPUT_VERSION }}" - else - R_VERSION=${GITHUB_REF:11} - fi - echo "RELEASE_VERSION=${R_VERSION}" >> $GITHUB_ENV - echo "Release version detected: $R_VERSION" - env: - EVENT_NAME: ${{ github.event_name }} - INPUT_VERSION: ${{ github.event.inputs.version }} - - name: Set up JDK uses: actions/setup-java@v4 with: @@ -137,7 +121,8 @@ jobs: - name: Build java client working-directory: java run: | - ./gradlew :client:publishToMavenLocal -Psigning.secretKeyRingFile=secring.gpg -Psigning.password="${{ secrets.GPG_PASSWORD }}" -Psigning.keyId=${{ secrets.GPG_KEY_ID }} + ./gradlew :client:publishToMavenLocal -Psigning.secretKeyRingFile=secring.gpg \ + -Psigning.password="${{ secrets.GPG_PASSWORD }}" -Psigning.keyId=${{ secrets.GPG_KEY_ID }} env: GLIDE_RELEASE_VERSION: ${{ env.RELEASE_VERSION }} @@ -158,3 +143,117 @@ jobs: name: java-${{ matrix.host.TARGET }} path: | java/bundle*.jar + + publish-to-maven-central-deployment: + if: ${{ inputs.maven_publish == true || github.event_name == 'push' }} + needs: [set-release-version, create-binaries-to-publish] + runs-on: ubuntu-latest + outputs: + DEPLOYMENT_ID: ${{ steps.maven-deployment.outputs.DEPLOYMENT_ID }} + env: + RELEASE_VERSION: ${{ needs.set-release-version.outputs.RELEASE_VERSION }} + steps: + - name: Download published artifacts + uses: actions/download-artifact@v4 + + - name: Move all required files to one directory + run: | + mkdir maven-files + cd maven-files + for file in $(find ../. -name "*.jar"); do jar xf "$file" ; done + + - name: Generate sha1 and md5 files for all Maven files + run: | + cd maven-files + for i in *.jar *.pom *.module; do md5sum $i | cut -d ' ' -f 1 > $i.md5; done + for i in *.jar *.pom *.module; do sha1sum $i | cut -d ' ' -f 1 > $i.sha1; done + + - name: Move files to the correct directory tree + run: | + mkdir -p build/io/valkey/valkey-glide/${{ env.RELEASE_VERSION }} + cp -a maven-files/* build/io/valkey/valkey-glide/${{ env.RELEASE_VERSION }} + rm -rf build/io/valkey/valkey-glide/${{ env.RELEASE_VERSION }}/META-INF + cd build + zip -r ../build io + + - name: Upload artifacts to publish + uses: actions/upload-artifact@v4 + with: + name: valkey-${{ env.RELEASE_VERSION }} + path: | + build + + - name: Publish to Maven Central + id: maven-deployment + run: | + export DEPLOYMENT_ID=`curl --request POST \ + -u "${{ secrets.CENTRAL_TOKEN_USERNAME }}:${{ secrets.CENTRAL_TOKEN_PASSWORD }}" \ + --form bundle=@build.zip \ + https://central.sonatype.com/api/v1/publisher/upload | tail -n 1` + echo "DEPLOYMENT_ID=$DEPLOYMENT_ID" >> $GITHUB_ENV + echo "DEPLOYMENT_ID=$DEPLOYMENT_ID" >> $GITHUB_OUTPUT + echo Uploaded to Maven deployment with deployment ID $DEPLOYMENT_ID. Will be released if smoke tests pass and approved for release. + + - name: Check status of deployment + run: | + for ((retries = 0; retries < 5; retries++)); do + sleep 5 + export DEPLOYMENT_STATUS=`curl --request POST \ + -u "${{ secrets.CENTRAL_TOKEN_USERNAME }}:${{ secrets.CENTRAL_TOKEN_PASSWORD }}" \ + "https://central.sonatype.com/api/v1/publisher/status?id=${{ env.DEPLOYMENT_ID }}" \ + | jq '.deploymentState'` + + if [[ $DEPLOYMENT_STATUS == ""\"VALIDATED"\"" ]]; then exit 0; fi + done + + curl --request POST \ + -u "${{ secrets.CENTRAL_TOKEN_USERNAME }}:${{ secrets.CENTRAL_TOKEN_PASSWORD }}" \ + "https://central.sonatype.com/api/v1/publisher/status?id=${{ env.DEPLOYMENT_ID }}" \ + | jq + exit 1 + + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: "11" + + - name: Install protoc (protobuf) + uses: arduino/setup-protoc@v3 + with: + version: "26.1" + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Test deployment + working-directory: java + run: | + export ORG_GRADLE_PROJECT_centralManualTestingAuthHeaderName="Authorization" + export ORG_GRADLE_PROJECT_centralManualTestingAuthHeaderValue="Bearer $(echo "${{ secrets.CENTRAL_TOKEN_USERNAME }}:${{ secrets.CENTRAL_TOKEN_PASSWORD }}" | base64)" + export RUN_DEPLOYMENT_TEST=true + export GLIDE_RELEASE_VERSION=${{ env.RELEASE_VERSION }} + ./gradlew run + + - name: Drop deployment if validation fails + if: ${{ failure() }} + run: | + curl --request DELETE \ + -u "${{ secrets.CENTRAL_TOKEN_USERNAME }}:${{ secrets.CENTRAL_TOKEN_PASSWORD }}" \ + "https://central.sonatype.com/api/v1/publisher/deployment/${{ env.DEPLOYMENT_ID }}" + + publish-release-to-maven: + if: ${{ inputs.maven_publish == true || github.event_name == 'push' }} + needs: [publish-to-maven-central-deployment] + runs-on: ubuntu-latest + environment: AWS_ACTIONS + env: + DEPLOYMENT_ID: ${{ needs.publish-to-maven-central-deployment.outputs.DEPLOYMENT_ID }} + steps: + - name: Publish to Maven + run: | + curl --request POST \ + -u "${{ secrets.CENTRAL_TOKEN_USERNAME }}:${{ secrets.CENTRAL_TOKEN_PASSWORD }}" \ + "https://central.sonatype.com/api/v1/publisher/deployment/${{ env.DEPLOYMENT_ID }}" diff --git a/CHANGELOG.md b/CHANGELOG.md index 655939fdd3..4fbbea0bd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -113,6 +113,9 @@ * Java: `XRange`/`XRevRange` should return `null` instead of `GlideException` when given a negative count ([#1920](https://github.com/valkey-io/valkey-glide/pull/1920)) * Python: Fix `XClaim` return type to `List[bytes]` instead of `List[TEncodable]` ([#2075](https://github.com/valkey-io/valkey-glide/pull/2075)) +### Operational Enhancements +* CI/CD: Add workflow for automating Maven release ([#2128](https://github.com/valkey-io/valkey-glide/pull/2128)) + ## 1.0.0 (2024-07-09) #### Changes diff --git a/java/benchmarks/build.gradle b/java/benchmarks/build.gradle index e5cba49fb3..e5c410c0f3 100644 --- a/java/benchmarks/build.gradle +++ b/java/benchmarks/build.gradle @@ -9,7 +9,13 @@ repositories { } dependencies { - implementation project(':client') + def releaseVersion = System.getenv("GLIDE_RELEASE_VERSION"); + + if (releaseVersion) { + implementation "io.valkey:valkey-glide:" + releaseVersion + } else { + implementation project(':client') + } // This dependency is used internally, and not exposed to consumers on their own compile classpath. implementation 'com.google.guava:guava:32.1.1-jre' diff --git a/java/build.gradle b/java/build.gradle index d36a4bf750..72c549812c 100644 --- a/java/build.gradle +++ b/java/build.gradle @@ -12,6 +12,17 @@ repositories { subprojects { repositories { + // Runs for GITHUB_ACTIONS for testing release Maven deployment. + if(System.getenv("RUN_DEPLOYMENT_TEST")) { + maven { + name = "centralManualTesting" + url "https://central.sonatype.com/api/v1/publisher/deployments/download/" + credentials(HttpHeaderCredentials) + authentication { + header(HttpHeaderAuthentication) + } + } + } mavenCentral() } // minimal java compatibility level