-
Notifications
You must be signed in to change notification settings - Fork 581
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add auto semver tagging for release automation (#712)
Adds basic action, built on top of [this](https://github.com/anothrNick/github-tag-action)... Put simply, merge to main will trigger a new `SNAPSHOT` version, one minor version up from the latest. A manual trigger will allow for a "clean tag" release which will publish assets. note: this does not yet publish a github release, this will remain manual for now
- Loading branch information
1 parent
fe29465
commit 353096c
Showing
5 changed files
with
284 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
#!/bin/bash | ||
|
||
set -o pipefail | ||
|
||
# config | ||
default_semvar_bump=${DEFAULT_BUMP:-minor} | ||
with_v=${WITH_V:-true} | ||
release_branches=${RELEASE_BRANCHES:-} | ||
custom_tag=${CUSTOM_TAG:-} | ||
source=${SOURCE:-.} | ||
dryrun=${DRY_RUN:-false} | ||
initial_version=${INITIAL_VERSION:-0.0.0} | ||
tag_context=${TAG_CONTEXT:-repo} | ||
prerelease=${PRERELEASE:-false} | ||
suffix=${PRERELEASE_SUFFIX:-beta} | ||
verbose=${VERBOSE:-false} | ||
major_string_token=${MAJOR_STRING_TOKEN:-#major} | ||
minor_string_token=${MINOR_STRING_TOKEN:-#minor} | ||
patch_string_token=${PATCH_STRING_TOKEN:-#patch} | ||
none_string_token=${NONE_STRING_TOKEN:-#none} | ||
# since https://github.blog/2022-04-12-git-security-vulnerability-announced/ runner uses? | ||
git config --global --add safe.directory /github/workspace | ||
|
||
cd "${GITHUB_WORKSPACE}/${source}" || exit 1 | ||
|
||
echo "*** CONFIGURATION ***" | ||
echo -e "\tDEFAULT_BUMP: ${default_semvar_bump}" | ||
echo -e "\tWITH_V: ${with_v}" | ||
echo -e "\tRELEASE_BRANCHES: ${release_branches}" | ||
echo -e "\tCUSTOM_TAG: ${custom_tag}" | ||
echo -e "\tSOURCE: ${source}" | ||
echo -e "\tDRY_RUN: ${dryrun}" | ||
echo -e "\tINITIAL_VERSION: ${initial_version}" | ||
echo -e "\tTAG_CONTEXT: ${tag_context}" | ||
echo -e "\tPRERELEASE: ${prerelease}" | ||
echo -e "\tPRERELEASE_SUFFIX: ${suffix}" | ||
echo -e "\tVERBOSE: ${verbose}" | ||
echo -e "\tMAJOR_STRING_TOKEN: ${major_string_token}" | ||
echo -e "\tMINOR_STRING_TOKEN: ${minor_string_token}" | ||
echo -e "\tPATCH_STRING_TOKEN: ${patch_string_token}" | ||
echo -e "\tNONE_STRING_TOKEN: ${none_string_token}" | ||
|
||
# verbose, show everything | ||
if $verbose | ||
then | ||
set -x | ||
fi | ||
|
||
setOutput() { | ||
echo "${1}=${2}" >> "${GITHUB_OUTPUT}" | ||
} | ||
|
||
current_branch=$(git rev-parse --abbrev-ref HEAD) | ||
|
||
pre_release="$prerelease" | ||
IFS=',' read -ra branch <<< "$release_branches" | ||
for b in "${branch[@]}"; do | ||
# check if ${current_branch} is in ${release_branches} | exact branch match | ||
if [[ "$current_branch" == "$b" ]] | ||
then | ||
pre_release="false" | ||
fi | ||
# verify non specific branch names like .* release/* if wildcard filter then =~ | ||
if [ "$b" != "${b//[\[\]|.? +*]/}" ] && [[ "$current_branch" =~ $b ]] | ||
then | ||
pre_release="false" | ||
fi | ||
done | ||
echo "pre_release = $pre_release" | ||
|
||
# fetch tags | ||
git fetch --tags | ||
|
||
tagFmt="^v?[0-9]+\.[0-9]+\.[0-9]+$" | ||
preTagFmt="^v?[0-9]+\.[0-9]+\.[0-9]+(-$suffix\.[0-9]+)$" | ||
|
||
# get latest tag that looks like a semver (with or without v) | ||
case "$tag_context" in | ||
*repo*) | ||
tag="$(git for-each-ref --sort=-v:refname --format '%(refname:lstrip=2)' | grep -E "$tagFmt" | head -n 1)" | ||
pre_tag="$(git for-each-ref --sort=-v:refname --format '%(refname:lstrip=2)' | grep -E "$preTagFmt" | head -n 1)" | ||
;; | ||
*branch*) | ||
tag="$(git tag --list --merged HEAD --sort=-v:refname | grep -E "$tagFmt" | head -n 1)" | ||
pre_tag="$(git tag --list --merged HEAD --sort=-v:refname | grep -E "$preTagFmt" | head -n 1)" | ||
;; | ||
* ) echo "Unrecognised context" | ||
exit 1;; | ||
esac | ||
|
||
echo "tag_context=$tag_context" | ||
|
||
# if there are none, start tags at INITIAL_VERSION | ||
if [ -z "$tag" ] | ||
then | ||
if $with_v | ||
then | ||
tag="v$initial_version" | ||
else | ||
tag="$initial_version" | ||
fi | ||
if [ -z "$pre_tag" ] && $pre_release | ||
then | ||
if $with_v | ||
then | ||
pre_tag="v$initial_version" | ||
else | ||
pre_tag="$initial_version" | ||
fi | ||
fi | ||
fi | ||
|
||
# get current commit hash for tag | ||
tag_commit=$(git rev-list -n 1 "$tag") | ||
echo "tag_commit=$tag_commit" | ||
|
||
# get current commit hash | ||
commit=$(git rev-parse HEAD) | ||
echo "commit=$commit" | ||
|
||
if [ "$tag_commit" == "$commit" ] | ||
then | ||
echo "No new commits since previous tag. Skipping..." | ||
setOutput "new_tag" "$tag" | ||
setOutput "tag" "$tag" | ||
exit 0 | ||
fi | ||
|
||
# get the merge commit message looking for #bumps | ||
log=$(git show -s --format=%s) | ||
echo "Last commit message: $log" | ||
|
||
case "$log" in | ||
*$major_string_token* ) new=$(semver -i major "$tag"); part="major";; | ||
*$minor_string_token* ) new=$(semver -i minor "$tag"); part="minor";; | ||
*$patch_string_token* ) new=$(semver -i patch "$tag"); part="patch";; | ||
*$none_string_token* ) | ||
echo "Default bump was set to none. Skipping..." | ||
setOutput "new_tag" "$tag" | ||
setOutput "tag" "$tag" | ||
exit 0;; | ||
* ) | ||
if [ "$default_semvar_bump" == "none" ] | ||
then | ||
echo "Default bump was set to none. Skipping..." | ||
setOutput "new_tag" "$tag" | ||
setOutput "tag" "$tag" | ||
exit 0 | ||
else | ||
new=$(semver -i "${default_semvar_bump}" "$tag") | ||
part=$default_semvar_bump | ||
fi | ||
;; | ||
esac | ||
|
||
if $pre_release | ||
then | ||
# already a pre-release available, bump it | ||
newPreTagFmt="$new+(-$suffix\.[0-9]+)$" | ||
exists="$(git tag --list --merged HEAD --sort=-v:refname | grep -E "$newPreTagFmt" | head -n 1)" | ||
if [[ $exists != "" ]] | ||
then | ||
echo -e "Found parent to ${new} pre-tag ${exists}..." | ||
new=$(semver -i prerelease "${exists}" --preid "${suffix}") | ||
echo -e "Bumping ${suffix} pre-tag ${exists}. New pre-tag ${new}" | ||
elif [[ "$pre_tag" =~ $new ]] && [[ "$pre_tag" =~ $suffix ]] | ||
then | ||
new=$(semver -i prerelease "${pre_tag}" --preid "${suffix}") | ||
echo -e "Bumping ${suffix} pre-tag ${pre_tag}. New pre-tag ${new}" | ||
else | ||
new="$new-$suffix.0" | ||
echo -e "Setting ${suffix} pre-tag ${pre_tag} - With pre-tag ${new}" | ||
fi | ||
part="pre-$part" | ||
fi | ||
|
||
if $with_v | ||
then | ||
new="v$new" | ||
fi | ||
|
||
echo -e "Bumping tag ${tag} - New tag ${new}" | ||
|
||
# as defined in readme if CUSTOM_TAG is used any semver calculations are irrelevant. | ||
if [ -n "$custom_tag" ] | ||
then | ||
new="$custom_tag" | ||
fi | ||
|
||
# set outputs | ||
setOutput "new_tag" "$new" | ||
setOutput "part" "$part" | ||
setOutput "tag" "$new" # this needs to go in v2 is breaking change | ||
setOutput "old_tag" "$tag" | ||
|
||
# dry run exit without real changes | ||
if $dryrun | ||
then | ||
exit 0 | ||
fi | ||
|
||
# create local git tag | ||
git tag "$new" | ||
|
||
# push new tag ref to github | ||
dt=$(date '+%Y-%m-%dT%H:%M:%SZ') | ||
full_name=$GITHUB_REPOSITORY | ||
git_refs_url=$(jq .repository.git_refs_url "$GITHUB_EVENT_PATH" | tr -d '"' | sed 's/{\/sha}//g') | ||
|
||
echo "$dt: **pushing tag $new to repo $full_name" | ||
|
||
git_refs_response=$( | ||
curl -s -X POST "$git_refs_url" \ | ||
-H "Authorization: token $GITHUB_TOKEN" \ | ||
-d @- << EOF | ||
{ | ||
"ref": "refs/tags/$new", | ||
"sha": "$commit" | ||
} | ||
EOF | ||
) | ||
|
||
git_ref_posted=$( echo "${git_refs_response}" | jq .ref | tr -d '"' ) | ||
|
||
echo "::debug::${git_refs_response}" | ||
if [ "${git_ref_posted}" = "refs/tags/${new}" ] | ||
then | ||
exit 0 | ||
else | ||
echo "::error::Tag was not created properly." | ||
exit 1 | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ name: goreleaser | |
on: | ||
push: | ||
tags: | ||
- 'v*.*.*' | ||
- 'v[0-9]+.[0-9]+.[0-9]+' | ||
|
||
permissions: | ||
contents: write | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ name: Maven Deploy | |
on: | ||
push: | ||
tags: | ||
- 'v*.*.*' | ||
- 'v[0-9]+.[0-9]+.[0-9]+' | ||
|
||
jobs: | ||
build: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
name: Version Bump | ||
on: | ||
push: | ||
branches: | ||
- main | ||
workflow_dispatch: | ||
inputs: | ||
prerelease: | ||
type: boolean | ||
description: Pre-release? | ||
default: true | ||
bump: | ||
type: choice | ||
description: Which version? | ||
default: 'minor' | ||
options: | ||
- minor | ||
- patch | ||
|
||
env: | ||
PRERELEASE: ${{github.event.inputs.prerelease}} | ||
DEFAULT_BUMP: ${{github.event.inputs.bump}} | ||
APP_ID: 257305 | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- name: Generate token | ||
id: generate_token | ||
uses: tibdex/github-app-token@v1 | ||
with: | ||
app_id: ${{ env.APP_ID }} | ||
private_key: ${{ secrets.TOKEN_EXCHANGE_GH_APP_PRIVATE_KEY }} | ||
repository: ${{ github.repository }} | ||
permissions: >- | ||
{"contents": "write"} | ||
- uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: "0" | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: 16 | ||
- run: npm install -g semver | ||
- name: Bump version and push tag | ||
env: | ||
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} | ||
run: .github/actions/github-tag-action/entrypoint.sh |