fix(tmog-bin): follow the Linux release manifest
This commit is contained in:
1 parent
1ede739640
commit
9b77934e0e
5 files changed
+138
-21
No files matched your search
@@ -1044,6 +1044,9 @@ EOF
|
|||||||
if ! bash "$BUILD_ROOT/pkgbuilds/cua-driver-bin/.omarchy/upstream-test.sh"; then
|
if ! bash "$BUILD_ROOT/pkgbuilds/cua-driver-bin/.omarchy/upstream-test.sh"; then
|
||||||
failures=$((failures + 1))
|
failures=$((failures + 1))
|
||||||
fi
|
fi
|
||||||
|
if ! bash "$BUILD_ROOT/pkgbuilds/tmog-bin/.omarchy/upstream-test.sh"; then
|
||||||
|
failures=$((failures + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
if [[ "$failures" -eq 0 ]]; then
|
if [[ "$failures" -eq 0 ]]; then
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# tmog-bin - repackaging a vendor tarball from a versionless URL
|
# tmog-bin - repackaging a versioned vendor tarball
|
||||||
|
|
||||||
## Overview
|
## 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:
|
under a versioned name with a `.sha256` sidecar beside it:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
https://tmog.org/rtm/version.txt
|
https://tmog.org/rtm/downloads/release-linux.json
|
||||||
https://tmog.org/rtm/downloads/TaskManagerOG-<version>-linux-x86_64.tar.gz
|
https://tmog.org/rtm/downloads/TaskManagerOG-<version>-linux-x86_64.tar.gz
|
||||||
https://tmog.org/rtm/downloads/TaskManagerOG-<version>-linux-x86_64.tar.gz.sha256
|
https://tmog.org/rtm/downloads/TaskManagerOG-<version>-linux-x86_64.tar.gz.sha256
|
||||||
```
|
```
|
||||||
|
|
||||||
`downloads/release.json` -- the manifest the macOS updater verifies -- still
|
`.omarchy/upstream.sh` reads the version from the Linux x86_64 manifest,
|
||||||
describes the DMG only, so `.omarchy/upstream.sh` reads the version from
|
validating its schema, platform, architecture, and version. The shared
|
||||||
`version.txt` and the checksum from the sidecar, and checks that the sidecar
|
`version.txt` can advance before Linux artifacts are published (it announced
|
||||||
names the tarball it was asked about. The check costs two small requests and
|
1.0.1 while the Linux manifest and artifacts were still at 1.0.0).
|
||||||
never downloads the tarball.
|
|
||||||
|
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,
|
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
|
`/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
|
## Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
bash pkgbuilds/tmog-bin/.omarchy/upstream-test.sh
|
||||||
|
bin/sync-upstream self-test
|
||||||
bin/sync-upstream tmog-bin
|
bin/sync-upstream tmog-bin
|
||||||
bin/repo build --package tmog-bin
|
bin/repo build --package tmog-bin
|
||||||
```
|
```
|
||||||
Executable
+103
@@ -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 ]]
|
||||||
@@ -1,18 +1,21 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# TMOG publishes no manifest for its Linux builds -- release.json describes the
|
# The Linux x86_64 manifest supplies the version: the shared version.txt can
|
||||||
# macOS DMG only -- so the version comes from /rtm/version.txt. Each Linux
|
# advance before Linux ships. Its checksum describes the AppImage, so keep
|
||||||
# artifact is published under a versioned name with a `<artifact>.sha256`
|
# using the tarball's own <artifact>.sha256 sidecar for the package checksum.
|
||||||
# sidecar beside it, and that sidecar is the checksum reported here, so the
|
# The six-hourly check costs at most two tiny requests, never the tarball.
|
||||||
# six-hourly check costs two tiny requests and never the tarball itself.
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
BASE_URL="https://tmog.org/rtm"
|
BASE_URL="https://tmog.org/rtm"
|
||||||
|
|
||||||
current=$(grep -m1 '^pkgver=' PKGBUILD | cut -d= -f2- | tr -d "\"'")
|
current=$(grep -m1 '^pkgver=' PKGBUILD | cut -d= -f2- | tr -d "\"'")
|
||||||
|
|
||||||
version=$(curl -fsSL "$BASE_URL/version.txt" | tr -d '[:space:]')
|
manifest_url="$BASE_URL/downloads/release-linux.json"
|
||||||
if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
manifest=$(curl -fsSL "$manifest_url")
|
||||||
echo "Unusable version from $BASE_URL/version.txt: '$version'" >&2
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -22,12 +25,12 @@ if [[ $version == "$current" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# The sidecar names the file it describes; insisting on that name catches a
|
# 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
|
# sidecar left over from another release or architecture. Fetch separately so
|
||||||
# a file without a trailing newline leaves `read` short, which the check below
|
# a failed curl cannot be hidden by process substitution or a partial response.
|
||||||
# reports rather than letting set -e exit silently.
|
|
||||||
artifact="TaskManagerOG-${version}-linux-x86_64.tar.gz"
|
artifact="TaskManagerOG-${version}-linux-x86_64.tar.gz"
|
||||||
|
checksum=$(curl -fsSL "$BASE_URL/downloads/$artifact.sha256")
|
||||||
sha256="" name=""
|
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
|
if [[ ! $sha256 =~ ^[0-9a-f]{64}$ || ${name#\*} != "$artifact" ]]; then
|
||||||
echo "Unusable checksum for $artifact: '$sha256 $name'" >&2
|
echo "Unusable checksum for $artifact: '$sha256 $name'" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
# Omarchy already installs.
|
# Omarchy already installs.
|
||||||
#
|
#
|
||||||
# .omarchy/upstream.sh rewrites the pkgver and sha256 below when
|
# .omarchy/upstream.sh rewrites the pkgver and sha256 below when
|
||||||
# /rtm/version.txt moves, taking the checksum from the .sha256 sidecar tmog.org
|
# the Linux x86_64 release manifest moves, taking the checksum from the .sha256
|
||||||
# publishes beside each versioned tarball.
|
# sidecar tmog.org publishes beside each versioned tarball.
|
||||||
|
|
||||||
pkgname=tmog-bin
|
pkgname=tmog-bin
|
||||||
pkgver=1.0.0
|
pkgver=1.0.0
|
||||||
|
|||||||
Reference in new issue
Block a user