diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index b6952d7f41f..f06a8022069 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -12,21 +12,29 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Publish Nessie release artifacts - +# Publishes all Nessie release artifacts and creates a Nessie release in GitHub. +# # Triggered when a `nessie-*` tag is being pushed. - -# Publishes the Maven and Docker artifacts. - -# GitHub environment name: -# release -# Required secrets: -# OSSRH_ACCESS_ID -# OSSRH_TOKEN -# MAVEN_GPG_PASSPHRASE -# PYPI_API_TOKEN -# DOCKER_USERNAME -# DOCKER_TOKEN +# +# GitHub environment name: release +# +# This workflow uses separate GH workflow jobs intentionally to be able to re-run +# failed "release targets" (Maven Central, Swaggerhub, GHCR, Helm) and not let +# the whole release fail (and force a completely new release). +# +# Jobs: +# Prepare -->--+ +# | +# +-->-- Publish to Maven Central -->--+ +# | | +# +-->-- Publish OpenAPI ----------->--+ +# | | +# +-->-- Publish Docker images ----->--+ +# | | +# +-->-- Publish Helm Chart -------->--+ +# | +# +-->-- GitHub Release notes +# name: Publish release @@ -42,240 +50,315 @@ on: required: true jobs: - publish-release: - name: Publish release + prepare: + name: Prepare + outputs: + release-version: ${{ steps.get_version.outputs.release-version }} + git-tag: ${{ steps.get_version.outputs.git-tag }} runs-on: ubuntu-22.04 + environment: release + timeout-minutes: 10 + steps: + # GH doesn't provide just the tag name, so this step strips `/refs/tags/nessie-` from `GITHUB_REF` + # and provides the outputs for the Git tag and the release-version derived from it, in case of a manual run, + # uses the input `releaseTag` as the input tag name. + - name: Get release version + id: get_version + run: | + if [[ "${{ github.event_name }}" == "push" ]] ; then + V="${GITHUB_REF/refs\/tags\/}" + else + V="${{ github.event.inputs.releaseTag }}" + fi + # check if tag matches patterns like nessie-0.5, nessie-0.10.4.3-alpha1, etc + if [[ ${V} =~ ^nessie-[0-9]+[.][0-9.]*[0-9](-[a-zA-Z0-9]+)?$ ]]; then + echo "release-version=${V/nessie-}" >> ${GITHUB_OUTPUT} + echo "git-tag=${V}" >> ${GITHUB_OUTPUT} + else + echo "Tag must start with nessie- followed by a valid version (got tag ${V}, ref is ${GITHUB_REF} )" + exit 1 + fi + + publish-maven-central: + name: Publish to Maven Central + runs-on: ubuntu-22.04 + environment: release timeout-minutes: 60 - if: github.repository == 'projectnessie/nessie' - # Runs in the `release` environment, which has the necessary secrets and defines the reviewers. - # See https://docs.github.com/en/actions/reference/environments + needs: + - prepare + env: + RELEASE_VERSION: ${{needs.prepare.outputs.release-version}} + ARTIFACTS: ../build-artifacts + steps: + ### BEGIN runner setup + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'push' }} + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'workflow_dispatch' }} + with: + ref: refs/tags/${{ github.event.inputs.releaseTag }} + - name: Setup runner + uses: ./.github/actions/setup-runner + - name: Setup Java, Gradle + uses: ./.github/actions/dev-tool-java + with: + gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} + ### END runner setup + + - name: Prepare artifacts directory + run: rm -rf "${ARTIFACTS}" ; mkdir -p "${ARTIFACTS}" + + - name: Gradle build + run: | + # 2 Retries - due to Gradle's old and unfixed CME bug + ./gradlew --no-scan compileAll jar || ./gradlew --no-scan compileAll jar || ./gradlew --no-scan compileAll jar + + - name: Check Licenses + run: ./gradlew --no-scan aggregatedLicenseReportsZip + + # Deploys Maven artifacts. Build and test steps were already ran in previous steps. + # Not running tests, because the environment contains secrets. + - name: Publish Maven artifacts for release + env: + # To release with Gradle + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} + ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.OSSRH_ACCESS_ID }} + ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.OSSRH_TOKEN }} + # To release commits that used Maven to build + MAVEN_USERNAME: ${{ secrets.OSSRH_ACCESS_ID }} + MAVEN_OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + run: | + # 2 Retries - to mitigate "HTTP/502 Bad Gateway" issues + ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -Prelease -Puber-jar --no-scan || \ + ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -Prelease -Puber-jar --no-scan || \ + ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -Prelease -Puber-jar --no-scan + + - name: Generate changelog + run: ./gradlew --no-scan --quiet --console=plain getChangelog --no-header --no-links > "${ARTIFACTS}/nessie-changelog-${RELEASE_VERSION}.md" + + - name: Collect artifacts + run: | + mv servers/quarkus-server/build/nessie-quarkus-${RELEASE_VERSION}-runner.jar "${ARTIFACTS}" + mv cli/cli/build/libs/nessie-cli-${RELEASE_VERSION}.jar "${ARTIFACTS}" + mv tools/server-admin/build/nessie-server-admin-tool-${RELEASE_VERSION}-runner.jar "${ARTIFACTS}" + mv gc/gc-tool/build/executable/nessie-gc.jar "${ARTIFACTS}/nessie-gc-${RELEASE_VERSION}.jar" + cp tools/aggregated-license-report/build/distributions/nessie-aggregated-license-report-${RELEASE_VERSION}.zip "${ARTIFACTS}" + + - name: Archive release artifacts + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4 + with: + name: nessie-release-artifacts + path: ../build-artifacts + if-no-files-found: error + + + publish-images: + name: Publish images + runs-on: ubuntu-22.04 environment: release - + timeout-minutes: 60 + needs: + - prepare steps: - - # GH doesn't provide just the tag name, so this step strips `/refs/tags/nessie-` from `GITHUB_REF` - # and provides the output `VERSION` or, in case of a manual run, uses the input `releaseTag` as - # the input tag name. - - name: Get release version - run: | - if [[ "${{ github.event_name }}" == "push" ]] ; then - V="${GITHUB_REF/refs\/tags\/}" - else - V="${{ github.event.inputs.releaseTag }}" - fi - # check if tag matches patterns like nessie-0.5, nessie-0.10.4.3-alpha1, etc - if [[ ${V} =~ ^nessie-[0-9]+[.][0-9.]*[0-9](-[a-zA-Z0-9]+)?$ ]]; then - echo "RELEASE_VERSION=${V/nessie-}" >> ${GITHUB_ENV} - echo "GIT_TAG=${V}" >> ${GITHUB_ENV} - else - echo "Tag must start with nessie- followed by a valid version (got tag ${V}, ref is ${GITHUB_REF} )" - exit 1 - fi - - ### BEGIN runner setup - - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - if: ${{ github.event_name == 'push' }} - with: - fetch-depth: '0' - - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - if: ${{ github.event_name == 'workflow_dispatch' }} - with: - fetch-depth: '0' - ref: refs/tags/${{ github.event.inputs.releaseTag }} - - name: Setup runner - uses: ./.github/actions/setup-runner - - name: Setup Java, Gradle - uses: ./.github/actions/dev-tool-java - with: - gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} - - name: Install Helm - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4 - with: - version: v3.6.3 - ### END runner setup - - # Deploys Maven artifacts. Build and test steps were already ran in previous steps. - # Not running tests, because the environment contains secrets. - - name: Publish Maven artifacts for release - env: - # To release with Gradle - ORG_GRADLE_PROJECT_signingKey: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} - ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.MAVEN_GPG_PASSPHRASE }} - ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.OSSRH_ACCESS_ID }} - ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.OSSRH_TOKEN }} - # To release commits that used Maven to build - MAVEN_USERNAME: ${{ secrets.OSSRH_ACCESS_ID }} - MAVEN_OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} - ARTIFACTS: ../build-artifacts - run: | - rm -rf "${ARTIFACTS}" - mkdir -p "${ARTIFACTS}" - - echo "::group::Gradle build" - # 2 Retries - due to Gradle's old and unfixed CME bug - ./gradlew compileAll jar testClasses || \ - ./gradlew compileAll jar testClasses || \ - ./gradlew compileAll jar testClasses - echo "::endgroup::" - - echo "::group::Check Licenses" - ./gradlew aggregatedLicenseReportsZip - echo "::endgroup::" - - echo "::group::Publish to Sonatype" - # 2 Retries - to mitigate "HTTP/502 Bad Gateway" issues - ./gradlew publishToMavenLocal publishToSonatype closeAndReleaseSonatypeStagingRepository -Prelease -Puber-jar || \ - ./gradlew publishToMavenLocal publishToSonatype closeAndReleaseSonatypeStagingRepository -Prelease -Puber-jar || \ - ./gradlew publishToMavenLocal publishToSonatype closeAndReleaseSonatypeStagingRepository -Prelease -Puber-jar - mv servers/quarkus-server/build/nessie-quarkus-${RELEASE_VERSION}-runner.jar "${ARTIFACTS}" - mv cli/cli/build/libs/nessie-cli-${RELEASE_VERSION}.jar "${ARTIFACTS}" - mv tools/server-admin/build/nessie-server-admin-tool-${RELEASE_VERSION}-runner.jar "${ARTIFACTS}" - mv gc/gc-tool/build/executable/nessie-gc.jar "${ARTIFACTS}"/nessie-gc-${RELEASE_VERSION}.jar - echo "::endgroup::" - - echo '${{ secrets.GITHUB_TOKEN }}' | docker login ghcr.io -u $ --password-stdin - tools/dockerbuild/build-push-images.sh \ - -g ":nessie-quarkus" \ - -p "servers/quarkus-server" \ - -d "Dockerfile-server" \ - ghcr.io/projectnessie/nessie - - tools/dockerbuild/build-push-images.sh \ - -g ":nessie-gc-tool" \ - -p "gc/gc-tool" \ - -d "Dockerfile-gctool" \ - ghcr.io/projectnessie/nessie-gc - - tools/dockerbuild/build-push-images.sh \ - -g ":nessie-server-admin-tool" \ - -p "tools/server-admin" \ - -d "Dockerfile-admintool" \ - ghcr.io/projectnessie/nessie-server-admin - - # Add version to the openapi file name - cp api/model/build/generated/openapi/META-INF/openapi/openapi.yaml api/model/build/nessie-openapi-${RELEASE_VERSION}.yaml - - echo "QUARKUS_UBER_JAR=${ARTIFACTS}/nessie-quarkus-${RELEASE_VERSION}-runner.jar" >> ${GITHUB_ENV} - echo "CLI_UBER_JAR=${ARTIFACTS}/nessie-cli-${RELEASE_VERSION}.jar" >> ${GITHUB_ENV} - echo "GC_UBER_JAR=${ARTIFACTS}/nessie-gc-${RELEASE_VERSION}.jar" >> ${GITHUB_ENV} - echo "SERVER_ADMIN_UBER_JAR=${ARTIFACTS}/nessie-server-admin-tool-${RELEASE_VERSION}-runner.jar" >> ${GITHUB_ENV} - echo "NESSIE_OPENAPI=api/model/build/nessie-openapi-${RELEASE_VERSION}.yaml" >> ${GITHUB_ENV} - echo "LICENSE_REPORTS=tools/aggregated-license-report/build/distributions/nessie-aggregated-license-report-${RELEASE_VERSION}.zip" >> ${GITHUB_ENV} - - echo "## Successfully released ${RELEASE_VERSION} to Sonatype" >> $GITHUB_STEP_SUMMARY - - # Packages Nessie Helm chart - - name: Package Nessie Helm chart for release - run: | - helm package helm/nessie --version ${RELEASE_VERSION} - - # Rename Nessie Helm chart - - name: Rename Nessie Helm chart for release - run: | - mv nessie-${RELEASE_VERSION}.tgz nessie-helm-${RELEASE_VERSION}.tgz - echo "NESSIE_HELM_CHART=nessie-helm-${RELEASE_VERSION}.tgz" >> ${GITHUB_ENV} - - # Publish Nessie Helm chart to Helm Repo - - name: Publish Nessie Helm chart to Helm Repo - run: | - wget https://raw.githubusercontent.com/projectnessie/charts.projectnessie.org/main/index.yaml - helm repo index . --merge index.yaml --url https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION} - echo ${{ secrets.CI_REPORTS_TOKEN }} | gh auth login --with-token - index_sha=$(gh api -X GET /repos/projectnessie/charts.projectnessie.org/contents/index.yaml --jq '.sha') - gh api -X PUT /repos/projectnessie/charts.projectnessie.org/contents/index.yaml -f message="Publishing Nessie Helm chart ${RELEASE_VERSION}" -f content=$(base64 -w0 index.yaml) -f sha=${index_sha} || true - - echo "## Successfully published Helm chart for ${RELEASE_VERSION}" >> $GITHUB_STEP_SUMMARY - - # Prepare Nessie release notes for GitHub - # - # The markdown file for the release is generated using some mostly simple shell script. - # - # `LAST_TAG` is evaluated using `git describe`, which is the name of the git tag before the release tag - # `NUM_COMMITS` is the total number of commits "between" LAST_TAG and GIT_TAG - # - # "Full Changelog" is the output of a `git log` considering the commits "between" LAST_TAG and - # GIT_TAG, removing the commits by `renovate` and `nessie-release-workflow`. - # Also removes commits that start with `[release] `. - # - # The final markdown is just a `cat` of the above information including some basic markdown formatting. - # - - name: Prepare Nessie release for GitHub - run: | - DIR=$(mktemp -d) - NOTES_FILE=${DIR}/release-notes.md - LAST_TAG=$(git describe --abbrev=0 --tags --match=nessie-* ${GIT_TAG}^1) - NUM_COMMITS=$(git log --format='format:%h' ${LAST_TAG}..HEAD^1 | wc -l) - - git log --perl-regexp --author '^(?!.*renovate|.*nessie-release-workflow).*$' --format='format:* %s' ${LAST_TAG}..${GIT_TAG} | grep -v '^\* \[release\] .*$' > ${DIR}/release-log - - Q_GC_TOOL_URL="https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION}/nessie-gc-${RELEASE_VERSION}.jar" - Q_UBER_URL="https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION}/nessie-quarkus-${RELEASE_VERSION}-runner.jar" - Q_SERVER_ADMIN_URL="https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION}/nessie-server-admin-tool-${RELEASE_VERSION}-runner.jar" - Q_HELM_CHART_URL="https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION}/nessie-helm-${RELEASE_VERSION}.tgz" - Q_MC_URL="https://search.maven.org/search?q=g:org.projectnessie+AND+a:nessie-quarkus+AND+v:${RELEASE_VERSION}" - - cat < ${NOTES_FILE} - # Nessie ${RELEASE_VERSION} release - - * ${NUM_COMMITS} commits since ${LAST_TAG#nessie-} - * Maven Central: https://search.maven.org/search?q=g:org.projectnessie.nessie+v:${RELEASE_VERSION} - * Docker images: https://github.com/projectnessie/nessie/pkgs/container/nessie and https://quay.io/repository/projectnessie/nessie?tab=tags - It is a multiplatform Java image (amd64, arm64, ppc64le, s390x): \`docker pull ghcr.io/projectnessie/nessie:${RELEASE_VERSION}-java\` - * PyPI: https://pypi.org/project/pynessie/ (See [pynessie](https://github.com/projectnessie/pynessie/releases)) - * Helm Chart repo: https://charts.projectnessie.org/ - - ## Try it - - The attached [\`nessie-quarkus-${RELEASE_VERSION}-runner.jar\`](${Q_UBER_URL}) is a standalone uber-jar file that runs on Java 17 or newer and it is also available via [Maven Central](${Q_MC_URL}). Download and run it (requires Java 17): - \`\`\` - wget ${Q_UBER_URL} - java -jar nessie-quarkus-${RELEASE_VERSION}-runner.jar - \`\`\` - - Nessie GC tool is attached as [\`nessie-gc-${RELEASE_VERSION}.jar\`](${Q_GC_TOOL_URL}), which is a standalone uber-jar file that runs on Java 11 or newer. Shell completion can be generated from the tool, check its \`help\` command. Nessie GC tool is also available as a Docker image: \`docker run --rm ghcr.io/projectnessie/nessie-gc:${RELEASE_VERSION} --help\`. - - Nessie Server Admin tool is attached as [\`nessie-server-admin-tool-${RELEASE_VERSION}-runner.jar\`](${Q_SERVER_ADMIN_URL}), which is a standalone uber-jar file that runs on Java 17 or newer. Shell completion can be generated from the tool, check its \`help\` command. Nessie Server Admin tool is also available as a Docker image: \`docker run --rm ghcr.io/projectnessie/nessie-server-admin:${RELEASE_VERSION} --help\`. - - The attached [\`nessie-helm-${RELEASE_VERSION}.tgz\`](${Q_HELM_CHART_URL}) is a packaged Helm chart, which can be downloaded and installed via Helm. There is also the [Nessie Helm chart repo](https://charts.projectnessie.org/), which can be added and used to install the Nessie Helm chart. - - ## Changelog - - $(./gradlew --quiet --console=plain getChangelog --no-header --no-links) - - ## Full Changelog (minus renovate commits): - - $(cat ${DIR}/release-log) - EOF - - echo "NOTES_FILE=${NOTES_FILE}" >> ${GITHUB_ENV} - - cat "${NOTES_FILE}" >> $GITHUB_STEP_SUMMARY - - - name: Create Nessie release in GitHub - run: | - echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token - gh release create ${GIT_TAG} \ - --notes-file ${{ env.NOTES_FILE }} \ - --title "Nessie ${RELEASE_VERSION}" \ - "${QUARKUS_UBER_JAR}" \ - "${CLI_UBER_JAR}" \ - "${GC_UBER_JAR}" \ - "${SERVER_ADMIN_UBER_JAR}" \ - "${NESSIE_OPENAPI}" \ - "${NESSIE_HELM_CHART}" \ - "${LICENSE_REPORTS}" - - - name: Update SwaggerHub - uses: smartbear/swaggerhub-cli@20e5eaf4866bbbc44d72e9eb8a48a942c0d9e43b # v0.9.0 - env: - XDG_CONFIG_HOME: "/tmp" - SWAGGERHUB_API_KEY: ${{ secrets.SWAGGERHUB_API_KEY }} - SWAGGERHUB_URL: "https://api.swaggerhub.com" - with: - args: api:create projectnessie/nessie -f ${{ env.NESSIE_OPENAPI }} --published=publish --setdefault --visibility=public - - - name: SwaggerHub info - run: echo "## Successfully updated SwaggerHub for ${RELEASE_VERSION}" >> $GITHUB_STEP_SUMMARY + ### BEGIN runner setup + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'push' }} + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'workflow_dispatch' }} + with: + ref: refs/tags/${{ github.event.inputs.releaseTag }} + - name: Setup runner + uses: ./.github/actions/setup-runner + - name: Setup Java, Gradle + uses: ./.github/actions/dev-tool-java + ### END runner setup + + - name: Gradle build + run: | + # 2 Retries - due to Gradle's old and unfixed CME bug + ./gradlew --no-scan compileAll jar || ./gradlew --no-scan compileAll jar || ./gradlew --no-scan compileAll jar + + - name: Docker login + run: | + echo '${{ secrets.GITHUB_TOKEN }}' | docker login ghcr.io -u $ --password-stdin + + - name: Publish Nessie Server + run: | + tools/dockerbuild/build-push-images.sh \ + -g ":nessie-quarkus" \ + -p "servers/quarkus-server" \ + -d "Dockerfile-server" \ + ghcr.io/projectnessie/nessie + + - name: Publish Nessie GC + run: | + tools/dockerbuild/build-push-images.sh \ + -g ":nessie-gc-tool" \ + -p "gc/gc-tool" \ + -d "Dockerfile-gctool" \ + ghcr.io/projectnessie/nessie-gc + + - name: Publish Nessie Server Admin Tool + run: | + tools/dockerbuild/build-push-images.sh \ + -g ":nessie-server-admin-tool" \ + -p "tools/server-admin" \ + -d "Dockerfile-admintool" \ + ghcr.io/projectnessie/nessie-server-admin + + + publish-helm: + name: Publish Helm Chart + runs-on: ubuntu-22.04 + environment: release + timeout-minutes: 60 + needs: + - prepare + env: + RELEASE_VERSION: ${{needs.prepare.outputs.release-version}} + steps: + ### BEGIN runner setup + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'push' }} + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'workflow_dispatch' }} + with: + ref: refs/tags/${{ github.event.inputs.releaseTag }} + - name: Install Helm + uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4 + with: + version: v3.6.3 + ### END runner setup + + - name: Package Nessie Helm chart + run: | + helm package helm/nessie --version ${RELEASE_VERSION} + mv nessie-${RELEASE_VERSION}.tgz nessie-helm-${RELEASE_VERSION}.tgz + + - name: Publish Nessie Helm chart to Helm Repo + run: | + wget https://raw.githubusercontent.com/projectnessie/charts.projectnessie.org/main/index.yaml + helm repo index . --merge index.yaml --url https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION} + echo ${{ secrets.CI_REPORTS_TOKEN }} | gh auth login --with-token + index_sha=$(gh api -X GET /repos/projectnessie/charts.projectnessie.org/contents/index.yaml --jq '.sha') + gh api -X PUT /repos/projectnessie/charts.projectnessie.org/contents/index.yaml -f message="Publishing Nessie Helm chart ${RELEASE_VERSION}" -f content=$(base64 -w0 index.yaml) -f sha=${index_sha} || true + + - name: Archive Helm chart artifact + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4 + with: + name: nessie-release-helm + path: ./nessie-helm-*.tgz + if-no-files-found: error + + + publish-openapi: + runs-on: ubuntu-22.04 + timeout-minutes: 60 + environment: release + needs: + - prepare + env: + RELEASE_VERSION: ${{needs.prepare.outputs.release-version}} + steps: + ### BEGIN runner setup + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'push' }} + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'workflow_dispatch' }} + with: + ref: refs/tags/${{ github.event.inputs.releaseTag }} + - name: Setup runner + uses: ./.github/actions/setup-runner + - name: Setup Java, Gradle + uses: ./.github/actions/dev-tool-java + ### END runner setup + + - name: Gradle build + run: | + # 2 Retries - due to Gradle's old and unfixed CME bug + ./gradlew --no-scan :nessie-model:jar || ./gradlew --no-scan :nessie-model:jar || ./gradlew --no-scan :nessie-model:jar + + - name: Copy OpenAPI yaml + run: cp api/model/build/generated/openapi/META-INF/openapi/openapi.yaml ./nessie-openapi-${RELEASE_VERSION}.yaml + + - name: Archive OpenAPI artifact + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4 + with: + name: nessie-release-openapi + path: ./nessie-openapi-*.yaml + if-no-files-found: error + + - name: Update SwaggerHub + uses: smartbear/swaggerhub-cli@20e5eaf4866bbbc44d72e9eb8a48a942c0d9e43b # v0.9.0 + env: + XDG_CONFIG_HOME: "/tmp" + SWAGGERHUB_API_KEY: ${{ secrets.SWAGGERHUB_API_KEY }} + SWAGGERHUB_URL: "https://api.swaggerhub.com" + with: + args: api:create projectnessie/nessie -f ./nessie-openapi-${RELEASE_VERSION}.yaml --published=publish --setdefault --visibility=public + + + create-github-release: + runs-on: ubuntu-22.04 + timeout-minutes: 60 + environment: release + needs: + - publish-maven-central + - publish-images + - publish-helm + - publish-openapi + env: + RELEASE_VERSION: ${{needs.prepare.outputs.release-version}} + GIT_TAG: ${{needs.prepare.outputs.git-tag}} + NOTES_FILE: current-release-notes.md + steps: + ### BEGIN runner setup + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'push' }} + with: + fetch-depth: 0 + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + if: ${{ github.event_name == 'workflow_dispatch' }} + with: + fetch-depth: 0 + ref: refs/tags/${{ github.event.inputs.releaseTag }} + ### END runner setup + + - name: Create dir + run: mkdir artifacts + + - name: Get release + OpenAPI + Helm chart artifacts + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4 + with: + path: current-release-artifacts + + - name: Create release notes file for GitHub release + run: | + LAST_TAG=$(cd nessie ; git describe --abbrev=0 --tags --match=nessie-* ${GIT_TAG}^1) + + tools/releases/create-gh-release-notes.sh \ + -n ${NOTES_FILE} \ + -l ${LAST_TAG} \ + -t ${GIT_TAG} \ + -r ${RELEASE_VERSION} + -c current-release-artifacts/nessie-changelog-${RELEASE_VERSION}.md + + cat "${NOTES_FILE}" >> $GITHUB_STEP_SUMMARY + + - name: GitHub login + run: echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token + + - name: Create Nessie release in GitHub + run: gh release create ${GIT_TAG} --notes-file ${{ env.NOTES_FILE }} --title "Nessie ${RELEASE_VERSION}" current-release-artifacts/* diff --git a/tools/releases/create-gh-release-notes.sh b/tools/releases/create-gh-release-notes.sh new file mode 100755 index 00000000000..be9de55bd91 --- /dev/null +++ b/tools/releases/create-gh-release-notes.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2024 Dremio +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Helper script to create the release notes for GitHub + +set -e + +NOTES_FILE="" +LAST_TAG="" +GIT_TAG="" +RELEASE_VERSION="" +CHANGELOG_FILE="" + +function usage() { + cat << ! > /dev/stderr + Usage: $0 -n NOTES_FILE -l LAST_TAG -t GIT_TAG -r RELEASE_VERSION -c CHANGELOG_FILE + + NOTES_FILE output file + LAST_TAG previously released Nessie Git tag + GIT_TAG current release Git tag + RELEASE_VERSION Nessie version being released + CHANGELOG_FILE Changelog file, generated by Gradle, example: + ./gradlew --no-scan --quiet --console=plain getChangelog --no-header --no-links \ + > ./nessie-changelog-${RELEASE_VERSION}.md +! +} + +while [[ $# -gt 0 ]]; do + arg="$1" + case "$arg" in + -n) + NOTES_FILE="$2" + shift + ;; + -l) + LAST_TAG="$2" + shift + ;; + -t) + GIT_TAG="$2" + shift + ;; + -r) + RELEASE_VERSION="$2" + shift + ;; + -c) + CHANGELOG_FILE="$2" + shift + ;; + -h | --help) + usage + exit 0 + ;; + *) + usage + exit 1 + ;; + esac + shift +done + +if [[ -z ${NOTES_FILE} || -z ${LAST_TAG} || -z ${GIT_TAG} || -z ${RELEASE_VERSION} || -z ${CHANGELOG_FILE} ]] ; then + usage + exit 1 +fi + +NUM_COMMITS=$(git log --format='format:%h' ${LAST_TAG}..HEAD^1 | wc -l) + +git log --perl-regexp --author '^(?!.*renovate|.*nessie-release-workflow).*$' --format='format:* %s' ${LAST_TAG}..${GIT_TAG} | grep -v '^\* \[release\] .*$' > ./release-log + +Q_GC_TOOL_URL="https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION}/nessie-gc-${RELEASE_VERSION}.jar" +Q_UBER_URL="https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION}/nessie-quarkus-${RELEASE_VERSION}-runner.jar" +Q_SERVER_ADMIN_URL="https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION}/nessie-server-admin-tool-${RELEASE_VERSION}-runner.jar" +Q_HELM_CHART_URL="https://github.com/projectnessie/nessie/releases/download/nessie-${RELEASE_VERSION}/nessie-helm-${RELEASE_VERSION}.tgz" +Q_MC_URL="https://search.maven.org/search?q=g:org.projectnessie+AND+a:nessie-quarkus+AND+v:${RELEASE_VERSION}" + +cat < ${NOTES_FILE} +# Nessie ${RELEASE_VERSION} release + +* ${NUM_COMMITS} commits since ${LAST_TAG#nessie-} +* Maven Central: https://search.maven.org/search?q=g:org.projectnessie.nessie+v:${RELEASE_VERSION} +* Docker images: https://github.com/projectnessie/nessie/pkgs/container/nessie and https://quay.io/repository/projectnessie/nessie?tab=tags + It is a multiplatform Java image (amd64, arm64, ppc64le, s390x): \`docker pull ghcr.io/projectnessie/nessie:${RELEASE_VERSION}-java\` +* PyPI: https://pypi.org/project/pynessie/ (See [pynessie](https://github.com/projectnessie/pynessie/releases)) +* Helm Chart repo: https://charts.projectnessie.org/ + +## Try it + +The attached [\`nessie-quarkus-${RELEASE_VERSION}-runner.jar\`](${Q_UBER_URL}) is a standalone uber-jar file that runs on Java 17 or newer and it is also available via [Maven Central](${Q_MC_URL}). Download and run it (requires Java 17): +\`\`\` +wget ${Q_UBER_URL} +java -jar nessie-quarkus-${RELEASE_VERSION}-runner.jar +\`\`\` + +Nessie GC tool is attached as [\`nessie-gc-${RELEASE_VERSION}.jar\`](${Q_GC_TOOL_URL}), which is a standalone uber-jar file that runs on Java 11 or newer. Shell completion can be generated from the tool, check its \`help\` command. Nessie GC tool is also available as a Docker image: \`docker run --rm ghcr.io/projectnessie/nessie-gc:${RELEASE_VERSION} --help\`. + +Nessie Server Admin tool is attached as [\`nessie-server-admin-tool-${RELEASE_VERSION}-runner.jar\`](${Q_SERVER_ADMIN_URL}), which is a standalone uber-jar file that runs on Java 17 or newer. Shell completion can be generated from the tool, check its \`help\` command. Nessie Server Admin tool is also available as a Docker image: \`docker run --rm ghcr.io/projectnessie/nessie-server-admin:${RELEASE_VERSION} --help\`. + +The attached [\`nessie-helm-${RELEASE_VERSION}.tgz\`](${Q_HELM_CHART_URL}) is a packaged Helm chart, which can be downloaded and installed via Helm. There is also the [Nessie Helm chart repo](https://charts.projectnessie.org/), which can be added and used to install the Nessie Helm chart. + +## Changelog + +$(cat ${CHANGELOG_FILE}) + +## Full Changelog (minus renovate commits): + +$(cat ./release-log) +EOF + +rm ./release-log