Anchor the update channel tag, and stop shipping a duplicate AppImage #52
@@ -335,7 +335,6 @@ jobs:
|
||||
run: |
|
||||
mkdir -p artifacts
|
||||
cp app/src-tauri/target/release/bundle/appimage/*.AppImage artifacts/ 2>/dev/null || true
|
||||
cp app/src-tauri/target/release/bundle/appimage/*.zsync artifacts/ 2>/dev/null || true
|
||||
ls -la artifacts/
|
||||
|
||||
# Assets, not workflow artifacts — see the note at the top of this file.
|
||||
|
||||
@@ -200,8 +200,10 @@ jobs:
|
||||
- name: Collect artifacts
|
||||
run: |
|
||||
mkdir -p artifacts
|
||||
# The versioned AppImage only. The update channel's copy lives in
|
||||
# bundle/appimage/update-channel/ precisely so this glob cannot pick
|
||||
# it up and publish an 80 MB duplicate under a second name.
|
||||
cp app/src-tauri/target/release/bundle/appimage/*.AppImage artifacts/ 2>/dev/null || true
|
||||
cp app/src-tauri/target/release/bundle/appimage/*.zsync artifacts/ 2>/dev/null || true
|
||||
ls -la artifacts/
|
||||
|
||||
- name: Upload to Gitea release
|
||||
@@ -286,7 +288,11 @@ jobs:
|
||||
if: gitea.event_name == 'push'
|
||||
env:
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
run: bash scripts/publish-update-channel.sh artifacts
|
||||
GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
GITEA_SHA: ${{ gitea.sha }}
|
||||
run: |
|
||||
bash scripts/publish-update-channel.sh \
|
||||
app/src-tauri/target/release/bundle/appimage/update-channel
|
||||
|
||||
build-macos:
|
||||
runs-on: macos-latest
|
||||
|
||||
@@ -91,6 +91,11 @@ HOOK="apprun-hooks/triple-c-wayland-fallback.sh"
|
||||
APPIMAGE_TOOL_URL="https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||
|
||||
APP_ID="com.triple-c.desktop"
|
||||
# The channel pair lives in its own directory. Left beside the versioned image
|
||||
# they are picked up by the release job's `*.AppImage` glob, and every release
|
||||
# then carries an eighty-megabyte byte-identical duplicate under a second name
|
||||
# — which is exactly as confusing on a downloads page as it sounds.
|
||||
CHANNEL_DIR="update-channel"
|
||||
STABLE_NAME="Triple-C_x86_64.AppImage"
|
||||
UPDATE_TAG="linux-latest"
|
||||
UPDATE_INFO="zsync|https://github.com/shadowdao/triple-c/releases/download/${UPDATE_TAG}/${STABLE_NAME}.zsync"
|
||||
@@ -211,13 +216,18 @@ chmod +x "$tool"
|
||||
|
||||
# --appimage-extract-and-run: CI runners generally have no FUSE.
|
||||
# -u embeds the update string and writes "$STABLE_NAME.zsync" beside the image.
|
||||
mkdir -p "$CHANNEL_DIR"
|
||||
ARCH=x86_64 "$tool" --appimage-extract-and-run \
|
||||
-u "$UPDATE_INFO" "$root" "$STABLE_NAME" >/dev/null
|
||||
chmod +x "$STABLE_NAME"
|
||||
-u "$UPDATE_INFO" "$root" "$CHANNEL_DIR/$STABLE_NAME" >/dev/null
|
||||
chmod +x "$CHANNEL_DIR/$STABLE_NAME"
|
||||
|
||||
# The versioned name is what the per-version release publishes; the stable one
|
||||
# and its .zsync go to the rolling tag. Same bytes, two names.
|
||||
cp "$STABLE_NAME" "$appimage"
|
||||
# and its .zsync go to the rolling tag. Same bytes, two names, two places.
|
||||
# zsyncmake writes the .zsync into the working directory, not beside the image
|
||||
# it describes, so it has to be collected rather than assumed in place.
|
||||
[ -e "$STABLE_NAME.zsync" ] && mv "$STABLE_NAME.zsync" "$CHANNEL_DIR/"
|
||||
|
||||
cp "$CHANNEL_DIR/$STABLE_NAME" "$appimage"
|
||||
chmod +x "$appimage"
|
||||
|
||||
# The guards are the test. Each one is a way the repack could look like it
|
||||
@@ -245,13 +255,18 @@ grep -q "^Categories=.\+" "$out"/*.desktop || fail "Categories is still empty."
|
||||
# the URL it fetched the .zsync from. That is exactly why the output is named
|
||||
# for the fixed tag: a versioned name here resolves to the build the client
|
||||
# already has.
|
||||
[ -e "$STABLE_NAME" ] || fail "the stable-named image is missing."
|
||||
[ -e "$STABLE_NAME.zsync" ] || fail "appimagetool wrote no $STABLE_NAME.zsync."
|
||||
[ -e "$CHANNEL_DIR/$STABLE_NAME" ] || fail "the stable-named image is missing."
|
||||
[ -e "$CHANNEL_DIR/$STABLE_NAME.zsync" ] || fail "appimagetool wrote no .zsync."
|
||||
|
||||
readelf -p .upd_info "$STABLE_NAME" 2>/dev/null | grep -q "$UPDATE_TAG" \
|
||||
readelf -p .upd_info "$CHANNEL_DIR/$STABLE_NAME" 2>/dev/null | grep -q "$UPDATE_TAG" \
|
||||
|| fail "the image carries no update information for the $UPDATE_TAG tag."
|
||||
grep -aq "^Filename: $STABLE_NAME$" "$STABLE_NAME.zsync" \
|
||||
grep -aq "^Filename: $STABLE_NAME$" "$CHANNEL_DIR/$STABLE_NAME.zsync" \
|
||||
|| fail "the .zsync names something other than $STABLE_NAME."
|
||||
|
||||
echo "OK: $appimage prefers the host $LIB (fallback kept), carries AppStream"
|
||||
echo " metadata, and updates from the $UPDATE_TAG tag via $STABLE_NAME.zsync."
|
||||
# The versioned release must carry one AppImage, not two. This is the guard
|
||||
# for the duplicate that shipped in 0.4.20 and 0.4.21.
|
||||
count="$(ls -1 *.AppImage 2>/dev/null | wc -l)"
|
||||
[ "$count" = "1" ] || fail "expected 1 AppImage beside the release, found $count."
|
||||
|
||||
echo "OK: $appimage prefers the host $LIB (fallback kept) and carries AppStream"
|
||||
echo " metadata. Channel pair in $CHANNEL_DIR/, updating from the $UPDATE_TAG tag."
|
||||
|
||||
@@ -17,7 +17,22 @@
|
||||
# It writes to GitHub rather than Gitea because that mirror is where updates
|
||||
# are pulled from. Needs GH_PAT with contents write on the mirror.
|
||||
#
|
||||
# Usage: GH_PAT=... publish-update-channel.sh <directory holding the artifacts>
|
||||
# **The tag has to exist in Gitea, not just on GitHub, and that is the whole
|
||||
# reason this script touches Gitea at all.** Gitea push-mirrors this repo to
|
||||
# GitHub, and a mirror push deletes remote refs that have no local counterpart.
|
||||
# A tag created only by GitHub's release API therefore survives until the next
|
||||
# mirror run and then vanishes — which is exactly what happened to 0.4.20 and
|
||||
# 0.4.21: the release was created and both URLs verified 200 at 00:38, and the
|
||||
# 13:04 mirror deleted the tag, leaving every installed copy checking a 404.
|
||||
# Versioned tags never had this problem because `create-tag` creates them in
|
||||
# Gitea first. So does this one, now, and before the GitHub release rather than
|
||||
# after, so there is no window where the two disagree.
|
||||
#
|
||||
# Note what this means for verification: publishing correctly is not evidence
|
||||
# the channel still works hours later. The Gitea tag is what makes it durable,
|
||||
# so its absence is treated as a failure rather than a warning.
|
||||
#
|
||||
# Usage: GH_PAT=... GITEA_TOKEN=... GITEA_SHA=... publish-update-channel.sh <dir>
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -26,7 +41,12 @@ TAG="linux-latest"
|
||||
API="https://api.github.com/repos/$REPO"
|
||||
ASSETS=("Triple-C_x86_64.AppImage" "Triple-C_x86_64.AppImage.zsync")
|
||||
|
||||
GITEA_API="${GITEA_API:-https://repo.anhonesthost.net/api/v1}"
|
||||
GITEA_REPO="${GITEA_REPO:-CyberCoveLLC/Triple-C}"
|
||||
|
||||
: "${GH_PAT:?GH_PAT is required to publish the update channel}"
|
||||
: "${GITEA_TOKEN:?GITEA_TOKEN is required to anchor the $TAG tag against the mirror}"
|
||||
: "${GITEA_SHA:?GITEA_SHA is required to point the $TAG tag at this build}"
|
||||
dir="${1:?usage: publish-update-channel.sh <artifacts directory>}"
|
||||
cd "$dir"
|
||||
|
||||
@@ -35,6 +55,21 @@ for asset in "${ASSETS[@]}"; do
|
||||
done
|
||||
|
||||
gh() { curl -sf -H "Authorization: Bearer $GH_PAT" -H "Accept: application/vnd.github+json" "$@"; }
|
||||
tea() { curl -sf -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" "$@"; }
|
||||
|
||||
# Anchor the tag in Gitea first — see the header. Moved rather than left
|
||||
# alone: it has to name this build, and the mirror will carry whatever Gitea
|
||||
# holds over the top of GitHub's copy.
|
||||
echo "==> Anchoring the $TAG tag in Gitea at ${GITEA_SHA:0:9}"
|
||||
tea -X DELETE "$GITEA_API/repos/$GITEA_REPO/tags/$TAG" >/dev/null 2>&1 || true
|
||||
tea -X POST "$GITEA_API/repos/$GITEA_REPO/tags" \
|
||||
-d "{\"tag_name\": \"$TAG\", \"target\": \"$GITEA_SHA\", \"message\": \"Rolling Linux update channel\"}" \
|
||||
>/dev/null
|
||||
|
||||
# Not best-effort. Without this tag the mirror removes GitHub's and the
|
||||
# channel dies silently somewhere between now and four hours from now.
|
||||
tea "$GITEA_API/repos/$GITEA_REPO/tags/$TAG" >/dev/null 2>&1 \
|
||||
|| { echo "FAILED: the $TAG tag does not exist in Gitea; the mirror would delete GitHub's copy." >&2; exit 1; }
|
||||
|
||||
echo "==> Looking for the $TAG release"
|
||||
release="$(gh "$API/releases/tags/$TAG" 2>/dev/null || true)"
|
||||
@@ -92,4 +127,4 @@ for asset in "${ASSETS[@]}"; do
|
||||
echo " $code $url"
|
||||
done
|
||||
|
||||
echo "OK: $TAG updated."
|
||||
echo "OK: $TAG updated, and anchored in Gitea so the mirror preserves it."
|
||||
|
||||
Reference in New Issue
Block a user