Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
# allowlist policy, asserted by test/unit/test_install_pins.jl). Dependabot
# advances those pins to the current SHA of the tracked version, so the
# pinning policy itself survives updates.
#
# The #124 rule: minor and patch updates are batched, because they are
# interchangeable in kind; a MAJOR (React 18->19, vite 6->8, TypeScript
# 5->7 -- which #124 landed as one grouped PR, with the build already red
# until #140 repaired it) is a migration, not an update. Every group below
# therefore names its update-types as minor and patch ONLY: an update that
# matches no group opens its own PR, carrying its own review and its own CI
# run. test/unit/test_install_pins.jl asserts this shape, so a new group
# cannot silently go back to batching majors.
version: 2
updates:
# The frontend is Bun-managed: package.json plus bun.lock, no npm/yarn/pnpm
Expand All @@ -25,8 +34,10 @@ updates:
commit-message:
prefix: "chore(deps)"
groups:
frontend:
# Minor and patch in one weekly PR; majors arrive one PR each.
frontend-minor-and-patch:
patterns: ["*"]
update-types: ["minor", "patch"]

- package-ecosystem: "github-actions"
directory: "/"
Expand All @@ -35,5 +46,8 @@ updates:
commit-message:
prefix: "chore(deps)"
groups:
actions:
# Same rule as the frontend: a new major of an action (checkout
# v4.4.0 -> v7.0.1 came through #123) gets a PR of its own.
actions-minor-and-patch:
patterns: ["*"]
update-types: ["minor", "patch"]
30 changes: 30 additions & 0 deletions test/unit/test_install_pins.jl
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,33 @@ end
end
@test isempty(extras)
end

@testset "dependabot never batches a major" begin
# #124 grouped every frontend update, and with nothing requiring the
# checks it merged five framework majors (React 18->19, vite 6->8,
# TypeScript 5->7, react-router-dom 6->7, plotly 2->4) in one PR, with
# tsc already red until #140 repaired it. A major is a migration, not an
# update, so it must open its own PR: a Dependabot group only claims an
# update when its patterns match AND its update-types admit it -- a
# dependency matching no group gets its own PR. Every group must
# therefore NAME its update-types, and never "major". The frontend must
# also stay on the "bun" ecosystem: the 2026-09 security-update runs
# proved this account's npm_and_yarn updater refuses a Bun-managed
# project (see the header of .github/dependabot.yml).
dependabot = YAML.load_file(joinpath(REPO_ROOT, ".github", "dependabot.yml"))
@test dependabot["version"] == 2
ecosystems = Dict{String,Any}()
for u in dependabot["updates"]
@test !haskey(ecosystems, u["package-ecosystem"])
ecosystems[u["package-ecosystem"]] = u
end
@test sort(collect(keys(ecosystems))) == ["bun", "github-actions"]
@test ecosystems["bun"]["directory"] == "/frontend"
for u in dependabot["updates"]
for (_, group) in get(u, "groups", Dict{String,Any}())
update_types = get(group, "update-types", nothing)
@test update_types !== nothing
@test !("major" in update_types)
end
end
end
Loading