|
1 | 1 | #!/usr/bin/env bash |
2 | | -# Usage: script/release-precheck |
| 2 | +# |
| 3 | +# Ensures repo is ready to release. |
| 4 | +# |
| 5 | +# Usage: script/preversion [-v] [--] [FILES...] |
| 6 | +# |
| 7 | +# Options: |
| 8 | +# -o Detect unreleased changes in (and only in) FILES |
| 9 | +# -v Print log since last tag |
| 10 | +# FILES Files to check for changes. |
| 11 | +# [default: package.json#files read via $npm_package_files_*] |
3 | 12 | # |
4 | 13 | # - fetch from origin |
5 | 14 | # - ensure it isn't already tagged |
6 | | -# - ensure currently on master branch |
| 15 | +# - ensure currently on main branch |
7 | 16 | # - ensure there are bin or definition changes to release |
8 | 17 |
|
9 | 18 | set -euo pipefail |
10 | 19 |
|
11 | | -git fetch --quiet --tags origin master |
| 20 | +[ -n "${DEBUG-}" ] && set -x |
| 21 | + |
| 22 | +unset verbose strict |
| 23 | +while getopts "ov" opt; do |
| 24 | + case "$opt" in |
| 25 | + o) strict=1 ;; |
| 26 | + v) verbose=1 ;; |
| 27 | + *) break ;; |
| 28 | + esac |
| 29 | +done |
| 30 | +shift $((OPTIND - 1)) |
| 31 | + |
| 32 | +if [ "${1-}" = -- ]; then |
| 33 | + shift |
| 34 | +fi |
| 35 | + |
| 36 | +abort() { |
| 37 | + echo "Aborting: $1" >&2 |
| 38 | + exit "${2:-1}" |
| 39 | +} |
| 40 | + |
| 41 | +declare -a files |
| 42 | +if [ "$#" -gt 0 ]; then |
| 43 | + files=("$@") |
| 44 | +else |
| 45 | + IFS=" " read -r -a files <<<"$(node -p 'require("./package").files.join(" ")')" |
| 46 | +fi |
| 47 | + |
| 48 | +git fetch --quiet --tags origin main |
12 | 49 |
|
13 | 50 | existing="$(git tag --points-at HEAD)" |
14 | 51 | if [ -n "$existing" ]; then |
15 | | - echo "Aborting: HEAD is already tagged as '${existing}'" >&2 |
16 | | - exit 1 |
| 52 | + abort "HEAD is already tagged as '${existing}'" |
17 | 53 | fi |
18 | 54 |
|
19 | 55 | current_branch="$(git symbolic-ref --short HEAD)" |
20 | | -if [ "$current_branch" != master ]; then |
21 | | - echo "Aborting: Not currently on master branch" >&2 |
22 | | - exit 1 |
| 56 | +if [ "$current_branch" != main ]; then |
| 57 | + abort "Not currently on main branch" 2 |
23 | 58 | fi |
24 | 59 |
|
25 | 60 | previous_tag="$(git describe --tags --abbrev=0)" |
26 | | -if git diff --quiet "${previous_tag}..HEAD" -- bin share; then |
27 | | - echo "Aborting: No features to release since '${previous_tag}'" >&2 |
28 | | - exit 1 |
| 61 | +if git diff --quiet "${previous_tag}..HEAD" -- "${files[@]}"; then |
| 62 | + abort "No features to release since '${previous_tag}'" |
| 63 | +fi |
| 64 | + |
| 65 | +allowed_changes=("${files[@]}" .github script *.md) |
| 66 | +allowed_changes=("${allowed_changes[@]/#/\':!\'}") # prefix pathspecs with git's "ignore" |
| 67 | + |
| 68 | +if [ -n "${strict-}" ] && |
| 69 | + ! git diff --quiet "${previous_tag}..HEAD" -- "${allowed_changes[@]}"; then |
| 70 | + { |
| 71 | + echo "git diff --stat ${previous_tag}..HEAD -- ${allowed_changes[*]}" |
| 72 | + git diff --stat "${previous_tag}..HEAD" -- "${allowed_changes[@]}" |
| 73 | + } >&2 |
| 74 | + abort "Changes detected outside '${allowed_changes[*]#:!}'" 2 |
| 75 | +fi |
| 76 | + |
| 77 | +if [ -n "${verbose-}" ]; then |
| 78 | + git log "$previous_tag"... --oneline -- "${files[@]}" |
29 | 79 | fi |
0 commit comments