From 4d88b34eded70459c15db9c5b88583b761c7fd38 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 8 Mar 2024 13:02:37 +0100 Subject: [PATCH] draft pre-release-checks --- src/releasing/pre-release-checks-git.doc.sh | 12 ++ src/releasing/pre-release-checks-git.sh | 128 ++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100755 src/releasing/pre-release-checks-git.doc.sh create mode 100755 src/releasing/pre-release-checks-git.sh diff --git a/src/releasing/pre-release-checks-git.doc.sh b/src/releasing/pre-release-checks-git.doc.sh new file mode 100755 index 00000000..498cb0b7 --- /dev/null +++ b/src/releasing/pre-release-checks-git.doc.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +shopt -s inherit_errexit +# Assumes tegonal's scripts were fetched with gt - adjust location accordingly +dir_of_tegonal_scripts="$(cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")" >/dev/null && pwd 2>/dev/null)/../lib/tegonal-scripts/src" +source "$dir_of_tegonal_scripts/setup.sh" "$dir_of_tegonal_scripts" + +# checks releasing v0.1.0 makes sense and the current branch is main +"$dir_of_tegonal_scripts/releasing/pre-release-checks-git.sh" -v v0.1.0 + +# checks releasing v0.1.0 makes sense and the current branch is hotfix-1.0 +"$dir_of_tegonal_scripts/releasing/pre-release-checks-git.sh" -v v0.1.0 -b hotfix-1.0 diff --git a/src/releasing/pre-release-checks-git.sh b/src/releasing/pre-release-checks-git.sh new file mode 100755 index 00000000..25fd0616 --- /dev/null +++ b/src/releasing/pre-release-checks-git.sh @@ -0,0 +1,128 @@ +#!/usr/bin/env bash +# +# __ __ +# / /____ ___ ____ ___ ___ _/ / This script is provided to you by https://github.com/tegonal/scripts +# / __/ -_) _ `/ _ \/ _ \/ _ `/ / Copyright 2022 Tegonal Genossenschaft +# \__/\__/\_, /\___/_//_/\_,_/_/ It is licensed under Apache License 2.0 +# /___/ Please report bugs and contribute back your improvements +# +# Version: v1.4.0-SNAPSHOT +####### Description ############# +# +# Checks that releasing a certain version (creating a corresponding git tag) makes sense: We check: +# - the version follows the format vX.Y.Z(-RC...) +# - there are no uncommitted changes +# - checks current branch is `main` (we assume the convention that main is your default branch) +# - the desired version does not exist as tag locally or on remote +# +####### Usage ################### +# +# #!/usr/bin/env bash +# set -euo pipefail +# shopt -s inherit_errexit +# # Assumes tegonal's scripts were fetched with gt - adjust location accordingly +# dir_of_tegonal_scripts="$(cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")" >/dev/null && pwd 2>/dev/null)/../lib/tegonal-scripts/src" +# source "$dir_of_tegonal_scripts/setup.sh" "$dir_of_tegonal_scripts" +# +# # checks releasing v0.1.0 makes sense and the current branch is +# "$dir_of_tegonal_scripts/releasing/pre-release-checks-git.sh" -v v0.1.0 +# +# # checks releasing v0.1.0 makes sense and the current branch is hotfix-1.0 +# "$dir_of_tegonal_scripts/releasing/pre-release-checks-git.sh" -v v0.1.0 -b hotfix-1.0 +# +################################### +set -euo pipefail +shopt -s inherit_errexit +unset CDPATH +export TEGONAL_SCRIPTS_VERSION='v1.3.0-SNAPSHOT' + +if ! [[ -v dir_of_tegonal_scripts ]]; then + dir_of_tegonal_scripts="$(cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")" >/dev/null && pwd 2>/dev/null)/.." + source "$dir_of_tegonal_scripts/setup.sh" "$dir_of_tegonal_scripts" +fi +sourceOnce "$dir_of_tegonal_scripts/utility/git-utils.sh" +sourceOnce "$dir_of_tegonal_scripts/utility/ask.sh" +sourceOnce "$dir_of_tegonal_scripts/utility/parse-args.sh" + +function preReleaseCheckGit() { + local version branch + # shellcheck disable=SC2034 # is passed by name to parseArguments + local -ra params=( + version '-v' "The version to release in the format vX.Y.Z(-RC...)" + branch '-b|--branch' '(optional) The expected branch which is currently checked out -- default: main' + ) + + parseArguments params "" "$TEGONAL_SCRIPTS_VERSION" "$@" + + local -r versionRegex="^(v[0-9]+)\.([0-9]+)\.[0-9]+(-RC[0-9]+)?$" + if ! [[ -v branch ]]; then branch="main"; fi + exitIfNotAllArgumentsSet params "" "$TEGONAL_SCRIPTS_VERSION" + + if ! [[ "$version" =~ $versionRegex ]]; then + die "-v should match vX.Y.Z(-RC...), was %s" "$version" + fi + + exitIfGitHasChanges + + local tags + tags=$(git tag) || die "The following command failed (see above): git tag" + if grep "$version" <<< "$tags" >/dev/null; then + logError "tag %s already exists locally, adjust version or delete it with git tag -d %s" "$version" "$version" + if hasRemoteTag "$version"; then + printf >&2 "Note, it also exists on the remote which means you also need to delete it there -- e.g. via git push origin :%s\n" "$version" + exit 1 + fi + logInfo "looks like the tag only exists locally." + if askYesOrNo "Shall I \`git tag -d %s\` and continue with the release?" "$version"; then + git tag -d "$version" || die "deleting tag %s failed" "$version" + else + exit 1 + fi + fi + + if hasRemoteTag "$version"; then + logError "tag %s already exists on remote origin, adjust version or delete it with git push origin :%s\n" "$version" "$version" + exit 1 + fi + + local currentBranch + currentBranch="$(currentGitBranch)" || die "could not determine current git branch, see above" + local -r currentBranch + if [[ $currentBranch != "$branch" ]]; then + logError "you need to be on the \033[0;36m%s\033[0m branch to release, check that you have merged all changes from your current branch \033[0;36m%s\033[0m." "$branch" "$currentBranch" + if askYesOrNo "Shall I switch to %s for you?" "$branch"; then + git checkout "$branch" || die "checking out branch \033[0;36m%s\033[0m failed" "$branch" + else + return 1 + fi + fi + + git fetch || die "could not fetch latest changes from origin, cannot verify if we are up-to-date with remote or not" + + if localGitIsAhead "$branch"; then + logError "you are ahead of origin, please push first and check if CI succeeds before releasing. Following your additional changes:" + git -P log "origin/${branch}..$branch" + if askYesOrNo "Shall I git push for you?"; then + git push + logInfo "please check if your push passes CI and re-execute the release command afterwards" + fi + return 1 + fi + + while localGitIsBehind "$branch"; do + git fetch || die "could not fetch latest changes from origin, cannot verify if we are up-to-date with remote or not" + logError "you are behind of origin. I already fetched the changes for you, please check if you still want to release. Following the additional changes in origin/main:" + git -P log "${branch}..origin/$branch" + if askYesOrNo "Do you want to git pull?"; then + git pull || die "could not pull the changes, have to abort the release, please fix yourself and re-launch the release command" + if ! askYesOrNo "Do you want to release now?"; then + return 1 + fi + else + return 1 + fi + done +} + +${__SOURCED__:+return} +releaseFiles "$@"