release (1405B)
1 #!/usr/bin/env bash 2 set -euo pipefail 3 cd "$(dirname "$0")/.." 4 5 BRANCH="master" 6 REMOTE="origin" 7 8 die() { 9 echo "error: $*" >&2 10 exit 1 11 } 12 13 update_version_file() { 14 local version="$1" 15 [ -f Cargo.toml ] || return 0 16 sed -i "s/^version = .*/version = \"$version\"/" Cargo.toml 17 git add Cargo.toml 18 if command -v cargo >/dev/null 2>&1; then 19 cargo generate-lockfile 20 [ -f Cargo.lock ] && git add Cargo.lock 21 fi 22 } 23 24 command -v git >/dev/null 2>&1 || die "git not found" 25 26 current=$(git tag --list 'v[0-9]*' --sort=-v:refname | head -n1) 27 current=${current#v} 28 usage="$(basename "$0") <version> [--push] (${current:-none})" 29 30 version="" 31 push=0 32 for arg in "$@"; do 33 case "$arg" in 34 --push) push=1 ;; 35 -*) die "unknown flag: $arg" ;; 36 *) 37 [ -z "$version" ] || die "unexpected argument: $arg" 38 version="$arg" 39 ;; 40 esac 41 done 42 43 [ -n "$version" ] || die "$usage" 44 echo "$version" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)*$' || 45 die "'$version' is not a semantic version" 46 47 [ "$(git rev-parse --abbrev-ref HEAD)" = "$BRANCH" ] || die "not on $BRANCH branch" 48 [ -z "$(git status --porcelain)" ] || die "working tree is dirty" 49 git rev-parse -q --verify "refs/tags/v$version" >/dev/null 2>&1 && die "tag v$version already exists" 50 51 update_version_file "$version" 52 53 git commit -m "release: v$version" 54 git tag -a "v$version" -m "v$version" 55 56 if [ "$push" -eq 1 ]; then 57 git push "$REMOTE" "$BRANCH" --follow-tags 58 fi