Merge pull request #917 from plbstl/improve-release-script

Improve release script
This commit is contained in:
Nick Alteen 2024-08-09 10:45:41 -04:00 committed by GitHub
commit 1d1be2dd61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 108 additions and 35 deletions

View File

@ -218,12 +218,18 @@ based on release tags. This script simplifies this process by performing the
following steps:
1. **Retrieving the latest release tag:** The script starts by fetching the most
recent release tag by looking at the local data available in your repository.
recent semver release tag of the current branch, by looking at the local data
available in your repository.
1. **Prompting for a new release tag:** The user is then prompted to enter a new
release tag. To assist with this, the script displays the latest release tag
and provides a regular expression to validate the format of the new tag.
1. **Tagging the new release:** Once a valid new tag is entered, the script tags
the new release.
1. **Pushing the new tag to the remote:** Finally, the script pushes the new tag
to the remote repository. From here, you will need to create a new release in
GitHub and users can easily reference the new tag in their workflows.
release tag. To assist with this, the script displays the tag retrieved in
the previous step, and validates the format of the inputted tag (vX.X.X). The
user is also reminded to update the version field in package.json.
1. **Tagging the new release:** The script then tags a new release and syncs the
separate major tag (e.g. v1, v2) with the new release tag (e.g. v1.0.0,
v2.1.2). When the user is creating a new major release, the script
auto-detects this and creates a `releases/v#` branch for the previous major
version.
1. **Pushing changes to remote:** Finally, the script pushes the necessary
commits, tags and branches to the remote repository. From here, you will need
to create a new release in GitHub so users can easily reference the new tags
in their workflows.

View File

@ -1,59 +1,126 @@
#!/bin/bash
# Exit early
# See: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#The-Set-Builtin
set -e
# About:
#
# This is a helper script to tag and push a new release. GitHub Actions use
# release tags to allow users to select a specific version of the action to use.
#
# See: https://github.com/actions/typescript-action#publishing-a-new-release
# See: https://github.com/actions/toolkit/blob/master/docs/action-versioning.md#recommendations
#
# This script will do the following:
#
# 1. Get the latest release tag
# 2. Prompt the user for a new release tag
# 3. Tag the new release
# 4. Push the new tag to the remote
# 1. Retrieve the latest release tag
# 2. Display the latest release tag
# 3. Prompt the user for a new release tag
# 4. Validate the new release tag
# 5. Remind user to update the version field in package.json
# 6. Tag a new release
# 7. Set 'is_major_release' variable
# 8. Point separate major release tag (e.g. v1, v2) to the new release
# 9. Push the new tags (with commits, if any) to remote
# 10. If this is a major release, create a 'releases/v#' branch and push
#
# Usage:
#
# script/release
# Variables
semver_tag_regex='v[0-9]+\.[0-9]+\.[0-9]+$'
semver_tag_glob='v[0-9].[0-9].[0-9]*'
git_remote='origin'
major_semver_tag_regex='\(v[0-9]*\)'
# Terminal colors
OFF='\033[0m'
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
BOLD_RED='\033[1;31m'
BOLD_GREEN='\033[1;32m'
BOLD_BLUE='\033[1;34m'
BOLD_PURPLE='\033[1;35m'
BOLD_UNDERLINED='\033[1;4m'
BOLD='\033[1m'
# Get the latest release tag
latest_tag=$(git describe --tags "$(git rev-list --tags --max-count=1)")
if [[ -z "$latest_tag" ]]; then
# 1. Retrieve the latest release tag
if ! latest_tag=$(git describe --abbrev=0 --match="$semver_tag_glob"); then
# There are no existing release tags
echo -e "No tags found (yet) - Continue to create and push your first tag"
latest_tag="[unknown]"
fi
# Display the latest release tag
echo -e "The latest release tag is: ${BLUE}${latest_tag}${OFF}"
# 2. Display the latest release tag
echo -e "The latest release tag is: ${BOLD_BLUE}${latest_tag}${OFF}"
# Prompt the user for the new release tag
# 3. Prompt the user for a new release tag
read -r -p 'Enter a new release tag (vX.X.X format): ' new_tag
# Validate the new release tag
tag_regex='v[0-9]+\.[0-9]+\.[0-9]+$'
if echo "$new_tag" | grep -q -E "$tag_regex"; then
echo -e "Tag: ${BLUE}$new_tag${OFF} is valid"
# 4. Validate the new release tag
if echo "$new_tag" | grep -q -E "$semver_tag_regex"; then
# Release tag is valid
echo -e "Tag: ${BOLD_BLUE}$new_tag${OFF} is valid syntax"
else
# Release tag is not `vX.X.X` format
echo -e "Tag: ${BLUE}$new_tag${OFF} is ${RED}not valid${OFF} (must be in vX.X.X format)"
# Release tag is not in `vX.X.X` format
echo -e "Tag: ${BOLD_BLUE}$new_tag${OFF} is ${BOLD_RED}not valid${OFF} (must be in ${BOLD}vX.X.X${OFF} format)"
exit 1
fi
# Tag the new release
git tag -a "$new_tag" -m "$new_tag Release"
echo -e "${GREEN}Tagged: $new_tag${OFF}"
# 5. Remind user to update the version field in package.json
echo -e -n "Make sure the version field in package.json is ${BOLD_BLUE}$new_tag${OFF}. Yes? [Y/${BOLD_UNDERLINED}n${OFF}] "
read -r YN
# Push the new tag to the remote
git push --tags
echo -e "${GREEN}Release tag pushed to remote${OFF}"
echo -e "${GREEN}Done!${OFF}"
if [[ ! ($YN == "y" || $YN == "Y") ]]; then
# Package.json version field is not up to date
echo -e "Please update the package.json version to ${BOLD_PURPLE}$new_tag${OFF} and commit your changes"
exit 1
fi
# 6. Tag a new release
git tag "$new_tag" --annotate --message "$new_tag Release"
echo -e "Tagged: ${BOLD_GREEN}$new_tag${OFF}"
# 7. Set 'is_major_release' variable
latest_major_release_tag=$(expr "$latest_tag" : "$major_semver_tag_regex")
new_major_release_tag=$(expr "$new_tag" : "$major_semver_tag_regex")
if ! [[ "$new_major_release_tag" = "$latest_major_release_tag" ]]; then
is_major_release='yes'
else
is_major_release='no'
fi
# 8. Point separate major release tag (e.g. v1, v2) to the new release
if [ $is_major_release = 'yes' ]; then
# Create a new major verison tag and point it to this release
git tag "$new_major_release_tag" --annotate --message "$new_major_release_tag Release"
echo -e "New major version tag: ${BOLD_GREEN}$new_major_release_tag${OFF}"
else
# Update the major verison tag to point it to this release
git tag "$latest_major_release_tag" --force --annotate --message "Sync $latest_major_release_tag tag with $new_tag"
echo -e "Synced ${BOLD_GREEN}$latest_major_release_tag${OFF} with ${BOLD_GREEN}$new_tag${OFF}"
fi
# 9. Push the new tags (with commits, if any) to remote
git push --follow-tags
if [ $is_major_release = 'yes' ]; then
# New major version tag is pushed with the '--follow-tags' flags
echo -e "Tags: ${BOLD_GREEN}$new_major_release_tag${OFF} and ${BOLD_GREEN}$new_tag${OFF} pushed to remote"
else
# Force push the updated major version tag
git push $git_remote "$latest_major_release_tag" --force
echo -e "Tags: ${BOLD_GREEN}$latest_major_release_tag${OFF} and ${BOLD_GREEN}$new_tag${OFF} pushed to remote"
fi
# 10. If this is a major release, create a 'releases/v#' branch and push
if [ $is_major_release = 'yes' ]; then
git branch "releases/$latest_major_release_tag" "$latest_major_release_tag"
echo -e "Branch: ${BOLD_BLUE}releases/$latest_major_release_tag${OFF} created from ${BOLD_BLUE}$latest_major_release_tag${OFF} tag"
git push --set-upstream $git_remote "releases/$latest_major_release_tag"
echo -e "Branch: ${BOLD_GREEN}releases/$latest_major_release_tag${OFF} pushed to remote"
fi
# Completed
echo -e "${BOLD_GREEN}Done!${OFF}"