diff options
Diffstat (limited to 'scripts/announce-release')
-rwxr-xr-x | scripts/announce-release | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/scripts/announce-release b/scripts/announce-release new file mode 100755 index 0000000..c990821 --- /dev/null +++ b/scripts/announce-release @@ -0,0 +1,279 @@ +#!/usr/bin/env bash +# prepares a template e-mail and HTML file to announce a new release +# Copyright (c) 2006-2016 Willy Tarreau <w@1wt.eu> +# +# In short : +# - requires git +# - wants that last commit is a release/tag +# - no restriction to master, uses last tag +# - creates mail-$version.txt +# - creates web-$version.html +# - indicates how to edit the mail and how to send it + +USAGE="Usage: ${0##*/} [-f] [-p] [-b branch] [-d date] [-o oldver] [-n newver] + -f: force to overwrite existing files and ignore local changes + -p: prepare future release (skip branch and tags existence checks) + -b: force the project branch name to this (def: inherited from the version) + -d: force the release date (e.g. to rework a failed announce) + -o: previous version (def: newver-1) + -n: new version (if not last tag) +" +PREPARE= +FORCE= +OUTPUT= +BRANCH= +HTML= +DATE= +YEAR= +OLD= +LASTCOM= +NEWVER= +NEWTAG= +DIR= + +die() { + [ "$#" -eq 0 ] || echo "$*" >&2 + exit 1 +} + +err() { + echo "$*" >&2 +} + +quit() { + [ "$#" -eq 0 ] || echo "$*" + exit 0 +} + +while [ -n "$1" -a -z "${1##-*}" ]; do + case "$1" in + -d) DATE="$2" ; shift 2 ;; + -b) BRANCH="$2" ; shift 2 ;; + -f) FORCE=1 ; shift ;; + -p) PREPARE=1 ; shift ;; + -o) OLD="$2" ; shift 2 ;; + -n) NEWVER="$2" ; shift 2 ;; + -h|--help) quit "$USAGE" ;; + *) die "$USAGE" ;; + esac +done + +if [ $# -gt 0 ]; then + die "$USAGE" +fi + +if ! git rev-parse --verify -q HEAD >/dev/null; then + die "Failed to check git HEAD." +fi + +# we want to go to the git root dir +DIR="$PWD" +cd $(git rev-parse --show-toplevel) + +if [ -z "$FORCE" -a "$(git diff HEAD|wc -c)" != 0 ]; then + err "You appear to have uncommitted local changes, please commit them first :" + git status -s -uno >&2 + die +fi + +if [ -z "$PREPARE" -a "$(git rev-parse --verify -q HEAD)" != "$(git rev-parse --verify -q master)" ]; then + die "git HEAD doesn't match master branch." +fi + +if [ -n "$NEWVER" ]; then + if git show-ref --tags "v$NEWVER" >/dev/null; then + NEWTAG="v$NEWVER" + else + echo "Note: no matching tag v$NEWVER, using HEAD". + fi +fi + +# version unspecified or no existing tag for it +if [ -z "$NEWTAG" ]; then + NEWTAG="$(git describe --tags HEAD --abbrev=0)" + + if [ -z "$NEWTAG" ]; then + die "Fatal: cannot determine new version, please specify it." + elif [ -n "$PREPARE" ] && ! git show-ref --tags HEAD >/dev/null; then + # HEAD not tagged, hence we have to pretend we're on one version + # after the current tag + echo "Current version not tagged, trying to determine next one." + NEWTAG="${NEWTAG#v}" + if [ -z "$OLD" ]; then + OLD="$NEWTAG" + fi + radix="$NEWTAG" + while [ -n "$radix" -a -z "${radix%%*[0-9]}" ]; do + radix="${radix%[0-9]}" + done + + number=${NEWTAG#$radix} + if [ -z "$number" -o "$radix" = "$NEWTAG" ]; then + die "Fatal: cannot determine new version, please specify it." + fi + NEWTAG="${radix}$((number+1))" + if [ -z "$NEWVER" ]; then + NEWVER="${NEWTAG}" + fi + NEWTAG="v$NEWTAG" + LASTCOM="$(git rev-parse --short HEAD)" + echo "Next version expected to be $NEWVER and next tag $NEWTAG based on commit $LASTCOM" + elif [ "$(git describe --tags HEAD)" != "$NEWTAG" ]; then + die "About to use current HEAD which doesn't seem tagged, it reports '$(git describe --tags HEAD 2>/dev/null)'. Did you release it ?" + fi +elif ! git show-ref --tags "$NEWTAG" >/dev/null 2>&1; then + die "git tag $NEWTAG doesn't exist, did you create the release ?" +fi + +if [ -z "$NEWVER" ]; then + NEWVER="${NEWTAG#v}" +fi + +if [ -z "$LASTCOM" ]; then + LASTCOM="$(git rev-parse --short ${NEWTAG}^)" +fi + +if [ -z "$OLD" ]; then + OLD="$(git describe --tags ${LASTCOM} --abbrev=0)" + OLD="${OLD#v}" +fi + +if ! git rev-parse --verify -q "v$OLD" >/dev/null; then + die "git tag v$OLD doesn't exist." +fi + +# determine the product branch from the new release +if [ -z "$BRANCH" ]; then + subvers=${NEWVER#[0-9]*.[0-9]*[-.]*[0-9].} + [ "${subvers}" = "${NEWVER}" ] && subvers="" + major=${NEWVER%.$subvers} + branch_ext=${major#*[0-9].*[0-9]} + BRANCH=${major%${branch_ext}} +fi + +# determine the release date +if [ -z "$DATE" ]; then + DATE="$(git log -1 --pretty=fuller ${NEWTAG} 2>/dev/null | sed -ne '/^CommitDate:/{s/\(^[^ ]*:\)\|\( [-+].*\)//gp;q}')" + DATE="$(date +%Y/%m/%d -d "$DATE")" +fi +YEAR="${DATE%%/*}" + +OUTPUT="$DIR/mail-haproxy-$NEWVER.txt" +HTML="$DIR/web-haproxy-$NEWVER.html" + +[ -z "$FORCE" ] || rm -f "${OUTPUT}" "${HTML}" + +if [ -e "$OUTPUT" ]; then + die "${OUTPUT##*/} already exists, please remove it or retry with -f." +fi + +if [ -e "$HTML" ]; then + die "$HTML already exists, please remove it or retry with -f." +fi + +( + echo "# Send this using:" + echo "# mutt -H <(tail -n +4 ${OUTPUT##*/}) -s \"[ANNOUNCE] haproxy-$NEWVER\" haproxy@formilux.org" +) >> "$OUTPUT" + +(echo + echo "Hi," + echo + echo -n "HAProxy $NEWVER was released on $DATE. It added " + echo -n $(git log --oneline --reverse --format="%s" "v$OLD".."$LASTCOM" | wc -l) + echo " new commits" + echo "after version $OLD." + echo + echo "- per tag :" + git log --oneline --reverse --format="%s" "v$OLD".."$LASTCOM" | cut -f1 -d':' | sort | uniq -c + echo + echo "major commits :" + git log --oneline --reverse --format=" - %s" "v$OLD".."$LASTCOM" | grep MAJOR + echo + echo "- per file :" + git show "v$OLD".."$LASTCOM" -- src/ | grep ^diff | awk '{ print substr($3,7)}' | sort | uniq -c | sort -nr | head -15 + echo + echo "- per topic :" + git log --oneline --reverse --format="%s" "v$OLD".."$LASTCOM" | cut -f2 -d':' | awk '{sub("s$","",$1); print $1}' | sort | uniq -c + echo + echo "- sorted changelog :" + git log --oneline --reverse --format="%s" "v$OLD".."$LASTCOM" | sort + echo + echo "#############################################################################################" +) >> "$OUTPUT" + +# report the download paths +if [ -z "${NEWVER##*-dev*}" ]; then + gitdir="haproxy.git" +else + gitdir="haproxy-$BRANCH.git" +fi + +(echo "Please find the usual URLs below :" + echo " Site index : https://www.haproxy.org/" + echo " Documentation : https://docs.haproxy.org/" + echo " Wiki : https://github.com/haproxy/wiki/wiki" + echo " Discourse : https://discourse.haproxy.org/" + echo " Slack channel : https://slack.haproxy.org/" + echo " Issue tracker : https://github.com/haproxy/haproxy/issues" + echo " Sources : https://www.haproxy.org/download/${BRANCH}/src/" + echo " Git repository : https://git.haproxy.org/git/${gitdir}/" + echo " Git Web browsing : https://git.haproxy.org/?p=${gitdir}" + echo " Changelog : https://www.haproxy.org/download/${BRANCH}/src/CHANGELOG" + echo " Dataplane API : https://github.com/haproxytech/dataplaneapi/releases/latest" + echo " Pending bugs : https://www.haproxy.org/l/pending-bugs" + echo " Reviewed bugs : https://www.haproxy.org/l/reviewed-bugs" + echo " Code reports : https://www.haproxy.org/l/code-reports" + echo " Latest builds : https://www.haproxy.org/l/dev-packages" +) >> "$OUTPUT" + +# sign +(echo + echo "${GIT_COMMITTER_NAME% *}" +) >> "$OUTPUT" + +(echo "---" + echo "Complete changelog :" + git shortlog "v$OLD".."$LASTCOM" + echo "---" +) >> "$OUTPUT" + + +# prepare the HTML update +set -- $(date +%e -d "$DATE") +case "$1" in + 11|12|13) day="${1}th" ;; + *1) day="${1}st" ;; + *2) day="${2}nd" ;; + *3) day="${1}rd" ;; + *) day="${1}th" ;; +esac + +humandate=$(date "+%B, $day, %Y" -d "$DATE") +(echo "$humandate</b> : <i>$NEWVER</i>" + echo " <p>" + echo " <ul>" + echo "<--------------------------- edit contents below --------------------------->" + echo "- per tag :" + git log --oneline --reverse --format="%s" "v$OLD".."$LASTCOM" | cut -f1 -d':' | sort | uniq -c + echo + echo "- per topic :" + git log --oneline --reverse --format="%s" "v$OLD".."$LASTCOM" | cut -f2 -d':' | awk '{sub("s$","",$1); print $1}' | sort | uniq -c + echo + echo "major commits :" + git log --oneline --reverse --format=" - %s" "v$OLD".."$LASTCOM" | grep MAJOR + echo + echo "<--------------------------------------------------------------------------->" + echo " Code and changelog are available <a href=\"/download/${BRANCH}/src/\">here</a> as usual." + echo " </ul>" + echo " <p>" + echo " <b>" +) >> "$HTML" + +echo "The announce was emitted into file $OUTPUT." +echo "You can edit it and send it this way :" +echo +echo " mutt -H <(tail -n +4 ${OUTPUT##*/}) -s \"[ANNOUNCE] haproxy-$NEWVER\" haproxy@formilux.org" +echo +echo "The HTML block was emitted into $HTML and needs to be finished by hand." +echo |