From 6f80575b80936e001ed158b0695e0c75401bd81b Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 30 Jun 2026 10:43:20 +0200 Subject: [PATCH 1/3] chore(deps): bump bpmn-visualization from 0.44.0 to 0.48.0 Bump bpmn-visualization to 0.48.0 in bpmn-rendering-miwg-test-suite and adapt the surrounding code and CI. - main.ts: switch from promise chains to async/await for clearer, linear control flow. The fetch and the response.ok check are split so only the fetch is wrapped in try/catch, avoiding a 'throw caught locally' warning while preserving the original error behavior. - Add a build workflow that runs on push to main and on PRs, path-filtered to the subproject. - Pin all third-party GitHub Actions to full commit SHAs (with version comments) to harden the supply chain; bonitasoft/* actions are external here since the repo lives under the process-analytics org. --- .github/workflows/build-miwg-test-suite.yml | 34 +++ .github/workflows/pr-metadata-checks.yml | 2 +- .../package-lock.json | 199 ++++++++++++++---- bpmn-rendering-miwg-test-suite/package.json | 2 +- bpmn-rendering-miwg-test-suite/src/main.ts | 25 ++- 5 files changed, 210 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/build-miwg-test-suite.yml diff --git a/.github/workflows/build-miwg-test-suite.yml b/.github/workflows/build-miwg-test-suite.yml new file mode 100644 index 0000000..57d262b --- /dev/null +++ b/.github/workflows/build-miwg-test-suite.yml @@ -0,0 +1,34 @@ +name: Build MIWG Test Suite + +on: + push: + branches: + - main + paths: + - 'bpmn-rendering-miwg-test-suite/**' + - '.github/workflows/build-miwg-test-suite.yml' + pull_request: + paths: + - 'bpmn-rendering-miwg-test-suite/**' + - '.github/workflows/build-miwg-test-suite.yml' + +defaults: + run: + working-directory: bpmn-rendering-miwg-test-suite + +jobs: + build: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version-file: bpmn-rendering-miwg-test-suite/.nvmrc + cache: npm + cache-dependency-path: bpmn-rendering-miwg-test-suite/package-lock.json + - name: Install dependencies + run: npm ci + - name: Build + run: npm run build diff --git a/.github/workflows/pr-metadata-checks.yml b/.github/workflows/pr-metadata-checks.yml index 3f93ebf..cded04f 100644 --- a/.github/workflows/pr-metadata-checks.yml +++ b/.github/workflows/pr-metadata-checks.yml @@ -11,4 +11,4 @@ jobs: pull-requests: write # post comments when the PR title doesn't match the "Conventional Commits" rules steps: - name: Check Pull Request title - uses: bonitasoft/actions/packages/pr-title-conventional-commits@v2 + uses: bonitasoft/actions/packages/pr-title-conventional-commits@dbdf8b0b5cd8289307663b1fd06413a115b24940 # v3.6.1 diff --git a/bpmn-rendering-miwg-test-suite/package-lock.json b/bpmn-rendering-miwg-test-suite/package-lock.json index 36cd833..57a84d1 100644 --- a/bpmn-rendering-miwg-test-suite/package-lock.json +++ b/bpmn-rendering-miwg-test-suite/package-lock.json @@ -7,7 +7,7 @@ "name": "bpmn-rendering-miwg-test-suite", "license": "Apache-2.0", "dependencies": { - "bpmn-visualization": "0.44.0" + "bpmn-visualization": "0.48.0" }, "devDependencies": { "playwright-chromium": "~1.52.0", @@ -106,6 +106,18 @@ "@emnapi/runtime": "^1.7.1" } }, + "node_modules/@nodable/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, "node_modules/@oxc-project/types": { "version": "0.137.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.137.0.tgz", @@ -470,6 +482,18 @@ "node": ">=0.4.0" } }, + "node_modules/anynum": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.1.tgz", + "integrity": "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -477,15 +501,15 @@ "dev": true }, "node_modules/bpmn-visualization": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/bpmn-visualization/-/bpmn-visualization-0.44.0.tgz", - "integrity": "sha512-XQfR0yRtSdmUktch6XFWeMWt8eQ1DDtZ7c/bqBgCZvSAnDl08UmKysznynHmXXVChIU8yZvLtn2kw0hyZQlGfA==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/bpmn-visualization/-/bpmn-visualization-0.48.0.tgz", + "integrity": "sha512-nCFhWXMzbj8z0BpaIvNgOKgp9fVmSwuiKtlzpILPjBBh7d/dN4u/+hsGdgLGF5Fj3XBpT1P1h6A6a6E+JLMjwg==", + "license": "Apache-2.0", "dependencies": { "@typed-mxgraph/typed-mxgraph": "~1.0.8", - "es-toolkit": "~1.16.0", - "fast-xml-parser": "4.4.1", - "mxgraph": "4.2.2", - "strnum": "1.0.5" + "es-toolkit": "~1.46.1", + "fast-xml-parser": "5.8.0", + "mxgraph": "4.2.2" } }, "node_modules/create-require": { @@ -514,26 +538,48 @@ } }, "node_modules/es-toolkit": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.16.0.tgz", - "integrity": "sha512-eNJh3zF1KmAHRYd1D8rFi1cMFMCjrC6tumBfwuuZdSur97mED/ifyeBoGzxS11L4owCMx3XSmWTo6oxJQkdGng==" + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.46.1.tgz", + "integrity": "sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, + "node_modules/fast-xml-builder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", + "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "path-expression-matcher": "^1.5.0", + "xml-naming": "^0.1.0" + } }, "node_modules/fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz", + "integrity": "sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" } ], + "license": "MIT", "dependencies": { - "strnum": "^1.0.5" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.2.0", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.3.0", + "xml-naming": "^0.1.0" }, "bin": { "fxparser": "src/cli/cli.js" @@ -876,6 +922,21 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/path-expression-matcher": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.1.tgz", + "integrity": "sha512-h7bxdzhHk8Knyc4Tj+jMaa7fEEoUJy7p1qtbVgkYg1Uhpe5Np5VuGXCRZnkZvU+Q42M1vStt0ifa3ueykRJPmQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -1000,9 +1061,19 @@ } }, "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.1.tgz", + "integrity": "sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "anynum": "^1.0.1" + } }, "node_modules/tinyglobby": { "version": "0.2.17", @@ -1179,6 +1250,21 @@ } } }, + "node_modules/xml-naming": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", + "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -1262,6 +1348,11 @@ "@tybys/wasm-util": "^0.10.3" } }, + "@nodable/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==" + }, "@oxc-project/types": { "version": "0.137.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.137.0.tgz", @@ -1445,6 +1536,11 @@ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, + "anynum": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.1.tgz", + "integrity": "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==" + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -1452,15 +1548,14 @@ "dev": true }, "bpmn-visualization": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/bpmn-visualization/-/bpmn-visualization-0.44.0.tgz", - "integrity": "sha512-XQfR0yRtSdmUktch6XFWeMWt8eQ1DDtZ7c/bqBgCZvSAnDl08UmKysznynHmXXVChIU8yZvLtn2kw0hyZQlGfA==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/bpmn-visualization/-/bpmn-visualization-0.48.0.tgz", + "integrity": "sha512-nCFhWXMzbj8z0BpaIvNgOKgp9fVmSwuiKtlzpILPjBBh7d/dN4u/+hsGdgLGF5Fj3XBpT1P1h6A6a6E+JLMjwg==", "requires": { "@typed-mxgraph/typed-mxgraph": "~1.0.8", - "es-toolkit": "~1.16.0", - "fast-xml-parser": "4.4.1", - "mxgraph": "4.2.2", - "strnum": "1.0.5" + "es-toolkit": "~1.46.1", + "fast-xml-parser": "5.8.0", + "mxgraph": "4.2.2" } }, "create-require": { @@ -1482,16 +1577,29 @@ "dev": true }, "es-toolkit": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.16.0.tgz", - "integrity": "sha512-eNJh3zF1KmAHRYd1D8rFi1cMFMCjrC6tumBfwuuZdSur97mED/ifyeBoGzxS11L4owCMx3XSmWTo6oxJQkdGng==" + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.46.1.tgz", + "integrity": "sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==" + }, + "fast-xml-builder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", + "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", + "requires": { + "path-expression-matcher": "^1.5.0", + "xml-naming": "^0.1.0" + } }, "fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz", + "integrity": "sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==", "requires": { - "strnum": "^1.0.5" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.2.0", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.3.0", + "xml-naming": "^0.1.0" } }, "fdir": { @@ -1622,6 +1730,11 @@ "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", "dev": true }, + "path-expression-matcher": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.1.tgz", + "integrity": "sha512-h7bxdzhHk8Knyc4Tj+jMaa7fEEoUJy7p1qtbVgkYg1Uhpe5Np5VuGXCRZnkZvU+Q42M1vStt0ifa3ueykRJPmQ==" + }, "picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -1692,9 +1805,12 @@ "dev": true }, "strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.1.tgz", + "integrity": "sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==", + "requires": { + "anynum": "^1.0.1" + } }, "tinyglobby": { "version": "0.2.17", @@ -1767,6 +1883,11 @@ "tinyglobby": "^0.2.17" } }, + "xml-naming": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", + "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==" + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/bpmn-rendering-miwg-test-suite/package.json b/bpmn-rendering-miwg-test-suite/package.json index 8a0496d..c0da74e 100644 --- a/bpmn-rendering-miwg-test-suite/package.json +++ b/bpmn-rendering-miwg-test-suite/package.json @@ -12,7 +12,7 @@ "generate-screenshots": "node --loader ts-node/esm scripts/generate-screenshots.ts" }, "dependencies": { - "bpmn-visualization": "0.44.0" + "bpmn-visualization": "0.48.0" }, "devDependencies": { "playwright-chromium": "~1.52.0", diff --git a/bpmn-rendering-miwg-test-suite/src/main.ts b/bpmn-rendering-miwg-test-suite/src/main.ts index 9fdcbd2..13e3c24 100644 --- a/bpmn-rendering-miwg-test-suite/src/main.ts +++ b/bpmn-rendering-miwg-test-suite/src/main.ts @@ -3,24 +3,27 @@ import {BpmnVisualization, FitType} from "bpmn-visualization"; const bpmnVisualization = new BpmnVisualization({container: 'bpmn-container', renderer: {ignoreBpmnColors: false}}); -const fetchBpmnContent = (url: string) => fetch(url) - .then(response => { - if (!response.ok) { - throw Error(String(response.status)); - } - return response.text(); - }) - .catch(error => { +const fetchBpmnContent = async (url: string) => { + let response: Response; + try { + response = await fetch(url); + } catch (error) { throw new Error(`Unable to fetch ${url}. ${error}`); - }); + } + if (!response.ok) { + throw new Error(`Unable to fetch ${url}. Error: ${response.status}`); + } + return response.text(); +}; const parameters = new URLSearchParams(window.location.search); const bpmnFileName = parameters.get('bpmnFileName'); -fetchBpmnContent(`/${bpmnFileName}.bpmn`).then(bpmn => bpmnVisualization.load(bpmn, { +const bpmn = await fetchBpmnContent(`/${bpmnFileName}.bpmn`); +bpmnVisualization.load(bpmn, { fit: { type: FitType.Center, margin: 10 } -})); +}); From cec0a28cd282c59da23fbf08fa4a8f2e0b66052b Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 30 Jun 2026 11:27:39 +0200 Subject: [PATCH 2/3] ci: skip playwright browser download in build job npm ci hung for over 20 minutes in the playwright-chromium postinstall, which downloads a full Chromium binary. The build job only runs tsc && vite build, which needs the playwright npm package but not the browser, so skip the download with PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1. The browser is only required by the generate-screenshots script, which this workflow does not run. --- .github/workflows/build-miwg-test-suite.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build-miwg-test-suite.yml b/.github/workflows/build-miwg-test-suite.yml index 57d262b..d65ee2a 100644 --- a/.github/workflows/build-miwg-test-suite.yml +++ b/.github/workflows/build-miwg-test-suite.yml @@ -29,6 +29,10 @@ jobs: cache: npm cache-dependency-path: bpmn-rendering-miwg-test-suite/package-lock.json - name: Install dependencies + # The build (tsc && vite build) does not need a browser; only the generate-screenshots script does. + # Skip the Chromium download so npm ci does not hang on the playwright-chromium postinstall. + env: + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 run: npm ci - name: Build run: npm run build From 3e9e55971c72ea1f37e6540790a2bce33d3e2044 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 30 Jun 2026 11:30:19 +0200 Subject: [PATCH 3/3] ci: use npm ci --ignore-scripts instead of playwright skip env Replace PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD with npm ci --ignore-scripts to prevent the playwright-chromium postinstall (Chromium download) from hanging the build job. --ignore-scripts is independent of playwright's env-var naming, which has changed across releases, so it keeps working across future playwright upgrades. The build only runs tsc && vite build, which needs no install scripts (fsevents is darwin-only). --- .github/workflows/build-miwg-test-suite.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-miwg-test-suite.yml b/.github/workflows/build-miwg-test-suite.yml index d65ee2a..abde15b 100644 --- a/.github/workflows/build-miwg-test-suite.yml +++ b/.github/workflows/build-miwg-test-suite.yml @@ -29,10 +29,9 @@ jobs: cache: npm cache-dependency-path: bpmn-rendering-miwg-test-suite/package-lock.json - name: Install dependencies - # The build (tsc && vite build) does not need a browser; only the generate-screenshots script does. - # Skip the Chromium download so npm ci does not hang on the playwright-chromium postinstall. - env: - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - run: npm ci + # The build (tsc && vite build) does not need install scripts. Skipping them avoids the + # playwright-chromium postinstall that downloads Chromium and hangs the job. Using --ignore-scripts + # instead of PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD keeps this working across playwright version upgrades. + run: npm ci --ignore-scripts - name: Build run: npm run build