-
Notifications
You must be signed in to change notification settings - Fork 39
144 lines (121 loc) · 5.79 KB
/
dependabot-major-analysis.yml
File metadata and controls
144 lines (121 loc) · 5.79 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
name: Dependabot Major Version Analysis
on:
pull_request_target:
types: [opened]
permissions:
contents: read
pull-requests: write
jobs:
analyze-major:
runs-on: ubuntu-latest
if: github.event.pull_request.user.login == 'dependabot[bot]'
steps:
- name: Fetch Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Analyze major version bump
if: >-
steps.metadata.outputs.package-ecosystem == 'github_actions' &&
steps.metadata.outputs.update-type == 'version-update:semver-major'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
DEP_NAME: ${{ steps.metadata.outputs.dependency-names }}
PREV_VERSION: ${{ steps.metadata.outputs.previous-version }}
NEW_VERSION: ${{ steps.metadata.outputs.new-version }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const depName = process.env.DEP_NAME;
const prevVersion = process.env.PREV_VERSION;
const newVersion = process.env.NEW_VERSION;
const parts = depName.split('/');
const owner = parts[0];
const repo = parts[1];
const repoSlug = `${owner}/${repo}`;
let releases = [];
try {
const { data } = await github.rest.repos.listReleases({ owner, repo, per_page: 50 });
releases = data;
} catch (err) {
core.warning(`Could not fetch releases for ${repoSlug}: ${err.message}`);
}
const prevMajor = parseInt(prevVersion.replace(/^v/, ''), 10);
const newMajor = parseInt(newVersion.replace(/^v/, ''), 10);
const relevantReleases = releases.filter(r => {
const major = parseInt(r.tag_name.replace(/^v/, ''), 10);
return major > prevMajor && major <= newMajor;
});
let releaseNotesSummary = '';
let breakingChanges = '';
if (relevantReleases.length === 0) {
releaseNotesSummary = '_No releases found between these versions._';
breakingChanges = `_Unable to determine breaking changes automatically. Please review the [full changelog](https://github.com/${repoSlug}/releases)._`;
} else {
for (const release of relevantReleases.slice(0, 10)) {
const body = (release.body || '_No release notes._').replace(/(?<=^|\s)@(?=[a-zA-Z0-9])(?![a-zA-Z0-9-]*\/)/gm, '');
releaseNotesSummary += `### ${release.tag_name}${release.name && release.name !== release.tag_name ? ' — ' + release.name : ''}\n\n`;
releaseNotesSummary += body.substring(0, 2000);
if (body.length > 2000) releaseNotesSummary += '\n\n_...truncated_';
releaseNotesSummary += '\n\n---\n\n';
const lines = body.split('\n');
for (const line of lines) {
if (/breaking|BREAKING|removed|deprecated|incompatible|migration/i.test(line)) {
breakingChanges += `- ${line.trim()}\n`;
}
}
}
}
if (!breakingChanges) {
breakingChanges = '_No explicit breaking changes detected in release notes. Manual review recommended._';
}
let commentBody = `## :warning: Major Version Update — Manual Review Required
| Field | Value |
|-------|-------|
| **Action** | [\`${depName}\`](https://github.com/${repoSlug}) |
| **Previous** | \`v${prevVersion}\` |
| **New** | \`v${newVersion}\` |
| **Type** | Major (\`v${prevMajor}\` → \`v${newMajor}\`) |
### Breaking Changes
${breakingChanges}
### Release Notes (v${prevMajor + 1} → v${newMajor})
${releaseNotesSummary}
### Next Steps
1. Review breaking changes above
2. Check if workflow inputs/outputs changed
3. Verify compatibility with your CI/CD configuration
> Full changelog: https://github.com/${repoSlug}/releases
---
_Generated automatically for Dependabot major version PRs._`.replace(/^ /gm, '');
if (commentBody.length > 64000) {
commentBody = commentBody.substring(0, 63900) + '\n\n_...comment truncated due to size limit._';
}
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: commentBody,
});
try {
const labelsToAdd = ['major-update', 'needs-review'];
for (const label of labelsToAdd) {
try {
await github.rest.issues.getLabel({ owner: context.repo.owner, repo: context.repo.repo, name: label });
} catch {
const colors = { 'major-update': 'B60205', 'needs-review': 'FBCA04' };
await github.rest.issues.createLabel({
owner: context.repo.owner, repo: context.repo.repo,
name: label, color: colors[label] || 'EDEDED',
});
}
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: labelsToAdd,
});
} catch (err) {
core.warning(`Could not add labels: ${err.message}`);
}