-
Notifications
You must be signed in to change notification settings - Fork 0
242 lines (200 loc) · 9.03 KB
/
Copy pathdependabot-verify.yml
File metadata and controls
242 lines (200 loc) · 9.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
name: Verify Dependabot Coverage
on:
pull_request:
paths:
- '.github/dependabot.yml'
- '.github/workflows/dependabot-verify.yml'
- 'package.json'
- 'packages/*/package.json'
push:
branches: [main]
paths:
- '.github/dependabot.yml'
- '.github/workflows/dependabot-verify.yml'
- 'package.json'
- 'packages/*/package.json'
schedule:
# Run weekly on Monday at 04:00 UTC (after Dependabot runs at 03:00)
- cron: '0 4 * * 1'
workflow_dispatch:
permissions:
contents: read
jobs:
verify-coverage:
name: Verify Package Coverage
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '24.x'
- name: Verify all packages are covered
run: |
echo "🔍 Checking Dependabot configuration coverage..."
# Find all package.json files (excluding node_modules)
packages=$(find . -name "package.json" -not -path "*/node_modules/*" -type f)
# Read dependabot config
config_file=".github/dependabot.yml"
if [ ! -f "$config_file" ]; then
echo "❌ Dependabot configuration not found!"
exit 1
fi
echo "📦 Found package.json files:"
echo "$packages"
echo ""
# Extract directories from dependabot.yml
echo "📋 Dependabot monitored directories:"
grep -A 1 "package-ecosystem: 'npm'" "$config_file" | grep "directory:" | awk '{print $2}' | tr -d "'"
echo ""
# Check if root package.json has workspaces configured
has_workspaces=$(jq -r '.workspaces // empty' package.json 2>/dev/null)
root_npm_config=$(grep -A 1 "package-ecosystem: 'npm'" "$config_file" | grep "directory: '/'")
if [ -n "$has_workspaces" ] && [ -n "$root_npm_config" ]; then
echo "ℹ️ npm workspaces detected with root Dependabot config"
echo " Root configuration covers all workspace packages"
echo ""
# Extract all dependabot directories for checking
dependabot_dirs=$(grep -A 1 "package-ecosystem: 'npm'" "$config_file" | grep "directory:" | awk '{print $2}' | tr -d "'")
# Verify all packages are covered (either in workspace or have individual config)
coverage_ok=true
for pkg in $packages; do
pkg_dir=$(dirname "$pkg")
if [ "$pkg_dir" = "." ]; then
echo "✅ $pkg_dir is covered (root)"
else
pkg_dir=${pkg_dir#./}
# Check if package is in workspace
if echo "$has_workspaces" | jq -e --arg dir "$pkg_dir" 'any(. == $dir or . == ($dir | split("/")[0] + "/*"))' >/dev/null 2>&1; then
echo "✅ $pkg_dir is covered (workspace)"
# Check if package has individual dependabot config
elif echo "$dependabot_dirs" | grep -q "^/$pkg_dir$"; then
echo "✅ $pkg_dir is covered (individual config)"
else
echo "❌ $pkg_dir is NOT covered!"
coverage_ok=false
fi
fi
done
else
# No workspaces - check each package directory individually
echo "ℹ️ No npm workspaces detected - verifying individual package coverage"
echo ""
coverage_ok=true
for pkg in $packages; do
# Get directory relative to root
pkg_dir=$(dirname "$pkg")
# For root package.json, directory should be "/"
if [ "$pkg_dir" = "." ]; then
search_dir="directory: '/'"
else
# Remove leading ./ if present
pkg_dir=${pkg_dir#./}
search_dir="directory: '/$pkg_dir'"
fi
# Check if this directory is in dependabot.yml
if grep -q "$search_dir" "$config_file"; then
echo "✅ $pkg_dir is covered"
else
echo "❌ $pkg_dir is NOT covered by Dependabot!"
coverage_ok=false
fi
done
fi
echo ""
if [ "$coverage_ok" = true ]; then
echo "✅ All packages are covered by Dependabot configuration"
else
echo "❌ Some packages are missing from Dependabot configuration"
echo ""
echo "Please update .github/dependabot.yml to include all package directories"
exit 1
fi
- name: Validate dependabot.yml against schema
uses: marocchino/validate-dependabot@d8ae5c0d03dd75fbd0ad5f8ab4ba8101ebbd4b37 # v3
with:
path: .github/dependabot.yml
- name: Check for duplicate directories
run: |
echo "🔍 Checking for duplicate directory entries..."
config_file=".github/dependabot.yml"
# Extract all npm directories
directories=$(grep -A 1 "package-ecosystem: 'npm'" "$config_file" | grep "directory:" | awk '{print $2}' | sort)
# Check for duplicates
duplicates=$(echo "$directories" | uniq -d)
if [ -n "$duplicates" ]; then
echo "❌ Found duplicate directory entries:"
echo "$duplicates"
exit 1
else
echo "✅ No duplicate directory entries found"
fi
- name: Verify group configurations
run: |
echo "🔍 Verifying group configurations..."
config_file=".github/dependabot.yml"
# Check that groups are defined
if ! grep -q "groups:" "$config_file"; then
echo "⚠️ No groups defined in Dependabot configuration"
echo "Consider adding groups to reduce PR volume"
else
echo "✅ Groups are configured"
# Count number of groups
group_count=$(grep -c "^ [a-z-]*:" "$config_file" || echo "0")
echo "📊 Found $group_count group(s) configured"
fi
- name: Validate @types/node ignore matches Node.js engines
run: |
echo "🔍 Validating @types/node ignore configuration..."
# Extract minimum Node.js version from package.json
node_version=$(jq -r '.engines.node // empty' package.json | grep -oP '>=\K[0-9]+' || echo "")
if [ -z "$node_version" ]; then
echo "⚠️ No Node.js version constraint found in package.json engines"
exit 0
fi
echo "📦 Minimum Node.js version: $node_version"
# Calculate expected @types/node ignore version (node_version + 1)
expected_ignore_version=$((node_version + 1))
echo "🎯 Expected @types/node ignore: >=$expected_ignore_version"
# Check if @types/node ignore rule exists and matches
config_file=".github/dependabot.yml"
if ! grep -q "dependency-name: '@types/node'" "$config_file"; then
echo "⚠️ No @types/node ignore rule found in Dependabot config"
echo "💡 Consider pinning @types/node to v$node_version to prevent using APIs unavailable in Node.js $node_version"
exit 0
fi
# Extract the version from the ignore rule
# Looking for pattern like: versions: ['>=21']
actual_ignore=$(grep -A 3 "dependency-name: '@types/node'" "$config_file" | grep "versions:" | grep -oP '>=\K[0-9]+' || echo "")
if [ -z "$actual_ignore" ]; then
echo "❌ Could not parse @types/node ignore version from Dependabot config"
exit 1
fi
echo "📋 Actual @types/node ignore: >=$actual_ignore"
if [ "$actual_ignore" -eq "$expected_ignore_version" ]; then
echo "✅ @types/node ignore configuration matches Node.js engines (pinned to v$node_version types)"
else
echo "❌ @types/node ignore mismatch!"
echo ""
echo "Expected: >=$expected_ignore_version (to pin to @types/node v$node_version)"
echo "Actual: >=$actual_ignore"
echo ""
echo "Please update .github/dependabot.yml ignore rule to:"
echo " ignore:"
echo " - dependency-name: \"@types/node\""
echo " update-types: [\"version-update:semver-major\"]"
echo " versions: [\">=$expected_ignore_version\"]"
exit 1
fi
- name: Summary
if: success()
run: |
echo "🎉 Dependabot configuration verification completed successfully!"
echo ""
echo "Configuration summary:"
echo "- All package directories are covered"
echo "- Configuration conforms to Dependabot schema"
echo "- No duplicate entries"
echo "- Groups are properly configured"
echo "- @types/node pinned to minimum Node.js version"