#!/bin/bash # Update release notes and tag a release # # Copyright (C) 2014-2023 Ryan Specialty, LLC. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set -euo pipefail declare -r RELEASE_FILE="${RELEASE_FILE:-RELEASES.md}" assert-valid-tag() { local -r tag="${1?Missing tag}" # Note that '$' is intentionally omitted to permit suffixes if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then echo "error: tag '$tag' must be of the form 'vM.m.r'" >&2 return 1 fi # Compare with the most recent tag and make sure this is greater local -r prev=$(git describe --abbrev=0) local -r gt=$(echo -e "$tag\n$prev" | sort -V | tail -n1) test "$tag" == "$gt" || { echo "error: tag '$tag' is not greater than previous tag '$prev'" >&2 return 1 } } extract-next() { local -r file="${1?Missing file}" awk ' /^NEXT$/ { out = 1; getline; next } /^====/ && out { nextfile } out { print } ' "$file" \ | head -n-1 } main() { local tag="${1?Missing new tag name}" assert-valid-tag "$tag" || return # We don't want to tag anything bad! make check || return local -r notes=$(extract-next "$RELEASE_FILE") test -n "$notes" || { echo "error: missing NEXT heading in $RELEASE_FILE" >&2 return 1 } local -r date=$(date +%Y-%m-%d) local -r heading="$tag ($date)" local -r hline="${heading//?/=}" echo echo "$heading" echo "$hline" echo "$notes" echo read -p "Accept above release notes and tag $tag? (y/N): " if [[ ! "$REPLY" =~ ^y(es?)? ]]; then echo "error: aborted by user" >&2 return 2 fi # Note that this also runs the release-check after tagging to ensure that # we've addressed all issues that would cause the CI job to blow up. set -x sed -i "/^NEXT\$/ { s|^NEXT$|$heading\n$hline| n;d }" "$RELEASE_FILE" \ && git add "$RELEASE_FILE" \ && git commit -m "RELEASES.md: Update for $tag" \ && git tag "$tag" -m "$notes" \ && build-aux/release-check set +x echo echo "Please review the above and then push your changes." echo echo "To reverse these actions, run:" echo " \$ git reset HEAD^" echo " \$ git checkout $RELEASE_FILE" echo " \$ git tag -d $tag" } main "$@" || { set +x code=$? echo "release failed" >&2 exit $code }