130 lines
4.0 KiB
JavaScript
130 lines
4.0 KiB
JavaScript
async function fetchRepoLabels({ github, owner, repo }) {
|
|
const { data } = await github.rest.issues.listLabelsForRepo({
|
|
owner,
|
|
repo,
|
|
per_page: 100, // the default value is 30, which is too small to fetch all labels
|
|
});
|
|
return data.map(({ name }) => name);
|
|
}
|
|
|
|
async function fetchPrLabels({ github, owner, repo, issue_number }) {
|
|
const { data } = await github.rest.issues.listLabelsOnIssue({
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
});
|
|
return data.map(({ name }) => name);
|
|
}
|
|
|
|
function isReleaseNoteLabel(name) {
|
|
return name.startsWith("rn/");
|
|
}
|
|
|
|
async function validateLabeled({ core, context, github }) {
|
|
const { user, html_url: pr_url } = context.payload.pull_request;
|
|
const { owner, repo } = context.repo;
|
|
const { number: issue_number } = context.issue;
|
|
|
|
// Skip validation on pull requests created by the automation bot
|
|
if (user.login === "mlflow-app[bot]") {
|
|
console.log("This pull request was created by the automation bot, skipping");
|
|
return;
|
|
}
|
|
|
|
const repoLabels = await fetchRepoLabels({ github, owner, repo });
|
|
const releaseNoteLabels = repoLabels.filter(isReleaseNoteLabel);
|
|
|
|
// Fetch the release-note category labels applied on this PR
|
|
const fetchAppliedLabels = async () => {
|
|
const backoffs = [0, 1, 2, 4, 8, 16];
|
|
for (const [index, backoff] of backoffs.entries()) {
|
|
console.log(`Attempt ${index + 1}/${backoffs.length}`);
|
|
await new Promise((r) => setTimeout(r, backoff * 1000));
|
|
const prLabels = await fetchPrLabels({
|
|
github,
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
});
|
|
const prReleaseNoteLabels = prLabels.filter((name) => releaseNoteLabels.includes(name));
|
|
|
|
if (prReleaseNoteLabels.length > 0) {
|
|
return prReleaseNoteLabels;
|
|
}
|
|
}
|
|
return [];
|
|
};
|
|
|
|
const prReleaseNoteLabels = await fetchAppliedLabels();
|
|
|
|
// If no release note category label is applied to this PR, set the action status to "failed"
|
|
if (prReleaseNoteLabels.length === 0) {
|
|
// Make sure '.github/pull_request_template.md' contains an HTML anchor with this name
|
|
const anchorName = "release-note-category";
|
|
|
|
// Fragmented URL to jump to the release note category section in the PR description
|
|
const anchorUrl = `${pr_url}#user-content-${anchorName}`;
|
|
const message = [
|
|
"No release-note label is applied to this PR. ",
|
|
`Please select a checkbox in the release note category section: ${anchorUrl} `,
|
|
"or manually apply a release note category label (e.g. 'rn/bug-fix') ",
|
|
"if you're a maintainer of this repository. ",
|
|
"If this job failed when a release note category label is already applied, ",
|
|
"please re-run it.",
|
|
].join("");
|
|
core.setFailed(message);
|
|
}
|
|
}
|
|
|
|
async function postMerge({ context, github }) {
|
|
const { user } = context.payload.pull_request;
|
|
const { owner, repo } = context.repo;
|
|
const { number: issue_number } = context.issue;
|
|
|
|
if (user.login === "mlflow-app[bot]") {
|
|
console.log("This PR was created by the automation bot, skipping");
|
|
return;
|
|
}
|
|
|
|
const repoLabels = await fetchRepoLabels({ github, owner, repo });
|
|
const releaseNoteLabels = repoLabels.filter(isReleaseNoteLabel);
|
|
const prLabels = await fetchPrLabels({
|
|
github,
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
});
|
|
const prReleaseNoteLabels = prLabels.filter((name) => releaseNoteLabels.includes(name));
|
|
|
|
if (prReleaseNoteLabels.length === 0) {
|
|
const pull = await github.rest.pulls.get({
|
|
owner,
|
|
repo,
|
|
pull_number: issue_number,
|
|
});
|
|
const { login: mergedBy } = pull.data.merged_by;
|
|
const noneLabel = "rn/none";
|
|
const body = [
|
|
`@${mergedBy} This PR is missing a release-note label, adding \`${noneLabel}\`. `,
|
|
"If this label is incorrect, please replace it with the correct label.",
|
|
].join("");
|
|
await github.rest.issues.createComment({
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
body,
|
|
});
|
|
await github.rest.issues.addLabels({
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
labels: [noneLabel],
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
validateLabeled,
|
|
postMerge,
|
|
};
|