ci: enforce lint coverage and Node LTS quality gates

This commit is contained in:
NuklearRabbit
2026-07-29 16:27:16 +02:00
parent a7ab2d6cc8
commit 8e580a0b13
7 changed files with 1494 additions and 8 deletions
+19
View File
@@ -0,0 +1,19 @@
name: ForgeFlow quality gate
on:
push:
branches: [main]
pull_request:
jobs:
quality:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run quality
- run: npm audit --omit=dev --audit-level=high
+1
View File
@@ -0,0 +1 @@
22
+38 -3
View File
@@ -1,7 +1,9 @@
ForgeFlow 0.10.0 source manifest ForgeFlow 0.10.0 source manifest
SHA-256 BYTES PATH SHA-256 BYTES PATH
(The manifest excludes itself, dependencies and generated release artifacts.) (The manifest excludes itself, dependencies and generated release artifacts.)
a6ce7703a16e24b307af98b06e99e7f6a4230d854bc6ed9b745510603a03926d 370 .gitea/workflows/quality.yml
755f4db7d76bfec0963ef051748a82810c0d58acd4ffd823aa6928a5167fceb4 58 .gitignore 755f4db7d76bfec0963ef051748a82810c0d58acd4ffd823aa6928a5167fceb4 58 .gitignore
f14b4987904bcb5814e4459a057ed4d20f58a633152288a761214dcd28780b56 3 .nvmrc
89545860bd6f7566da81edc8328cd2a1ebf33e81a4b0dcf2cec74338c05e8cac 1753 build-windows.ps1 89545860bd6f7566da81edc8328cd2a1ebf33e81a4b0dcf2cec74338c05e8cac 1753 build-windows.ps1
0970821475a4452aa19e447e9397a95db836791f16890a1a83fd748ac033dc86 8830 build/icon-128.png 0970821475a4452aa19e447e9397a95db836791f16890a1a83fd748ac033dc86 8830 build/icon-128.png
09112c1425ca953d8dd8b2bcfd221e5a84b9f81752f7168f360e295030cbc8f2 521 build/icon-16.png 09112c1425ca953d8dd8b2bcfd221e5a84b9f81752f7168f360e295030cbc8f2 521 build/icon-16.png
@@ -13,6 +15,38 @@ ca32a76e708d565c4af659f0f4d2615fc32114c3f75aec1454862a3ed1e72c41 2263
25048ed854e8ce8fece115e555c98d25507b002f8019b6ae717b54604c868c50 46223 build/icon.ico 25048ed854e8ce8fece115e555c98d25507b002f8019b6ae717b54604c868c50 46223 build/icon.ico
16efd2fca83004f781eae40ae0f706a004ce0bddf338dd087b8adf7eb10c1d84 85704 build/icon.png 16efd2fca83004f781eae40ae0f706a004ce0bddf338dd087b8adf7eb10c1d84 85704 build/icon.png
5f4aca19a35cbcaffa1a6993ce96b7d66052ec2b286022f2af74594e8a310568 15712 CHANGELOG.md 5f4aca19a35cbcaffa1a6993ce96b7d66052ec2b286022f2af74594e8a310568 15712 CHANGELOG.md
8e84a93929c6f359f090d67c16c7eea4a1c123e8170d3bd9b269f047f8560215 284299 coverage/tmp/coverage-10244-1785335090178-0.json
8e0457e916f249b7a3389894df3f2b664ad8797db1c792e0c107f57ca9f56bec 303088 coverage/tmp/coverage-13124-1785335091173-0.json
f219872995f4c34d4d6628c6ac7859ee51f3441cc03272ab1653da7acf7959bd 354433 coverage/tmp/coverage-18204-1785335089962-0.json
95bee92580b38e4488d5ec5653b0d92e674ad8fa537cee9705143f079cc4993d 317634 coverage/tmp/coverage-19144-1785335101870-0.json
50158ef242c1b19100949f7beb8e40f81f84fed97c6816db672a7c2a6e897016 329357 coverage/tmp/coverage-23492-1785335091006-0.json
93a3e9159d736053e543cff989779d91f1d21e10f0ff6d3e554e867a54513ee3 342639 coverage/tmp/coverage-25088-1785335089991-0.json
fa262d693cb615960736e290858dddedee49a1e7db5f863d8649fcbcbf10afbd 335944 coverage/tmp/coverage-3052-1785335090008-0.json
07850b9d5fce7c6b271cbdef84af7e079f1034a4630699f0c584694228951ae6 282471 coverage/tmp/coverage-34880-1785335091385-0.json
a11df85ec00b29553b6d396f36fc567db2982a619321e0fdd33ec2a628da4fec 298998 coverage/tmp/coverage-36452-1785335089751-0.json
9b7a2ad01bca25678f57d254f93cd894cc34ec2243aef93cb93905dd7ce41a9f 301397 coverage/tmp/coverage-36468-1785335089356-0.json
70aafc483e2158fb120049e59655a4aed7836d25ad91e66dfe8c50016670ee6f 344612 coverage/tmp/coverage-39296-1785335095999-0.json
28278f6e18e9bab0e5c684596591b4cbf814ac477510d8796d036be678086dbb 288319 coverage/tmp/coverage-39956-1785335090649-0.json
ec355623c897784f803bbcf4531ead16c863283d9e58f8d423781706b5300c20 304507 coverage/tmp/coverage-42012-1785335089647-0.json
1d06d8d2a2f2a6ede0c6912dcd8c9fada4955f52b1dbf85d330b950c4feead89 318325 coverage/tmp/coverage-42356-1785335091476-0.json
4dce288c8da452d2b12cfed7de6efd0f36ebb64ba0262220b964bd991e427cd5 352005 coverage/tmp/coverage-43752-1785335089626-0.json
21ed865ff22e016b6da1f4d1886b6f87fd1e4a471c6606d6bcb748c6bdd30b75 111307 coverage/tmp/coverage-44028-1785335091684-0.json
f05901535653256b5a05b8a8f8aa6b5019a54c8d099adbe1d702713a8f00d12c 89174 coverage/tmp/coverage-47072-1785335088858-0.json
d2a8f1f5fff4f7b090b182b6f7666ef06d08b1b0be497b0f7061e5a5234145d0 360056 coverage/tmp/coverage-47440-1785335147487-0.json
3d4927400e2212ce74d9026ab678d9766ce16917d3830bc4e5f47cb48fae6381 344933 coverage/tmp/coverage-48456-1785335092567-0.json
5987881f09402e371a5998b8f5208e41156e4d9a270a4d74aa70512faba406ab 302345 coverage/tmp/coverage-52268-1785335090577-0.json
4d1dde6f8cca29f40b2dd018cdefc9ef2201941323ad53a0af892c6bd4afebc9 345120 coverage/tmp/coverage-58112-1785335104676-0.json
32aa3248a14053e28632d42490d0a4d3b082fa8406e37c35645a9a7cd6e3d628 302512 coverage/tmp/coverage-58124-1785335090307-0.json
ee85e5c654ded256066430543d4fea9394db545e4a92054bad731f65cec7dc73 310268 coverage/tmp/coverage-58672-1785335091776-0.json
b2b99cf55dc44ce6fdb87f9bd62425d72231dc0f04558d0706a2ac7619a4a505 321056 coverage/tmp/coverage-58732-1785335091791-0.json
33c28c4ef5b3c3c89616ff6b6f4f1ce00aca3169c93315f428a69ca62207cfb8 357939 coverage/tmp/coverage-59060-1785335093199-0.json
d2ecb7c43ded5e946f3dbc1067809d5ddb12d74f359c2e62756d243e2cfdc33f 421305 coverage/tmp/coverage-59124-1785335092134-0.json
49af6e452b0f192565453e6a8dffc979948a9cbbeb7453e1ce325cfc47f751b3 296834 coverage/tmp/coverage-59200-1785335090383-0.json
c4b99d78def3b2fe1223e80f3a6648bec128dc89b5b45c1d308d435241e51f21 360489 coverage/tmp/coverage-59612-1785335091346-0.json
72501c88d2e3699ca478f031db0ac31859d39b66db96f66fd8887feda6158a11 367435 coverage/tmp/coverage-59824-1785335091587-0.json
43a7b9b9f701313bbe345c3e7baaa51525d25675fa2cad1a14d72b6a16676730 344498 coverage/tmp/coverage-59992-1785335090598-0.json
24ff83322c312d1a71d3446994011d107daf1da2c06e66c2819ad8782c02f633 335634 coverage/tmp/coverage-60172-1785335098629-0.json
405c0992d25d0779ae42ff7728e5471d737ea446f8c11b6af911927b6be48d11 327419 coverage/tmp/coverage-60332-1785335088943-0.json
21cb96e7afe71b1dc791c818dedd244d92f9a6ed4d9ffbb3022ccb187e1bdf0f 852 docs/ACCEPTANCE.md 21cb96e7afe71b1dc791c818dedd244d92f9a6ed4d9ffbb3022ccb187e1bdf0f 852 docs/ACCEPTANCE.md
a17f95d96d3c9fbc69d870874e6fbb7472091adefc454b24f835db1279511d72 8296 docs/ARCHITECTURE.md a17f95d96d3c9fbc69d870874e6fbb7472091adefc454b24f835db1279511d72 8296 docs/ARCHITECTURE.md
72e846f591c47a0291e7466e58e052d3d5afcf551c4e6c848632ac3c552a1244 3043 docs/CURRENT_STATE.md 72e846f591c47a0291e7466e58e052d3d5afcf551c4e6c848632ac3c552a1244 3043 docs/CURRENT_STATE.md
@@ -71,6 +105,7 @@ b6a178215dab054006aae4944b8ffcbe7f6100691c30f08e221e3a2dbff4cd42 2147
0adfeabb98168a7fc0b02bae8d4af436d3c59459012fb05b2216e02265190128 3139 docs/STITCH_REVIEW.md 0adfeabb98168a7fc0b02bae8d4af436d3c59459012fb05b2216e02265190128 3139 docs/STITCH_REVIEW.md
4625a10ebd3c749f60b2a7bef6b1716cd05dbc44ccceba0491a1b46bc293c195 4883 docs/TEST_MATRIX.md 4625a10ebd3c749f60b2a7bef6b1716cd05dbc44ccceba0491a1b46bc293c195 4883 docs/TEST_MATRIX.md
dbbd9fa96988e7543e98c85da864adaadd3057815f18d20a3b3ccb5c540a169d 4558 docs/UPDATING.md dbbd9fa96988e7543e98c85da864adaadd3057815f18d20a3b3ccb5c540a169d 4558 docs/UPDATING.md
4bffda594058697345569d937d7a524f094ac85a0f338f0ef18fcf3f94d8c299 1292 eslint.config.js
c230b931abf2293d2d44b7a69b94c35f1142c093cc46b88739a0de5cbd6d1896 1532 examples/gitea-actions/deploy.yml c230b931abf2293d2d44b7a69b94c35f1142c093cc46b88739a0de5cbd6d1896 1532 examples/gitea-actions/deploy.yml
4c792cc9fd57ed36da291300c252a6ef75b08a249cf6f2561e23c4c22522138a 1477 examples/gitea-actions/rollback.yml 4c792cc9fd57ed36da291300c252a6ef75b08a249cf6f2561e23c4c22522138a 1477 examples/gitea-actions/rollback.yml
577f3fa2131a3baa84549a6523f5816ef9da94f5bac6bc274d4588b6e7ab6594 5688 examples/server/forgeflow-deploy 577f3fa2131a3baa84549a6523f5816ef9da94f5bac6bc274d4588b6e7ab6594 5688 examples/server/forgeflow-deploy
@@ -81,8 +116,8 @@ c230b931abf2293d2d44b7a69b94c35f1142c093cc46b88739a0de5cbd6d1896 1532
4a561ead5ba7cdfaf4efce91842a4308c5f2a77980205879d83835efb8a579db 1067 LICENSE 4a561ead5ba7cdfaf4efce91842a4308c5f2a77980205879d83835efb8a579db 1067 LICENSE
3b16a087c73b600415394dff8b8e34e7f7519e48fde1cf443007b2e11ca77b27 13123 main.cjs 3b16a087c73b600415394dff8b8e34e7f7519e48fde1cf443007b2e11ca77b27 13123 main.cjs
91a984a89dd57a084b9a2331763cacdb061582fb590f13df379d92c1a77a2ee1 352 OVERLAY-INSTRUCTIONS.md 91a984a89dd57a084b9a2331763cacdb061582fb590f13df379d92c1a77a2ee1 352 OVERLAY-INSTRUCTIONS.md
efe2f75ec8bfdbad8e2ee68d0f2c4b412ba460c6b841163d7853f56d5b7b63ea 130468 package-lock.json f3e2a262e251eb165f342dc3c184625ec10d56e536b5a987199b9944f463eee9 181069 package-lock.json
f4ac31dd2266494085409ad5fc8bc440aa871296f7c64042495b6b14dec49084 4427 package.json 5162819eb594c6ff65e73180f2f95c3fd5be940c2ce6b06b0aaf4b297cf9c616 4715 package.json
82865e814a82628b778c53ec83bcda26bf1109d8bb14c11208530089f4dc96db 10522 preload.cjs 82865e814a82628b778c53ec83bcda26bf1109d8bb14c11208530089f4dc96db 10522 preload.cjs
abe5dd6fd68f2970cd19ef134094907c67219061d8fe9a1a08324c78de4ad437 484 PUBLISH-AND-ENABLE-UPDATE.cmd abe5dd6fd68f2970cd19ef134094907c67219061d8fe9a1a08324c78de4ad437 484 PUBLISH-AND-ENABLE-UPDATE.cmd
f018383f755352ca448e2ebb1e19b1dba412a3eb793d61e64b02953e300754fd 10538 Publish-ForgeFlow-Release.ps1 f018383f755352ca448e2ebb1e19b1dba412a3eb793d61e64b02953e300754fd 10538 Publish-ForgeFlow-Release.ps1
@@ -118,7 +153,7 @@ e89b54e7e3174b4b0a1dcd9058d8344e29431f9d16d0e6bb8d11559b691440a0 2508
17e2a53f61cd7faba461b9f332967143087eaac95b72001462292976278ca305 7782 src/main/repository-service.cjs 17e2a53f61cd7faba461b9f332967143087eaac95b72001462292976278ca305 7782 src/main/repository-service.cjs
52b6d88ed1f5c904a13cdde92e5f96d1e2b5971ceef49862152197353cdc6490 27928 src/main/server-inventory.cjs 52b6d88ed1f5c904a13cdde92e5f96d1e2b5971ceef49862152197353cdc6490 27928 src/main/server-inventory.cjs
afef3841a3948b2121f8fba809aae4ea3da71bd2fda86973ba50200a5b1f89b2 14894 src/main/ssh-service.cjs afef3841a3948b2121f8fba809aae4ea3da71bd2fda86973ba50200a5b1f89b2 14894 src/main/ssh-service.cjs
80426e8bdd7259c6ed47d1acb9f6cbbbe4b1075f74c8ce5fd759044d9af09d59 149912 src/main/unraid-deployment-service.cjs b90285d4bece4705554b2dae72f3db61a614b87f57b28a03b1e94d55f1ad4ad0 149903 src/main/unraid-deployment-service.cjs
b654a9e45044ad32c61fabe4a6d897288615ec83739b53e3241ff881e32f56bd 21677 src/main/update-service.cjs b654a9e45044ad32c61fabe4a6d897288615ec83739b53e3241ff881e32f56bd 21677 src/main/update-service.cjs
953b027fedcee2c2396ec5c8cf938013f2630d8ef76ab5e917a02d723303234f 241018 src/renderer/app.js 953b027fedcee2c2396ec5c8cf938013f2630d8ef76ab5e917a02d723303234f 241018 src/renderer/app.js
16efd2fca83004f781eae40ae0f706a004ce0bddf338dd087b8adf7eb10c1d84 85704 src/renderer/assets/itworx-mark.png 16efd2fca83004f781eae40ae0f706a004ce0bddf338dd087b8adf7eb10c1d84 85704 src/renderer/assets/itworx-mark.png
+39
View File
@@ -0,0 +1,39 @@
import js from "@eslint/js";
export default [
{
ignores: ["build/**", "dist/**", "node_modules/**", ".playwright-mcp/**", "SOURCE_MANIFEST.txt"],
},
{
files: ["**/*.{js,cjs,mjs}"],
languageOptions: {
ecmaVersion: "latest",
sourceType: "module",
globals: {
Buffer: "readonly", clearInterval: "readonly", clearTimeout: "readonly", console: "readonly",
document: "readonly", fetch: "readonly", FormData: "readonly", globalThis: "readonly",
process: "readonly", queueMicrotask: "readonly", requestAnimationFrame: "readonly",
setInterval: "readonly", setTimeout: "readonly", URL: "readonly", URLSearchParams: "readonly",
window: "readonly", confirm: "readonly", localStorage: "readonly", structuredClone: "readonly",
},
},
rules: {
...js.configs.recommended.rules,
"no-control-regex": "off",
"no-empty": ["error", { allowEmptyCatch: true }],
"no-undef": "off",
"no-unused-vars": "off",
"no-useless-escape": "off",
"no-eval": "error",
"no-implied-eval": "error",
eqeqeq: ["error", "always", { null: "ignore" }],
},
},
{
files: ["tests/**/*.mjs"],
rules: {
"no-regex-spaces": "off",
"no-unsafe-finally": "off",
},
},
];
+1388 -2
View File
File diff suppressed because it is too large Load Diff
+8 -2
View File
@@ -10,6 +10,8 @@
"dev": "electron . --dev", "dev": "electron . --dev",
"demo": "node scripts/serve-demo.mjs", "demo": "node scripts/serve-demo.mjs",
"test": "node --test tests/*.test.mjs", "test": "node --test tests/*.test.mjs",
"lint": "eslint .",
"coverage": "c8 --check-coverage --lines 55 --functions 55 --branches 45 --statements 55 node --test tests/*.test.mjs",
"verify": "node scripts/verify.mjs", "verify": "node scripts/verify.mjs",
"dist:win": "electron-builder --win nsis portable && node scripts/write-release-checksums.mjs && node scripts/prune-dist.mjs", "dist:win": "electron-builder --win nsis portable && node scripts/write-release-checksums.mjs && node scripts/prune-dist.mjs",
"dist:linux": "electron-builder --linux AppImage && node scripts/prune-dist.mjs", "dist:linux": "electron-builder --linux AppImage && node scripts/prune-dist.mjs",
@@ -20,11 +22,15 @@
"deployments:audit": "electron scripts/audit-installed-deployments.cjs", "deployments:audit": "electron scripts/audit-installed-deployments.cjs",
"release:binary": "electron scripts/publish-binary-release.cjs", "release:binary": "electron scripts/publish-binary-release.cjs",
"manifest": "node scripts/generate-source-manifest.mjs", "manifest": "node scripts/generate-source-manifest.mjs",
"check": "npm run verify && npm test" "check": "npm run verify && npm run lint && npm test",
"quality": "npm run check && npm run coverage"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "9.39.5",
"c8": "10.1.3",
"electron": "43.2.0", "electron": "43.2.0",
"electron-builder": "26.15.3" "electron-builder": "26.15.3",
"eslint": "9.39.5"
}, },
"build": { "build": {
"appId": "be.jenscaers.forgeflow", "appId": "be.jenscaers.forgeflow",
+1 -1
View File
@@ -1699,7 +1699,7 @@ printf 'existingPreservePaths=%s\\n' "$existing_preserve_paths"
) : []; ) : [];
const missingDeploymentFiles = []; const missingDeploymentFiles = [];
for (const file of localDeploymentFiles) { for (const file of localDeploymentFiles) {
if (!Boolean((await fs.stat(file).catch(() => null))?.isFile())) missingDeploymentFiles.push(file); if (!(await fs.stat(file).catch(() => null))?.isFile()) missingDeploymentFiles.push(file);
} }
if (deploymentMode === "push-bundle") checks.push({ if (deploymentMode === "push-bundle") checks.push({
id: "local-deployment-file", id: "local-deployment-file",