Skip to content

ci: Improve error message in title checker #35

ci: Improve error message in title checker

ci: Improve error message in title checker #35

Workflow file for this run

name: PR Title Checker
on:
pull_request_target:
types: [opened, edited, reopened]
jobs:
check-title:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Validate PR Title and Apply Labels
uses: actions/github-script@v7
with:
script: |
const title = context.payload.pull_request.title;
const { owner, repo } = context.repo;
const pr_number = context.payload.pull_request.number;
const regex = /^([a-z-]+)(?:\(([^)]+)\))?(!?): ([A-Z].+)$/;
const match = title.match(regex);
if (!match) {
core.setFailed("PR title does not follow any of the accepted formats:\n 'type(scope)!: Description'\n 'type(scope): Description'\n 'type!: Description'\n 'type: Description'\n See https://www.conventionalcommits.org/ for more details");
return;
}
const [_, type, scope, breaking, __] = match;
const displayTitle = `${title} (#${pr_number})`;
const maxLength = 72;
if (displayTitle.length > maxLength) {
core.setFailed(
`PR title is too long by ${displayTitle.length-maxLength} characters.`
);
return;
}
const repoLabels = await github.rest.issues.listLabelsForRepo({
owner,
repo,
per_page: 100,
});
const labelNames = repoLabels.data.map(l => l.name);
const labelsToAdd = [];
const typeLabel = `cc: ${type}`;
if (!labelNames.includes(typeLabel)) {
core.setFailed(`Invalid type: "${type}". No label "${typeLabel}" found in repo.`);
return;
}
labelsToAdd.push(typeLabel);
if (scope) {
const scopeLabel = `package: ${scope}`;
if (!labelNames.includes(scopeLabel)) {
core.setFailed(`Invalid scope: "${scope}". No label "${scopeLabel}" found in repo.`);
return;
}
labelsToAdd.push(scopeLabel);
}
if (breaking === '!') {
if (!labelNames.includes('breaking-change')) {
core.setFailed('No "breaking-change" label found in repo.');
return;
}
labelsToAdd.push('breaking-change');
}
const prLabels = await github.rest.issues.listLabelsOnIssue({
owner,
repo,
issue_number: pr_number,
per_page: 100,
});
const managedPrefixes = ['cc: ', 'package: '];
const labelsToRemove = prLabels.data
.map(l => l.name)
.filter(n => managedPrefixes.some(p => n.startsWith(p)) || n === 'breaking-change');
for (const label of labelsToRemove) {
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: pr_number,
name: label
});
}
await github.rest.issues.addLabels({
owner,
repo,
issue_number: pr_number,
labels: labelsToAdd
});
console.log(`Successfully added labels: ${labelsToAdd.join(', ')}`);