Skip to content

Commit d2f3ace

Browse files
Update Managed Files (#343)
1 parent 40ead16 commit d2f3ace

1 file changed

Lines changed: 71 additions & 24 deletions

File tree

.github/workflows/dependabot-cursor-review.yml renamed to .github/workflows/dependency-cursor-review.yml

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
# Managed by repo-content-updater
2-
# Dependabot Cursor Review workflow
2+
# Dependency Cursor Review workflow
33
#
4-
# Runs Cursor CLI analysis for Dependabot PRs by using:
4+
# Runs Cursor CLI analysis for Dependabot/Renovate PRs by using:
55
# - Dependabot PR body release notes + commit list
66
# - An upstream dependency checkout
77
# - Local usage hints in the target repo
88
#
99
# Source documentation: https://cursor.com/docs/cli/github-actions
10-
name: Dependabot Cursor Review
10+
name: Dependency Cursor Review
1111

1212
on:
1313
pull_request:
1414
types: [opened, synchronize, reopened]
1515
workflow_dispatch:
1616
inputs:
1717
pr_number:
18-
description: "Dependabot PR number to analyze"
18+
description: "Dependabot/Renovate PR number to analyze"
1919
required: true
2020
type: number
2121

@@ -28,7 +28,7 @@ permissions:
2828
pull-requests: write
2929

3030
jobs:
31-
dependabot-review:
31+
dependency-review:
3232
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && (github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'renovate[bot]'))
3333
runs-on: ubuntu-latest
3434
timeout-minutes: 15
@@ -61,7 +61,7 @@ jobs:
6161
return;
6262
}
6363
const allowedBots = ['dependabot[bot]', 'renovate[bot]'];
64-
if (context.eventName !== 'workflow_dispatch' && !allowedBots.includes(pr.user?.login)) {
64+
if (!allowedBots.includes(pr.user?.login)) {
6565
core.setFailed(`Target PR #${pr.number} is not opened by an allowed bot. Author: ${pr.user?.login}`);
6666
return;
6767
}
@@ -112,8 +112,9 @@ jobs:
112112
}
113113
114114
function extractDetailsSection(text, summaryLabel) {
115+
// Allow optional trailing text after the label (e.g. Renovate appends " (pkgalias)").
115116
const summaryRe = new RegExp(
116-
`<details[^>]*>\\s*<summary>\\s*${escapeRegex(summaryLabel)}\\s*</summary>`,
117+
`<details[^>]*>\\s*<summary>\\s*${escapeRegex(summaryLabel)}[^<]*</summary>`,
117118
'i'
118119
);
119120
const summaryMatch = summaryRe.exec(text);
@@ -146,34 +147,79 @@ jobs:
146147
.trim();
147148
}
148149
149-
const releaseNotes = extractDetailsSection(body, 'Release notes');
150-
const commits = extractDetailsSection(body, 'Commits');
151150
// Prefer the dependency link from Dependabot's lead sentence.
152151
// Fallback to any GitHub repo URL if that sentence format changes.
152+
// Both github.com and redirect.github.com (used by Renovate) are matched.
153153
const dependencyRepoMatch = body.match(
154-
/^\s*(?:Bumps|Update(?:s|d)?)\s+\[[^\]]+\]\(\s*https?:\/\/github\.com\/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)(?:[\/#?][^)\s]*)?\s*\)/im
154+
/^\s*(?:Bumps|Update(?:s|d)?)\s+\[[^\]]+\]\(\s*https?:\/\/(?:redirect\.)?github\.com\/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)(?:[\/#?][^)\s]*)?\s*\)/im
155155
);
156156
const repoMatch = dependencyRepoMatch || body.match(
157-
/https?:\/\/github\.com\/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)(?=\/|$|[)\]>\s"'?#])/i
157+
/https?:\/\/(?:redirect\.)?github\.com\/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)(?=\/|$|[)\]>\s"'?#])/i
158158
);
159159
const upstreamRepo = repoMatch ? repoMatch[1].replace(/\.git$/i, '') : '';
160+
161+
// Release notes: Dependabot uses <details><summary>Release notes</summary>,
162+
// Renovate uses <details><summary>org/repo (pkg)</summary> under a ### Release Notes heading.
163+
let releaseNotes = extractDetailsSection(body, 'Release notes');
164+
if (!releaseNotes && upstreamRepo) {
165+
releaseNotes = extractDetailsSection(body, upstreamRepo);
166+
}
167+
if (!releaseNotes) {
168+
const rnHeading = body.match(/###\s*Release\s+Notes?\s*\n([\s\S]*?)(?=\n---|\n###\s|$)/i);
169+
if (rnHeading) releaseNotes = rnHeading[1].trim();
170+
}
171+
172+
// Commits: Dependabot uses <details><summary>Commits</summary>.
173+
// Renovate omits this section, so fall back to extracting any SHA-like hex strings from the body.
174+
let commits = extractDetailsSection(body, 'Commits');
175+
if (!commits) {
176+
const shaMatches = body.match(/\b[0-9a-f]{7,40}\b/gi);
177+
if (shaMatches && shaMatches.length > 0) commits = shaMatches.join('\n');
178+
}
179+
160180
const title = ${{ toJSON(steps.target_pr.outputs.title) }} || '';
181+
// Dependabot-style titles (3 groups: pkg, fromVersion, toVersion).
161182
const titleMatch =
162183
title.match(/[Uu]pdate\s+(.+?)\s+requirement\s+from\s+([^\s]+)\s+to\s+([^\s]+)/) ||
163184
title.match(/[Bb]ump\s+(.+?)\s+from\s+([^\s]+)\s+to\s+([^\s]+)/) ||
164185
title.match(/[Uu]pdate\s+(.+?)\s+from\s+([^\s]+)\s+to\s+([^\s]+)/);
165-
const packageName = titleMatch ? titleMatch[1].trim() : '';
166-
const fromVersion = titleMatch ? titleMatch[2].trim() : '';
167-
const toVersion = titleMatch ? titleMatch[3].trim() : '';
186+
// Renovate-style titles (2 groups: pkg, toVersion — no "from" clause).
187+
const renovateTitleMatch = !titleMatch && (
188+
title.match(/(?:update|pin)\s+dependency\s+(.+?)\s+to\s+v?([^\s]+)/i) ||
189+
title.match(/(?:update|pin)\s+(.+?)\s+(?:action|digest|docker\s+tag)\s+to\s+v?([^\s]+)/i) ||
190+
title.match(/(?:update|pin)\s+(.+?)\s+to\s+v?([^\s]+)/i)
191+
);
192+
let packageName, fromVersion, toVersion;
193+
if (titleMatch) {
194+
packageName = titleMatch[1].trim();
195+
fromVersion = titleMatch[2].trim();
196+
toVersion = titleMatch[3].trim();
197+
} else if (renovateTitleMatch) {
198+
packageName = renovateTitleMatch[1].trim();
199+
fromVersion = '';
200+
toVersion = renovateTitleMatch[2].trim();
201+
} else {
202+
packageName = '';
203+
fromVersion = '';
204+
toVersion = '';
205+
}
206+
// Body-based version fallback: recover missing from/to from Renovate's table (e.g. `1.2.3` -> `1.2.4`).
207+
if (!fromVersion || !toVersion) {
208+
const bodyVersionMatch = body.match(/`([^`\s]+)`\s*(?:->|→)\s*`([^`\s]+)`/);
209+
if (bodyVersionMatch) {
210+
if (!fromVersion) fromVersion = bodyVersionMatch[1].replace(/^v/i, '');
211+
if (!toVersion) toVersion = bodyVersionMatch[2].replace(/^v/i, '');
212+
}
213+
}
168214
169215
if (!upstreamRepo) {
170-
core.setFailed('Dependabot PR body is missing an upstream GitHub repository link.');
216+
core.setFailed('PR body is missing an upstream GitHub repository link.');
171217
return;
172218
}
173219
const normalizedReleaseNotes =
174-
releaseNotes || 'Dependabot did not include a Release notes details section.';
220+
releaseNotes || 'PR body did not include a Release notes details section.';
175221
const normalizedCommits =
176-
commits || 'Dependabot did not include a Commits details section.';
222+
commits || 'PR body did not include a Commits details section.';
177223
178224
const out = {
179225
prNumber: Number('${{ steps.target_pr.outputs.number }}'),
@@ -688,12 +734,13 @@ jobs:
688734
fi
689735
} > "$output_summary"
690736
737+
_gheof="GHEOF_$(uuidgen)"
691738
{
692739
echo "status=$status"
693740
echo "changed_files_count=$changed_count"
694-
echo "summary<<EOF"
741+
echo "summary<<${_gheof}"
695742
cat "$output_summary"
696-
echo "EOF"
743+
echo "${_gheof}"
697744
} >> "$GITHUB_OUTPUT"
698745
699746
if [ "$total_count" -gt 0 ] && [ "$warn_only" = true ]; then
@@ -709,7 +756,7 @@ jobs:
709756
PACKAGE_NAME: ${{ steps.dependabot_context.outputs.package_name }}
710757
run: |
711758
if [ -z "$PACKAGE_NAME" ]; then
712-
echo "No package detected from Dependabot metadata." > package_usage.txt
759+
echo "No package detected from PR metadata." > package_usage.txt
713760
else
714761
{
715762
echo "Search pattern: $PACKAGE_NAME"
@@ -745,7 +792,7 @@ jobs:
745792
return ""
746793
747794
base_context = f"""
748-
This is a Dependabot PR review request.
795+
This is a dependency bot PR review request.
749796
750797
PR title:
751798
{os.getenv("PR_TITLE", "")}
@@ -758,13 +805,13 @@ jobs:
758805
- from: {os.getenv("FROM_VERSION", "")}
759806
- to: {os.getenv("TO_VERSION", "")}
760807
761-
Dependabot comment context JSON:
808+
PR context JSON:
762809
{read_file("dependabot_comment_context.json")}
763810
764-
Dependabot Release notes:
811+
Release notes:
765812
{read_file("dependabot_release_notes.md")}
766813
767-
Dependabot Commits:
814+
Commits:
768815
{read_file("dependabot_commits.md")}
769816
770817
Local usage hints (non-authoritative rg hits):

0 commit comments

Comments
 (0)