#!/bin/bash # The Gitea release record, against a stand-in for Gitea's API. # # Nothing here reaches the real Gitea. The stand-in keeps tags, releases # and assets in memory, answers the handful of calls tools/gitea-release # makes the way Gitea 1.27 answers them, and refuses any write that does # not carry the token. The questions are the ones that matter for a # permanent record: a tag is never moved, an asset's bytes are never # replaced, and the record only ever grows. set -uo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" WORK="$(mktemp -d)" SERVER_PID="" cleanup() { [[ -z "$SERVER_PID" ]] || kill "$SERVER_PID" 2>/dev/null rm -rf "$WORK" } trap cleanup EXIT passed=0 failed=0 check() { local label="$1" shift if "$@" >/dev/null 2>&1; then echo " ok $label" passed=$((passed + 1)) else echo " FAIL $label" failed=$((failed + 1)) fi } refuses() { ! "$@" } python3 "$ROOT/tests/fake-gitea.py" > "$WORK/port" 2>"$WORK/gitea.log" & SERVER_PID=$! for _ in $(seq 1 50); do [[ -s "$WORK/port" ]] && break sleep 0.1 done export GITEA_URL="http://127.0.0.1:$(cat "$WORK/port")" export GITEA_REPO=church/classroom export GITEA_TOKEN=not-a-real-token RELEASE="$ROOT/tools/gitea-release" A=$(printf 'a%.0s' {1..40}) B=$(printf 'b%.0s' {1..40}) printf 'the package\n' > "$WORK/ekklesia-classroom_0.9.1_amd64.deb" printf '# 0.9.1\n\nNotes.\n' > "$WORK/notes.md" echo "1. a release, created once, at one commit" check "no release yet is its own answer" \ bash -c "'$RELEASE' show v0.9.1; [[ \$? -eq 3 ]]" check "it is created at the commit named" \ "$RELEASE" create v0.9.1 "$A" "0.9.1" "$WORK/notes.md" --prerelease check "and its tag names that commit" \ bash -c "[[ \$(curl -fsS '$GITEA_URL/api/v1/repos/church/classroom/tags/v0.9.1' | python3 -c 'import json,sys; print(json.load(sys.stdin)[\"commit\"][\"sha\"])') == $A ]]" check "it is a pre-release until it is promoted" \ bash -c "api() { curl -fsS '$GITEA_URL/api/v1/repos/church/classroom'\$1; }; api /releases/tags/v0.9.1 | grep -q '\"prerelease\": true'" check "creating it again at the same commit changes nothing" \ "$RELEASE" create v0.9.1 "$A" "0.9.1" "$WORK/notes.md" --prerelease check "a tag is never moved to another commit" \ refuses "$RELEASE" create v0.9.1 "$B" "0.9.1" "$WORK/notes.md" check "nor is a tag that already exists taken over" \ refuses "$RELEASE" create v0.1.5 "$B" "0.1.5" "$WORK/notes.md" echo "2. assets: attached once, never replaced" check "the package is attached" \ "$RELEASE" upload v0.9.1 "$WORK/ekklesia-classroom_0.9.1_amd64.deb" check "and reads back as the same bytes" \ bash -c "'$RELEASE' download v0.9.1 ekklesia-classroom_0.9.1_amd64.deb '$WORK/back.deb' \ && cmp -s '$WORK/back.deb' '$WORK/ekklesia-classroom_0.9.1_amd64.deb'" check "the same file again is left alone, and is not an error" \ bash -c "'$RELEASE' upload v0.9.1 '$WORK/ekklesia-classroom_0.9.1_amd64.deb' | grep -q 'left alone'" mkdir -p "$WORK/rebuilt" printf 'a different build\n' > "$WORK/rebuilt/ekklesia-classroom_0.9.1_amd64.deb" check "different bytes under the same name are refused" \ refuses "$RELEASE" upload v0.9.1 "$WORK/rebuilt/ekklesia-classroom_0.9.1_amd64.deb" check "and the published bytes are still the first ones" \ bash -c "'$RELEASE' download v0.9.1 ekklesia-classroom_0.9.1_amd64.deb '$WORK/back2.deb' \ && cmp -s '$WORK/back2.deb' '$WORK/ekklesia-classroom_0.9.1_amd64.deb'" check "an asset the release does not have is refused, not invented" \ refuses "$RELEASE" download v0.9.1 nothing.deb "$WORK/nothing" curl -fsS "$GITEA_URL/test/tamper/v0.9.1/ekklesia-classroom_0.9.1_amd64.deb" >/dev/null check "an asset changed by hand is caught at the next upload" \ refuses "$RELEASE" upload v0.9.1 "$WORK/ekklesia-classroom_0.9.1_amd64.deb" echo "3. the record only grows" check "a line is recorded" \ "$RELEASE" record v0.9.1 "published to Preview (canary)" check "and another" \ "$RELEASE" record v0.9.1 "promoted to Stable" check "the notes, the creation line and both records are all there, in order" \ bash -c "curl -fsS '$GITEA_URL/api/v1/repos/church/classroom/releases/tags/v0.9.1' \ | python3 -c 'import json,sys b = json.load(sys.stdin)[\"body\"] order = [b.index(t) for t in (\"Notes.\", \"## Record\", \"release created at\", \"Preview (canary)\", \"promoted to Stable\")] assert order == sorted(order), order assert b.count(\"## Record\") == 1'" check "the notes and record read back as text" \ bash -c "'$RELEASE' notes v0.9.1 | grep -q 'Preview (canary)'" check "and asking for a release there is none of is refused" \ refuses "$RELEASE" notes v0.0.0 check "promoted, it is no longer a pre-release" \ bash -c "'$RELEASE' stable v0.9.1 && curl -fsS '$GITEA_URL/api/v1/repos/church/classroom/releases/tags/v0.9.1' | grep -q '\"prerelease\": false'" echo "4. credentials" check "a write without the token is refused by Gitea, and reported" \ refuses env GITEA_TOKEN= "$RELEASE" record v0.9.1 "nobody" check "the token never appears in anything it prints" \ bash -c "! { '$RELEASE' show v0.9.1; '$RELEASE' record v0.9.1 x; '$RELEASE' upload v0.9.1 '$WORK/rebuilt/ekklesia-classroom_0.9.1_amd64.deb'; } 2>&1 | grep -q not-a-real-token" check "nothing works without knowing which Gitea" \ refuses env -u GITEA_URL -u GITHUB_SERVER_URL "$RELEASE" show v0.9.1 echo echo "$passed passed, $failed failed" [[ $failed -eq 0 ]]