feat(launcher): bake Gitea base_url/owner/repo into pack from env or channel file
- inject-release-channel.js merges GITEA_* (or fractured-release-channel.json) into default-launcher.json before electron-builder. - CI passes existing GITEA_BASE_URL/OWNER/REPO secrets into the Windows pack job. - npm run pack:win/publish:win run the injector; workflows use npm run pack:win. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -38,9 +38,13 @@ jobs:
|
|||||||
cache-dependency-path: tools/fractured-launcher-electron/package-lock.json
|
cache-dependency-path: tools/fractured-launcher-electron/package-lock.json
|
||||||
|
|
||||||
- name: Install and pack (NSIS + portable)
|
- 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: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
npx electron-builder --win nsis portable --x64 --publish never
|
npm run pack:win
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -74,11 +74,15 @@ jobs:
|
|||||||
|
|
||||||
- name: Install and pack (NSIS + portable)
|
- name: Install and pack (NSIS + portable)
|
||||||
working-directory: tools/fractured-launcher-electron
|
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: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
# --publish never: on tagged checkouts electron-builder otherwise tries to
|
# pack:win runs inject-release-channel.js then electron-builder --publish never
|
||||||
# push to GitHub releases and fails without GH_TOKEN (we upload via Gitea).
|
npm run pack:win
|
||||||
npx electron-builder --win nsis portable --x64 --publish never
|
|
||||||
|
|
||||||
- name: Stage launcher files for upload
|
- name: Stage launcher files for upload
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ Produces under **`dist/`**:
|
|||||||
| `Fractured-Launcher-${version}-Setup.exe` (NSIS) | **Recommended for players** — supports seamless **auto-update** and restart. |
|
| `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. |
|
| `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)
|
||||||
|
|
||||||
|
**`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).
|
||||||
|
|
||||||
|
- **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.
|
||||||
|
|
||||||
## Auto-update behaviour
|
## Auto-update behaviour
|
||||||
|
|
||||||
- **Packaged** builds only (`npm run pack:win` output). In `npm start` dev mode, update checks are skipped (button still explains that).
|
- **Packaged** builds only (`npm run pack:win` output). In `npm start` dev mode, update checks are skipped (button still explains that).
|
||||||
@@ -81,7 +90,7 @@ CI workflow **Sync release to Gitea** (`.github/workflows/gitea-release-sync.yml
|
|||||||
|
|
||||||
**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 workflow must create a new Gitea release** and Gitea needs `target_commitish` (defaults to **`main`** in the upload script if unset).
|
||||||
|
|
||||||
**Player `launcher.json`:** set **`gitea`** so **`from_release`** files resolve on your instance:
|
**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`**:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"gitea": {
|
"gitea": {
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"gitea": {
|
||||||
|
"base_url": "",
|
||||||
|
"owner": "",
|
||||||
|
"repo": "",
|
||||||
|
"release_tag": "latest"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,8 +9,8 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "electron .",
|
"start": "electron .",
|
||||||
"pack:win": "electron-builder --win nsis portable --x64 --publish never",
|
"pack:win": "node scripts/inject-release-channel.js && electron-builder --win nsis portable --x64 --publish never",
|
||||||
"publish:win": "electron-builder --win nsis portable --x64 --publish never"
|
"publish:win": "node scripts/inject-release-channel.js && electron-builder --win nsis portable --x64 --publish never"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
#!/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();
|
||||||
Reference in New Issue
Block a user