on-merge/index.ts (107 lines of code) (raw):
import * as core from '@actions/core';
import { context, getOctokit } from '@actions/github';
import { PullRequestEvent } from '@octokit/webhooks-definitions/schema';
import { backportRun } from 'backport';
import { resolveTargets } from './backportTargets';
import { getPrPackageVersion, getPrBackportData, labelsContain } from './util';
import { parseVersions } from './versions';
async function init() {
const { payload, repo } = context;
if (!payload.pull_request) {
throw Error('Only pull_request events are supported.');
}
const accessToken = core.getInput('github_token', { required: true });
const github = getOctokit(accessToken).rest;
const versionsConfig = await github.repos.getContent({
...context.repo,
ref: 'main',
path: 'versions.json',
});
const backportConfig = await github.repos.getContent({
...context.repo,
ref: 'main',
path: '.backportrc.json',
});
const versionsJSON = Buffer.from((versionsConfig.data as any).content, 'base64').toString();
const backportJSON = Buffer.from((backportConfig.data as any).content, 'base64').toString();
const versionsRaw = JSON.parse(versionsJSON);
const backportRaw = JSON.parse(backportJSON);
const versions = parseVersions(versionsRaw);
const versionMap = backportRaw?.branchLabelMapping || {};
const pullRequestPayload = payload as PullRequestEvent;
const pullRequest = pullRequestPayload.pull_request;
if (pullRequest.base.ref === 'main') {
const currentLabel = `v${versions.currentMinor.version}`;
if (!pullRequest.labels.some((label) => label.name === currentLabel)) {
await github.issues.addLabels({
...context.repo,
issue_number: pullRequest.number,
labels: [currentLabel],
});
}
const targets = resolveTargets(
versions,
versionMap,
pullRequest.labels.map((label) => label.name),
);
if (!labelsContain(pullRequest.labels, 'backport:skip') && targets.length) {
try {
let actionUrl = '';
if (process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY && process.env.GITHUB_RUN_ID) {
actionUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
}
await github.issues.createComment({
...repo,
issue_number: pullRequest.number,
body: `Starting backport for target branches: ${targets.join(', ')}${
actionUrl ? '\n\n' + actionUrl : ''
}`,
});
await github.pulls.update({
...repo,
pull_number: pullRequest.number,
body: `${pullRequest.body}\n\n<!--ONMERGE ${JSON.stringify({
backportTargets: targets,
})} ONMERGE-->`,
});
} catch (error) {
console.error('An error occurred', error);
core.setFailed(error.message);
}
await backportRun({
options: {
repoOwner: repo.owner,
repoName: repo.repo,
accessToken,
interactive: false,
pullNumber: pullRequest.number,
assignees: [pullRequest.user.login],
autoMerge: true,
autoMergeMethod: 'squash',
targetBranches: targets,
publishStatusCommentOnFailure: true,
publishStatusCommentOnSuccess: true, // TODO this will flip to false once we have backport summaries implemented
},
});
}
} else if (labelsContain(pullRequest.labels, 'backport')) {
const prData = getPrBackportData(pullRequest.body);
if (prData) {
const version = await getPrPackageVersion(github, repo.owner, repo.repo, pullRequest.base.ref);
for (const pr of prData) {
if (!pr.sourcePullRequest) {
continue;
}
await github.issues.addLabels({
...context.repo,
issue_number: pr.sourcePullRequest.number,
labels: [`v${version}`], // TODO switch this to use getVersionLabel when it's appropriate to increment patch versions after BCs
});
}
}
}
}
init().catch((error) => {
console.error('An error occurred', error);
core.setFailed(error.message);
});