summaryrefslogtreecommitdiff
path: root/maint/cargo-publish
blob: 761baf59d7e17729b607bf4526d22bcd88cd9e55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/usr/bin/env bash
#
# usage:
#   maint/cargo-publish [<OPTIONS>] VERSION
#
# options:
#   --dry-run
#   --force                go ahead even if problems detected
#   --branch BRANCH        expect to be releasing origin/BRANCH, not HEAD
#   --origin ORIGIN        replace repo URL to look for BRANCH on
#
# Preconditions:
#   See doc/Release.md
#
# Running a different version to the one in the arti.git being published:
# You can invoke this as ../PATH/TO/maint/cargo-publish.
# That maint/ directory must contain compatible versions of the support
# utilities, but it need not match the one in the CWD.
# The version that is published is the one from the CWD.

set -e

origin='[email protected]:tpo/core/arti'
branch='main'
maint="$(dirname "$0")"
: "${CARGO:=cargo}"

# Note for users of nailing-cargo: use this setting:
#   CARGO='nailing-cargo --preclean=full --no-nail --git -o'

# shellcheck source=maint/crates-io-utils.sh
source "$maint/crates-io-utils.sh"

#===== utilities =====

all_ok=true

problem () {
    echo >&2 "problem: $*"
    all_ok=false
}

check_equal () {
    local a="$1"
    local b="$2"
    local a_what="$3"
    local b_what="$4"
    if [ "$a" != "$b" ]; then
	problem "mismatch: $a_what ($a) != $b_what ($b)"
    fi
}

#===== temporary files =====

tmp_trap_exit_setup

#===== argument parsing =====

dry_run=false
force=false

while [ $# != 0 ]; do
    case "$1" in
	--) break;;
	-*) ;;
	*) break;;
    esac
    arg="$1"; shift
    case "$arg" in
	--dry-run) dry_run=true ;;
	--force) force=true ;;
	--branch|--origin)
	    eval "${arg#--}=\$1"
	    shift || fail "$arg takes an argument"
	;;
	*) fail "unknown option: $1";;
    esac
done

case $# in
    1) version=$1 ;;
    *) fail "bad usage, needs arti version"
esac

#===== checks and preparation =====

jq </dev/null . || fail "jq is not installed, try   apt install jq"

#----- check that we are identical to our main repo's `main`

git fetch --quiet "$origin" "$branch"

origin_head=$(git rev-parse FETCH_HEAD~0)
our_head=$(git rev-parse HEAD~0)

check_equal "$our_head" "$origin_head" \
	    "our HEAD commit" "origin commit $origin"

# TODO somehow check that CI failed there!

#----- check that arti version matches

arti=$("$maint"/list-crates -p arti --version)
arti=${arti##* }

check_equal "$arti" "$version" \
	    "version of the arti crate, in-tree" \
	    "specified version to release"

#----- Check that our release date is reasonable.

"$maint/update-release-date" --check

#----- compare already-published versions -----

"$maint"/list-crates --version >"$tmp/all-crates"

exec 3<"$tmp/all-crates"

# shellcheck disable=SC2162 # we don't need -r, it has no backslashes
while <&3 read p v; do
    printf "checking status of %-30s %10s ..." "$p" "$v"

    crates_io_api_call "v1/crates/$p/$v" .version.crate "$tmp/$p.json"

    case "$http_code" in
	200) echo ' already published.';;
	404)
	    echo ' needs publishing.'
	    to_publish+=" $p"
	    ;;
    esac
done

#===== commitment point =====

prefix=xxxx

running () {
    echo "    $*"
    "$@"
}

if $dry_run; then
    if $all_ok; then
	echo 'all seems OK, would run the following commands:'
	prefix='echo'
    elif $force; then
	echo 'PROBLEMS, but --force passed, would run:'
	prefix='echo'
    else
	echo 'PROBLEMS - would not run!'
	prefix='echo false'
    fi
else
    if $all_ok; then
	echo 'all OK, running publication!'
	prefix='running'
    elif $force; then
	echo 'PROBLEMS, but --force passed, going ahead!'
	prefix='running'
    else
	fail 'problems (see above), stopping'
    fi
fi

for p in $to_publish; do
    # shellcheck disable=SC2086 # we want to split on spaces in $prefix and $CARGO
    $prefix $CARGO publish -p "$p"
done

echo 'all published.'

tmp_trap_exit_finish_ok