chiark / gitweb /
make-release: Set pipefail
[otter.git] / make-release
1 #!/bin/bash
2 #
3 # usage:
4 #    ./make-release --dry-run|--real <branch>
5 # eg
6 #    ./make-release --dry-run main
7
8 #---------- argument parsing and options ----------
9
10 set -e
11 set -o pipefail
12
13 fail () { echo >&2 "${0##*/}: error: $*"; exit 12; }
14
15 dryrun=x-dry-run-unset
16 cargo_dryrun=--not-a-cargo-option-please-crash
17
18 case "$#.$1" in
19 2.--real)    dryrun=x     ; cargo_dryrun=''         ; ;;
20 2.--dry-run) dryrun=dryrun; cargo_dryrun='--dry-run'; ;;
21 *)           fail "bad usage" ;;
22 esac
23
24 keyid=0x559AE46C2D6B6D3265E7CBA1E3E3392348B50D39
25
26 branch="$2"
27
28 dryrun () { echo "WOULD  $*"; }
29 x () { echo >&2 "+ $*"; "$@"; }
30
31 trouble=false
32 trouble () { echo >&2 "***TROUBLE***: $*"; trouble=true; }
33
34 #---------- checks ----------
35
36 version=$(perl <Cargo.toml -ne '
37     next unless m{^version\s*=\s*\"([0-9.]+)\"\s*$};
38     print "$1\n" or die $!;
39     exit 0;
40 ')
41
42 case "$version" in
43 '') fail "no version?" ;;
44 esac
45
46 echo "version $version"
47
48 equals () {
49     diff <(git rev-parse refs/heads/$1) <(git rev-parse HEAD) \
50         || trouble "HEAD not equal to $1"
51 }
52
53 equals $branch
54 equals tested
55
56 bad=$(git status --porcelain)
57 if [ "x$bad" != x ]; then
58     printf >&2 '%s\n' "$bad"
59     trouble 'tree is dirty'
60 fi
61
62 tag="otter-$version"
63 tag_exists=$(git for-each-ref "[r]efs/tags/$tag")
64 if [ "x$tag_exists" != x ]; then trouble "tag $tag already exists"; fi
65
66 head -1 CHANGELOG.md | grep "^Version $version" \
67 || trouble "CHANGELOG.md not updated"
68
69 cargo_order='base . cli daemon wasm apitest wdriver'
70 missing=(git ls-files :\*/Cargo.toml :Cargo.toml)
71 for x in $cargo_order; do missing+=(:!$x/Cargo.toml); done
72 missing=$( "${missing[@]}" )
73 if [ "x$missing" != x ]; then trouble "missing cargo package(s) $missing"; fi
74
75 #---------- end of checks ----------
76
77 if $trouble; then
78     $dryrun fail "trouble! checks failed!"
79 else
80     echo 'checks passed'
81 fi
82
83 #---------- actually do the work ----------
84
85 $dryrun git push chiark $branch
86 $dryrun git push origin $branch
87
88 #---------- non-idempotent things ----------
89
90 $dryrun make -j12 publish
91
92 $dryrun git tag -s -u "$keyid" -m "Otter v$version" $tag
93 $dryrun git push chiark $tag
94 $dryrun git push origin $tag
95
96
97 for cargo_dir in $cargo_order; do
98     $dryrun_no_more_cargo \
99     nailing-cargo --no-nail --linkfarm=git --- \
100         sh -xec "
101           find . ! -type l ! -type d ! -path './target/*' -print0 \
102               | xargs -0r rm --
103           cd $cargo_dir; cargo publish $cargo_dryrun
104         "
105     dryrun_no_more_cargo=$dryrun
106
107 done
108
109 #---------- finish ----------
110
111 $dryrun cat <<END
112
113
114 Successfully released to
115   - git tags
116   - all git branches
117   - cargo publish
118
119 Consider
120   - make deploy
121
122 You need to write release announcements
123   - sgo-software-announce
124   - blog
125
126 END