diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml index 25440811..0aad76bc 100644 --- a/.github/workflows/build-wheels.yml +++ b/.github/workflows/build-wheels.yml @@ -5,7 +5,26 @@ on: types: [released] jobs: + enforce_stable_semver: + name: Require Stable Release Semver + runs-on: ubuntu-24.04 + outputs: + version: ${{ steps.parse.outputs.version }} + steps: + - name: Parse Release Version + id: parse + shell: bash + run: | + if [[ "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is a stable release semver ref" + echo "version=${GITHUB_REF_NAME#v}" | tee -a $GITHUB_OUTPUT + else + echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is not a stable release semver ref" >&2 + exit 1 + fi + build_wheels: + needs: enforce_stable_semver defaults: run: working-directory: sdk/python/sdk/zrok diff --git a/.github/workflows/homebrew.yml b/.github/workflows/homebrew.yml index 41b48764..a1d1d994 100644 --- a/.github/workflows/homebrew.yml +++ b/.github/workflows/homebrew.yml @@ -5,7 +5,26 @@ on: types: [released] jobs: + enforce_stable_semver: + name: Require Stable Release Semver + runs-on: ubuntu-24.04 + outputs: + version: ${{ steps.parse.outputs.version }} + steps: + - name: Parse Release Version + id: parse + shell: bash + run: | + if [[ "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is a stable release semver ref" + echo "version=${GITHUB_REF_NAME#v}" | tee -a $GITHUB_OUTPUT + else + echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is not a stable release semver ref" >&2 + exit 1 + fi + update-brew: + needs: enforce_stable_semver if: github.repository_owner == 'openziti' runs-on: ubuntu-latest steps: diff --git a/.github/workflows/node-sdk.yml b/.github/workflows/node-sdk.yml index 2705daea..8645c3bf 100644 --- a/.github/workflows/node-sdk.yml +++ b/.github/workflows/node-sdk.yml @@ -8,7 +8,28 @@ on: jobs: + enforce_stable_semver: + name: Require Stable Release Semver + if: github.event.action == 'released' + runs-on: ubuntu-24.04 + outputs: + version: ${{ steps.parse.outputs.version }} + steps: + - name: Parse Release Version + id: parse + shell: bash + run: | + if [[ "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is a stable release semver ref" + echo "version=${GITHUB_REF_NAME#v}" | tee -a $GITHUB_OUTPUT + else + echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is not a stable release semver ref" >&2 + exit 1 + fi + build: + needs: enforce_stable_semver + if: always() name: Build for Node-${{ matrix.node_ver }} ${{ matrix.config.target }}/${{ matrix.config.arch }} runs-on: ${{ matrix.config.os }} @@ -69,4 +90,3 @@ jobs: npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - diff --git a/.github/workflows/promote-downstreams.yml b/.github/workflows/promote-downstreams.yml index 8835f395..6e46c3df 100644 --- a/.github/workflows/promote-downstreams.yml +++ b/.github/workflows/promote-downstreams.yml @@ -13,7 +13,7 @@ concurrency: cancel-in-progress: true jobs: - parse_version: + enforce_stable_semver: name: Require Stable Release Semver runs-on: ubuntu-24.04 outputs: @@ -33,7 +33,7 @@ jobs: promote_docker: name: Tag Container Image ${{ matrix.image.repo }}:latest - needs: parse_version + needs: enforce_stable_semver runs-on: ubuntu-24.04 strategy: fail-fast: true @@ -52,11 +52,11 @@ jobs: run: > docker buildx imagetools create --tag ${{ matrix.image.repo }}:latest - ${{ matrix.image.repo }}:${{ needs.parse_version.outputs.version }} + ${{ matrix.image.repo }}:${{ needs.enforce_stable_semver.outputs.version }} promote_artifactory: name: Promote ${{ matrix.package_name }}-${{ matrix.arch.rpm }}.${{ matrix.packager }} - needs: parse_version + needs: enforce_stable_semver strategy: fail-fast: true matrix: @@ -93,7 +93,7 @@ jobs: --recursive=false --flat=true --fail-no-op=true - ${{ env.ZITI_RPM_TEST_REPO }}/redhat/${{ matrix.arch.rpm }}/${{ matrix.package_name }}-${{ needs.parse_version.outputs.version }}-1.${{ matrix.arch.rpm }}.rpm + ${{ env.ZITI_RPM_TEST_REPO }}/redhat/${{ matrix.arch.rpm }}/${{ matrix.package_name }}-${{ needs.enforce_stable_semver.outputs.version }}-1.${{ matrix.arch.rpm }}.rpm ${{ env.ZITI_RPM_PROD_REPO }}/redhat/${{ matrix.arch.rpm }}/ - name: Copy DEB from test repo to stable repo with jFrog CLI @@ -104,5 +104,5 @@ jobs: --recursive=false --flat=true --fail-no-op=true - ${{ env.ZITI_DEB_TEST_REPO }}/pool/${{ matrix.package_name }}/${{ matrix.arch.deb }}/${{ matrix.package_name }}_${{ needs.parse_version.outputs.version }}-1_${{ matrix.arch.deb }}.deb + ${{ env.ZITI_DEB_TEST_REPO }}/pool/${{ matrix.package_name }}/${{ matrix.arch.deb }}/${{ matrix.package_name }}_${{ needs.enforce_stable_semver.outputs.version }}-1_${{ matrix.arch.deb }}.deb ${{ env.ZITI_DEB_PROD_REPO }}/pool/${{ matrix.package_name }}/${{ matrix.arch.deb }}/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b7c7448..11ddbe79 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -92,10 +92,18 @@ jobs: run: | set -o xtrace shopt -s nullglob + SEMVER=${GITHUB_REF_NAME#v} + SEMVER_CORE=${SEMVER%%-*} + if [[ "$SEMVER_CORE" == ${SEMVER#*-} ]]; then + SEMVER_PRE="" # no semver pre-release suffix + else + SEMVER_PRE=${SEMVER#*-} + fi for PAX in zrok{,-share}; do - _pattern="./dist/${PAX}-${GITHUB_REF_NAME#v}-*.${ARCH}.rpm" + _pattern="./dist/${PAX}-${SEMVER_CORE}${SEMVER_PRE:+~${SEMVER_PRE}}*.${ARCH}.rpm" if ! compgen -G "$_pattern" > /dev/null; then echo "ERROR: No RPM files found matching pattern '${_pattern}'" >&2 + ls -1 ./dist/ exit 1 fi _rpms=( $_pattern ) @@ -120,10 +128,18 @@ jobs: run: | set -o xtrace shopt -s nullglob + SEMVER=${GITHUB_REF_NAME#v} + SEMVER_CORE=${SEMVER%%-*} + if [[ "$SEMVER_CORE" == ${SEMVER#*-} ]]; then + SEMVER_PRE="" # no semver pre-release suffix + else + SEMVER_PRE=${SEMVER#*-} + fi for PAX in zrok{,-share}; do - _pattern="./dist/${PAX}_${GITHUB_REF_NAME#v}-*_${ARCH}.deb" + _pattern="./dist/${PAX}_${SEMVER_CORE}${SEMVER_PRE:+~${SEMVER_PRE}}*_${ARCH}.deb" if ! compgen -G "$_pattern" > /dev/null; then echo "ERROR: No DEB files found matching pattern '${_pattern}'" >&2 + ls -1 ./dist/ exit 1 fi _debs=( $_pattern ) diff --git a/RELEASING.md b/RELEASING.md index 814f0d51..56770cf8 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,7 +1,17 @@ # Releasing zrok -## Manual Steps +## Semantic Versioning + +This project uses semantic versioning. See [here](https://semver.org/) for more information. + +Release tags like `v3.2.1` are eligible for promotion to stable status in GitHub and downstream distribution channels. + +Pre-release tags like `v3.2.1-rc1` (with a semver hyphenated pre-release suffix) are published in GitHub as pre-releases, and are blocked from promotion to downstream distribution channels if they are marked "stable" by mistake and the GitHub "released" event fires. + +Pre-release version strings must contain exactly one hyphen, and may not contain an underscore. + +## How to Trigger Release Automation > [!NOTE] > Each trigger is outlined separately, but some may occur simultaneously, e.g., when a draft release is published as stable rather than first publishing it as a pre-release, or a pre-release is promoted to stable and marked as latest at the same time. @@ -12,7 +22,7 @@ 1. A release is drafted in GitHub. 1. Edit the draft and publish the release as a pre-release (`isPrerelease: true`). 1. The one-time GitHub "published" event fires, and binaries are available in GitHub. -1. Edit the pre-release to mark it as a stable release (`isPrerelease: false`). +1. If the release does not have a pre-release suffix, mark it as stable by un-checking (`isPrerelease: false`). 1. The one-time GitHub "released" event fires. 1. Linux packages are promoted to "stable" in Artifactory. 1. Docker images are promoted to `:latest` in Docker Hub.