Public Access
Read the release id out of the front of the response, not the back
The nightly release was created and the step said it had not been:
Gitea accepted the release call and returned no id:
{"id":1,"tag_name":"nightly",…,"author":{"id":-2,…},"assets":[]}
`sed -n 's/.*"id":\([0-9]*\).*/\1/p'` — the leading .* is greedy, so it walked past the release's own id
to the last "id": in the document, which belongs to the embedded author object and is -2. [0-9]* then
matched no digits at all and the answer was the empty string. The release is real; only the reading of
it was wrong, which is why the page exists and carries nothing but source tarballs.
It broke both readings and the other one silently. The existing-release lookup got the same empty id, so
the delete never fired, so the next run would have failed to create a release for a tag that already had
one — a rolling channel that works exactly once. Both now go through one function, and grep matching
left to right with [0-9]+ cannot reach the author's -2 at all.
And the step now asks for the release back and checks its own uploads are on it. The failure this
channel is exposed to is a release that exists and carries nothing: a phone reads that as a feed it can
never update from and a person reads it as a page offering source tarballs. The run before this one left
exactly that behind, and it would have reported success for every upload it never made.
Checked against the response body the failing run printed: the old expression answers empty, the new one
answers 1, and the verification rejects that release and accepts one with an asset on it. The bad
release is not cleaned up by hand — the next run on main deletes and recreates it, which is what the
rolling tag does anyway.
This commit is contained in:
@@ -489,14 +489,40 @@ jobs:
|
||||
api="$FORGE/api/v1/repos/$REPO"
|
||||
auth="Authorization: token $TOKEN"
|
||||
|
||||
# ◆ THE FIRST "id" IN THE DOCUMENT, AND NOT THE LAST ONE A GREEDY MATCH LANDS ON.
|
||||
#
|
||||
# This was `sed -n 's/.*"id":\([0-9]*\).*/\1/p'`, and the leading .* is greedy, so it walked past
|
||||
# the release's own id to the last "id": in the response — which belongs to the embedded author
|
||||
# object and is -2. [0-9]* then matched no digits at all and the answer was the empty string. A
|
||||
# release had been created and the step failed saying none had.
|
||||
#
|
||||
# It broke both readings, and the other one silently: the existing-release lookup below got the
|
||||
# same empty id, so the delete never fired, so the second run would have failed to create a
|
||||
# release for a tag that already had one. A rolling channel that works exactly once.
|
||||
#
|
||||
# grep matches left to right and [0-9]\+ needs a digit, so the author's -2 cannot match at all
|
||||
# and head -1 takes the release's. jq would say this in four characters and is not on this
|
||||
# runner; anything parsing JSON with a regex should say which assumption it is making, and this
|
||||
# one is: the release id is the first "id": with digits after it.
|
||||
release_id() {
|
||||
grep -oE '"id":[0-9]+' | head -1 | cut -d: -f2
|
||||
}
|
||||
|
||||
# Deleted and recreated rather than updated in place. A rolling tag has to move, and moving one
|
||||
# through this API is two calls with no atomic form either way — so the shape with the fewest
|
||||
# states is to remove both and make them again. The window where no nightly exists is a few
|
||||
# seconds and the client's answer to it is the same as to an unreachable forge: try later.
|
||||
existing="$(curl -fsS -H "$auth" "$api/releases/tags/nightly" 2>/dev/null || true)"
|
||||
if [ -n "$existing" ]; then
|
||||
id="$(printf '%s' "$existing" | sed -n 's/.*"id":\([0-9]*\).*/\1/p' | head -1)"
|
||||
[ -n "$id" ] && curl -fsS -X DELETE -H "$auth" "$api/releases/$id" >/dev/null || true
|
||||
id="$(printf '%s' "$existing" | release_id)"
|
||||
if [ -n "$id" ]; then
|
||||
echo "Removing the previous nightly release $id"
|
||||
curl -fsS -X DELETE -H "$auth" "$api/releases/$id" >/dev/null || true
|
||||
else
|
||||
echo "A nightly release exists and its id could not be read:" >&2
|
||||
printf '%s\n' "$existing" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
curl -fsS -X DELETE -H "$auth" "$api/tags/nightly" >/dev/null 2>&1 || true
|
||||
|
||||
@@ -505,7 +531,7 @@ jobs:
|
||||
"$GITHUB_SHA" "$VERSION" "$GITHUB_SHA")" \
|
||||
"$api/releases")"
|
||||
|
||||
release="$(printf '%s' "$created" | sed -n 's/.*"id":\([0-9]*\).*/\1/p' | head -1)"
|
||||
release="$(printf '%s' "$created" | release_id)"
|
||||
if [ -z "$release" ]; then
|
||||
echo "Gitea accepted the release call and returned no id:" >&2
|
||||
printf '%s\n' "$created" >&2
|
||||
@@ -515,14 +541,31 @@ jobs:
|
||||
# The APK first and the manifest last, which is the ordering the client depends on: it reads the
|
||||
# manifest and then fetches what the manifest names, so a manifest published before its APK is a
|
||||
# few seconds in which every phone is told to download something that is not there yet.
|
||||
names=""
|
||||
for file in "$STAGED"/*.apk "$STAGED"/android-nightly.json; do
|
||||
echo "Uploading $(basename "$file")"
|
||||
name="$(basename "$file")"
|
||||
echo "Uploading $name ($(wc -c < "$file") bytes)"
|
||||
curl -fsS -X POST -H "$auth" \
|
||||
-F "attachment=@$file" \
|
||||
"$api/releases/$release/assets?name=$(basename "$file")" >/dev/null
|
||||
"$api/releases/$release/assets?name=$name" >/dev/null
|
||||
names="$names $name"
|
||||
done
|
||||
|
||||
echo "Published nightly $VERSION"
|
||||
# Asked for back rather than assumed, because the failure this whole channel is exposed to is a
|
||||
# release that exists and carries nothing — which is what a phone sees as a feed it can read and
|
||||
# never update from, and what a person sees as a release page offering source tarballs. That is
|
||||
# exactly what the run before this one left behind, and it reported success for every upload it
|
||||
# never made.
|
||||
published="$(curl -fsS -H "$auth" "$api/releases/$release")"
|
||||
for name in $names; do
|
||||
if ! printf '%s' "$published" | grep -qF "\"name\":\"$name\""; then
|
||||
echo "The release was created but $name is not on it:" >&2
|
||||
printf '%s\n' "$published" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Published nightly $VERSION with$names"
|
||||
|
||||
image:
|
||||
name: api image
|
||||
|
||||
Reference in New Issue
Block a user