Skip to content

feat(remote): one entry per release, and one per person #1249

feat(remote): one entry per release, and one per person

feat(remote): one entry per release, and one per person #1249

Workflow file for this run

name: Label PR
on:
pull_request:
types: [opened, synchronize]
permissions:
contents: read
pull-requests: write
jobs:
label:
runs-on: ubuntu-latest
timeout-minutes: 5
# Prefer the maintainer-provided PAT (`LABELER_PAT`) when set, fall
# back to the workflow's auto-generated `GITHUB_TOKEN` otherwise.
# GitHub started rejecting the auto token on POST /labels with
# spurious 401 "Bad credentials" earlier in 2026; a fine-grained
# PAT scoped to this repo (issues: write + pull_requests: write)
# is the documented escape hatch. Empty secrets are falsy in this
# ternary, so unset β†’ fallback works without extra plumbing.
env:
LABEL_TOKEN: ${{ secrets.LABELER_PAT || secrets.GITHUB_TOKEN }}
steps:
# Scope labels based on changed files
- name: Path-based labels
uses: actions/labeler@bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13 # v7.0.0
with:
repo-token: ${{ env.LABEL_TOKEN }}
sync-labels: true
# Type labels based on PR title (conventional commits)
# Note: context.payload.pull_request.title is used safely within
# github-script JS context (not interpolated into shell), no injection risk
- name: Type labels
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ env.LABEL_TOKEN }}
script: |
const title = context.payload.pull_request.title;
const prefixMap = {
'feat': 'type: feat',
'fix': 'type: fix',
'chore': 'type: chore',
'docs': 'type: docs',
'refactor': 'type: refactor',
'perf': 'type: perf',
'test': 'type: test',
'ci': 'type: ci',
};
const match = title.match(/^(\w+)(\(.+\))?[!]?:/);
const prefix = match?.[1];
const label = prefixMap[prefix];
if (label) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: [label],
});
}
# Size labels based on diff
- name: Size labels
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ env.LABEL_TOKEN }}
script: |
const { data: files } = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
per_page: 100,
});
const lines = files.reduce((sum, f) => sum + f.additions + f.deletions, 0);
const sizeLabels = [
{ max: 10, label: 'size: xs' },
{ max: 50, label: 'size: s' },
{ max: 200, label: 'size: m' },
{ max: 500, label: 'size: l' },
];
const sizeLabel = sizeLabels.find(s => lines <= s.max)?.label || 'size: xl';
// Remove old size labels
const current = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
for (const l of current.data.filter(l => l.name.startsWith('size:'))) {
if (l.name !== sizeLabel) {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: l.name,
});
}
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: [sizeLabel],
});