Skip to content

Commit

Permalink
feat: Support picking rebased PRs for patch releases
Browse files Browse the repository at this point in the history
Signed-off-by: Sebastian Malton <sebastian@malton.name>
  • Loading branch information
Nokel81 committed May 19, 2023
1 parent 32a6179 commit c5bfdd0
Showing 1 changed file with 41 additions and 10 deletions.
51 changes: 41 additions & 10 deletions packages/release-tool/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
import assert from "assert";
import chalk from "chalk";
import child_process, { ExecFileOptions, spawn as _spawn } from "child_process";
import child_process, { spawn as _spawn } from "child_process";
import { readFile } from "fs/promises";
import inquirer from "inquirer";
import { createInterface, ReadLine } from "readline";
Expand All @@ -24,11 +24,15 @@ const exec = ((cmd, ...args) => {
return _exec(cmd, ...args as any[]);
}) as typeof _exec;

const execFile = (file: string, args: string[], opts?: ExecFileOptions) => {
console.log("EXEC", file, args);
const execFile = ((file: string, ...rest) => {
if (Array.isArray(rest[0])) {
console.log("EXEC-FILE", file, rest[0]);
} else {
console.log("EXEC-FILE", file);
}

return _execFile(file, args, opts);
};
return _execFile(file, ...rest as [any, any]);
}) as typeof _execFile;

const spawn = ((file, ...args) => {
console.log("SPAWN", file);
Expand All @@ -49,10 +53,15 @@ async function pipeExecFile(file: string, args: string[], opts?: { stdin: string
await p;
}

interface GithubAuthor {
email: string;
id: string;
login: string;
name: string;
}

interface GithubPrData {
author: {
login: string;
};
author: GithubAuthor;
labels: {
id: string;
name: string;
Expand All @@ -62,6 +71,14 @@ interface GithubPrData {
mergeCommit: {
oid: string;
};
commits: {
authoredDate: string;
committedDate: string;
messageBody: string;
messageHeadline: string;
oid: string;
authors: GithubAuthor[];
}[];
mergedAt: string;
milestone: {
number: number;
Expand Down Expand Up @@ -227,7 +244,7 @@ async function getRelevantPRs(previousReleasedVersion: string, baseBranch: strin
"--limit=500", // Should be big enough, if not we need to release more often ;)
"--state=merged",
`--base=${baseBranch}`,
"--json mergeCommit,title,author,labels,number,milestone,mergedAt",
"--json mergeCommit,title,author,labels,number,milestone,mergedAt,commits",
];

const mergedPrs = JSON.parse((await exec(getMergedPrsArgs.join(" "), { encoding: "utf-8" })).stdout) as GithubPrData[];
Expand Down Expand Up @@ -325,13 +342,27 @@ function formatChangelog(previousReleasedVersion: string, prs: ExtendedGithubPrD
].join("\n");
}

async function computeIfPrWasSquashed(pr: ExtendedGithubPrData): Promise<boolean> {
const { stdout: mergeCommitSubject } = await execFile("git", ["log", "-1", "--format=%s", pr.mergeCommit.oid]);

return pr.commits.every(commit => commit.messageHeadline !== mergeCommitSubject);
}

async function cherryPickCommits(prs: ExtendedGithubPrData[]): Promise<void> {
const rl = createInterface(process.stdin);
const cherryPickCommit = cherryPickCommitWith(rl);

for (const pr of prs) {
if (pr.shouldAttemptCherryPick) {
await cherryPickCommit(pr.mergeCommit.oid);
const wasSquashed = await computeIfPrWasSquashed(pr);

if (wasSquashed) {
await cherryPickCommit(pr.mergeCommit.oid);
} else {
for (const commit of pr.commits) {
await cherryPickCommit(commit.oid);
}
}
} else {
console.log(`Skipping cherry picking of #${pr.number} - ${pr.title}`);
}
Expand Down

0 comments on commit c5bfdd0

Please sign in to comment.