chiark / gitweb /
make-release: Add a checklist entry for cargo audit
[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
9 # Overall release steps:
10 #
11 #  - update dependencies (cargo update, cargo upgrades)
12 #  - check `cargo audit`
13 #  - edit CHANGELOG.md
14 #  - update versions
15 #  - ensure pretest == tested == main
16 #  - make deploy and test that chiark still works
17 #  - make-release --dry-run
18 #  - make-release
19 #  - release announcement to mailing list
20 #  - blog post
21
22 #---------- argument parsing and options ----------
23
24 set -e
25 set -o pipefail
26
27 fail () { echo >&2 "${0##*/}: error: $*"; exit 12; }
28
29 dryrun=x-dry-run-unset
30 cargo_dryrun=--not-a-cargo-option-please-crash
31
32 case "$#.$1" in
33 2.--real)    dryrun=x     ; cargo_dryrun=''         ; ;;
34 2.--dry-run) dryrun=dryrun; cargo_dryrun='--dry-run'; ;;
35 *)           fail "bad usage" ;;
36 esac
37
38 keyid=0x559AE46C2D6B6D3265E7CBA1E3E3392348B50D39
39
40 cratesio_raw_url=\
41 https://raw.githubusercontent.com/rust-lang/crates.io-index/master
42
43 branch="$2"
44
45 dryrun () { echo "WOULD  $*"; }
46 x () { echo >&2 "+ $*"; "$@"; }
47
48 trouble=false
49 trouble () { echo >&2 "***TROUBLE***: $*"; trouble=true; }
50
51 #---------- checks ----------
52
53 version=$(perl <Cargo.toml -ne '
54     next unless m{^version\s*=\s*\"([0-9.]+)\"\s*$};
55     print "$1\n" or die $!;
56     exit 0;
57 ')
58
59 case "$version" in
60 '') fail "no version?" ;;
61 esac
62
63 echo "version $version"
64
65 equals () {
66     diff <(git rev-parse refs/heads/$1) <(git rev-parse HEAD) \
67         || trouble "HEAD not equal to $1"
68 }
69
70 equals $branch
71 equals tested
72
73 bad=$(git status --porcelain)
74 if [ "x$bad" != x ]; then
75     printf >&2 '%s\n' "$bad"
76     trouble 'tree is dirty'
77 fi
78
79 tag="otter-$version"
80 tag_exists=$(git for-each-ref "[r]efs/tags/$tag")
81 if [ "x$tag_exists" != x ]; then trouble "tag $tag already exists"; fi
82
83 head -1 CHANGELOG.md | grep "^Version $version" \
84 || trouble "CHANGELOG.md not updated"
85
86 cargo_order='base support . cli daemon wasm apitest wdriver jstest'
87 missing=(git ls-files :\*/Cargo.toml :Cargo.toml)
88 for x in $cargo_order; do missing+=(:!$x/Cargo.toml); done
89 missing=$( "${missing[@]}" )
90 if [ "x$missing" != x ]; then trouble "missing cargo package(s) $missing"; fi
91
92 #---------- end of checks ----------
93
94 if $trouble; then
95     $dryrun fail "trouble! checks failed!"
96 else
97     echo 'checks passed'
98 fi
99
100 #---------- actually do the work ----------
101
102 $dryrun git push chiark $branch
103 $dryrun git push origin $branch
104
105 #---------- non-idempotent things ----------
106
107 $dryrun make -j12 PUBLISH_VERSION=$version publish
108 $dryrun make -j12 PUBLISH_VERSION=$version publish-make-current
109
110 $dryrun git tag -s -u "$keyid" -m "Otter v$version" $tag
111 $dryrun git push chiark $tag
112 $dryrun git push origin $tag
113
114 #---------- oh woe cargo ----------
115
116 # https://github.com/rust-lang/cargo/issues/9507
117 wait_for_crates_io () {
118     local p=$1
119     local delay=1
120     local url="$cratesio_raw_url/${p:0:2}/${p:2:2}/$p"
121     printf >&2 "waiting for upload of %s to take effect" "$p"
122     while sleep $delay; do
123         printf >&2 .
124         local got=$(
125             curl -sS "$url" | jq '.vers | select(. == "'"$version"'")'
126         )
127         if [ "x$got" != x ]; then break; fi
128         delay=$(( $delay * 11 / 10 + 1 ))
129     done
130     echo >&2 'done'
131 }
132
133 for cargo_dir in $cargo_order; do
134     $dryrun_no_more_cargo \
135     nailing-cargo --no-nail --preclean-build=src --git --- \
136         sh -xec "
137           cd $cargo_dir; cargo publish $cargo_dryrun
138         "
139
140     cargo_package=$(
141         sed -n '/^name *=/ { s/^name *= *"\(.*\)" *$/\1/; p; q }' \
142             <$cargo_dir/Cargo.toml
143     )
144
145     wait_for_crates_io "$cargo_package"
146
147     dryrun_no_more_cargo=$dryrun
148
149 done
150
151 #---------- finish ----------
152
153 $dryrun cat <<END
154
155
156 Successfully released to
157   - git tags
158   - all git branches
159   - cargo publish
160
161 Consider
162   - make deploy
163
164 You need to write release announcements
165   - sgo-software-announce
166   - blog
167
168 END