mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
fix(release): avoid unused root commit file lookups
This commit is contained in:
1 parent
0f411508c3
commit
8736fe3226
12 files changed
+3854
-30
No files matched your search
@@ -53,7 +53,7 @@ export const releaseInventorySchema = z.object({
|
||||
pullRequests: z.array(pullRequest),
|
||||
});
|
||||
|
||||
export async function readReleaseHistory(run, base, target) {
|
||||
export async function requireCompleteReleaseHistory(run) {
|
||||
if (
|
||||
(await run("git", ["rev-parse", "--is-shallow-repository"])).trim() !==
|
||||
"false"
|
||||
@@ -61,6 +61,10 @@ export async function readReleaseHistory(run, base, target) {
|
||||
throw new Error(
|
||||
"Release inventory requires complete Git history; fetch --unshallow first",
|
||||
);
|
||||
}
|
||||
|
||||
export async function readReleaseHistory(run, base, target) {
|
||||
await requireCompleteReleaseHistory(run);
|
||||
const resolve = async (ref) =>
|
||||
sha.parse(
|
||||
(
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
export function applyReleasePleasePatch(directory?: string): Promise<void>;
|
||||
|
||||
export function releaseProposalSearchDepth(
|
||||
run: (command: string, args: string[]) => Promise<string>,
|
||||
sourceSha: string,
|
||||
): Promise<number>;
|
||||
@@ -0,0 +1,61 @@
|
||||
import { execFile } from "node:child_process";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { createRequire } from "node:module";
|
||||
import { dirname, relative } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { requireCompleteReleaseHistory } from "./release-notes.mjs";
|
||||
|
||||
const execute = promisify(execFile);
|
||||
const require = createRequire(import.meta.url);
|
||||
const project = fileURLToPath(new URL("../../", import.meta.url));
|
||||
const patch = fileURLToPath(
|
||||
new URL("../../patches/release-please+17.3.0.patch", import.meta.url),
|
||||
);
|
||||
|
||||
export async function applyReleasePleasePatch(
|
||||
directory = dirname(require.resolve("release-please/package.json")),
|
||||
) {
|
||||
const metadata = JSON.parse(
|
||||
await readFile(`${directory}/package.json`, "utf8"),
|
||||
);
|
||||
if (metadata.version !== "17.3.0") {
|
||||
throw new Error(
|
||||
"The release proposal patch requires release-please 17.3.0",
|
||||
);
|
||||
}
|
||||
const args = ["--directory", relative(project, directory), patch];
|
||||
const check = async (reverse) => {
|
||||
try {
|
||||
await execute(
|
||||
"git",
|
||||
["apply", "--check", ...(reverse ? ["--reverse"] : []), ...args],
|
||||
{ cwd: project },
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error.code === 1) return false;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
if (await check(false)) {
|
||||
await execute("git", ["apply", ...args], { cwd: project });
|
||||
} else if (!(await check(true))) {
|
||||
throw new Error(
|
||||
"The release proposal dependency patch does not match the installed source",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function releaseProposalSearchDepth(run, sourceSha) {
|
||||
if (!/^[a-f0-9]{40}$/u.test(sourceSha ?? "")) {
|
||||
throw new Error("Expected an exact release proposal source SHA");
|
||||
}
|
||||
await requireCompleteReleaseHistory(run);
|
||||
const text = (await run("git", ["rev-list", "--count", sourceSha])).trim();
|
||||
const count = Number(text);
|
||||
if (!/^[1-9][0-9]*$/u.test(text) || !Number.isSafeInteger(count)) {
|
||||
throw new Error("Git returned an invalid release history size");
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env node
|
||||
import { execFile } from "node:child_process";
|
||||
import { appendFile } from "node:fs/promises";
|
||||
import { parseArgs, promisify } from "node:util";
|
||||
import {
|
||||
applyReleasePleasePatch,
|
||||
releaseProposalSearchDepth,
|
||||
} from "./lib/release-proposal.mjs";
|
||||
|
||||
const execute = promisify(execFile);
|
||||
|
||||
async function main() {
|
||||
const { values } = parseArgs({
|
||||
options: {
|
||||
"target-branch": { type: "string" },
|
||||
"source-sha": { type: "string" },
|
||||
},
|
||||
});
|
||||
const repository = process.env.GITHUB_REPOSITORY;
|
||||
const token = process.env.GH_TOKEN;
|
||||
if (
|
||||
!repository ||
|
||||
!/^[\w.-]+\/[\w.-]+$/u.test(repository) ||
|
||||
!token ||
|
||||
!values["target-branch"]
|
||||
) {
|
||||
throw new Error("Expected GITHUB_REPOSITORY, GH_TOKEN and --target-branch");
|
||||
}
|
||||
const depth = await releaseProposalSearchDepth(
|
||||
async (command, args) =>
|
||||
(await execute(command, args, { encoding: "utf8" })).stdout,
|
||||
values["source-sha"],
|
||||
);
|
||||
// Patch before import: only proposal generation uses this maintained upstream fix.
|
||||
// Publication continues through the pinned release-please action.
|
||||
await applyReleasePleasePatch();
|
||||
const { GitHub, Manifest } = await import("release-please");
|
||||
const [owner, repo] = repository.split("/");
|
||||
const branch = values["target-branch"];
|
||||
const github = await GitHub.create({
|
||||
owner,
|
||||
repo,
|
||||
token,
|
||||
defaultBranch: branch,
|
||||
});
|
||||
const manifest = await Manifest.fromManifest(
|
||||
github,
|
||||
branch,
|
||||
undefined,
|
||||
undefined,
|
||||
{
|
||||
commitSearchDepth: depth,
|
||||
},
|
||||
);
|
||||
const prs = (await manifest.createPullRequests()).filter(Boolean);
|
||||
if (process.env.GITHUB_OUTPUT) {
|
||||
await appendFile(
|
||||
process.env.GITHUB_OUTPUT,
|
||||
`prs_created=${prs.length > 0}\n${prs.length ? `pr=${JSON.stringify(prs[0])}\nprs=${JSON.stringify(prs)}\n` : ""}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await main().catch((error) => {
|
||||
process.stderr.write(
|
||||
`Release proposal failed: ${error instanceof Error ? error.message : String(error)}\n`,
|
||||
);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
Reference in new issue
Block a user