Skip to content

Commit 2810358

Browse files
Fix: contain Dependabot PR fan-out (#427)
## What changed - Consolidates eleven Cargo update blocks into one `directories:` block. - Groups the same dependency across fleet crates with `group-by: dependency-name`. - Reduces the Cargo version-PR ceiling from 55 to 3. - Makes both Dependabot fixer scripts generate bounded, grouped configurations. - Makes the coverage fixer consolidate directories and refuse already-duplicated ecosystems instead of appending more blocks. ## Root cause Dependabot applies its open-PR limit per update block. Eleven Cargo blocks using the default limit of five admitted 55 simultaneous PRs. The coverage fixer could reproduce the same N×5 shape. ## Validation - Fixture tests for creation, consolidation, idempotency, and duplicate refusal - `bash -n` - `yq eval` - `git diff --check` - ShellCheck (only two pre-existing warnings: dynamic source and required-but-unused finding JSON)
1 parent d37567e commit 2810358

3 files changed

Lines changed: 78 additions & 79 deletions

File tree

.github/dependabot.yml

Lines changed: 23 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,58 +10,26 @@ updates:
1010
patterns:
1111
- "*"
1212

13-
# Rust dependencies
14-
- package-ecosystem: "cargo"
15-
directory: "/robot-repo-automaton"
16-
schedule:
17-
interval: "weekly"
18-
19-
- package-ecosystem: "cargo"
20-
directory: "/shared-context"
21-
schedule:
22-
interval: "weekly"
23-
24-
- package-ecosystem: "cargo"
25-
directory: "/bots/echidnabot"
26-
schedule:
27-
interval: "weekly"
28-
29-
- package-ecosystem: "cargo"
30-
directory: "/bots/glambot"
31-
schedule:
32-
interval: "weekly"
33-
34-
- package-ecosystem: "cargo"
35-
directory: "/bots/rhodibot"
36-
schedule:
37-
interval: "weekly"
38-
39-
- package-ecosystem: "cargo"
40-
directory: "/bots/seambot"
41-
schedule:
42-
interval: "weekly"
43-
44-
- package-ecosystem: "cargo"
45-
directory: "/bots/sustainabot"
46-
schedule:
47-
interval: "weekly"
48-
49-
- package-ecosystem: "cargo"
50-
directory: "/bots/finishingbot"
51-
schedule:
52-
interval: "weekly"
53-
54-
- package-ecosystem: "cargo"
55-
directory: "/bots/accessibilitybot"
56-
schedule:
57-
interval: "weekly"
58-
59-
- package-ecosystem: "cargo"
60-
directory: "/bots/cipherbot"
61-
schedule:
62-
interval: "weekly"
63-
64-
- package-ecosystem: "cargo"
65-
directory: "/bots/panicbot"
66-
schedule:
67-
interval: "weekly"
13+
# Rust dependencies. Keep every Cargo project in one update entry so the
14+
# open-PR limit applies to the fleet as a whole, rather than once per bot.
15+
# Grouping by dependency name updates a shared crate across every affected
16+
# project in one PR instead of opening one PR per Cargo.lock.
17+
- package-ecosystem: "cargo"
18+
directories:
19+
- "/robot-repo-automaton"
20+
- "/shared-context"
21+
- "/bots/echidnabot"
22+
- "/bots/glambot"
23+
- "/bots/rhodibot"
24+
- "/bots/seambot"
25+
- "/bots/sustainabot"
26+
- "/bots/finishingbot"
27+
- "/bots/accessibilitybot"
28+
- "/bots/cipherbot"
29+
- "/bots/panicbot"
30+
schedule:
31+
interval: "weekly"
32+
open-pull-requests-limit: 3
33+
groups:
34+
fleet-dependencies:
35+
group-by: dependency-name

scripts/fix-dependabot-coverage.sh

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,48 +51,68 @@ if [[ ! -f "${DEPENDABOT_FILE}" ]]; then
5151
exit 1
5252
fi
5353

54+
if ! command -v yq >/dev/null 2>&1; then
55+
echo "ERROR: yq v4 is required to update Dependabot coverage safely." >&2
56+
exit 1
57+
fi
58+
5459
# --- Functions ---
5560

5661
# Check whether a given ecosystem+directory pair already exists in dependabot.yml.
57-
# Uses a simple text-based check: looks for the ecosystem line followed by
58-
# the directory line within a few lines of each other.
5962
entry_exists() {
6063
local ecosystem="$1"
6164
local directory="$2"
6265

63-
# Normalise directory for matching: dependabot uses "/" for root,
64-
# "/subdir" for subdirectories.
65-
local dir_pattern
66-
if [[ "${directory}" == "/" ]]; then
67-
dir_pattern='directory: "/"'
68-
else
69-
dir_pattern="directory: \"${directory}\""
70-
fi
71-
72-
# Search for the ecosystem+directory pair within the file.
73-
# We look for both on adjacent lines (within 5 lines of each other).
74-
if awk -v eco="\"${ecosystem}\"" -v dir="${dir_pattern}" '
75-
/package-ecosystem:/ && $0 ~ eco { found_eco=NR }
76-
found_eco && NR <= found_eco+5 && $0 ~ dir { exit 0 }
77-
END { exit 1 }
78-
' "${DEPENDABOT_FILE}"; then
79-
return 0
80-
else
81-
return 1
82-
fi
66+
ECOSYSTEM="${ecosystem}" DIRECTORY="${directory}" yq -e '
67+
.updates[]
68+
| select(."package-ecosystem" == strenv(ECOSYSTEM))
69+
| select(
70+
.directory == strenv(DIRECTORY) or
71+
(.directories[]? == strenv(DIRECTORY))
72+
)
73+
' "${DEPENDABOT_FILE}" >/dev/null 2>&1
8374
}
8475

8576
# Append a new ecosystem+directory entry to dependabot.yml.
8677
append_entry() {
8778
local ecosystem="$1"
8879
local directory="$2"
80+
local entry_count
81+
82+
entry_count="$(ECOSYSTEM="${ecosystem}" yq '
83+
[.updates[] | select(."package-ecosystem" == strenv(ECOSYSTEM))] | length
84+
' "${DEPENDABOT_FILE}")"
85+
86+
if [[ "${entry_count}" -gt 1 ]]; then
87+
echo "ERROR: ${ecosystem} already has ${entry_count} update blocks." >&2
88+
echo "Consolidate them into one directories: block before adding coverage." >&2
89+
return 1
90+
fi
91+
92+
if [[ "${entry_count}" -eq 1 ]]; then
93+
ECOSYSTEM="${ecosystem}" DIRECTORY="${directory}" yq -i '
94+
(.updates[] | select(."package-ecosystem" == strenv(ECOSYSTEM))) |= (
95+
.directories = (((.directories // [.directory]) + [strenv(DIRECTORY)]) | unique)
96+
| del(.directory)
97+
| ."open-pull-requests-limit" =
98+
([(."open-pull-requests-limit" // 3), 3] | min)
99+
| .groups."coverage-shared"."group-by" = "dependency-name"
100+
)
101+
' "${DEPENDABOT_FILE}"
102+
echo " CONSOLIDATED: ${ecosystem} @ ${directory}"
103+
return 0
104+
fi
89105

90106
cat >> "${DEPENDABOT_FILE}" <<EOF
91107
92108
- package-ecosystem: "${ecosystem}"
93109
directory: "${directory}"
94110
schedule:
95-
interval: "daily"
111+
interval: "weekly"
112+
open-pull-requests-limit: 3
113+
groups:
114+
dependency-updates:
115+
patterns: ["*"]
96116
EOF
97117
echo " ADDED: ${ecosystem} @ ${directory}"
98118
}

scripts/fix-dependabot.sh

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,24 @@ HEADER
7474
directory="/"
7575
fi
7676

77+
if [[ "${eco}" == "github-actions" ]]; then
78+
limit=2
79+
group=actions
80+
else
81+
limit=3
82+
group=dependency-updates
83+
fi
84+
7785
cat <<EOF
7886
- package-ecosystem: "${eco}"
7987
directory: "${directory}"
8088
schedule:
8189
interval: "weekly"
8290
target-branch: "main"
83-
open-pull-requests-limit: 5
91+
open-pull-requests-limit: ${limit}
92+
groups:
93+
${group}:
94+
patterns: ["*"]
8495
EOF
8596
done
8697
} > "${REPO_PATH}/.github/dependabot.yml"

0 commit comments

Comments
 (0)