Skip to content

Cut a new release

Cut a new release #28

name: Cut a new release
on:
workflow_dispatch:
inputs:
version:
type: string
description: Version of the next release (e.g. v0.15.0)
required: true
env:
git-user: github-actions[bot]
git-email: 41898282+github-actions[bot]@users.noreply.github.com
main-branch: main
jobs:
workflow-metadata:
name: Extract workflow metadata
runs-on: ubuntu-22.04
outputs:
ref: ${{ steps.extract.outputs.ref }}
base-version: ${{ steps.extract.outputs.base-version }}
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GH_TOKEN }}
fetch-depth: 0
- name: Extract
id: extract
shell: bash
run: |
REF=$(echo "${{ env.main-branch }}")
# Valid version format
if [[ "${{ inputs.version }}" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
# Find release branch from provided version. This resolves '0.14' from 'v0.14.0|1|2...'
BASE_VERSION=$(echo "${{ inputs.version }}" | cut -c2- | awk 'BEGIN{FS=OFS="."}NF--')
echo "Finding branch: release-${BASE_VERSION}..."
branch_exists=$(git ls-remote --heads origin release-${BASE_VERSION})
if [[ -z ${branch_exists} ]]; then
echo "release-${BASE_VERSION} is not found."
else
echo "release-${BASE_VERSION} is found, now REF=release-${BASE_VERSION}"
REF=$(echo "release-${BASE_VERSION}")
fi
echo "ref=$REF" >> $GITHUB_OUTPUT
echo "base-version=$BASE_VERSION" >> $GITHUB_OUTPUT
else
# Fail entire job if it is not a valid format
echo "${{ inputs.version }} is not a valid version format. Use something like 'v0.14.0'"
exit 1
fi
release-branch:
name: Prepare ${{ inputs.version }}
runs-on: ubuntu-22.04
needs: [workflow-metadata]
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.workflow-metadata.outputs.ref }}
token: ${{ secrets.GH_TOKEN }}
fetch-depth: 0
- name: Set git 'user.name' and 'user.email'
run: |
git config user.name "${{ env.git-user }}"
git config user.email ${{ env.git-email }}
- name: Add note for previous version
run: |
git fetch --all
if [[ ${{ needs.workflow-metadata.outputs.ref }} == ${{ env.main-branch }} ]]; then
PREV_VERSION=$(git for-each-ref --sort=-creatordate --format '%(refname)' refs/tags | grep -E "\.0$" | awk -F'refs/tags/' '{ print $2 }'| head -1)
echo "The latest tag on ${{ env.main-branch }} is ${PREV_VERSION}"
else
PATCH_VERSION=$(echo ${{ inputs.version }} | awk -F'.' '{ print $3 }')
PREV_VERSION=$(echo "v${{ needs.workflow-metadata.outputs.base-version }}.$((PATCH_VERSION - 1))")
fi
git fetch origin "refs/notes/*:refs/notes/*"
NOTE_COMMIT=$(git notes --ref release-${{ needs.workflow-metadata.outputs.base-version }} list | awk '{print $2}')
if [[ ! -z "$NOTE_COMMIT" ]]; then
echo "Pruning previous notes in release-${{ needs.workflow-metadata.outputs.base-version }}"
git notes --ref release-${{ needs.workflow-metadata.outputs.base-version }} remove ${NOTE_COMMIT} || true
fi
echo "Adding new note: previous-version: ${PREV_VERSION},current-version: ${{ inputs.version }}"
git notes --ref release-${{ needs.workflow-metadata.outputs.base-version }} add -m "previous-version: ${PREV_VERSION},current-version: ${{ inputs.version }}"
git push origin 'refs/notes/*'
# Since we don't push by branch creation for patch releases
if [[ ${{ needs.workflow-metadata.outputs.ref }} != ${{ env.main-branch }} ]]; then
git commit --allow-empty -m "Trigger next rc build for ${{ inputs.version }}"
git push origin release-${{ needs.workflow-metadata.outputs.base-version }} --force
fi
- name: Create a release branch
if: ${{ contains(needs.workflow-metadata.outputs.ref, env.main-branch ) }}
run: |
git checkout -b release-${{ needs.workflow-metadata.outputs.base-version }}
git push origin release-${{ needs.workflow-metadata.outputs.base-version }}