Files
BillyOutlast a8a82aeb76 ci: fix fallow SARIF upload, upstream-sync token dead end, guard coverage; refresh vuln docs (#124)
* ci: fix fallow SARIF, upstream-sync token dead end, guard coverage; refresh vuln docs

Four independent defects found while reviewing the open Dependabot queue.

fallow.yml
- `--format` and `--output` are the SAME option (`--output` is a documented
  alias of `--format`), so `--format sarif --output fallow.sarif` aborted with
  "the argument '--format <FORMAT>' cannot be used multiple times" and never
  wrote the file. The following `upload-sarif` step then failed with
  "Path does not exist: fallow.sarif", reddening `Fallow full scan` on master
  and on every PR. Use `--output-file` for the path.
- Pin the CLI to 3.27.0. A bare `npx fallow` resolves the `latest` dist-tag at
  run time and was observed returning 3.3.0 on one run and 3.27.0 on another,
  so the full scan could silently disagree with the `audit` job (which pins
  3.27.0 through the action's `version:` input).

upstream-sync.yml
- Org policy forces a read-only GITHUB_TOKEN and no SYNC_PAT secret exists, so
  `gh pr create` can never succeed ("Resource not accessible by integration")
  and the run failed with exit 1 every day. The branch is already pushed by
  that point, so degrade to a warning plus a ready-to-click compare URL in the
  step summary instead of failing.

check-lockfiles.js
- `newIDE/visual-tests/package-lock.json` existed on disk but was absent from
  the guard's list (10 lockfiles, 9 guarded). Added.

dependabot.yml
- Drop the `ignore:` block pinning electron to 32.x. Both manifests are now on
  the current release line (newIDE/electron-app 44.4.3, GDJS/Runtime/Electron
  44.3.0), so the block only suppressed legitimate updates.
- `exclude-patterns` on the newIDE/app weekly group: for 0.x packages a
  "minor" bump is breaking by semver convention, so the group silently carried
  migrations like three 0.160->0.186 and spine-pixi-v7 4.2->4.3 alongside real
  patch bumps. One such group PR grew into a 19-package migration.
- Raise newIDE/app's `open-pull-requests-limit` 5 -> 10; 6 PRs are already
  open there, so new ones were being suppressed at the source.

KNOWN_VULNS.md
- Rewritten against the live API and the manifests. The previous revision
  claimed the fork stays on electron 32.x with 47 advisories (it is on 44.4.3),
  and that all non-electron vulnerabilities were remediated (the API reports
  49 open alerts: 22 high, 25 medium, 2 low, across 18 packages).
- Documented two guard gaps: the `tar` floor (`< 6.2.1`) is bypassed by the
  guard's same-major rule while advisories cover `<= 7.5.17`, and
  newIDE/visual-tests was unguarded.
- Recorded the four no-patch advisories as accepted risk.

DEPENDABOT_PR_REMEDIATION_PLAN.md
- Full review of the 32 open PRs: 6 root causes, all reproduced locally, with
  fixes verified before being proposed.

* fix(deps): repair three lockfiles already desynced on master; gate lockfile sync in CI

`npm ci` hard-fails when package.json and package-lock.json disagree, but CI
only installed the directories some later job happened to need. Three lockfiles
had rotted on master without anything noticing:

  GDJS                        16 missing packages (@pixi/* 7.4.3)
  newIDE/electron-app/app      6 missing + 3 invalid (electron 44.4.3, @electron/get)
  SharedLibs/TileMapHelper    36 missing + 2 invalid (@webassemblyjs/*, terser)

Each only failed the moment someone tried to install in that directory — which
is how the GDJS one stayed invisible while PR #121 was being reviewed for an
unrelated reason.

Regenerated all three with `npm install --package-lock-only`. All ten manifests
now install clean under `npm ci --dry-run`:

  GDevelop.js GDJS GDJS/tests newIDE/app newIDE/electron-app
  newIDE/electron-app/app newIDE/web-app newIDE/visual-tests
  SharedLibs/TileMapHelper SharedLibs/ThreeAddons      -> rc=0, 0 sync errors

Added a `lockfile-sync` matrix job over all ten directories so drift fails on
the PR that causes it. `--ignore-scripts` keeps postinstall hooks
(patch-package, import-resources) out of it — the job only asserts that the
lockfile resolves.

`node scripts/security/check-lockfiles.js` still exits 0.

* fix(deps): bump adm-zip 0.6.0 -> 0.6.1, closing 2 high advisories

`[email protected]` is vulnerable to GHSA-7q85-xj36-vmfc (high, patched in 0.6.1).
It is a *direct* dependency declared as `^0.6.0` in both manifests, so 0.6.1 was
already permitted — the lockfiles were simply pinned at the vulnerable 0.6.0 and
never re-resolved.

Verified the overrides already present in both manifests (`^0.6.0`) are harmless
here: a fresh resolution with or without them yields 0.6.1. Raising the override
to `^0.6.1` is NOT the fix — npm rejects it with EOVERRIDE because the override
would conflict with the direct dependency. Regenerating is the correct fix.

  newIDE/app/package-lock.json          adm-zip 0.6.0 -> 0.6.1
  newIDE/electron-app/package-lock.json adm-zip 0.6.0 -> 0.6.1

Closes 2 of the 22 open high-severity alerts. The remaining `adm-zip` medium
advisory (GHSA-vwc7-r8mq-g2x9) has no patch and stays documented as accepted
risk in KNOWN_VULNS.md.

All ten manifests verified: `npm ci --dry-run` rc=0, 0 sync errors, and
`node scripts/security/check-lockfiles.js` exits 0.

* docs: record execution status for the PR remediation plan

Queue 32 -> 25 open; 8 merged. Adds the evidence used to justify each merge,
the repo fixes landed in PR #124, the three master lockfiles found already
desynced (GDJS, newIDE/electron-app/app, SharedLibs/TileMapHelper) and the
adm-zip 0.6.0 -> 0.6.1 bump that closed 2 high advisories.

Also records the rebase mechanics blocker: PRs 18/26/37/39/40/104 do not move
on '@dependabot rebase' because they were edited by hand; only #40 reports it.

* Merge master into chore/ci-remediation

Master advanced 10 merges (our own dependency PRs), so the lockfiles this
branch regenerated were stale against it. The merge reverted
newIDE/electron-app/package-lock.json to master's pre-regeneration copy;
regenerated it again (adm-zip stays 0.6.1).

All ten manifests verified in the merged state: npm ci --dry-run rc=0,
0 sync errors, guard exits 0.

* ci: run lockfile-sync as one job, not a 10-way matrix

Each matrix entry was a dry-run resolve taking a few seconds, so the 10-way
matrix bought ~30s of wall clock at the cost of 10 runners. The queue
contention that produced was starving the slower build-libgd and Jest jobs,
which dominate the workflow anyway.

Now a single job loops the same ten directories, continues past a failure so
one run reports every drifted manifest, and exits 1 at the end. Verified both
paths locally: on a good tree it prints "All lockfiles in sync." and exits 0;
with one drifted manifest it prints the per-directory ❌ with the npm
Missing:/Invalid: lines, keeps checking the rest, and exits 1.
2026-09-21 20:51:37 -04:00
..