Skip to content

[Feature] Dependabot version updates watch one of thirteen package.json manifests, through an updater that cannot read the lockfile beside it #1596

Description

@pathosDev

Problem

The repository tracks thirteen package.json manifests. .github/dependabot.yml
watches one of them for version updates — the root, through the npm ecosystem —
and that one through an updater that cannot read the lockfile beside it.

manifest lockfile beside it in dependabot.yml
/ bun.lock npm
/docs bun.lock —
/devtools-ui bun.lock —
/benchmarks/comparison bun.lock —
/tests/integration/brokers none (the runner images install unfrozen) —
/examples/{chat,voice}/frontend-{angular,next,react,svelte} (8) package-lock.json and bun.lock (#1402) —

Two consequences, both measured against the PR list rather than assumed:

  1. Twelve manifests get no version updates at all. What they do get is security
    updates — Dependabot opens those from the dependency graph regardless of this file — which
    is why the npm_and_yarn group across N directories PRs exist (build(deps): bump the npm_and_yarn group across 6 directories with 5 updates #307, chore(deps): bump the npm_and_yarn group across 4 directories with 12 updates #343, chore(deps): bump the npm_and_yarn group across 9 directories with 7 updates #472, chore(deps): bump the npm_and_yarn group across 2 directories with 2 updates #890,
    chore(deps): bump the npm_and_yarn group across 2 directories with 1 update #1401, build(deps): bump the npm_and_yarn group across 4 directories with 4 updates #1518). All of them touched the examples, one (chore(deps): bump the npm_and_yarn group across 9 directories with 7 updates #472) also docs/; none ever
    proposed a non-advisory bump. Keeping those trees current is a hand sweep ([Feature] Dependency sweep 2026-09: every manifest to latest, and off the deprecated nats package #1520 did all thirteen at
    once, and the issue body says why: "Dependabot sees only some of them").

  2. The root entry sees only majors. The npm ecosystem has no Bun code
    (npm_and_yarn/ in dependabot-core does not mention bun.lock once), so for the root it
    runs in manifest-only mode. A caret range already admits every minor and patch, so an
    in-range update changes nothing Dependabot can see, and the npm-minor-and-patch group
    configured since b5464448 has never opened a PR in five months — every root PR
    Dependabot has opened, thirteen from chore(deps)(deps-dev): bump @types/node from 20.19.39 to 25.6.0 #29 to chore(deps)(deps-dev): bump @types/better-sqlite3 from 7.6.13 to 9.6.0 #908, is a major. The PRs it does open edit package.json alone and go red on every
    frozen-lockfile step until someone regenerates bun.lock by hand — [Feature] Auto-sync bun.lock on Dependabot PRs (or evaluate Renovate) #817's whole
    complaint. [Security] bun.lock currently pins fastify 5.10.0 with advisory-carrying transitives (find-my-way 9.6.0, fast-uri 3.1.0/4.1.0) inside the runtime closure, and no workflow queries an advisory database #779 is what the blind spot costs: all nineteen high advisories the runtime
    closure carried were fixed by releases inside the declared ranges, i.e. exactly the
    in-range updates that never surfaced.

Proposed fix

Watch every manifest, through the ecosystem that can write the lockfile CI installs
from.

  • package-ecosystem: "bun" for the five Bun-installed manifests — /, /docs,
    /devtools-ui, /benchmarks/comparison, /tests/integration/brokers. The ecosystem is
    GA (no beta flag), supports version updates, and its updater runs
    bun install <dep>@<version> --save-text-lockfile and commits the regenerated
    bun.lock, so the PR arrives green on --frozen-lockfile instead of red by
    construction. It also sees the pinned versions, so in-range minor/patch updates finally
    surface as the grouped daily PR the current config has always described. Security updates
    are unaffected: they never came from this entry.
  • package-ecosystem: "npm" with directories: for the eight example frontends —
    npm ci from package-lock.json is what examples.yml builds, and the bun half of the
    pair is [Security] Example frontends carry an unmaintained second lockfile: Dependabot patches package-lock.json while bun.lock keeps the vulnerable version #1402's open decision. A minor-and-patch group spans the eight directories (one
    PR a day, not eight), and a group-by: dependency-name group lands a major in the
    chat/voice pair at once instead of as two PRs.
  • One entry per Bun directory rather than one directories: list. A grouped PR across
    directories is a single PR, and the DevTools UI half of it is red by construction: any
    bump to devtools-ui/package.json moves the source-hash that bun run check:ui
    compares, so the PR needs bun run build:ui before it is green — the same step a source
    change there needs. Separate entries keep that from blocking a root or docs bump.
  • A guard in tests/unit/ci/WorkflowHygiene.test.ts, which already parses this file:
    every tracked package.json is watched by exactly one entry, and the entry's ecosystem is
    npm iff a package-lock.json sits beside the manifest. A fourteenth manifest without an
    entry, or a stale path, is a red test rather than a silent gap.

Notes

  • The updater's Bun is 1.3.14 and reads lockfileVersion ≤ 1. dependabot-core#15896
    (2026-08-14) made a newer lockfile a hard DependencyFileNotSupported rather than the
    silent v1 downgrade it was before; dependabot-core#16071 raises the ceiling and is still
    open. Bun 1.4 stamps a fresh lockfile 2 but preserves an existing 1 on every
    re-save, so root, docs, benchmarks and the examples (all born under 1.3) are fine —
    devtools-ui/bun.lock was born under 1.4.0 (65548aa9) and is 2. The content of a v1
    and a v2 lockfile is byte-identical apart from the stamp (v2 only added parse-time
    strictness), so the file is restamped to 1 and the guard pins the ceiling with the
    reference, to be raised when #16071 lands.
  • Side finding, ui:install: bun install --cwd devtools-ui is the one CI install
    that is not --frozen-lockfile, and the frozen-install guard cannot see it because it is a
    package.json script rather than a workflow run: line. Recorded here, not folded in.
  • Side finding, commit prefixes: prefix: "chore(deps)" + include: "scope" yields
    chore(deps)(deps-dev): … (every root PR in the log). The rewritten entries use
    prefix: "chore" so Dependabot's scope produces chore(deps) / chore(deps-dev), the
    two scopes AGENTS.md lists. The github-actions entry is left alone.
  • The file header still says PRs open against main; they target the default branch,
    develop.
  • Same shape as Dependabot splits a codeql-action bump into one PR per sub-path, and each half fails CI by construction #1348 and Dependabot re-proposes @types/node majors against the deliberate engines-floor pin (4th round: #481) #906: behaviour of a bot that no gate can see, fixed by a rule in
    this file plus a comment saying why the rule exists, plus a test that reads the file.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    dependenciesPull requests that update a dependency fileenhancementNew feature or requestinfrastructureCI / build / live-integration testspriority: mediumUseful, not urgent

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions