infra: release_gitea.mjs --skip-build + playwright in devDeps

Two release-pipeline fixes that previously forced manual workarounds.

- scripts/release_gitea.mjs no longer unconditionally runs npm run dist:win.
  New --skip-build flag, plus auto-skip when all 3 required artifacts
  (Setup-<v>.exe, Setup-<v>.exe.blockmap, latest.yml) already exist for
  the requested version. The previous behaviour re-ran the entire test
  suite + electron-builder on every release attempt — unusable when the
  test path was broken.
- playwright ^1.59.1 added to devDependencies. test:e2e / test:e2e:guide
  / test:e2e:full now invoke node scripts/smoke-test*.js directly instead
  of "npm exec --yes --package=playwright -- node ...", which failed with
  MODULE_NOT_FOUND when npm exec could not resolve playwright on the fly.
  No browser binaries needed — the smoke tests drive Electron via
  _electron, not a browser.

All test paths verified after the change: test:e2e, test:e2e:guide,
test:e2e:full, test:merge-split, test:e2e:update-logic — all pass with
the simplified scripts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xRangerDE 2026-05-03 15:29:17 +02:00
parent 707c98e19d
commit b4faf67db7
3 changed files with 85 additions and 8 deletions

48
package-lock.json generated
View File

@ -19,6 +19,7 @@
"electron-builder": "^24.9.0",
"eslint": "^10.1.0",
"eslint-plugin-security": "^4.0.0",
"playwright": "^1.59.1",
"typescript": "^5.3.0",
"typescript-eslint": "^8.57.1"
}
@ -3218,6 +3219,21 @@
"dev": true,
"license": "ISC"
},
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@ -4366,6 +4382,38 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/playwright": {
"version": "1.59.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz",
"integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.59.1"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/playwright-core": {
"version": "1.59.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz",
"integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"playwright-core": "cli.js"
},
"engines": {
"node": ">=18"
}
},
"node_modules/plist": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",

View File

@ -9,9 +9,9 @@
"build": "tsc",
"start": "npm run build && electron .",
"test:e2e:update-logic": "node scripts/smoke-test-update-version-logic.js",
"test:e2e": "npm exec --yes --package=playwright -- node scripts/smoke-test.js",
"test:e2e:guide": "npm exec --yes --package=playwright -- node scripts/smoke-test-template-guide.js",
"test:e2e:full": "npm exec --yes --package=playwright -- node scripts/smoke-test-full.js",
"test:e2e": "node scripts/smoke-test.js",
"test:e2e:guide": "node scripts/smoke-test-template-guide.js",
"test:e2e:full": "node scripts/smoke-test-full.js",
"test:e2e:release": "npm run build && npm run test:e2e:update-logic && npm run test:e2e && npm run test:e2e:guide && npm run test:e2e:full",
"test:e2e:stress": "npm run test:e2e:release && npm run test:e2e:release && npm run test:e2e:release",
"pack": "npm run build && electron-builder --dir",
@ -31,6 +31,7 @@
"electron-builder": "^24.9.0",
"eslint": "^10.1.0",
"eslint-plugin-security": "^4.0.0",
"playwright": "^1.59.1",
"typescript": "^5.3.0",
"typescript-eslint": "^8.57.1"
},

View File

@ -28,10 +28,13 @@ function parseArgs(argv) {
if (args.includes("--help") || args.includes("-h")) {
return { help: true };
}
const FLAGS = new Set(["--dry-run", "--skip-build"]);
const dryRun = args.includes("--dry-run");
const version = args.find((arg) => arg !== "--dry-run") || "";
const notes = args.filter((arg) => arg !== "--dry-run").slice(1).join(" ").trim();
return { help: false, dryRun, version, notes };
const skipBuild = args.includes("--skip-build");
const positional = args.filter((arg) => !FLAGS.has(arg));
const version = positional[0] || "";
const notes = positional.slice(1).join(" ").trim();
return { help: false, dryRun, skipBuild, version, notes };
}
function ensureVersion(version) {
@ -122,10 +125,22 @@ async function uploadAssets(baseApi, releaseId, authHeader, releaseDir, files) {
}
}
function hasAllArtifactsForVersion(version) {
const releaseDir = path.join(process.cwd(), "release");
const files = [
`Twitch-VOD-Manager-Setup-${version}.exe`,
`Twitch-VOD-Manager-Setup-${version}.exe.blockmap`,
"latest.yml"
];
return files.every((f) => fs.existsSync(path.join(releaseDir, f)));
}
async function main() {
const args = parseArgs(process.argv);
if (args.help) {
process.stdout.write("Usage: npm run release:gitea -- <version> [release notes] [--dry-run]\n");
process.stdout.write("Usage: npm run release:gitea -- <version> [release notes] [--skip-build] [--dry-run]\n");
process.stdout.write(" --skip-build skip dist:win when release/ already has the 3 required artifacts\n");
process.stdout.write(" (auto-skipped when artifacts already exist for this version)\n");
process.stdout.write("Env: GITEA_BASE_URL, GITEA_REPO_OWNER, GITEA_REPO_NAME, GITEA_TOKEN\n");
return;
}
@ -141,7 +156,20 @@ async function main() {
run("git", ["push", "origin", tag]);
}
// Skip the rebuild when the user passed --skip-build OR when all artifacts
// for this version are already on disk. The original unconditional dist:win
// re-ran the full test suite + electron-builder even when the .exe already
// existed, which made the script unusable when test:e2e was broken.
const artifactsExist = hasAllArtifactsForVersion(version);
const shouldBuild = !args.skipBuild && !artifactsExist;
if (shouldBuild) {
run(NPM_EXECUTABLE, ["run", "dist:win"]);
} else if (artifactsExist) {
process.stdout.write(`Skipping dist:win — artifacts for ${tag} already exist in release/\n`);
} else {
process.stdout.write(`Skipping dist:win (--skip-build)\n`);
}
const assets = ensureAssets(version);
if (args.dryRun) {
process.stdout.write(`Dry run complete for ${tag}\n`);