mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-06 07:21:16 +08:00
95 lines
2.7 KiB
TypeScript
95 lines
2.7 KiB
TypeScript
import { setOutput } from '@actions/core';
|
|
import { program } from 'commander';
|
|
// eslint-disable-next-line depend/ban-dependencies
|
|
import ora from 'ora';
|
|
import picocolors from 'picocolors';
|
|
import invariant from 'tiny-invariant';
|
|
|
|
import { esMain } from '../utils/esmain';
|
|
import { git } from './utils/git-client';
|
|
import { getUnpickedPRs } from './utils/github-client';
|
|
|
|
program.name('pick-patches').description('Cherry pick patch PRs back to main');
|
|
|
|
const logger = console;
|
|
|
|
const OWNER = 'storybookjs';
|
|
const REPO = 'storybook';
|
|
const SOURCE_BRANCH = 'next';
|
|
|
|
interface PR {
|
|
number: number;
|
|
id: string;
|
|
branch: string;
|
|
title: string;
|
|
mergeCommit: string;
|
|
}
|
|
|
|
function formatPR(pr: PR): string {
|
|
return `https://github.com/${OWNER}/${REPO}/pull/${pr.number} "${pr.title}" ${picocolors.yellow(
|
|
pr.mergeCommit
|
|
)}`;
|
|
}
|
|
|
|
export const run = async (_: unknown) => {
|
|
if (!process.env.GH_TOKEN) {
|
|
logger.error('GH_TOKEN environment variable must be set, exiting.');
|
|
process.exit(1);
|
|
}
|
|
|
|
const sourceBranch = SOURCE_BRANCH;
|
|
|
|
const spinner = ora('Searching for patch PRs to cherry-pick').start();
|
|
|
|
const patchPRs = await getUnpickedPRs(sourceBranch);
|
|
|
|
if (patchPRs.length > 0) {
|
|
spinner.succeed(`Found ${patchPRs.length} PRs to cherry-pick to main.`);
|
|
} else {
|
|
spinner.warn('No PRs found.');
|
|
}
|
|
|
|
const failedCherryPicks: string[] = [];
|
|
|
|
for (const pr of patchPRs) {
|
|
const prSpinner = ora(`Cherry picking #${pr.number}`).start();
|
|
|
|
try {
|
|
await git.raw(['cherry-pick', '-m', '1', '--keep-redundant-commits', '-x', pr.mergeCommit]);
|
|
prSpinner.succeed(`Picked: ${formatPR(pr)}`);
|
|
} catch (pickError) {
|
|
invariant(pickError instanceof Error);
|
|
prSpinner.fail(`Failed to automatically pick: ${formatPR(pr)}`);
|
|
logger.error(pickError.message);
|
|
const abort = ora(`Aborting cherry pick for merge commit: ${pr.mergeCommit}`).start();
|
|
try {
|
|
await git.raw(['cherry-pick', '--abort']);
|
|
abort.stop();
|
|
} catch (abortError) {
|
|
invariant(abortError instanceof Error);
|
|
abort.warn(`Failed to abort cherry pick (${pr.mergeCommit})`);
|
|
logger.error(abortError.message);
|
|
}
|
|
failedCherryPicks.push(pr.mergeCommit);
|
|
prSpinner.info(
|
|
`This PR can be picked manually with: ${picocolors.gray(
|
|
`git cherry-pick -m1 -x ${pr.mergeCommit}`
|
|
)}`
|
|
);
|
|
}
|
|
}
|
|
|
|
if (process.env.GITHUB_ACTIONS === 'true') {
|
|
setOutput('no-patch-prs', patchPRs.length === 0);
|
|
setOutput('failed-cherry-picks', JSON.stringify(failedCherryPicks));
|
|
}
|
|
};
|
|
|
|
if (esMain(import.meta.url)) {
|
|
const options = program.parse(process.argv);
|
|
run(options).catch((err) => {
|
|
console.error(err);
|
|
process.exit(1);
|
|
});
|
|
}
|