refactor(release)!: simplify and streamline release workflow (#3309)

This commit is contained in:
James Rich 2025-10-03 10:46:31 -05:00 committed by GitHub
parent a7183cc8ca
commit ee74d4700a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 184 additions and 493 deletions

View file

@ -3,15 +3,9 @@ name: Create Internal Release Tag
on:
workflow_dispatch:
inputs:
release_type:
description: "Type of release (auto|patch|minor|major|hotfix)"
base_version:
description: "Base version to iterate on (e.g. 2.6.7). The next internal iteration will be created for this version."
required: true
default: auto
type: choice
options: [auto, patch, minor, major, hotfix]
hotfix_base_version:
description: "Base version for hotfix (e.g. 2.5.0) required if release_type=hotfix"
required: false
dry_run:
description: "If true, calculate but do not push tag"
required: false
@ -29,86 +23,21 @@ jobs:
with:
fetch-depth: 0
- name: Determine Latest Base Version
id: latest
run: |
set -euo pipefail
# List base tags (exclude track/hotfix suffixes)
BASE_TAGS=$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-version:refname | head -n1 || true)
echo "Found latest base tag: $BASE_TAGS"
echo "latest_base_tag=$BASE_TAGS" >> $GITHUB_OUTPUT
- name: Compute Next Version (auto/patch/minor/major)
id: compute
if: ${{ inputs.release_type != 'hotfix' }}
run: |
set -euo pipefail
RTYPE='${{ inputs.release_type }}'
LAST='${{ steps.latest.outputs.latest_base_tag }}'
if [ -z "$LAST" ]; then
BASE_MAJOR=0; BASE_MINOR=0; BASE_PATCH=0
else
V=${LAST#v}
IFS='.' read -r BASE_MAJOR BASE_MINOR BASE_PATCH <<< "$V"
fi
if [ "$RTYPE" = 'auto' ]; then
echo "Determining bump type from commits since $LAST..."
RANGE="$LAST..HEAD"
[ -z "$LAST" ] && RANGE="HEAD" # first release
LOG=$(git log --format=%s $RANGE || true)
BUMP="patch"
if echo "$LOG" | grep -Eiq 'BREAKING CHANGE'; then BUMP=major; fi
if echo "$LOG" | grep -Eiq '^[a-zA-Z]+!:'; then BUMP=major; fi
if [ "$BUMP" != major ] && echo "$LOG" | grep -Eiq '^feat(\(|:)' ; then BUMP=minor; fi
RTYPE=$BUMP
echo "Auto-detected bump: $RTYPE"
fi
case "$RTYPE" in
major)
NEW_MAJOR=$((BASE_MAJOR+1)); NEW_MINOR=0; NEW_PATCH=0;;
minor)
NEW_MAJOR=$BASE_MAJOR; NEW_MINOR=$((BASE_MINOR+1)); NEW_PATCH=0;;
patch)
NEW_MAJOR=$BASE_MAJOR; NEW_MINOR=$BASE_MINOR; NEW_PATCH=$((BASE_PATCH+1));;
*) echo "Unsupported release_type for this step: $RTYPE"; exit 1;;
esac
NEW_VERSION="${NEW_MAJOR}.${NEW_MINOR}.${NEW_PATCH}"
echo "base_version=$NEW_VERSION" >> $GITHUB_OUTPUT
- name: Compute Hotfix Version
id: hotfix
if: ${{ inputs.release_type == 'hotfix' }}
run: |
set -euo pipefail
BASE='${{ inputs.hotfix_base_version }}'
if [ -z "$BASE" ]; then
echo "hotfix_base_version required for hotfix release_type" >&2
exit 1
fi
if ! git tag --list | grep -q "^v$BASE$"; then
echo "Base version tag v$BASE not found (production tag required)." >&2
exit 1
fi
EXISTING=$(git tag --list "v${BASE}-hotfix*" | sed -E 's/^v[0-9]+\.[0-9]+\.[0-9]+-hotfix([0-9]+).*$/\1/' | sort -n | tail -1 || true)
if [ -z "$EXISTING" ]; then NEXT=1; else NEXT=$((EXISTING+1)); fi
HOTFIX_VERSION="${BASE}-hotfix${NEXT}"
echo "hotfix_version=$HOTFIX_VERSION" >> $GITHUB_OUTPUT
- name: Decide Internal Tag
- name: Compute Tag
id: tag
run: |
set -euo pipefail
if [ '${{ inputs.release_type }}' = 'hotfix' ]; then
BASE='${{ steps.hotfix.outputs.hotfix_version }}'
else
BASE='${{ steps.compute.outputs.base_version }}'
fi
INTERNAL_TAG="v${BASE}-internal.1"
if git tag --list | grep -q "^${INTERNAL_TAG}$"; then
echo "Tag ${INTERNAL_TAG} already exists." >&2
BASE='${{ inputs.base_version }}'
# Find the highest existing internal tag for this base version and increment it.
EXISTING=$(git tag --list "v${BASE}-internal.*" | sed -E 's/^v.*-internal\.([0-9]+)$/\1/' | sort -n | tail -1 || true)
if [ -z "$EXISTING" ]; then NEXT=1; else NEXT=$((EXISTING+1)); fi
FINAL_TAG="v${BASE}-internal.${NEXT}"
# Check if the tag already exists for some reason (e.g. race condition).
if git tag --list | grep -q "^${FINAL_TAG}$"; then
echo "Tag ${FINAL_TAG} already exists." >&2
exit 1
fi
echo "internal_tag=$INTERNAL_TAG" >> $GITHUB_OUTPUT
echo "internal_tag=$FINAL_TAG" >> $GITHUB_OUTPUT
- name: Dry Run Preview
if: ${{ inputs.dry_run == 'true' }}
@ -120,7 +49,7 @@ jobs:
if: ${{ inputs.dry_run != 'true' }}
run: |
TAG='${{ steps.tag.outputs.internal_tag }}'
MSG="Initial internal build for ${TAG}"
MSG="Internal build iteration for ${TAG}"
git tag -a "$TAG" -m "$MSG"
git push origin "$TAG"
echo "Created and pushed $TAG"
@ -129,11 +58,5 @@ jobs:
run: |
echo "### Internal Tag Created" >> $GITHUB_STEP_SUMMARY
echo "Tag: ${{ steps.tag.outputs.internal_tag }}" >> $GITHUB_STEP_SUMMARY
echo "Release Type: ${{ inputs.release_type }}" >> $GITHUB_STEP_SUMMARY
if [ '${{ inputs.release_type }}' = 'hotfix' ]; then
echo "Base Hotfix Series: ${{ steps.hotfix.outputs.hotfix_version }}" >> $GITHUB_STEP_SUMMARY
else
echo "Base Version: ${{ steps.compute.outputs.base_version }}" >> $GITHUB_STEP_SUMMARY
fi
echo "Base Version: ${{ inputs.base_version }}" >> $GITHUB_STEP_SUMMARY
echo "Dry Run: ${{ inputs.dry_run }}" >> $GITHUB_STEP_SUMMARY