Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/workflows/labeler-dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Labeler - Dependabot

on:
pull_request:

Comment on lines +3 to +5
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description states the workflow (a) runs on pull_request “all event types” and (b) follows the documented dependabot/fetch-metadata pattern, but the workflow currently uses default pull_request event types and doesn’t call dependabot/fetch-metadata. Either update the workflow to match (e.g., specify types: and/or add fetch-metadata) or adjust the PR description to reflect the implemented approach.

Copilot uses AI. Check for mistakes.
permissions:
contents: read
pull-requests: write
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github.rest.issues.* endpoints (label creation + applying labels) require the issues: write permission on GITHUB_TOKEN. With only pull-requests: write, these API calls can fail with 403 in repos where issues write isn’t implicitly granted. Add issues: write (and keep/remove pull-requests as needed).

Suggested change
pull-requests: write
pull-requests: write
issues: write

Copilot uses AI. Check for mistakes.

env:
ENSURE_LABELS_EXIST: 'true' # Set to 'false' to skip label creation

jobs:
label-dependabot:
runs-on: ubuntu-latest
# Only run for Dependabot PRs that have not already been labeled
if: >-
github.actor == 'dependabot[bot]' &&
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The job filter uses github.actor == 'dependabot[bot]'. That ties execution to who triggered the event, not who authored the PR, so Dependabot PRs may not get labeled on event types initiated by humans (e.g., edited) or when re-running the workflow. Prefer checking github.event.pull_request.user.login == 'dependabot[bot]' (and/or the PR author association) to ensure it always targets Dependabot PRs.

Suggested change
github.actor == 'dependabot[bot]' &&
github.event.pull_request.user.login == 'dependabot[bot]' &&

Copilot uses AI. Check for mistakes.
!contains(github.event.pull_request.labels.*.name, 'dependabot-security-update') &&
!contains(github.event.pull_request.labels.*.name, 'dependabot-version-update')
steps:
# Ensure the custom labels exist before applying them.
# Skipped when ENSURE_LABELS_EXIST is 'false' (e.g. labels are managed centrally).
- name: Ensure labels exist
if: env.ENSURE_LABELS_EXIST == 'true'
uses: actions/github-script@v7
with:
script: |
const labels = ['dependabot-security-update', 'dependabot-version-update'];
const existing = await github.rest.issues.listLabelsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100
});
const existingNames = existing.data.map(l => l.name);

for (const label of labels) {
if (!existingNames.includes(label)) {
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label
});
Comment on lines +39 to +43
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issues.createLabel is missing required fields (notably color). As written, label creation will fail when the labels don’t already exist. Provide a color (and optionally description) when creating the labels.

Copilot uses AI. Check for mistakes.
core.info(`Created label: ${label}`);
Comment on lines +30 to +44
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listLabelsForRepo is limited to per_page: 100 with no pagination. If the repo has >100 labels, an existing label may not be found, leading to a failing createLabel call. Consider using issues.getLabel per label, paginate, or catch/ignore the “already exists” error (422).

Suggested change
const existing = await github.rest.issues.listLabelsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100
});
const existingNames = existing.data.map(l => l.name);
for (const label of labels) {
if (!existingNames.includes(label)) {
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label
});
core.info(`Created label: ${label}`);
// Fetch all labels with pagination to avoid the 100-label per-page limit.
const existingLabels = await github.paginate(
github.rest.issues.listLabelsForRepo,
{
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100
}
);
const existingNames = existingLabels.map(l => l.name);
for (const label of labels) {
if (!existingNames.includes(label)) {
try {
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label
});
core.info(`Created label: ${label}`);
} catch (error) {
// Ignore "already exists" errors (HTTP 422), rethrow others.
if (error.status === 422) {
core.info(`Label already exists, skipping creation: ${label}`);
} else {
throw error;
}
}

Copilot uses AI. Check for mistakes.
}
}

# Dependabot security update PRs are identified by two phrases in their body.
# Version update PRs never contain either phrase.
- name: Detect update type and apply label
uses: actions/github-script@v7
with:
script: |
const prBody = context.payload.pull_request.body || '';
const isSecurityUpdate = prBody.includes('[Security Alerts page]') ||
prBody.includes('You can disable automated security fix PRs');

const label = isSecurityUpdate ? 'dependabot-security-update' : 'dependabot-version-update';
core.info(`PR #${context.payload.pull_request.number} is ${isSecurityUpdate ? '' : 'not '}a security update — adding label: ${label}`);

await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: [label]
});
Comment on lines +59 to +66
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When ENSURE_LABELS_EXIST is set to 'false' and the labels don’t exist, issues.addLabels will fail with a generic API error. Consider handling that case explicitly (e.g., check label existence before labeling or catch the error and emit a clear message explaining how to create the missing labels).

Suggested change
core.info(`PR #${context.payload.pull_request.number} is ${isSecurityUpdate ? '' : 'not '}a security update — adding label: ${label}`);
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: [label]
});
const prNumber = context.payload.pull_request.number;
core.info(`PR #${prNumber} is ${isSecurityUpdate ? '' : 'not '}a security update — adding label: ${label}`);
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: [label]
});
} catch (error) {
const ensureLabels = process.env.ENSURE_LABELS_EXIST;
const hint = ensureLabels === 'false'
? "The label may not exist because ENSURE_LABELS_EXIST is set to 'false'. Create the label in the repository's Labels settings, or set ENSURE_LABELS_EXIST to 'true' so this workflow can create it automatically."
: "Ensure the label exists in the repository's Labels settings, or set ENSURE_LABELS_EXIST to 'true' so this workflow can create it automatically.";
core.setFailed(`Failed to add label '${label}' to PR #${prNumber}. ${hint} Original error: ${error.message}`);
}

Copilot uses AI. Check for mistakes.
Loading