mirror of
https://github.com/awalsh128/cache-apt-pkgs-action.git
synced 2026-07-06 17:14:36 +00:00
130 lines
3 KiB
JavaScript
130 lines
3 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import process from "node:process";
|
|
import {
|
|
ROOT_DIR,
|
|
assertNonEmpty,
|
|
confirmPrompt,
|
|
fail,
|
|
logInfo,
|
|
logSuccess,
|
|
run,
|
|
runCaptureOutput,
|
|
tryRun,
|
|
usage,
|
|
} from "./lib.mjs";
|
|
|
|
const issueId = process.argv[2] ?? "";
|
|
const base = process.argv[3] ?? "";
|
|
const usageMessage = usage(process.argv[1], "<issue ID> <target branch>");
|
|
|
|
assertNonEmpty(issueId, "Issue ID is empty", usageMessage);
|
|
assertNonEmpty(base, "Target branch is empty", usageMessage);
|
|
|
|
if (!/^\d+$/.test(issueId)) {
|
|
fail("Issue ID must be an integer.");
|
|
}
|
|
|
|
const branchSuffix = `issue-${issueId}`;
|
|
const hotfixBranch = `hotfix/${branchSuffix}`;
|
|
|
|
function branchExistsOnOrigin(branch) {
|
|
return tryRun("git", [
|
|
"ls-remote",
|
|
"--exit-code",
|
|
"--heads",
|
|
"origin",
|
|
branch,
|
|
]).ok;
|
|
}
|
|
|
|
function createOrCheckoutBranch(checkoutBranch, baseBranch) {
|
|
if (branchExistsOnOrigin(checkoutBranch)) {
|
|
logInfo(
|
|
`Branch ${checkoutBranch} exists. Checking out and merging ${baseBranch}...`,
|
|
);
|
|
run("git", ["checkout", checkoutBranch]);
|
|
run("git", ["pull", "origin", checkoutBranch]);
|
|
run("git", ["merge", baseBranch]);
|
|
} else {
|
|
logInfo(`Creating hotfix branch for issue ${issueId}...`);
|
|
run("git", ["checkout", baseBranch]);
|
|
run("git", ["checkout", "-b", checkoutBranch]);
|
|
run("git", ["merge", baseBranch]);
|
|
}
|
|
}
|
|
|
|
function commitIfNeeded(message) {
|
|
run("git", ["add", "."]);
|
|
const commit = tryRun("git", ["commit", "-m", message]);
|
|
if (commit.ok) {
|
|
return;
|
|
}
|
|
|
|
const combined = `${commit.stdout}\n${commit.stderr}`;
|
|
if (/nothing to commit|no changes added to commit/i.test(combined)) {
|
|
logSuccess("No local changes to commit.");
|
|
return;
|
|
}
|
|
|
|
process.stderr.write(commit.stderr);
|
|
process.exit(commit.status ?? 1);
|
|
}
|
|
|
|
function pushChanges(fixType, syncBranch, syncBase) {
|
|
const message = `${fixType}: resolve critical production issue in #${issueId}`;
|
|
commitIfNeeded(message);
|
|
|
|
const prUrl = runCaptureOutput("gh", [
|
|
"pr",
|
|
"list",
|
|
"--head",
|
|
syncBranch,
|
|
"--base",
|
|
syncBase,
|
|
"--state",
|
|
"open",
|
|
"--json",
|
|
"url",
|
|
"--jq",
|
|
".[0].url",
|
|
]);
|
|
|
|
if (prUrl) {
|
|
logSuccess(`PR already exists: ${prUrl}`);
|
|
} else {
|
|
logInfo("No PR found. Creating new PR...");
|
|
run("gh", [
|
|
"pr",
|
|
"create",
|
|
"--head",
|
|
syncBranch,
|
|
"--base",
|
|
syncBase,
|
|
"--title",
|
|
message,
|
|
]);
|
|
}
|
|
|
|
logInfo(`Pushing changes from ${syncBase} to ${syncBranch}...`);
|
|
run("git", ["push", "origin", syncBranch]);
|
|
}
|
|
|
|
async function main() {
|
|
createOrCheckoutBranch(hotfixBranch, base);
|
|
|
|
await confirmPrompt(
|
|
"Edit files and confirm to continue. This can always be rerun to pickup where you left off. Continue?",
|
|
);
|
|
|
|
pushChanges("fix", hotfixBranch, base);
|
|
|
|
const syncBranch = `sync/staging-${branchSuffix}`;
|
|
createOrCheckoutBranch(syncBranch, hotfixBranch);
|
|
pushChanges("sync", syncBranch, "staging");
|
|
}
|
|
|
|
main().catch((error) => {
|
|
fail(error instanceof Error ? error.message : String(error));
|
|
});
|