diff --git a/README.md b/README.md index 2f818c3..00767e6 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ The app shell is complete and every game in the catalogue is playable end to end | | | | --- | --- | -| **Cards** | Euchre, Kaiser, President, Golf, Wizard, Crazy 8s, Cribbage | -| **Board** | Sequence, Chess, Checkers, Backgammon, Mastermind, Nine Men's Morris, Pirates and Bulgars, Ta Yü | +| **Cards** | Euchre, Kaiser, President, Golf, Wizard, Crazy 8s, Cribbage, Hearts, Klondike, FreeCell, Spider, Pyramid | +| **Table** | Sequence, Chess, Checkers, Backgammon, Mastermind, Nine Men's Morris, Peg Solitaire, Yahtzee, Pirates and Bulgars, Ta Yü | Nothing is marked *Coming soon* at the moment, because nothing is waiting. The machinery for it is still there and still tested: a game listed in `GameCatalog` diff --git a/docs/CI.md b/docs/CI.md index 80a623e..3a22c9d 100644 --- a/docs/CI.md +++ b/docs/CI.md @@ -97,10 +97,15 @@ GITEA_TOKEN=… ./scripts/publish-release.sh v1.4.1001 app/build/outputs/apk/deb ``` The script takes ` [target-sha]`, creates the -release through `POST /api/v1/repos/{owner}/{repo}/releases`, and attaches the -APK through `POST …/releases/{id}/assets` — which is the upload route Gitea's -Swagger declares for this instance (1.27.3). If the tag already exists it -publishes into the existing release instead of failing, so a retry is safe. +release through `POST /api/v1/repos/{owner}/{repo}/releases`, attaches the APK +through `POST …/releases/{id}/assets` — which is the upload route Gitea's +Swagger declares for this instance (1.27.3) — and then reads the release back +and corrects its state if it did not stick. That last step is not decoration: +this instance has been observed to accept `draft: false` at create time and +store the release as a draft after the attachment lands, and a draft is +invisible to the updater, so the script verifies rather than assumes. If the +tag already exists it publishes into the existing release instead of failing, +so a retry is safe. ## What the in-app updater reads diff --git a/scripts/publish-release.sh b/scripts/publish-release.sh index a41f74b..8ff208a 100755 --- a/scripts/publish-release.sh +++ b/scripts/publish-release.sh @@ -86,6 +86,10 @@ fi id="$(grep -o '"id":[0-9]*' "$tmp/create.json" | head -n1 | tr -dc '0-9' || true)" [ -n "$id" ] || { echo "publish-release: no release id in response" >&2; cat "$tmp/create.json" >&2; echo >&2; exit 1; } +# Attach the APK first, then check the stored state: uploading has been +# observed to leave a freshly created release as a draft, whatever the create +# response said, so the check has to be the last thing that happens rather +# than a step in the middle. code="$(curl -sS -o "$tmp/asset.json" -w '%{http_code}' -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ -F "attachment=@${apk};filename=${apk_name}" \ @@ -98,4 +102,25 @@ if [ "$code" != "201" ] && [ "$code" != "200" ]; then exit 1 fi +# Read back what the database actually stored before declaring success. A draft +# is invisible to the updater — exactly what a channel must not silently become +# — and this instance has been seen to report one as published at create time +# and store it as a draft by the time it is read. +curl -sS -o "$tmp/stored.json" -H "Authorization: token ${GITEA_TOKEN}" "$api/releases/${id}" +if grep -q '"draft":true' "$tmp/stored.json" || + ! grep -q "\"prerelease\":${prerelease}" "$tmp/stored.json"; then + state="$(curl -sS -o "$tmp/fix.json" -w '%{http_code}' -X PATCH \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"draft\":false,\"prerelease\":${prerelease}}" \ + "$api/releases/${id}")" + if [ "$state" != "200" ]; then + echo "publish-release: release ${tag} is stored with the wrong state (HTTP ${state})" >&2 + cat "$tmp/fix.json" >&2 + echo >&2 + exit 1 + fi + echo "publish-release: corrected the stored state of ${tag} (it was saved as a draft)" +fi + echo "publish-release: ${tag} -> release ${id} on ${api#*/repos/}, asset ${apk_name}"