#!/bin/bash # developed on macOS and probably doesn't work on Linux yet due to minor # differences in flags on sed # requires github cli tool for automatic release draft creation set -eEuo pipefail DIR=$1 LINUX="" MACOS="" if [ "$(uname)" = "Darwin" ]; then MACOS="1" fi CARGO_MANIFEST=$DIR/Cargo.toml README_FILE=$DIR/README.md # determine changelog file name if [ -f "$DIR/CHANGES.md" ]; then CHANGELOG_FILE="$DIR/CHANGES.md" elif [ -f "$DIR/CHANGELOG.md" ]; then CHANGELOG_FILE="$DIR/CHANGELOG.md" fi # get current version PACKAGE_NAME="$(sed -nE 's/^name ?= ?"([^"]+)"$/\1/ p' "$CARGO_MANIFEST" | head -n 1)" CURRENT_VERSION="$(sed -nE 's/^version ?= ?"([^"]+)"$/\1/ p' "$CARGO_MANIFEST" | head -n 1)" CHANGE_CHUNK_FILE="$(mktemp)" echo saving changelog to $CHANGE_CHUNK_FILE echo if [ -n "${CHANGELOG_FILE-}" ]; then # get changelog chunk and save to temp file cat "$CHANGELOG_FILE" | # skip up to unreleased heading sed '1,/Unreleased/ d' | # take up to previous version heading sed "/$CURRENT_VERSION/ q" | # drop last line sed '$d' \ >"$CHANGE_CHUNK_FILE" fi # if word count of changelog chunk is 0 then insert filler changelog chunk if [ "$(wc -w "$CHANGE_CHUNK_FILE" | awk '{ print $1 }')" = "0" ]; then echo "- No significant changes since \`$CURRENT_VERSION\`." >"$CHANGE_CHUNK_FILE" echo >>"$CHANGE_CHUNK_FILE" fi if [ -n "${2-}" ]; then NEW_VERSION="$2" else echo echo "--- Changes since $CURRENT_VERSION ----" cat "$CHANGE_CHUNK_FILE" echo read -p "Update version to: " NEW_VERSION fi # strip leading v from input if [ "${NEW_VERSION:0:1}" = "v" ]; then NEW_VERSION="${NEW_VERSION:1}" fi echo "updating from $CURRENT_VERSION => $NEW_VERSION" # update package.version field sed -i.bak -E "s/^version ?= ?\"[^\"]+\"$/version = \"$NEW_VERSION\"/" "$CARGO_MANIFEST" # update readme [ -f "$README_FILE" ] && sed -i.bak -E "s#$CURRENT_VERSION([/)])#$NEW_VERSION\1#g" "$README_FILE" if [ -n "${CHANGELOG_FILE-}" ]; then # update changelog file ( sed '/Unreleased/ q' "$CHANGELOG_FILE" # up to unreleased heading echo # blank line echo "## $NEW_VERSION" # new version heading cat "$CHANGE_CHUNK_FILE" # previously unreleased changes sed "/$CURRENT_VERSION/ q" "$CHANGELOG_FILE" | tail -n 1 # the previous version heading sed "1,/$CURRENT_VERSION/ d" "$CHANGELOG_FILE" # everything after previous version heading ) >"$CHANGELOG_FILE.bak" mv "$CHANGELOG_FILE.bak" "$CHANGELOG_FILE" # format CHANGELOG file according to prettier npx -y prettier --write "$CHANGELOG_FILE" || true fi # done; remove backup files rm -f $CARGO_MANIFEST.bak rm -f $README_FILE.bak if [ -n "${CHANGELOG_FILE-}" ]; then rm -f $CHANGELOG_FILE.bak fi echo "manifest, changelog, and readme updated" echo echo "check other references:" rg --glob='**/{Cargo.toml,README.md}' "\ ${PACKAGE_NAME} ?= ?\"[^\"]+\"\ |${PACKAGE_NAME} ?=.*version ?= ?\"([^\"]+)\"\ |package ?= ?\"${PACKAGE_NAME}\".*version ?= ?\"([^\"]+)\"\ |version ?= ?\"([^\"]+)\".*package ?= ?\"${PACKAGE_NAME}\"" || true echo read -p "Update all references: (y/N) " UPDATE_REFERENCES UPDATE_REFERENCES="${UPDATE_REFERENCES:-n}" if [ "$UPDATE_REFERENCES" = 'y' ] || [ "$UPDATE_REFERENCES" = 'Y' ]; then if [[ $NEW_VERSION == *".0.0" ]]; then NEW_VERSION_SPEC="${NEW_VERSION%.0.0}" elif [[ $NEW_VERSION == *".0" ]]; then NEW_VERSION_SPEC="${NEW_VERSION%.0}" else NEW_VERSION_SPEC="$NEW_VERSION" fi for f in $(fd Cargo.toml); do sed -i.bak -E \ "s/^(${PACKAGE_NAME} ?= ?\")[^\"]+(\")$/\1${NEW_VERSION_SPEC}\2/g" $f sed -i.bak -E \ "s/^(${PACKAGE_NAME} ?=.*version ?= ?\")[^\"]+(\".*)$/\1${NEW_VERSION_SPEC}\2/g" $f sed -i.bak -E \ "s/^(.*package ?= ?\"${PACKAGE_NAME}\".*version ?= ?\")[^\"]+(\".*)$/\1${NEW_VERSION_SPEC}\2/g" $f sed -i.bak -E \ "s/^(.*version ?= ?\")[^\"]+(\".*package ?= ?\"${PACKAGE_NAME}\".*)$/\1${NEW_VERSION_SPEC}\2/g" $f # remove backup file rm -f $f.bak done fi if [ $MACOS ]; then printf "chore($PACKAGE_NAME): prepare release $NEW_VERSION" | pbcopy echo "placed the recommended commit message on the clipboard" else echo echo "commit message:" echo "chore($PACKAGE_NAME): prepare release $NEW_VERSION" fi SHORT_PACKAGE_NAME="$(echo $PACKAGE_NAME | sed 's/^actix-web-//' | sed 's/^actix-//')" GIT_TAG="$(echo $SHORT_PACKAGE_NAME-v$NEW_VERSION)" RELEASE_TITLE="$(echo $PACKAGE_NAME: v$NEW_VERSION)" if [ "$(echo $NEW_VERSION | grep beta)" ] || [ "$(echo $NEW_VERSION | grep rc)" ] || [ "$(echo $NEW_VERSION | grep alpha)" ]; then FLAGS="--prerelease" else FLAGS="--latest" fi echo echo "GitHub release command:" GH_CMD="gh release create \"$GIT_TAG\" --draft --title \"$RELEASE_TITLE\" --notes-file \"$CHANGE_CHUNK_FILE\" ${FLAGS:-}" echo "$GH_CMD" read -p "Submit draft GH release: (y/N) " GH_RELEASE GH_RELEASE="${GH_RELEASE:-n}" if [ "$GH_RELEASE" = 'y' ] || [ "$GH_RELEASE" = 'Y' ]; then eval "$GH_CMD" fi echo