feat(launcher): script to replace launcher-only on legacy Gitea release
- gitea-replace-launcher-only.sh: swap Fractured-Launcher* + yml without wiping MPQs - Only remove latest.yml / latest-linux.yml if a replacement exists in dist/ - README: bridge rollout steps and checklist item Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -115,6 +115,17 @@ CI workflow **Sync release to Gitea** (`.github/workflows/gitea-release-sync.yml
|
|||||||
|
|
||||||
**Manual upload:** `bash scripts/upload-release-to-gitea.sh /path/to/files v1.0.0` with the same env vars as CI.
|
**Manual upload:** `bash scripts/upload-release-to-gitea.sh /path/to/files v1.0.0` with the same env vars as CI.
|
||||||
|
|
||||||
|
**Legacy “bridge” after changing `baked-gitea-channel.js`:** Players still using the old Gitea URL only receive launcher updates from that host. Build **Windows + Linux** installers (e.g. download **Fractured launcher CI** artifacts, or run **`npm run pack:win`** / **`npm run pack:linux`**), put **`dist/`** contents in one folder if needed, then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export GITEA_BASE_URL=http://your-old-host:port # legacy base, no trailing slash
|
||||||
|
export GITEA_TOKEN=... GITEA_OWNER=Dawnsorrow GITEA_REPO=Fractured-Distro
|
||||||
|
bash tools/fractured-launcher-electron/scripts/gitea-replace-launcher-only.sh \
|
||||||
|
tools/fractured-launcher-electron/dist latest
|
||||||
|
```
|
||||||
|
|
||||||
|
That script deletes only **`Fractured-Launcher*`**, **`latest.yml`** (only if you supply a new **`latest.yml`** in **`dist/`**), **`latest-linux.yml`** (only if supplied), **`*.blockmap`**, and **`builder-debug.yml`** on the release, then uploads the new files — **Wow.exe**, MPQs, and **`patch-manifest.json`** are left alone. If you only built Linux locally, merge **Windows CI `dist/`** files into the same folder first so **`latest.yml`** is not removed without a replacement. Use release tag **`latest`** if that is what **`release_tag`** points at.
|
||||||
|
|
||||||
### Sync did not run / Gitea unchanged — checklist
|
### Sync did not run / Gitea unchanged — checklist
|
||||||
|
|
||||||
1. **Git tag ≠ GitHub Release** — Only **Releases** (published on the GitHub **Releases** page) trigger this workflow. If your teammate only **`git push --tags`**, create a **Release** from that tag and click **Publish** (or run **Actions → Sync release to Gitea → Run workflow** and enter the tag).
|
1. **Git tag ≠ GitHub Release** — Only **Releases** (published on the GitHub **Releases** page) trigger this workflow. If your teammate only **`git push --tags`**, create a **Release** from that tag and click **Publish** (or run **Actions → Sync release to Gitea → Run workflow** and enter the tag).
|
||||||
@@ -130,6 +141,7 @@ CI workflow **Sync release to Gitea** (`.github/workflows/gitea-release-sync.yml
|
|||||||
11. **`EBUSY` / file locked on Windows** — The client (or antivirus) may keep **`.MPQ`** files open. The launcher **retries** for a short window and downloads the new file **before** replacing the old one; if sync still fails, **exit WoW** (and any tool previewing that folder) and run **Download updates** again.
|
11. **`EBUSY` / file locked on Windows** — The client (or antivirus) may keep **`.MPQ`** files open. The launcher **retries** for a short window and downloads the new file **before** replacing the old one; if sync still fails, **exit WoW** (and any tool previewing that folder) and run **Download updates** again.
|
||||||
12. **`.bak-*` clutter** — When **Download updates** finishes without error, the launcher removes matching **`*.bak-YYYYMMDD-HHmmss`** files from earlier runs (same pattern it uses when replacing files). Failed syncs do not delete backups.
|
12. **`.bak-*` clutter** — When **Download updates** finishes without error, the launcher removes matching **`*.bak-YYYYMMDD-HHmmss`** files from earlier runs (same pattern it uses when replacing files). Failed syncs do not delete backups.
|
||||||
13. **Gitea still shows an old launcher version** — The sync workflow overlays **`tools/fractured-launcher-electron` from the default branch**, so **`package.json`** there defines the built version. Ensure launcher changes are **merged to `main`** before publishing the GitHub release (or re-run **Actions → Sync release to Gitea** after merging). Previously, **Fractured-Launcher\*** files **attached on the GitHub release** were merged too, which could leave **two** installer versions on Gitea; those assets are now skipped in favor of CI-only builds.
|
13. **Gitea still shows an old launcher version** — The sync workflow overlays **`tools/fractured-launcher-electron` from the default branch**, so **`package.json`** there defines the built version. Ensure launcher changes are **merged to `main`** before publishing the GitHub release (or re-run **Actions → Sync release to Gitea** after merging). Previously, **Fractured-Launcher\*** files **attached on the GitHub release** were merged too, which could leave **two** installer versions on Gitea; those assets are now skipped in favor of CI-only builds.
|
||||||
|
14. **Migrating `baked-gitea-channel.js` to a new host** — Publish **`gitea-replace-launcher-only.sh`** (see **Manual upload** above) on the **old** Gitea **`latest`** release so auto-update still works until clients move to the new URL.
|
||||||
|
|
||||||
### Private Gitea token for players
|
### Private Gitea token for players
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Replace only launcher installer + latest.yml attachments on a Gitea release.
|
||||||
|
# Does NOT delete Wow.exe, MPQs, or patch-manifest — use this to publish a
|
||||||
|
# "bridge" build (e.g. 1.0.13 with new baked Gitea URL) on a legacy host while
|
||||||
|
# keeping game assets already on that release.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# export GITEA_BASE_URL=http://legacy-host:port # or https://...
|
||||||
|
# export GITEA_TOKEN=gta_...
|
||||||
|
# export GITEA_OWNER=Dawnsorrow
|
||||||
|
# export GITEA_REPO=Fractured-Distro
|
||||||
|
# ./gitea-replace-launcher-only.sh /path/to/electron/dist latest
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
# shellcheck source=release-sync-filters.sh
|
||||||
|
. "$SCRIPT_DIR/release-sync-filters.sh"
|
||||||
|
|
||||||
|
DIST_DIR="${1:?first arg: electron-builder dist directory (contains .exe / .AppImage / latest*.yml)}"
|
||||||
|
TAG="${2:?second arg: release tag (e.g. latest)}"
|
||||||
|
|
||||||
|
: "${GITEA_BASE_URL:?Set GITEA_BASE_URL}"
|
||||||
|
: "${GITEA_TOKEN:?Set GITEA_TOKEN}"
|
||||||
|
: "${GITEA_OWNER:?Set GITEA_OWNER}"
|
||||||
|
: "${GITEA_REPO:?Set GITEA_REPO}"
|
||||||
|
|
||||||
|
BASE="${GITEA_BASE_URL%/}"
|
||||||
|
API="$BASE/api/v1"
|
||||||
|
AUTH_H=(-H "Authorization: token ${GITEA_TOKEN}" -H "Accept: application/json")
|
||||||
|
|
||||||
|
TAG_ENC=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=''))" "$TAG")
|
||||||
|
REL_JSON=$(mktemp)
|
||||||
|
trap 'rm -f "$REL_JSON"' EXIT
|
||||||
|
|
||||||
|
code=$(curl -sS -o "$REL_JSON" -w "%{http_code}" "${AUTH_H[@]}" \
|
||||||
|
"$API/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/tags/${TAG_ENC}")
|
||||||
|
|
||||||
|
if [ "$code" != "200" ]; then
|
||||||
|
echo "Gitea GET release by tag failed HTTP $code (release must already exist):" >&2
|
||||||
|
cat "$REL_JSON" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
rel_id=$(jq -r '.id' "$REL_JSON")
|
||||||
|
if [ -z "$rel_id" ] || [ "$rel_id" = "null" ]; then
|
||||||
|
echo "Could not resolve Gitea release id" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
should_delete_attachment() {
|
||||||
|
local l
|
||||||
|
l=$(printf '%s' "${1##*/}" | tr '[:upper:]' '[:lower:]')
|
||||||
|
case "$l" in
|
||||||
|
fractured-launcher*) return 0 ;;
|
||||||
|
*.blockmap) return 0 ;;
|
||||||
|
builder-debug.yml|builder-debug.yaml) return 0 ;;
|
||||||
|
esac
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
should_delete_yml_attachment() {
|
||||||
|
local l
|
||||||
|
l=$(printf '%s' "${1##*/}" | tr '[:upper:]' '[:lower:]')
|
||||||
|
case "$l" in
|
||||||
|
latest.yml) [ -f "$DIST_DIR/latest.yml" ] ;;
|
||||||
|
latest-linux.yml) [ -f "$DIST_DIR/latest-linux.yml" ] ;;
|
||||||
|
latest-mac.yml) [ -f "$DIST_DIR/latest-mac.yml" ] ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
while read -r line; do
|
||||||
|
[ -z "$line" ] && continue
|
||||||
|
aid=$(printf '%s' "$line" | cut -f1)
|
||||||
|
aname=$(printf '%s' "$line" | cut -f2-)
|
||||||
|
if should_delete_attachment "$aname" || should_delete_yml_attachment "$aname"; then
|
||||||
|
echo "Removing old attachment: $aname (id=$aid)"
|
||||||
|
curl -fsS -X DELETE "${AUTH_H[@]}" \
|
||||||
|
"$API/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/${rel_id}/assets/${aid}" || true
|
||||||
|
fi
|
||||||
|
done < <(jq -r '(.attachments // .assets // [])[] | "\(.id)\t\(.name)"' "$REL_JSON")
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
upload_paths=()
|
||||||
|
for f in "$DIST_DIR"/Fractured-Launcher*.exe "$DIST_DIR"/Fractured-Launcher*.AppImage \
|
||||||
|
"$DIST_DIR"/latest.yml "$DIST_DIR"/latest-linux.yml "$DIST_DIR"/latest-mac.yml; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
bn=$(basename "$f")
|
||||||
|
if should_skip_gitea_upload "$bn"; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
upload_paths+=("$f")
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${#upload_paths[@]}" -eq 0 ]; then
|
||||||
|
echo "No launcher files to upload under $DIST_DIR (expected Fractured-Launcher*.exe, *.AppImage, latest.yml, latest-linux.yml)." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for f in "${upload_paths[@]}"; do
|
||||||
|
bn=$(basename "$f")
|
||||||
|
echo "Uploading $bn …"
|
||||||
|
curl -fsS -X POST "${AUTH_H[@]}" \
|
||||||
|
-F "attachment=@${f}" \
|
||||||
|
"$API/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/${rel_id}/assets"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Done. Release $TAG (id=$rel_id): replaced ${#upload_paths[@]} launcher file(s); game assets left intact."
|
||||||
Reference in New Issue
Block a user