ci: Gitea-first launcher release; VPS origin migration
- Gitea release workflow downloads existing Gitea attachments, merges CI-built launchers, uploads merged set (no GitHub release mirror). - Add download-release-from-gitea.sh; clarify release-sync filters. - VPS update: repoint github.com/HighSocietyRaiding/Fractured remote to Gitea before git pull unless skipped via env. - Docs and bootstrap comment; distro workflow uses shared skip helper. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -111,7 +111,7 @@ jobs:
|
||||
for f in /tmp/from-main/*; do
|
||||
if [ -f "$f" ]; then
|
||||
bn=$(basename "$f")
|
||||
if should_skip_merge_from_github "$bn"; then
|
||||
if should_skip_existing_launcher_artifact "$bn"; then
|
||||
echo "Skipping GitHub release asset (CI launcher or excluded): $bn"
|
||||
continue
|
||||
fi
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
# Primary path for player-facing binaries: every *published* GitHub Release on this repo
|
||||
# is mirrored to your self-hosted Gitea (same tag). No public GitHub distro repo.
|
||||
# Player-facing binaries live on self-hosted Gitea releases (same tag as this run).
|
||||
# This workflow builds the Electron launcher (Windows + Linux) and uploads it together with
|
||||
# whatever attachments already exist on that Gitea release (patches, Wow exe, …). It does **not**
|
||||
# copy from GitHub releases anymore — create/publish the release on Gitea first, then run CI.
|
||||
#
|
||||
# Triggers:
|
||||
# - release: published / released → GitHub “Release” (not a raw git tag alone).
|
||||
# - workflow_dispatch → Actions → this workflow → “Run workflow” (enter tag).
|
||||
# - release: published / released → GitHub “Release” (optional hook; tag must match Gitea).
|
||||
# - workflow_dispatch → Actions → this workflow → “Run workflow” (enter tag = Gitea release tag).
|
||||
#
|
||||
# Troubleshooting: “Re-run failed jobs” on an OLD run replays the *original* workflow
|
||||
# YAML (e.g. still runs `npm run pack:win` without --publish never). After changing this
|
||||
# file on default branch, start a *new* run via “Run workflow”, not Re-run on a pre-fix run.
|
||||
# YAML. After changing this file on default branch, start a *new* run via “Run workflow”.
|
||||
#
|
||||
# Important: pushing only a git tag does NOT run this — you must create/publish a
|
||||
# Release on github.com (Releases → Draft/new release → Publish). The workflow
|
||||
# definition must exist on the repo DEFAULT branch (GitHub runs it from there).
|
||||
# Important: the Gitea release for the chosen tag must already exist with non-launcher assets
|
||||
# if you expect them on the final upload (CI rewrites all attachments on that release).
|
||||
#
|
||||
# Steps: Windows (NSIS+portable) + Linux (AppImage) in parallel, launcher from DEFAULT BRANCH
|
||||
# overlay on tag checkout → merge with GitHub release assets → upload all to Gitea.
|
||||
# overlay on tag checkout → download existing Gitea attachments → merge CI launcher → upload to Gitea.
|
||||
#
|
||||
# Secrets: GITEA_BASE_URL, GITEA_TOKEN, GITEA_OWNER, GITEA_REPO
|
||||
# Optional variable: GITEA_TARGET_REF (see tools/fractured-launcher-electron/README.md)
|
||||
#
|
||||
# Job guard: edit `if:` if github.repository is not HighSocietyRaiding/Fractured.
|
||||
|
||||
name: Sync release to Gitea
|
||||
name: Gitea release — attach launcher builds
|
||||
|
||||
on:
|
||||
release:
|
||||
@@ -29,7 +29,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Git tag only (e.g. v0.7.11-paragon-foo). NOT the release title — open the release and copy the tag next to the title.'
|
||||
description: 'Gitea release tag (e.g. v0.7.11-paragon-foo). Must match an existing Gitea release on GITEA_OWNER/GITEA_REPO.'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
if printf '%s' "$TAG" | grep -q '[[:space:]]'; then
|
||||
echo '::error::Tag contains whitespace — that is usually the **release title**, not the tag. On GitHub → Releases → open the release → copy the **tag** (short ref like v0.7.11-…), not the long title line.'
|
||||
echo '::error::Tag contains whitespace — use the exact Gitea tag (e.g. v0.7.11-…), not the release title.'
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@@ -202,33 +202,19 @@ jobs:
|
||||
name: electron-dist-linux
|
||||
path: /tmp/electron-linux
|
||||
|
||||
- name: Merge GitHub release assets + Electron build
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
- name: Merge Gitea release assets + Electron build
|
||||
run: |
|
||||
set -euo pipefail
|
||||
. tools/fractured-launcher-electron/scripts/release-sync-filters.sh
|
||||
TAG="${{ needs.meta.outputs.tag }}"
|
||||
mkdir -p combined
|
||||
mkdir -p /tmp/from-main
|
||||
if gh release download "$TAG" -R "${{ github.repository }}" -D /tmp/from-main 2>/tmp/dl.err; then
|
||||
shopt -s nullglob
|
||||
for f in /tmp/from-main/*; do
|
||||
if [ -f "$f" ]; then
|
||||
bn=$(basename "$f")
|
||||
if should_skip_merge_from_github "$bn"; then
|
||||
echo "Skipping GitHub release asset (CI launcher or excluded): $bn"
|
||||
continue
|
||||
fi
|
||||
cp -f "$f" combined/
|
||||
fi
|
||||
done
|
||||
echo "Merged assets from ${{ github.repository }} release $TAG"
|
||||
else
|
||||
echo "GitHub release download note (continuing with launcher only):"
|
||||
cat /tmp/dl.err || true
|
||||
fi
|
||||
mkdir -p /tmp/from-gitea
|
||||
bash tools/fractured-launcher-electron/scripts/download-release-from-gitea.sh /tmp/from-gitea "$TAG"
|
||||
shopt -s nullglob
|
||||
for f in /tmp/from-gitea/*; do
|
||||
if [ -f "$f" ]; then
|
||||
cp -f "$f" combined/
|
||||
fi
|
||||
done
|
||||
for f in /tmp/electron-win/* /tmp/electron-linux/*; do
|
||||
if [ -f "$f" ]; then
|
||||
cp -f "$f" combined/
|
||||
|
||||
@@ -22,9 +22,16 @@
|
||||
# bash scripts/vps-update-server.sh --dry-run
|
||||
# bash scripts/vps-update-server.sh --run-after 'custom command here'
|
||||
#
|
||||
# Canonical Fractured source (Gitea): https://git.hisora.dev/HighSocietyRaiding/Fractured.git
|
||||
# If this clone still has github.com/HighSocietyRaiding/Fractured on the pull remote, the script
|
||||
# rewrites that remote URL to Gitea before pulling (override with FRACTURED_GITEA_ORIGIN_URL;
|
||||
# disable with FRACTURED_SKIP_ORIGIN_MIGRATION=1).
|
||||
#
|
||||
# Environment:
|
||||
# FRACTURED_GIT_REMOTE — remote name (default: origin)
|
||||
# FRACTURED_POST_UPDATE_CMD — shell command run after compile (used by bare --run-after)
|
||||
# FRACTURED_GIT_REMOTE — remote name (default: origin)
|
||||
# FRACTURED_GITEA_ORIGIN_URL — URL used when auto-migrating off GitHub (default: Gitea HTTPS above)
|
||||
# FRACTURED_SKIP_ORIGIN_MIGRATION — set to 1 to never rewrite remote URLs
|
||||
# FRACTURED_POST_UPDATE_CMD — shell command run after compile (used by bare --run-after)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -40,6 +47,7 @@ DO_RESTART=0
|
||||
INSTALL_PREFIX=""
|
||||
POST_UPDATE_CMD="${FRACTURED_POST_UPDATE_CMD:-}"
|
||||
GIT_REMOTE="${FRACTURED_GIT_REMOTE:-origin}"
|
||||
FRACTURED_GITEA_ORIGIN_URL="${FRACTURED_GITEA_ORIGIN_URL:-https://git.hisora.dev/HighSocietyRaiding/Fractured.git}"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
@@ -59,8 +67,10 @@ Options:
|
||||
If CMD is omitted, uses FRACTURED_POST_UPDATE_CMD.
|
||||
|
||||
Environment:
|
||||
FRACTURED_GIT_REMOTE Git remote (default: origin).
|
||||
FRACTURED_POST_UPDATE_CMD Used with bare --run-after.
|
||||
FRACTURED_GIT_REMOTE Git remote name (default: origin).
|
||||
FRACTURED_GITEA_ORIGIN_URL Target URL when auto-migrating from GitHub Fractured remote.
|
||||
FRACTURED_SKIP_ORIGIN_MIGRATION Set to 1 to skip GitHub → Gitea remote rewrite.
|
||||
FRACTURED_POST_UPDATE_CMD Used with bare --run-after.
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -178,12 +188,27 @@ current_branch() {
|
||||
git symbolic-ref -q --short HEAD || git rev-parse --short HEAD
|
||||
}
|
||||
|
||||
# Old VPS clones may still have origin → github.com/HighSocietyRaiding/Fractured; repoint to Gitea.
|
||||
ensure_fractured_origin_on_gitea() {
|
||||
if [[ "${FRACTURED_SKIP_ORIGIN_MIGRATION:-0}" == "1" ]]; then
|
||||
return 0
|
||||
fi
|
||||
local url
|
||||
url="$(git remote get-url "$GIT_REMOTE" 2>/dev/null || true)"
|
||||
[[ -z "$url" ]] && return 0
|
||||
if [[ "$url" =~ github\.com[:/]HighSocietyRaiding/Fractured ]]; then
|
||||
echo "==> $GIT_REMOTE still points at GitHub Fractured; switching to Gitea: $FRACTURED_GITEA_ORIGIN_URL"
|
||||
run git remote set-url "$GIT_REMOTE" "$FRACTURED_GITEA_ORIGIN_URL"
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$NO_PULL" -eq 0 ]]; then
|
||||
ref="$(current_branch)"
|
||||
if [[ "$ref" == "HEAD" ]]; then
|
||||
echo "error: detached HEAD; checkout a branch or use --no-pull." >&2
|
||||
exit 1
|
||||
fi
|
||||
ensure_fractured_origin_on_gitea
|
||||
echo "==> git pull $GIT_REMOTE $ref"
|
||||
run git pull "$GIT_REMOTE" "$ref"
|
||||
else
|
||||
|
||||
@@ -43,7 +43,7 @@ npm install
|
||||
npm run pack:linux
|
||||
```
|
||||
|
||||
Produces **`dist/Fractured-Launcher-${version}-Linux-x86_64.AppImage`**. Same **`lib/baked-gitea-channel.js`** and **`default-launcher.json`** as Windows; run on **Linux** (or use **Fractured launcher CI** / **Sync release to Gitea**, which upload this file to Gitea with the Windows installers).
|
||||
Produces **`dist/Fractured-Launcher-${version}-Linux-x86_64.AppImage`**. Same **`lib/baked-gitea-channel.js`** and **`default-launcher.json`** as Windows; run on **Linux** (or use **Fractured launcher CI** / **Gitea release — attach launcher builds**, which upload this file to Gitea with the Windows installers).
|
||||
|
||||
**Quick local test (avoids tag snapshot / CI):**
|
||||
- **Linux:** from repo root, **`bash tools/fractured-launcher-electron/scripts/manual-pack-linux.sh`** → **`dist/*.AppImage`**.
|
||||
@@ -66,7 +66,7 @@ Produces **`dist/Fractured-Launcher-${version}-Linux-x86_64.AppImage`**. Same **
|
||||
|
||||
### Where launcher updates are hosted
|
||||
|
||||
**`npm run publish:win`** runs **`electron-builder` with `--publish never`** — artifacts stay in **`dist/`**; CI uploads them to Gitea when you **publish a GitHub release**. For ad-hoc uploads, use **`scripts/upload-release-to-gitea.sh`**. For launcher auto-update, prefer:
|
||||
**`npm run publish:win`** runs **`electron-builder` with `--publish never`** — artifacts stay in **`dist/`**; CI uploads them to Gitea when you run **Gitea release — attach launcher builds** (see below). For ad-hoc uploads, use **`scripts/upload-release-to-gitea.sh`**. For launcher auto-update, prefer:
|
||||
|
||||
- Set **`update_feed_url`** (or **`LAUNCHER_UPDATE_URL`**) to a **generic** HTTPS base URL where **`latest.yml`** and the installer files are hosted (often the same Gitea release attachment URLs pattern your reverse proxy exposes), **or**
|
||||
- Keep publishing to a GitHub release only for **`latest.yml`** + installers if you accept that small metadata/binary channel there.
|
||||
@@ -78,17 +78,18 @@ Produces **`dist/Fractured-Launcher-${version}-Linux-x86_64.AppImage`**. Same **
|
||||
### Publishing a new launcher version
|
||||
|
||||
1. Bump **`version`** in `package.json` on `main` (or your release branch) and merge.
|
||||
2. Create a **GitHub release** (tag + attach patches / `Wow.exe` if needed) and click **Publish** — **Sync release to Gitea** builds **Windows + Linux** launcher artifacts and mirrors everything to Gitea.
|
||||
3. Local check: **`npm run pack:win`** (on Windows) or **`npm run pack:linux`** / **`scripts/manual-pack-linux.sh`**, then **`scripts/upload-release-to-gitea.sh`** with the same **`GITEA_*`** env vars as CI if you need a manual upload.
|
||||
2. Create/publish the **Gitea** release for that tag (attach patches / `Wow.exe`, **`patch-manifest.json`**, etc.).
|
||||
3. Run **GitHub Actions → Gitea release — attach launcher builds** (or publish a **GitHub** release with the same tag if you still use that trigger) so CI builds **Windows + Linux** launchers and re-uploads **all** release files to Gitea (see workflow header).
|
||||
4. Local check: **`npm run pack:win`** (on Windows) or **`npm run pack:linux`** / **`scripts/manual-pack-linux.sh`**, then **`scripts/upload-release-to-gitea.sh`** with the same **`GITEA_*`** env vars as CI if you need a manual upload.
|
||||
|
||||
## Sync to Gitea (patches + launcher binaries)
|
||||
## Gitea release + launcher (patches + binaries)
|
||||
|
||||
CI workflow **Sync release to Gitea** (`.github/workflows/gitea-release-sync.yml`) runs on **every published GitHub release** on this repo:
|
||||
CI workflow **Gitea release — attach launcher builds** (`.github/workflows/gitea-release-sync.yml`) attaches CI-built launcher binaries to the **Gitea** release that already exists for the chosen tag:
|
||||
|
||||
1. Triggers on **release published** on **`HighSocietyRaiding/Fractured`** (or **workflow_dispatch** with a tag).
|
||||
1. Triggers on **release published** on **`HighSocietyRaiding/Fractured`** (optional) or **workflow_dispatch** with a tag (the tag must match a **Gitea** release on **`GITEA_OWNER` / `GITEA_REPO`**).
|
||||
2. Builds **Windows** (NSIS + portable) and **Linux** (AppImage) in parallel, each using **`tools/fractured-launcher-electron` from the default branch** (overlaid onto the tag checkout), so older release tags never ship a launcher missing new **`lib/*.js`** files.
|
||||
3. Downloads **all assets** attached to that **GitHub** release (MPQs, patched `Wow.exe`, etc.).
|
||||
4. Merges with the built launcher artifacts and uploads to a **Gitea release** with the **same tag** (existing attachments on that Gitea release are replaced). **Launcher installers** attached on GitHub (**`Fractured-Launcher*`**, case-insensitive) are **not** merged — the **CI build from the default branch** is the only source of launcher binaries, so an old installer on the GitHub release cannot “stick” on Gitea next to a newer build. **`*.blockmap`** and **`builder-debug.yml`** are omitted from the merge and from Gitea uploads.
|
||||
3. Downloads **existing attachments** from that **Gitea** release (MPQs, patched `Wow.exe`, etc.).
|
||||
4. Merges with the built launcher artifacts and **replaces** all attachments on the same Gitea release (the upload script clears prior attachments, then posts the merged set). **Launcher installers** already on Gitea (**`Fractured-Launcher*`**, case-insensitive) are **not** re-downloaded — the **CI build from the default branch** is the only source of launcher binaries. **`*.blockmap`** and **`builder-debug.yml`** are omitted from the merge and from Gitea uploads.
|
||||
|
||||
**GitHub Actions secrets** (repository → Settings → Secrets and variables → Actions):
|
||||
|
||||
@@ -99,7 +100,7 @@ CI workflow **Sync release to Gitea** (`.github/workflows/gitea-release-sync.yml
|
||||
| **`GITEA_OWNER`** | Organization or username on Gitea |
|
||||
| **`GITEA_REPO`** | Repository name — must already have **at least one commit** (Gitea returns HTTP 422 “repo is empty” for zero-commit repos; push e.g. a README on **`main`** or set **`GITEA_TARGET_REF`** to your default branch) |
|
||||
|
||||
**Optional variable** (Settings → Variables): **`GITEA_TARGET_REF`** — default branch/commitish used **only when the workflow must create a new Gitea release** and Gitea needs `target_commitish` (defaults to **`main`** in the upload script if unset).
|
||||
**Optional variable** (Settings → Variables): **`GITEA_TARGET_REF`** — default branch/commitish used **only when the upload script must create a new Gitea release** (no release for that tag yet) and Gitea needs `target_commitish` (defaults to **`main`** in the upload script if unset). Prefer creating the release on Gitea **before** CI so patches ship in the same run.
|
||||
|
||||
**Player `launcher.json`:** packaged builds should already include **`gitea.base_url` / `owner` / `repo`** from the bake step above. Players only need to set **`GITEA_TOKEN`** (or your **`token_env`**) if the Gitea repo is **private**. To point at another instance, edit **`gitea`** in **`launcher.json`**:
|
||||
|
||||
@@ -126,28 +127,29 @@ bash tools/fractured-launcher-electron/scripts/gitea-replace-launcher-only.sh \
|
||||
|
||||
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
|
||||
### Launcher attach 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).
|
||||
2. **Manual run: tag vs title** — **Run workflow** must receive the **git tag** (e.g. `v0.7.11-paragon-…`), copied from the release page’s tag badge. Pasting the **release title** (long line with spaces/parentheses) breaks `git fetch` with `invalid refspec`.
|
||||
3. **Draft release** — Must click **Publish release**; drafts do not mirror.
|
||||
4. **Workflow on default branch** — GitHub runs `release` workflows from the **default branch** (e.g. `main`). Ensure `.github/workflows/gitea-release-sync.yml` is merged there.
|
||||
5. **Repo name guard** — Jobs use `if: github.repository == 'HighSocietyRaiding/Fractured'`. Forks or renames must change that line or runs are skipped (GitHub Actions only; canonical clone is Gitea).
|
||||
6. **Secrets** — **`GITEA_BASE_URL`**, **`GITEA_TOKEN`**, **`GITEA_OWNER`**, **`GITEA_REPO`** must be set under **Settings → Secrets and variables → Actions**. A failed “Upload to Gitea” step usually prints which is missing.
|
||||
7. **Actions tab** — Open the latest **Sync release to Gitea** run; a red **build-electron** (old tag without `package-lock.json`, etc.) or **Upload to Gitea** step shows the real error.
|
||||
8. **HTTP 422 `repo is empty`** — The Gitea repo has **no commits** yet. Push any initial commit (e.g. **Add README** in the Gitea web UI, or `git push` to **`main`**). Optionally set **`GITEA_TARGET_REF`** to match your real default branch if it is not **`main`**. From this repo you can run **`scripts/bootstrap-gitea-repo.sh`** (see script header for `GITEA_*` env or pass the HTTPS/SSH clone URL as the first argument).
|
||||
9. **`sync Wow.exe: fetch failed`** — Often **HTTPS/TLS** to Gitea; use **`http://…`** in **`lib/baked-gitea-channel.js`** if you only serve plain HTTP, or fix certs / **`NODE_EXTRA_CA_CERTS`**. Ensure **`Wow-patched.exe`** exists on the release (**`release_tag`**: `latest` vs pinned). Errors include the failing URL when possible.
|
||||
10. **Wine + Windows portable** — If the folder picker returns **`/home/...`**, the launcher maps it to **`Z:\home\...`** (Wine’s Unix root). **`Wow.exe`** is matched case-insensitively for Linux-backed folders. Re-save the WoW folder after upgrading if validation still fails.
|
||||
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.
|
||||
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.
|
||||
1. **Gitea release missing** — The workflow downloads from **Gitea** first. Create/publish a release on **`GITEA_OWNER` / `GITEA_REPO`** with the **same tag** before running CI (or rely on upload script to create an empty release — you still need **`GITEA_TARGET_REF`** if the repo default branch is not **`main`**).
|
||||
2. **GitHub-only tag** — If you use the **release published** trigger on GitHub, the tag must still exist as a **Gitea** release with your patch assets. Otherwise use **Actions → Gitea release — attach launcher builds → Run workflow** after the Gitea release exists.
|
||||
3. **Manual run: tag vs title** — **Run workflow** must receive the **git tag** (e.g. `v0.7.11-paragon-…`), not the long human-readable release title (spaces break the tag).
|
||||
4. **Draft release** — On Gitea, publish the release; drafts may not be visible to the API the same way — use a published release.
|
||||
5. **Workflow on default branch** — GitHub runs `release` workflows from the **default branch** (e.g. `main`). Ensure `.github/workflows/gitea-release-sync.yml` is merged there.
|
||||
6. **Repo name guard** — Jobs use `if: github.repository == 'HighSocietyRaiding/Fractured'`. Forks or renames must change that line or runs are skipped (GitHub Actions only; canonical clone is Gitea).
|
||||
7. **Secrets** — **`GITEA_BASE_URL`**, **`GITEA_TOKEN`**, **`GITEA_OWNER`**, **`GITEA_REPO`** must be set under **Settings → Secrets and variables → Actions**. A failed “Upload to Gitea” step usually prints which is missing.
|
||||
8. **Actions tab** — Open the latest **Gitea release — attach launcher builds** run; a red **build-electron** (old tag without `package-lock.json`, etc.), **Merge Gitea release assets**, or **Upload to Gitea** step shows the real error.
|
||||
9. **HTTP 422 `repo is empty`** — The Gitea repo has **no commits** yet. Push any initial commit (e.g. **Add README** in the Gitea web UI, or `git push` to **`main`**). Optionally set **`GITEA_TARGET_REF`** to match your real default branch if it is not **`main`**. From this repo you can run **`scripts/bootstrap-gitea-repo.sh`** (see script header for `GITEA_*` env or pass the HTTPS/SSH clone URL as the first argument).
|
||||
10. **`sync Wow.exe: fetch failed`** — Often **HTTPS/TLS** to Gitea; use **`http://…`** in **`lib/baked-gitea-channel.js`** if you only serve plain HTTP, or fix certs / **`NODE_EXTRA_CA_CERTS`**. Ensure **`Wow-patched.exe`** exists on the release (**`release_tag`**: `latest` vs pinned). Errors include the failing URL when possible.
|
||||
11. **Wine + Windows portable** — If the folder picker returns **`/home/...`**, the launcher maps it to **`Z:\home\...`** (Wine’s Unix root). **`Wow.exe`** is matched case-insensitively for Linux-backed folders. Re-save the WoW folder after upgrading if validation still fails.
|
||||
12. **`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.
|
||||
13. **`.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.
|
||||
14. **Gitea still shows an old launcher version** — The 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 attaching to the release (or re-run **Actions → Gitea release — attach launcher builds** after merging). **Fractured-Launcher\*** files already on Gitea are skipped when re-downloading so CI is the only launcher source.
|
||||
15. **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
|
||||
|
||||
Do **not** embed a shared admin PAT in a shipped `launcher.json`. Prefer read-only tokens scoped to one repo, short-lived tokens, or a small auth service that redirects to signed URLs.
|
||||
|
||||
**Release asset names** must match **`files[].source`** when **`from_release`**: true. Use **`release_tag`**: `"latest"` or a pinned tag matching both GitHub and Gitea.
|
||||
**Release asset names** must match **`files[].source`** when **`from_release`**: true. Use **`release_tag`**: `"latest"` or a pinned tag matching your Gitea releases.
|
||||
|
||||
## Patch versions (same filenames, different bytes)
|
||||
|
||||
@@ -166,13 +168,13 @@ cd /path/to/staging
|
||||
node tools/fractured-launcher-electron/scripts/generate-patch-manifest.js v0.9.0-client Wow-patched.exe > patch-manifest.json
|
||||
```
|
||||
|
||||
Attach **`patch-manifest.json`** together with the MPQ/exe to the GitHub release (CI sync copies it to Gitea with everything else).
|
||||
Attach **`patch-manifest.json`** together with the MPQ/exe to the **Gitea** release (same files CI merges before upload).
|
||||
|
||||
## CI
|
||||
|
||||
Workflow **Fractured launcher CI** (`.github/workflows/fractured-launcher-ci.yml`) runs on pushes/PRs under `tools/fractured-launcher-electron/`: **Windows** (`npm run pack:win`) and **Linux** (`npm run pack:linux`) jobs, each **`electron-builder … --publish never`**. **Actions → Fractured launcher CI → Run workflow** runs it manually.
|
||||
|
||||
**Sync release to Gitea** (`.github/workflows/gitea-release-sync.yml`) uses the same pack commands. If you see `GH_TOKEN` / `GitHubPublisher` errors in logs, the job is almost certainly an old **Re-run failed jobs** — open **Actions → Sync release to Gitea → Run workflow**, enter the tag, and start a **new** run instead.
|
||||
**Gitea release — attach launcher builds** (`.github/workflows/gitea-release-sync.yml`) uses the same pack commands. If you see stale behaviour after a workflow edit, start a **new** run (**Actions → Gitea release — attach launcher builds → Run workflow**) instead of **Re-run failed jobs** on an old run.
|
||||
|
||||
## Config
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ git checkout -q -b "$BRANCH"
|
||||
cat >README.md <<'EOF'
|
||||
# Fractured release mirror
|
||||
|
||||
Release assets (launcher builds, patches, `patch-manifest.json`, etc.) are uploaded here by **GitHub Actions** (“Sync release to Gitea”) from the main Fractured repository.
|
||||
Release assets (launcher builds, patches, `patch-manifest.json`, etc.) are uploaded here by **GitHub Actions** (**Gitea release — attach launcher builds**) from the main Fractured repository.
|
||||
|
||||
This initial commit exists because **Gitea requires at least one commit** in the repository before releases can be created.
|
||||
EOF
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
# Download attachments from an existing Gitea release (same tag as CI). Skips filenames that
|
||||
# the launcher CI rebuilds (see release-sync-filters.sh) so Electron artifacts can replace them.
|
||||
#
|
||||
# Usage:
|
||||
# export GITEA_BASE_URL=https://git.example.com
|
||||
# export GITEA_TOKEN=gta_...
|
||||
# export GITEA_OWNER=myorg
|
||||
# export GITEA_REPO=Fractured
|
||||
# ./download-release-from-gitea.sh /tmp/gitea-assets v1.0.0
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=release-sync-filters.sh
|
||||
. "$SCRIPT_DIR/release-sync-filters.sh"
|
||||
|
||||
OUTDIR="${1:?first arg: output directory}"
|
||||
TAG="${2:?second arg: release tag (e.g. v1.0.0)}"
|
||||
|
||||
: "${GITEA_BASE_URL:?Set GITEA_BASE_URL (no trailing slash required)}"
|
||||
: "${GITEA_TOKEN:?Set GITEA_TOKEN}"
|
||||
: "${GITEA_OWNER:?Set GITEA_OWNER}"
|
||||
: "${GITEA_REPO:?Set GITEA_REPO}"
|
||||
|
||||
BASE="${GITEA_BASE_URL%/}"
|
||||
API="$BASE/api/v1"
|
||||
AUTH_JSON=(-H "Authorization: token ${GITEA_TOKEN}" -H "Accept: application/json")
|
||||
|
||||
mkdir -p "$OUTDIR"
|
||||
|
||||
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_JSON[@]}" \
|
||||
"$API/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/tags/${TAG_ENC}")
|
||||
|
||||
if [ "$code" != "200" ]; then
|
||||
echo "Gitea GET release by tag \"$TAG\" failed HTTP $code — create/publish that release on Gitea first, then run this workflow." >&2
|
||||
cat "$REL_JSON" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
count=0
|
||||
while IFS= read -r obj; do
|
||||
[ -z "$obj" ] && continue
|
||||
name=$(jq -r '.name // empty' <<<"$obj")
|
||||
url=$(jq -r '(.browser_download_url // .download_url // empty)' <<<"$obj")
|
||||
[ -z "$name" ] || [ "$name" = "null" ] && continue
|
||||
[ -z "$url" ] || [ "$url" = "null" ] && continue
|
||||
if should_skip_existing_launcher_artifact "$name"; then
|
||||
echo "Skipping existing launcher artifact (CI replaces): $name"
|
||||
continue
|
||||
fi
|
||||
if [[ "$url" != http://* && "$url" != https://* ]]; then
|
||||
if [[ "$url" != /* ]]; then
|
||||
echo "Unexpected attachment URL for $name: $url" >&2
|
||||
exit 1
|
||||
fi
|
||||
url="${BASE}${url}"
|
||||
fi
|
||||
echo "Downloading $name …"
|
||||
curl -fsSL -H "Authorization: token ${GITEA_TOKEN}" -o "$OUTDIR/$name" "$url"
|
||||
count=$((count + 1))
|
||||
done < <(jq -c '(.attachments // .assets // [])[]' "$REL_JSON")
|
||||
|
||||
echo "Downloaded $count non-launcher attachment(s) from Gitea release $TAG."
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shared filters for GitHub → Gitea / distro release merges and Gitea uploads.
|
||||
# Shared filters for release merges (GitHub/Gitea sources) and Gitea uploads.
|
||||
# shellcheck shell=bash
|
||||
|
||||
# Skip when copying assets from `gh release download` into combined/: CI-built launcher is authoritative.
|
||||
should_skip_merge_from_github() {
|
||||
# Skip when copying existing release assets into combined/: CI-built launcher wins on collision.
|
||||
should_skip_existing_launcher_artifact() {
|
||||
local l
|
||||
l=$(printf '%s' "${1##*/}" | tr '[:upper:]' '[:lower:]')
|
||||
case "$l" in
|
||||
@@ -14,6 +14,11 @@ should_skip_merge_from_github() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Legacy name (GitHub release download step); same rules as Gitea merge.
|
||||
should_skip_merge_from_github() {
|
||||
should_skip_existing_launcher_artifact "$@"
|
||||
}
|
||||
|
||||
# Skip when POSTing attachments to Gitea (belt-and-suspenders if something slips into combined/).
|
||||
should_skip_gitea_upload() {
|
||||
local l
|
||||
|
||||
@@ -41,7 +41,7 @@ elif [ "$code" = "404" ]; then
|
||||
body=$(jq -n \
|
||||
--arg tag "$TAG" \
|
||||
--arg name "Fractured $TAG" \
|
||||
--arg body "Synced from GitHub Actions (Fractured)." \
|
||||
--arg body "Fractured $TAG (CI)." \
|
||||
--arg target "$TARGET" \
|
||||
'{tag_name:$tag,name:$name,body:$body,draft:false,prerelease:false,target_commitish:$target}')
|
||||
code=$(curl -sS -o "$REL_JSON" -w "%{http_code}" -X POST "${AUTH_H[@]}" \
|
||||
|
||||
Reference in New Issue
Block a user