Skip to content

Commit da7d65b

Browse files
committed
feat: add Dependabot automation workflows
- Add auto-approve workflow for patch updates - Auto-approves all semver-patch Dependabot PRs - Only auto-merges dev dependency patches (safer for security project) - Production dependencies require manual merge after CI passes - Add stale overrides checker workflow - Runs weekly on Monday 6 AM UTC - Detects pnpm.overrides in package.json - Creates tracking issue when overrides exist - Helps clean up subdependency pins after upstream fixes
1 parent 95764aa commit da7d65b

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: Check Stale Overrides
2+
3+
on:
4+
schedule:
5+
- cron: '0 6 * * 1' # Weekly on Monday 6 AM UTC
6+
workflow_dispatch: # Manual trigger
7+
8+
jobs:
9+
check-overrides:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- uses: pnpm/action-setup@v4
15+
with:
16+
version: 10
17+
18+
- uses: actions/setup-node@v4
19+
with:
20+
node-version: '22'
21+
cache: 'pnpm'
22+
23+
- name: Install dependencies
24+
run: pnpm install --frozen-lockfile
25+
26+
- name: Check for stale overrides
27+
id: check
28+
run: |
29+
# Extract overrides from package.json
30+
OVERRIDES=$(node -e "
31+
const pkg = require('./package.json');
32+
const overrides = pkg.pnpm?.overrides || {};
33+
Object.entries(overrides).forEach(([name, version]) => {
34+
console.log(name + '@' + version);
35+
});
36+
")
37+
38+
if [ -z "$OVERRIDES" ]; then
39+
echo "No pnpm overrides configured"
40+
echo "has_overrides=false" >> $GITHUB_OUTPUT
41+
exit 0
42+
fi
43+
44+
echo "has_overrides=true" >> $GITHUB_OUTPUT
45+
echo "## Current pnpm.overrides" >> $GITHUB_STEP_SUMMARY
46+
echo "" >> $GITHUB_STEP_SUMMARY
47+
echo "The following overrides are pinned in package.json:" >> $GITHUB_STEP_SUMMARY
48+
echo "" >> $GITHUB_STEP_SUMMARY
49+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
50+
echo "$OVERRIDES" >> $GITHUB_STEP_SUMMARY
51+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
52+
echo "" >> $GITHUB_STEP_SUMMARY
53+
echo "### Action Required" >> $GITHUB_STEP_SUMMARY
54+
echo "Check if parent packages have been updated to use fixed versions of these dependencies." >> $GITHUB_STEP_SUMMARY
55+
echo "If so, remove the override from \`package.json\` and run \`pnpm install\`." >> $GITHUB_STEP_SUMMARY
56+
57+
- name: Create issue if overrides exist
58+
if: steps.check.outputs.has_overrides == 'true'
59+
uses: actions/github-script@v7
60+
with:
61+
script: |
62+
const pkg = require('./package.json');
63+
const overrides = pkg.pnpm?.overrides || {};
64+
65+
if (Object.keys(overrides).length === 0) return;
66+
67+
// Check if issue already exists
68+
const issues = await github.rest.issues.listForRepo({
69+
owner: context.repo.owner,
70+
repo: context.repo.repo,
71+
labels: 'stale-overrides',
72+
state: 'open'
73+
});
74+
75+
if (issues.data.length > 0) {
76+
console.log('Issue already exists, skipping');
77+
return;
78+
}
79+
80+
const overrideList = Object.entries(overrides)
81+
.map(([name, version]) => `- \`${name}\`: ${version}`)
82+
.join('\n');
83+
84+
await github.rest.issues.create({
85+
owner: context.repo.owner,
86+
repo: context.repo.repo,
87+
title: 'Review pnpm.overrides for stale security fixes',
88+
labels: ['stale-overrides', 'dependencies'],
89+
body: `## Stale Override Check
90+
91+
The following subdependency overrides are configured in \`package.json\`:
92+
93+
${overrideList}
94+
95+
### Action Required
96+
97+
1. Check if the parent packages have been updated to include fixed versions
98+
2. Remove any overrides that are no longer needed:
99+
- Edit \`package.json\` and remove the override from \`pnpm.overrides\`
100+
- Run \`pnpm install\` to update the lockfile
101+
- Verify the vulnerability is resolved with \`pnpm audit\`
102+
103+
### Why This Matters
104+
105+
Overrides pin subdependencies to specific versions. Once upstream packages are fixed, these overrides become stale and may:
106+
- Prevent you from getting newer fixes
107+
- Create version conflicts
108+
- Make \`pnpm audit\` report false negatives
109+
110+
---
111+
*This issue was automatically created by the stale-overrides workflow.*`
112+
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Dependabot Auto-Approve
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
jobs:
12+
auto-approve:
13+
runs-on: ubuntu-latest
14+
if: github.actor == 'dependabot[bot]'
15+
steps:
16+
- name: Fetch Dependabot metadata
17+
id: metadata
18+
uses: dependabot/fetch-metadata@v2
19+
with:
20+
github-token: "${{ secrets.GITHUB_TOKEN }}"
21+
22+
# Auto-approve patch updates to reduce friction
23+
# Still requires CI to pass and manual merge for production dependencies
24+
- name: Auto-approve patch updates
25+
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
26+
run: gh pr review --approve "$PR_URL"
27+
env:
28+
PR_URL: ${{ github.event.pull_request.html_url }}
29+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
31+
# Only auto-merge for DEVELOPMENT dependencies (test tools, linters, etc.)
32+
# Production/runtime dependencies still require manual merge after CI passes
33+
- name: Enable auto-merge for dev dependency patches only
34+
if: |
35+
steps.metadata.outputs.update-type == 'version-update:semver-patch' &&
36+
steps.metadata.outputs.dependency-type == 'direct:development'
37+
run: gh pr merge --auto --squash "$PR_URL"
38+
env:
39+
PR_URL: ${{ github.event.pull_request.html_url }}
40+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)