82 lines
2.4 KiB
JavaScript
82 lines
2.4 KiB
JavaScript
module.exports = async ({ github, context }) => {
|
|
const { owner, repo } = context.repo;
|
|
const { body, number: issue_number } = context.payload.issue || context.payload.pull_request;
|
|
const pattern = /- \[(.*?)\]\s*`(.+?)`/g;
|
|
// Labels extracted from the issue/PR body
|
|
const bodyLabels = [];
|
|
let match;
|
|
while ((match = pattern.exec(body)) !== null) {
|
|
bodyLabels.push({ checked: match[1].trim().toLowerCase() === "x", name: match[2].trim() });
|
|
}
|
|
console.log("Body labels:", bodyLabels);
|
|
|
|
const events = await github.paginate(github.rest.issues.listEvents, {
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
});
|
|
// Labels added or removed by a user
|
|
const userLabels = events
|
|
.filter(({ event, actor }) => ["labeled", "unlabeled"].includes(event) && actor.type === "User")
|
|
.map(({ label }) => label.name);
|
|
console.log("User labels:", userLabels);
|
|
|
|
// Labels available in the repository
|
|
const repoLabels = (
|
|
await github.paginate(github.rest.issues.listLabelsForRepo, {
|
|
owner,
|
|
repo,
|
|
})
|
|
).map(({ name }) => name);
|
|
|
|
// Exclude labels that are not available in the repository or have been added/removed by a user
|
|
const labels = bodyLabels.filter(
|
|
({ name }) => repoLabels.includes(name) && !userLabels.includes(name)
|
|
);
|
|
console.log("Labels to add/remove:", labels);
|
|
|
|
const existingLabels = (
|
|
await github.paginate(github.rest.issues.listLabelsOnIssue, {
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
})
|
|
).map(({ name }) => name);
|
|
console.log("Existing labels:", existingLabels);
|
|
|
|
const labelsToAdd = labels
|
|
.filter(({ name, checked }) => checked && !existingLabels.includes(name))
|
|
.map(({ name }) => name);
|
|
console.log("Labels to add:", labelsToAdd);
|
|
if (labelsToAdd.length > 0) {
|
|
await github.rest.issues.addLabels({
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
labels: labelsToAdd,
|
|
});
|
|
}
|
|
|
|
const labelsToRemove = labels
|
|
.filter(({ name, checked }) => !checked && existingLabels.includes(name))
|
|
.map(({ name }) => name);
|
|
console.log("Labels to remove:", labelsToRemove);
|
|
if (labelsToRemove.length > 0) {
|
|
const results = await Promise.allSettled(
|
|
labelsToRemove.map((name) =>
|
|
github.rest.issues.removeLabel({
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
name,
|
|
})
|
|
)
|
|
);
|
|
for (const { status, reason } of results) {
|
|
if (status === "rejected") {
|
|
console.error(reason);
|
|
}
|
|
}
|
|
}
|
|
};
|