feat(launcher): sync release assets from manifest or attachment list (no fixed exe name)

- default files []: resolve sync list from patch-manifest keys, else discover
  release attachments (exclude launcher artifacts).
- Explicit files[] still overrides; strip deprecated Wow-patched.exe on merge.
- listReleaseAttachmentNames + fetchGiteaReleaseRecord helpers.
- Version 1.0.7; README config docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Docker Build
2026-05-10 22:04:48 -05:00
parent f409ffad12
commit 9cef99f0ff
9 changed files with 193 additions and 29 deletions
@@ -75,8 +75,10 @@ async function loadManifest(cfg) {
*/
async function patchesMatchManifest(cfg, manifest, onStatus) {
if (!validateManifest(manifest)) return false;
const { buildResolvedReleaseFiles } = require('./release-sync');
const entries = await buildResolvedReleaseFiles(cfg, manifest);
const gameDir = cfg.game_dir;
for (const entry of cfg.files || []) {
for (const entry of entries) {
if (!entry.from_release) continue;
const spec = manifest.files[entry.source];
if (!spec || !spec.sha256) return false;
@@ -98,7 +100,9 @@ async function patchesMatchManifest(cfg, manifest, onStatus) {
async function verifyInstalledAgainstManifest(cfg, manifest) {
if (!validateManifest(manifest)) return;
for (const entry of cfg.files || []) {
const { buildResolvedReleaseFiles } = require('./release-sync');
const entries = await buildResolvedReleaseFiles(cfg, manifest);
for (const entry of entries) {
if (!entry.from_release) continue;
const spec = manifest.files[entry.source];
if (!spec || !spec.sha256) {
@@ -119,8 +123,10 @@ async function verifyInstalledAgainstManifest(cfg, manifest) {
async function recordPatchState(cfg, manifest) {
if (!validateManifest(manifest)) return;
const { buildResolvedReleaseFiles } = require('./release-sync');
const entries = await buildResolvedReleaseFiles(cfg, manifest);
const shas = {};
for (const entry of cfg.files || []) {
for (const entry of entries) {
if (!entry.from_release) continue;
const parts = String(entry.dest).replace(/\\/g, '/').split('/').filter(Boolean);
const destAbs = path.join(cfg.game_dir, ...parts);