From 9b77934e0e809259c8b23b74087f00b0057e9a2c Mon Sep 17 00:00:00 2001 From: Dylan <107251949+dyl-joseph@users.noreply.github.com> Date: Fri, 2 Oct 2026 08:19:58 -0500 Subject: [PATCH] fix(tmog-bin): follow the Linux release manifest --- bin/sync-upstream | 3 + pkgbuilds/tmog-bin/.omarchy/README.md | 22 ++-- pkgbuilds/tmog-bin/.omarchy/upstream-test.sh | 103 +++++++++++++++++++ pkgbuilds/tmog-bin/.omarchy/upstream.sh | 27 ++--- pkgbuilds/tmog-bin/PKGBUILD | 4 +- 5 files changed, 138 insertions(+), 21 deletions(-) create mode 100755 pkgbuilds/tmog-bin/.omarchy/upstream-test.sh diff --git a/bin/sync-upstream b/bin/sync-upstream index 5aae830..68b691f 100755 --- a/bin/sync-upstream +++ b/bin/sync-upstream @@ -1044,6 +1044,9 @@ EOF if ! bash "$BUILD_ROOT/pkgbuilds/cua-driver-bin/.omarchy/upstream-test.sh"; then failures=$((failures + 1)) fi + if ! bash "$BUILD_ROOT/pkgbuilds/tmog-bin/.omarchy/upstream-test.sh"; then + failures=$((failures + 1)) + fi echo "" if [[ "$failures" -eq 0 ]]; then diff --git a/pkgbuilds/tmog-bin/.omarchy/README.md b/pkgbuilds/tmog-bin/.omarchy/README.md index a97049d..3295532 100644 --- a/pkgbuilds/tmog-bin/.omarchy/README.md +++ b/pkgbuilds/tmog-bin/.omarchy/README.md @@ -1,4 +1,4 @@ -# tmog-bin - repackaging a vendor tarball from a versionless URL +# tmog-bin - repackaging a versioned vendor tarball ## Overview @@ -42,16 +42,22 @@ Since 1.0.0 the site lives under `/rtm/`, and each Linux artifact is published under a versioned name with a `.sha256` sidecar beside it: ```text -https://tmog.org/rtm/version.txt +https://tmog.org/rtm/downloads/release-linux.json https://tmog.org/rtm/downloads/TaskManagerOG--linux-x86_64.tar.gz https://tmog.org/rtm/downloads/TaskManagerOG--linux-x86_64.tar.gz.sha256 ``` -`downloads/release.json` -- the manifest the macOS updater verifies -- still -describes the DMG only, so `.omarchy/upstream.sh` reads the version from -`version.txt` and the checksum from the sidecar, and checks that the sidecar -names the tarball it was asked about. The check costs two small requests and -never downloads the tarball. +`.omarchy/upstream.sh` reads the version from the Linux x86_64 manifest, +validating its schema, platform, architecture, and version. The shared +`version.txt` can advance before Linux artifacts are published (it announced +1.0.1 while the Linux manifest and artifacts were still at 1.0.0). + +The Linux manifest's checksum describes the AppImage, not the tarball, so the +hook still reads the tarball's checksum from its own sidecar and checks that +the sidecar names the requested artifact. Missing or invalid manifests and +checksums fail the sync; there is no fallback to the shared version or an +unchecked download. An unchanged Linux version costs one small request; an +update costs two, and neither downloads the tarball. Up to 0.1.1 every release was served from one versionless path, `/downloads/TMOG-Task-Manager-Linux-x86_64.tar.gz`, and the hook downloaded it @@ -67,6 +73,8 @@ moving to `source_x86_64`/`source_aarch64` and reporting both keys. ## Testing ```bash +bash pkgbuilds/tmog-bin/.omarchy/upstream-test.sh +bin/sync-upstream self-test bin/sync-upstream tmog-bin bin/repo build --package tmog-bin ``` diff --git a/pkgbuilds/tmog-bin/.omarchy/upstream-test.sh b/pkgbuilds/tmog-bin/.omarchy/upstream-test.sh new file mode 100755 index 0000000..3626391 --- /dev/null +++ b/pkgbuilds/tmog-bin/.omarchy/upstream-test.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# Offline fixtures, also run by bin/sync-upstream self-test. Needs bash and jq. +set -euo pipefail +hook="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/upstream.sh" +fixture_dir=$(mktemp -d) +trap 'rm -rf "$fixture_dir"' EXIT +cd "$fixture_dir" +printf 'pkgver=1.0.0\npkgrel=1\n' > PKGBUILD +cp PKGBUILD PKGBUILD.before + +failures=0 +check() { + if [[ "$2" == "$3" ]]; then + echo " ok: $1" + else + echo " FAIL: $1 (expected '$2', got '$3')" + failures=$((failures + 1)) + fi +} + +curl() { + local url="${!#}" + printf '%s\n' "$url" >> "$REQUESTS" + case "$url" in + https://tmog.org/rtm/downloads/release-linux.json) + printf '%s' "$MANIFEST" + [[ "$FAIL_FETCH" != manifest ]] + ;; + https://tmog.org/rtm/downloads/TaskManagerOG-1.0.1-linux-x86_64.tar.gz.sha256) + printf '%s' "$CHECKSUM" + [[ "$FAIL_FETCH" != checksum ]] + ;; + *) echo "unexpected fixture URL: $url" >&2; return 22 ;; + esac +} +export -f curl +export MANIFEST CHECKSUM FAIL_FETCH REQUESTS="$fixture_dir/requests" +FAIL_FETCH='' +sum=$(printf 'a%.0s' {1..64}) +appimage_sum=$(printf 'b%.0s' {1..64}) +artifact=TaskManagerOG-1.0.1-linux-x86_64.tar.gz +current_manifest=$(jq -cn --arg sha256 "$appimage_sum" \ + '{schemaVersion: 1, platform: "Linux", architecture: "x86_64", version: "1.0.0", sha256: $sha256}') +new_manifest=$(jq -c '.version = "1.0.1"' <<<"$current_manifest") +CHECKSUM="$sum $artifact" + +run_hook() { + : > "$REQUESTS" + status=0 + out=$(bash "$hook" 2>stderr) || status=$? + check 'hook leaves the recipe untouched' yes "$(cmp -s PKGBUILD PKGBUILD.before && echo yes || echo no)" +} +expect_failure() { + run_hook + check "$1 fails closed" yes "$([[ "$status" != 0 ]] && echo yes || echo no)" + check "$1 emits no update" '' "$out" +} + +echo 'TMOG Linux release hook:' +# Regression: the shared version.txt can say 1.0.1 while Linux is still 1.0.0. +# Any attempt to fetch that shared feed (or a tarball) is rejected by curl(). +MANIFEST="$current_manifest" +run_hook +check 'unchanged Linux release succeeds' 0 "$status" +check 'shared feed cannot advance Linux' '{}' "$out" +check 'unchanged release requests only its manifest' \ + 'https://tmog.org/rtm/downloads/release-linux.json' "$(cat "$REQUESTS")" + +MANIFEST="$new_manifest" +run_hook +check 'new Linux release succeeds without trailing checksum newline' 0 "$status" +check 'Linux version is reported' 1.0.1 "$(jq -r '.pkgver' <<<"$out")" +check 'tarball checksum, not AppImage checksum, is reported' "$sum" "$(jq -r '.sha256sums.any[0]' <<<"$out")" +check 'update requests only the manifest and its tarball sidecar' \ + "$(printf '%s\n' 'https://tmog.org/rtm/downloads/release-linux.json' "https://tmog.org/rtm/downloads/$artifact.sha256")" "$(cat "$REQUESTS")" + +CHECKSUM="$sum *$artifact"$'\n' +run_hook +check 'binary-mode sidecar is accepted' 0 "$status" + +for filter in '.schemaVersion = 2' '.platform = "macOS"' \ + '.architecture = "aarch64"' 'del(.architecture)' '.version = 1' \ + '.version = "1.0.1-rc1"' '.version = "1.0.1\n"' 'del(.version)'; do + MANIFEST=$(jq -c "$filter" <<<"$new_manifest") + expect_failure "invalid manifest ($filter)" + check 'invalid manifest never requests a checksum' 1 "$(wc -l < "$REQUESTS" | tr -d ' ')" +done +for MANIFEST in '' 'not json' 'null' '[]'; do + expect_failure "invalid manifest body ($MANIFEST)" +done + +MANIFEST="$new_manifest" +FAIL_FETCH=manifest +expect_failure 'failed manifest fetch with a valid-looking partial body' +FAIL_FETCH=checksum +expect_failure 'failed checksum fetch with a valid-looking partial body' +FAIL_FETCH='' +for CHECKSUM in '' "invalid $artifact" "$sum TaskManagerOG-1.0.0-linux-x86_64.tar.gz" \ + "$sum TaskManagerOG-1.0.1-linux-aarch64.tar.gz" "$sum $artifact.extra"; do + expect_failure 'missing or invalid tarball checksum' +done + +[[ "$failures" == 0 ]] diff --git a/pkgbuilds/tmog-bin/.omarchy/upstream.sh b/pkgbuilds/tmog-bin/.omarchy/upstream.sh index 55a76c0..9f2fa54 100755 --- a/pkgbuilds/tmog-bin/.omarchy/upstream.sh +++ b/pkgbuilds/tmog-bin/.omarchy/upstream.sh @@ -1,18 +1,21 @@ #!/bin/bash -# TMOG publishes no manifest for its Linux builds -- release.json describes the -# macOS DMG only -- so the version comes from /rtm/version.txt. Each Linux -# artifact is published under a versioned name with a `.sha256` -# sidecar beside it, and that sidecar is the checksum reported here, so the -# six-hourly check costs two tiny requests and never the tarball itself. +# The Linux x86_64 manifest supplies the version: the shared version.txt can +# advance before Linux ships. Its checksum describes the AppImage, so keep +# using the tarball's own .sha256 sidecar for the package checksum. +# The six-hourly check costs at most two tiny requests, never the tarball. set -euo pipefail BASE_URL="https://tmog.org/rtm" current=$(grep -m1 '^pkgver=' PKGBUILD | cut -d= -f2- | tr -d "\"'") -version=$(curl -fsSL "$BASE_URL/version.txt" | tr -d '[:space:]') -if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Unusable version from $BASE_URL/version.txt: '$version'" >&2 +manifest_url="$BASE_URL/downloads/release-linux.json" +manifest=$(curl -fsSL "$manifest_url") +if ! version=$(jq -er ' + select(.schemaVersion == 1 and .platform == "Linux" and .architecture == "x86_64") + | .version | select(type == "string" and test("\\A[0-9]+\\.[0-9]+\\.[0-9]+\\z")) +' <<<"$manifest"); then + echo "Unusable Linux x86_64 release manifest from $manifest_url" >&2 exit 1 fi @@ -22,12 +25,12 @@ if [[ $version == "$current" ]]; then fi # The sidecar names the file it describes; insisting on that name catches a -# sidecar left over from another release or architecture. A failed download or -# a file without a trailing newline leaves `read` short, which the check below -# reports rather than letting set -e exit silently. +# sidecar left over from another release or architecture. Fetch separately so +# a failed curl cannot be hidden by process substitution or a partial response. artifact="TaskManagerOG-${version}-linux-x86_64.tar.gz" +checksum=$(curl -fsSL "$BASE_URL/downloads/$artifact.sha256") sha256="" name="" -read -r sha256 name < <(curl -fsSL "$BASE_URL/downloads/$artifact.sha256") || true +read -r sha256 name <<<"$checksum" if [[ ! $sha256 =~ ^[0-9a-f]{64}$ || ${name#\*} != "$artifact" ]]; then echo "Unusable checksum for $artifact: '$sha256 $name'" >&2 exit 1 diff --git a/pkgbuilds/tmog-bin/PKGBUILD b/pkgbuilds/tmog-bin/PKGBUILD index b239771..68c63fe 100644 --- a/pkgbuilds/tmog-bin/PKGBUILD +++ b/pkgbuilds/tmog-bin/PKGBUILD @@ -6,8 +6,8 @@ # Omarchy already installs. # # .omarchy/upstream.sh rewrites the pkgver and sha256 below when -# /rtm/version.txt moves, taking the checksum from the .sha256 sidecar tmog.org -# publishes beside each versioned tarball. +# the Linux x86_64 release manifest moves, taking the checksum from the .sha256 +# sidecar tmog.org publishes beside each versioned tarball. pkgname=tmog-bin pkgver=1.0.0