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