fix-version-gaps/fixGaps.ts (80 lines of code) (raw):

import { Octokit } from '@octokit/rest'; import { PullRequest } from '@octokit/webhooks-definitions/schema'; import { ConfigFileOptions } from 'backport'; export function getLowestVersionsOnPr(pr: PullRequest) { const lowestVersionsOnPr: Record<string, string> = {}; for (const label of pr.labels) { const matches = label.name.match(/^v([0-9.]+)$/); if (matches) { const [major, minor] = matches[1].split('.'); if (!lowestVersionsOnPr[major]) { lowestVersionsOnPr[major] = minor; } else if (parseInt(lowestVersionsOnPr[major], 10) > parseInt(minor, 10)) { lowestVersionsOnPr[major] = minor; } } } return lowestVersionsOnPr; } export function getVersionsFromBackportConfig(config: ConfigFileOptions) { const highestVersions = []; for (const label in config.branchLabelMapping) { const matches = label.match(/^\^v([0-9.]+)\$$/); if (matches) { const version = matches[1]; highestVersions.push(version); } } return highestVersions; } export function getVersionLabelsToAdd(config: ConfigFileOptions, pr: PullRequest) { const versionsFromBackportConfig = getVersionsFromBackportConfig(config); const lowestVersionsOnPr = getLowestVersionsOnPr(pr); const allLabels = pr.labels.map((label) => label.name); const versionLabelsToAdd = []; for (const version of versionsFromBackportConfig) { const [major, minor] = version.split('.'); const nextVersion = parseInt(lowestVersionsOnPr[major], 10) + 1; for (let i = nextVersion; i <= parseInt(minor, 10); i++) { const label = `v${major}.${i}.0`; if (!allLabels.find((labelToCheck) => labelToCheck.match(`^v${major}\\.${i}\\.`))) { versionLabelsToAdd.push(label); } } } return versionLabelsToAdd; } export function getCommentFromLabels(labelsToAdd: string[]) { return [ 'The following labels were identified as gaps in your version labels and will be added automatically:', ...labelsToAdd.map((label) => `- ${label}`), '', 'If any of these should not be on your pull request, please manually remove them.', ].join('\n'); } function createComment(octokit: Octokit, pr: PullRequest, labelsToAdd: string[]) { return octokit.issues.createComment({ owner: pr.base.repo.owner.login, repo: pr.base.repo.name, issue_number: pr.number, body: getCommentFromLabels(labelsToAdd), }); } function addLabels(octokit: Octokit, pr: PullRequest, labelsToAdd: string[]) { return octokit.issues.addLabels({ owner: pr.base.repo.owner.login, repo: pr.base.repo.name, issue_number: pr.number, labels: labelsToAdd, }); } export async function fixGaps(accessToken: string, config: ConfigFileOptions, pr: PullRequest) { const labelsToAdd = getVersionLabelsToAdd(config, pr); if (labelsToAdd.length > 0) { const octokit = new Octokit({ auth: accessToken, }); await createComment(octokit, pr, labelsToAdd); await addLabels(octokit, pr, labelsToAdd); } }