-
Notifications
You must be signed in to change notification settings - Fork 4
113 lines (99 loc) · 4.16 KB
/
Copy pathdependabot-retry.yml
File metadata and controls
113 lines (99 loc) · 4.16 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
name: Dependabot Auto Retry
on:
workflow_call:
secrets:
APP_ID:
description: "GitHub App ID for aws-geo-auto-release-sec-bot"
required: true
APP_PRIVATE_KEY:
description: "GitHub App private key for aws-geo-auto-release-sec-bot"
required: true
permissions:
security-events: write
pull-requests: read
jobs:
retry-dependabot-alerts:
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Retry stale Dependabot alerts
uses: actions/github-script@v7
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
// Alert ecosystem → Dependabot branch slug mapping
const ecosystemToBranchSlug = {
npm: 'npm_and_yarn',
go: 'gomod',
actions: 'github_actions',
rubygems: 'bundler',
pip: 'pip',
cargo: 'cargo',
composer: 'composer',
nuget: 'nuget',
maven: 'maven',
docker: 'docker',
hex: 'hex',
elm: 'elm',
pub: 'pub',
swift: 'swift',
gradle: 'gradle',
github_actions: 'github_actions',
};
// List open dependabot alerts
const alerts = await github.paginate(
github.rest.dependabot.listAlertsForRepo,
{ owner, repo, state: 'open', sort: 'created', direction: 'asc', per_page: 100 }
);
const staleAlerts = alerts.filter(a => a.created_at < oneDayAgo);
core.info(`Found ${staleAlerts.length} open alerts older than 1 day (of ${alerts.length} total)`);
// Get open Dependabot PRs to find which alerts already have a PR
const pulls = await github.paginate(
github.rest.pulls.list,
{ owner, repo, state: 'open', per_page: 100 }
);
const dependabotPRs = pulls.filter(p => p.user?.login === 'dependabot[bot]');
const dependabotBranches = new Set(dependabotPRs.map(p => p.head.ref));
let retried = 0;
let skipped = 0;
for (const alert of staleAlerts) {
const pkg = alert.dependency?.package?.name || 'unknown';
const ecosystem = alert.dependency?.package?.ecosystem || '';
const branchSlug = ecosystemToBranchSlug[ecosystem] || ecosystem;
// Check branch names using the correct slug
const branchMatch = [...dependabotBranches].some(
b => b.startsWith(`dependabot/${branchSlug}/`) && b.includes(pkg)
);
// Also check PR titles to catch group PRs (whose branches don't contain package names)
const titleMatch = dependabotPRs.some(
p => p.title.includes(pkg)
);
if (branchMatch || titleMatch) {
core.info(`Skipping alert #${alert.number} (${pkg}) — PR already exists`);
skipped++;
continue;
}
core.info(`Retrying alert #${alert.number} (${pkg})`);
try {
await github.request('POST /repos/{owner}/{repo}/dependabot/alerts/{alert_number}/rerun', {
owner,
repo,
alert_number: alert.number,
});
core.info(` ✓ Alert #${alert.number} retried`);
retried++;
} catch (err) {
core.warning(` ✗ Failed to retry alert #${alert.number}: ${err.message}`);
}
}
core.summary.addHeading('Dependabot Auto Retry', 2);
core.summary.addRaw(`Retried ${retried} alerts, skipped ${skipped} (PR already exists)`);
await core.summary.write();