From c1fc9a7298f2894fec6db45220ef278ea1c5208d Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 3 Jul 2026 10:28:54 -0700 Subject: [PATCH 1/2] fix(deps): drop stale @aws-sdk/core override + add desktop packaging CI gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Windows desktop installer failed to package: electron-builder's production-dependency walk rejected `@aws-sdk/core@3.974.26` because `@aws-sdk/credential-provider-env` (resolved in the `--legacy` deploy closure) requires `^3.974.27`. Root cause: an incidental `pnpm.overrides` entry pinning `@aws-sdk/core` to the exact version `3.974.26` (added without rationale in an unrelated commit) which force-held core below what its consumers now demand — the classic stale-exact-pin trap. Fixes / prevention: - Remove the `@aws-sdk/core` override so the deploy closure resolves core to 3.974.27 (satisfies all consumers). The main lockfile still resolves core to 3.974.26 for its own consistent graph, so the published @runfusion/fusion closure is unchanged (no changeset needed). Verified locally: a fresh `@fusion/desktop build` + `electron-builder --dir` now passes the dependency walk with no manual patch. - Add an advisory, path-gated `Desktop packaging` job to pr-checks.yml that reproduces electron-builder's production-dependency walk (`--dir`, no NSIS/signing) plus a `pnpm dedupe --check` early-warning. This is the only check that validates the packageable closure, which previously ran only in release/manual workflows — so any future dependency skew now fails at PR time, for ANY dependency, instead of at release/local-build time. Kept OUT of the required set so the thin merge gate [Lint, Typecheck, Build, Gate] and branch protection are untouched; promote to blocking by adding it to required checks. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/pr-checks.yml | 57 +++++++++++++++++++++++++++++++++ package.json | 1 - pnpm-lock.yaml | 1 - 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 5edec3f778..63989f531d 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -130,3 +130,60 @@ jobs: - name: Gate tests (curated engine-core + CI-shape) run: pnpm test:gate + + # FNXC:CI 2026-07-03-11:10: + # Desktop packaging validation. electron-builder's production-dependency walk is the ONLY thing that + # validates the packageable dependency closure, and it historically ran only in workflow_dispatch / + # release workflows. So a lockfile version skew — e.g. a stale `pnpm.overrides` entry force-holding + # `@aws-sdk/core` at a version its consumers no longer accepted — sailed through the thin gate and only + # detonated at release / local installer build time (the exact incident this job prevents). Reproduce + # that walk on PRs that touch the dependency closure so any future skew fails HERE, for ANY dependency. + # + # ADVISORY, not in the required set: the merge gate stays exactly [Lint, Typecheck, Build, Gate] and + # branch protection is untouched. Promote to merge-blocking by adding "Desktop packaging" to the repo's + # required checks. Path-gated + electron-builder --dir (skips NSIS/signing) keeps it cheap; the + # dependency walk that catches skew runs regardless of target platform, so ubuntu suffices. + desktop-pack: + name: Desktop packaging + runs-on: ubuntu-latest + timeout-minutes: 25 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + # Need history to diff against the PR base for the path gate below. + fetch-depth: 0 + + - name: Detect dependency / desktop-closure changes + id: changes + run: | + base="${{ github.event.pull_request.base.sha }}" + if git diff --name-only "$base"...HEAD \ + | grep -qE '^(pnpm-lock\.yaml|package\.json|pnpm-workspace\.yaml|packages/(desktop|dashboard|engine|core)/|plugins/)'; then + echo "relevant=true" >> "$GITHUB_OUTPUT" + else + echo "relevant=false" >> "$GITHUB_OUTPUT" + echo "No dependency/desktop-closure changes; skipping the packaging walk." + fi + + - name: Setup Node.js and pnpm + if: steps.changes.outputs.relevant == 'true' + uses: ./.github/actions/setup-node-pnpm + + # Early-warning (item 3): a lockfile that can still be deduped often signals the version drift that + # later breaks packaging. Non-fatal — surfaces as a warning so it informs without failing on benign + # dedupe opportunities. + - name: Lockfile dedupe check (early warning) + if: steps.changes.outputs.relevant == 'true' + run: pnpm dedupe --check || echo "::warning::pnpm dedupe --check found dedupable/inconsistent dependencies; run 'pnpm dedupe' and review." + + - name: Build desktop package (stages the production deploy closure) + if: steps.changes.outputs.relevant == 'true' + run: pnpm --filter @fusion/desktop build + + # Authoritative check: electron-builder's production-dependency walk over the staged closure. + # --dir skips installer/signing but still FAILS if any production dependency's declared version + # range is unsatisfied in the closure — which is exactly the aws-sdk skew that broke the release. + - name: Validate packageable closure (electron-builder --dir) + if: steps.changes.outputs.relevant == 'true' + run: pnpm --filter @fusion/desktop exec electron-builder --projectDir deploy --dir --publish never diff --git a/package.json b/package.json index a3c4bf0fac..3d133d11fb 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,6 @@ "protobufjs" ], "overrides": { - "@aws-sdk/core": "3.974.26", "@types/node": "^25.5.2", "protobufjs": "^7.5.8" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e1124a728..7c457e9fdb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,6 @@ settings: excludeLinksFromLockfile: false overrides: - '@aws-sdk/core': 3.974.26 '@types/node': ^25.5.2 protobufjs: ^7.5.8 From 682de0e050cca31f05eacc13490615a0d8f1caf5 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 3 Jul 2026 11:27:03 -0700 Subject: [PATCH 2/2] fix(ci): move desktop-pack out of pr-checks.yml into its own workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The desktop-pack job broke the CI-shape invariant (ci-workflow.test.ts) that pr-checks.yml contains exactly [build, gate, lint, typecheck] — the gate's job set maps 1:1 to branch-protection required checks. Extract the advisory desktop-packaging validation into desktop-packaging.yml, still PR-triggered and non-required, so the thin gate stays pure. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/desktop-packaging.yml | 79 +++++++++++++++++++++++++ .github/workflows/pr-checks.yml | 59 +----------------- 2 files changed, 82 insertions(+), 56 deletions(-) create mode 100644 .github/workflows/desktop-packaging.yml diff --git a/.github/workflows/desktop-packaging.yml b/.github/workflows/desktop-packaging.yml new file mode 100644 index 0000000000..b4b9c7e92e --- /dev/null +++ b/.github/workflows/desktop-packaging.yml @@ -0,0 +1,79 @@ +name: Desktop packaging + +# FNXC:CI 2026-07-03-18:20: +# Advisory desktop-packaging validation, kept in its OWN workflow so the thin merge gate +# (pr-checks.yml) stays exactly [Lint, Typecheck, Build, Gate] — that file's job set maps +# 1:1 to the branch-protection required checks, and the CI-shape test enforces the invariant. +# electron-builder's production-dependency walk is the ONLY thing that validates the packageable +# dependency closure, and it historically ran only in workflow_dispatch / release workflows. So a +# lockfile version skew — e.g. a stale `pnpm.overrides` entry force-holding `@aws-sdk/core` at a +# version its consumers no longer accepted — sailed through the gate and only detonated at release / +# local installer build time (the exact incident this job prevents). Reproduce that walk on PRs that +# touch the dependency closure so any future skew fails HERE, for ANY dependency. +# +# ADVISORY, not in the required set: branch protection is untouched. Promote to merge-blocking by +# adding "Desktop packaging" to the repo's required checks. Path-gated + electron-builder --dir +# (skips NSIS/signing) keeps it cheap; the dependency walk that catches skew runs regardless of +# target platform, so ubuntu suffices. + +on: + pull_request: + branches: [main] + +concurrency: + group: desktop-packaging-${{ github.ref }} + cancel-in-progress: true + +# Least-privilege token: only reads the repo (checkout + cache). +permissions: + contents: read + +# FN-4863: Opt JavaScript actions into Node 24 ahead of GitHub's forced cutover on 2026-06-02. +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" + +jobs: + desktop-pack: + name: Desktop packaging + runs-on: ubuntu-latest + timeout-minutes: 25 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + # Need history to diff against the PR base for the path gate below. + fetch-depth: 0 + + - name: Detect dependency / desktop-closure changes + id: changes + run: | + base="${{ github.event.pull_request.base.sha }}" + if git diff --name-only "$base"...HEAD \ + | grep -qE '^(pnpm-lock\.yaml|package\.json|pnpm-workspace\.yaml|packages/(desktop|dashboard|engine|core)/|plugins/)'; then + echo "relevant=true" >> "$GITHUB_OUTPUT" + else + echo "relevant=false" >> "$GITHUB_OUTPUT" + echo "No dependency/desktop-closure changes; skipping the packaging walk." + fi + + - name: Setup Node.js and pnpm + if: steps.changes.outputs.relevant == 'true' + uses: ./.github/actions/setup-node-pnpm + + # Early-warning (item 3): a lockfile that can still be deduped often signals the version drift that + # later breaks packaging. Non-fatal — surfaces as a warning so it informs without failing on benign + # dedupe opportunities. + - name: Lockfile dedupe check (early warning) + if: steps.changes.outputs.relevant == 'true' + run: pnpm dedupe --check || echo "::warning::pnpm dedupe --check found dedupable/inconsistent dependencies; run 'pnpm dedupe' and review." + + - name: Build desktop package (stages the production deploy closure) + if: steps.changes.outputs.relevant == 'true' + run: pnpm --filter @fusion/desktop build + + # Authoritative check: electron-builder's production-dependency walk over the staged closure. + # --dir skips installer/signing but still FAILS if any production dependency's declared version + # range is unsatisfied in the closure — which is exactly the aws-sdk skew that broke the release. + - name: Validate packageable closure (electron-builder --dir) + if: steps.changes.outputs.relevant == 'true' + run: pnpm --filter @fusion/desktop exec electron-builder --projectDir deploy --dir --publish never diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 63989f531d..7da29fd619 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -131,59 +131,6 @@ jobs: - name: Gate tests (curated engine-core + CI-shape) run: pnpm test:gate - # FNXC:CI 2026-07-03-11:10: - # Desktop packaging validation. electron-builder's production-dependency walk is the ONLY thing that - # validates the packageable dependency closure, and it historically ran only in workflow_dispatch / - # release workflows. So a lockfile version skew — e.g. a stale `pnpm.overrides` entry force-holding - # `@aws-sdk/core` at a version its consumers no longer accepted — sailed through the thin gate and only - # detonated at release / local installer build time (the exact incident this job prevents). Reproduce - # that walk on PRs that touch the dependency closure so any future skew fails HERE, for ANY dependency. - # - # ADVISORY, not in the required set: the merge gate stays exactly [Lint, Typecheck, Build, Gate] and - # branch protection is untouched. Promote to merge-blocking by adding "Desktop packaging" to the repo's - # required checks. Path-gated + electron-builder --dir (skips NSIS/signing) keeps it cheap; the - # dependency walk that catches skew runs regardless of target platform, so ubuntu suffices. - desktop-pack: - name: Desktop packaging - runs-on: ubuntu-latest - timeout-minutes: 25 - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - # Need history to diff against the PR base for the path gate below. - fetch-depth: 0 - - - name: Detect dependency / desktop-closure changes - id: changes - run: | - base="${{ github.event.pull_request.base.sha }}" - if git diff --name-only "$base"...HEAD \ - | grep -qE '^(pnpm-lock\.yaml|package\.json|pnpm-workspace\.yaml|packages/(desktop|dashboard|engine|core)/|plugins/)'; then - echo "relevant=true" >> "$GITHUB_OUTPUT" - else - echo "relevant=false" >> "$GITHUB_OUTPUT" - echo "No dependency/desktop-closure changes; skipping the packaging walk." - fi - - - name: Setup Node.js and pnpm - if: steps.changes.outputs.relevant == 'true' - uses: ./.github/actions/setup-node-pnpm - - # Early-warning (item 3): a lockfile that can still be deduped often signals the version drift that - # later breaks packaging. Non-fatal — surfaces as a warning so it informs without failing on benign - # dedupe opportunities. - - name: Lockfile dedupe check (early warning) - if: steps.changes.outputs.relevant == 'true' - run: pnpm dedupe --check || echo "::warning::pnpm dedupe --check found dedupable/inconsistent dependencies; run 'pnpm dedupe' and review." - - - name: Build desktop package (stages the production deploy closure) - if: steps.changes.outputs.relevant == 'true' - run: pnpm --filter @fusion/desktop build - - # Authoritative check: electron-builder's production-dependency walk over the staged closure. - # --dir skips installer/signing but still FAILS if any production dependency's declared version - # range is unsatisfied in the closure — which is exactly the aws-sdk skew that broke the release. - - name: Validate packageable closure (electron-builder --dir) - if: steps.changes.outputs.relevant == 'true' - run: pnpm --filter @fusion/desktop exec electron-builder --projectDir deploy --dir --publish never + # Advisory desktop-packaging validation lives in its OWN workflow (desktop-packaging.yml) so this + # thin gate stays exactly [Lint, Typecheck, Build, Gate] — the job set here maps 1:1 to the + # branch-protection required checks (CI-shape test enforces the invariant).