From 48826e21d6deb695216f75282f5ed2d1934dc77e Mon Sep 17 00:00:00 2001 From: Docker Build Date: Sun, 10 May 2026 20:15:38 -0500 Subject: [PATCH] refactor(launcher): hardcode Gitea channel in lib/baked-gitea-channel.js - Merge baked base_url/owner/repo/release_tag at load time (no inject script, no fractured-release-channel.json, no CI env for pack). - Fix mergeConfig deep-merge for gitea, patch_manifest, launcher_updates_from_github. - Remove inject-release-channel.js and fractured-release-channel.json. Co-authored-by: Cursor --- .github/workflows/fractured-launcher-ci.yml | 4 - .github/workflows/gitea-release-sync.yml | 6 -- tools/fractured-launcher-electron/README.md | 9 +-- .../fractured-release-channel.json | 8 -- .../lib/baked-gitea-channel.js | 13 ++++ .../lib/config-store.js | 34 ++++++-- .../fractured-launcher-electron/package.json | 5 +- .../scripts/inject-release-channel.js | 77 ------------------- 8 files changed, 48 insertions(+), 108 deletions(-) delete mode 100644 tools/fractured-launcher-electron/fractured-release-channel.json create mode 100644 tools/fractured-launcher-electron/lib/baked-gitea-channel.js delete mode 100644 tools/fractured-launcher-electron/scripts/inject-release-channel.js diff --git a/.github/workflows/fractured-launcher-ci.yml b/.github/workflows/fractured-launcher-ci.yml index 3339e4c..2236397 100644 --- a/.github/workflows/fractured-launcher-ci.yml +++ b/.github/workflows/fractured-launcher-ci.yml @@ -38,10 +38,6 @@ jobs: cache-dependency-path: tools/fractured-launcher-electron/package-lock.json - name: Install and pack (NSIS + portable) - env: - GITEA_BASE_URL: ${{ secrets.GITEA_BASE_URL }} - GITEA_OWNER: ${{ secrets.GITEA_OWNER }} - GITEA_REPO: ${{ secrets.GITEA_REPO }} run: | npm ci npm run pack:win diff --git a/.github/workflows/gitea-release-sync.yml b/.github/workflows/gitea-release-sync.yml index 3032d74..6033984 100644 --- a/.github/workflows/gitea-release-sync.yml +++ b/.github/workflows/gitea-release-sync.yml @@ -85,14 +85,8 @@ jobs: - name: Install and pack (NSIS + portable) working-directory: tools/fractured-launcher-electron - env: - # Same values as upload step — baked into default-launcher.json (no token). - GITEA_BASE_URL: ${{ secrets.GITEA_BASE_URL }} - GITEA_OWNER: ${{ secrets.GITEA_OWNER }} - GITEA_REPO: ${{ secrets.GITEA_REPO }} run: | npm ci - # pack:win runs inject-release-channel.js then electron-builder --publish never npm run pack:win - name: Stage launcher files for upload diff --git a/tools/fractured-launcher-electron/README.md b/tools/fractured-launcher-electron/README.md index 823f4f4..a8c7a86 100644 --- a/tools/fractured-launcher-electron/README.md +++ b/tools/fractured-launcher-electron/README.md @@ -35,14 +35,11 @@ Produces under **`dist/`**: | `Fractured-Launcher-${version}-Setup.exe` (NSIS) | **Recommended for players** — supports seamless **auto-update** and restart. | | `Fractured-Launcher-${version}-Windows-Portable.exe` | No installer; players replace the file manually. Auto-update is **less reliable** than NSIS. | -### Baked Gitea channel (non-token) +### Hardcoded Gitea channel (non-token) -**`npm run pack:win`** runs **`scripts/inject-release-channel.js`** first. It merges **`gitea.base_url`**, **`owner`**, **`repo`**, and optional **`release_tag`** into **`default-launcher.json`** for that build only (then **electron-builder** packs that file). +**`lib/baked-gitea-channel.js`** exports **`base_url`**, **`owner`**, **`repo`**, **`release_tag`**. Set those strings once in the repo (same values you use for CI upload — not secret). At runtime **`config-store`** merges them into **`gitea.*`** so **`launcher.json`** does not need those fields; **`GITEA_TOKEN`** (or **`gitea.token_env`**) is still only for **private** Gitea. Leave a field **`''`** in the baked file to fall back to **`default-launcher.json`** / user **`launcher.json`** for that key. -- **GitHub Actions** — **Sync release to Gitea** and **Fractured launcher CI** export **`GITEA_BASE_URL`**, **`GITEA_OWNER`**, **`GITEA_REPO`** (same names as your upload secrets) for the pack step, so installers match the repo you sync to. Nothing embeds **`GITEA_TOKEN`**. -- **Local packs** — put the same values in **`fractured-release-channel.json`** (committed or personal copy) **or** export those env vars before **`npm run pack:win`**. - -First launch still copies **`default-launcher.json`** → **`launcher.json`** beside the exe, so players get the baked **`gitea.*`** without editing unless they override. +**`npm run pack:win`** is plain **electron-builder** — no inject step, no extra JSON beside the app. ## Auto-update behaviour diff --git a/tools/fractured-launcher-electron/fractured-release-channel.json b/tools/fractured-launcher-electron/fractured-release-channel.json deleted file mode 100644 index 8663169..0000000 --- a/tools/fractured-launcher-electron/fractured-release-channel.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "gitea": { - "base_url": "", - "owner": "", - "repo": "", - "release_tag": "latest" - } -} diff --git a/tools/fractured-launcher-electron/lib/baked-gitea-channel.js b/tools/fractured-launcher-electron/lib/baked-gitea-channel.js new file mode 100644 index 0000000..1cb2d56 --- /dev/null +++ b/tools/fractured-launcher-electron/lib/baked-gitea-channel.js @@ -0,0 +1,13 @@ +'use strict'; + +/** + * Production Gitea mirror (non-secret). Edit here and ship — no inject script, + * no fractured-release-channel.json, no CI env needed for these fields. + * Token stays in env: GITEA_TOKEN or launcher.json → gitea.token_env. + */ +module.exports = { + base_url: '', + owner: '', + repo: '', + release_tag: 'latest', +}; diff --git a/tools/fractured-launcher-electron/lib/config-store.js b/tools/fractured-launcher-electron/lib/config-store.js index d2fdfbb..89bec51 100644 --- a/tools/fractured-launcher-electron/lib/config-store.js +++ b/tools/fractured-launcher-electron/lib/config-store.js @@ -11,7 +11,13 @@ function mergeConfig(defaults, user) { user.update_feed_url != null && user.update_feed_url !== '' ? user.update_feed_url : defaults.update_feed_url, + launcher_updates_from_github: + user.launcher_updates_from_github != null + ? user.launcher_updates_from_github + : defaults.launcher_updates_from_github, github: { ...defaults.github, ...(user.github || {}) }, + gitea: { ...defaults.gitea, ...(user.gitea || {}) }, + patch_manifest: { ...defaults.patch_manifest, ...(user.patch_manifest || {}) }, launch: { ...defaults.launch, ...(user.launch || {}) }, auth: user.auth != null ? { ...defaults.auth, ...user.auth } : defaults.auth, realmlist: user.realmlist != null ? { ...defaults.realmlist, ...user.realmlist } : defaults.realmlist, @@ -19,6 +25,23 @@ function mergeConfig(defaults, user) { }; } +/** Hardcoded Gitea host/repo (see lib/baked-gitea-channel.js). Non-empty baked values win. */ +function applyBakedGitea(cfg) { + let baked; + try { + baked = require('./baked-gitea-channel'); + } catch { + return cfg; + } + if (!baked || typeof baked !== 'object') return cfg; + cfg.gitea = { ...(cfg.gitea || {}) }; + for (const k of ['base_url', 'owner', 'repo', 'release_tag']) { + const v = baked[k]; + if (v != null && String(v).trim() !== '') cfg.gitea[k] = String(v).trim(); + } + return cfg; +} + function getConfigPath(app) { if (process.env.FRACTURED_LAUNCHER_CONFIG) return process.env.FRACTURED_LAUNCHER_CONFIG; if (app && app.isPackaged) { @@ -33,11 +56,12 @@ async function loadConfig(app) { const defaults = JSON.parse(await fs.readFile(defPath, 'utf8')); try { const user = JSON.parse(await fs.readFile(p, 'utf8')); - return { configPath: p, config: mergeConfig(defaults, user) }; + return { configPath: p, config: applyBakedGitea(mergeConfig(defaults, user)) }; } catch (e) { if (e.code === 'ENOENT') { - await fs.writeFile(p, JSON.stringify(defaults, null, 2), 'utf8'); - return { configPath: p, config: JSON.parse(JSON.stringify(defaults)) }; + const initial = applyBakedGitea(mergeConfig(defaults, {})); + await fs.writeFile(p, JSON.stringify(initial, null, 2), 'utf8'); + return { configPath: p, config: JSON.parse(JSON.stringify(initial)) }; } throw e; } @@ -48,7 +72,7 @@ async function saveGameDir(configPath, gameDir) { const defaults = JSON.parse(await fs.readFile(defPath, 'utf8')); const user = JSON.parse(await fs.readFile(configPath, 'utf8')); user.game_dir = gameDir; - const merged = mergeConfig(defaults, user); + const merged = applyBakedGitea(mergeConfig(defaults, user)); await fs.writeFile(configPath, JSON.stringify(merged, null, 2), 'utf8'); return merged; } @@ -60,4 +84,4 @@ function resolveGameDir(cfg, configPath) { return path.normalize(path.join(path.dirname(configPath), gd)); } -module.exports = { getConfigPath, loadConfig, saveGameDir, resolveGameDir, mergeConfig }; +module.exports = { getConfigPath, loadConfig, saveGameDir, resolveGameDir, mergeConfig, applyBakedGitea }; diff --git a/tools/fractured-launcher-electron/package.json b/tools/fractured-launcher-electron/package.json index 799d5dc..0320aa8 100644 --- a/tools/fractured-launcher-electron/package.json +++ b/tools/fractured-launcher-electron/package.json @@ -9,8 +9,8 @@ }, "scripts": { "start": "electron .", - "pack:win": "node scripts/inject-release-channel.js && electron-builder --win nsis portable --x64 --publish never", - "publish:win": "node scripts/inject-release-channel.js && electron-builder --win nsis portable --x64 --publish never" + "pack:win": "electron-builder --win nsis portable --x64 --publish never", + "publish:win": "electron-builder --win nsis portable --x64 --publish never" }, "author": "", "license": "GPL-3.0", @@ -35,6 +35,7 @@ "renderer.js", "styles.css", "default-launcher.json", + "lib/baked-gitea-channel.js", "lib/gitea-release.js", "lib/patch-manifest.js", "lib/**/*" diff --git a/tools/fractured-launcher-electron/scripts/inject-release-channel.js b/tools/fractured-launcher-electron/scripts/inject-release-channel.js deleted file mode 100644 index e14f874..0000000 --- a/tools/fractured-launcher-electron/scripts/inject-release-channel.js +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -/** - * Merge Gitea release channel (non-token) into default-launcher.json before pack. - * Precedence: env → fractured-release-channel.json → leave existing default-launcher values. - * - * Env (any of these names): - * FRACTURED_LAUNCHER_GITEA_BASE_URL | GITEA_BASE_URL - * FRACTURED_LAUNCHER_GITEA_OWNER | GITEA_OWNER - * FRACTURED_LAUNCHER_GITEA_REPO | GITEA_REPO - * FRACTURED_LAUNCHER_GITEA_RELEASE_TAG | GITEA_RELEASE_TAG - */ -const fs = require('fs'); -const path = require('path'); - -const root = path.join(__dirname, '..'); -const defPath = path.join(root, 'default-launcher.json'); -const channelPath = path.join(root, 'fractured-release-channel.json'); - -function pickEnv() { - return { - base_url: String( - process.env.FRACTURED_LAUNCHER_GITEA_BASE_URL || process.env.GITEA_BASE_URL || '' - ).trim(), - owner: String( - process.env.FRACTURED_LAUNCHER_GITEA_OWNER || process.env.GITEA_OWNER || '' - ).trim(), - repo: String( - process.env.FRACTURED_LAUNCHER_GITEA_REPO || process.env.GITEA_REPO || '' - ).trim(), - release_tag: String( - process.env.FRACTURED_LAUNCHER_GITEA_RELEASE_TAG || process.env.GITEA_RELEASE_TAG || '' - ).trim(), - }; -} - -function main() { - const cfg = JSON.parse(fs.readFileSync(defPath, 'utf8')); - cfg.gitea = cfg.gitea && typeof cfg.gitea === 'object' ? cfg.gitea : {}; - - let fileGitea = {}; - try { - const raw = JSON.parse(fs.readFileSync(channelPath, 'utf8')); - if (raw && raw.gitea && typeof raw.gitea === 'object') fileGitea = raw.gitea; - } catch (e) { - if (e.code !== 'ENOENT') throw e; - } - - const env = pickEnv(); - const keys = ['base_url', 'owner', 'repo', 'release_tag']; - let changed = false; - - for (const k of keys) { - const fromEnv = env[k]; - const fromFile = - fileGitea[k] != null && String(fileGitea[k]).trim() !== '' ? String(fileGitea[k]).trim() : ''; - const val = (fromEnv && String(fromEnv).trim()) || fromFile; - if (!val) continue; - if (cfg.gitea[k] !== val) { - cfg.gitea[k] = val; - changed = true; - } - } - - if (!changed) { - console.log( - 'inject-release-channel: no overrides (set GITEA_* env and/or fill fractured-release-channel.json)' - ); - return; - } - - fs.writeFileSync(defPath, `${JSON.stringify(cfg, null, 2)}\n`, 'utf8'); - console.log('inject-release-channel: wrote gitea.* into default-launcher.json for this build'); -} - -main();