@decaf-ts/utils
Version:
module management utils for decaf-ts
207 lines • 7.18 kB
JavaScript
import { Command } from "./../command.js";
import { DefaultCommandOptions } from "./../constants.js";
import { dispatchReleaseChainWorkflow, runReleaseChain, } from "./../../release-chain/index.js";
import { getPackage } from "./../../utils/index.js";
import { execSync } from "node:child_process";
import { printCommandHelp } from "./help.command.js";
const releaseChainArgs = {
meta: {
type: "string",
default: process.env.RELEASE_CHAIN_META_REPO_URL || "",
},
branch: {
type: "string",
default: process.env.RELEASE_CHAIN_BRANCH ||
process.env.GITHUB_REF_NAME ||
"main",
},
current: {
type: "string",
default: process.env.RELEASE_CHAIN_CURRENT || process.env.GITHUB_REPOSITORY || "",
},
package: {
type: "string",
default: "",
},
token: {
type: "string",
default: process.env.RELEASE_CHAIN_TOKEN || "",
},
submoduleFile: {
type: "string",
default: process.env.RELEASE_CHAIN_FILE || "",
},
submodulePath: {
type: "string",
default: process.env.RELEASE_CHAIN_FILE_PATH || "",
},
workflow: {
type: "string",
default: process.env.RELEASE_CHAIN_WORKFLOW || "release-chain.yaml",
},
repo: {
type: "string",
default: process.env.RELEASE_CHAIN_REPO || "",
},
ref: {
type: "string",
default: process.env.RELEASE_CHAIN_REF || "",
},
targetBase: {
type: "string",
default: process.env.RELEASE_CHAIN_TARGET || "",
},
};
export class ReleaseChainCommand extends Command {
constructor() {
super("ReleaseChain", Object.assign({}, DefaultCommandOptions, releaseChainArgs));
}
help() {
printCommandHelp(this.log, "release-chain", "Run the release-chain workflow locally across repositories.", "release-chain [options]", [
{ flag: "--meta <url>", description: "Meta repository URL" },
{
flag: "--branch <name>",
description: "Branch to update downstream repositories",
defaultValue: "main or detected branch",
},
{
flag: "--current <owner/repo>",
description: "Current repository slug to resume after in the chain",
},
{
flag: "--package <name>",
description: "Override detected package name",
},
{
flag: "--token <token>",
description: "GitHub token for cloning and pushing",
},
{
flag: "--submodule-file <file>",
description: "Override submodule file name",
},
{
flag: "--submodule-path <path>",
description: "Use a local submodule file instead of downloading",
},
{
flag: "--target-base <branch>",
description: "Base branch for downstream pull requests",
},
{
flag: "-h, --help",
description: "Show this help text and exit",
},
], [
"Missing meta or branch values are detected from git and environment variables when possible.",
]);
}
async run(options) {
const answerMap = options;
const packageName = answerMap.package ||
getPackage(process.cwd())?.name;
if (!packageName) {
throw new Error("Unable to determine package name");
}
const metaRepo = answerMap.meta || detectRemoteUrl();
if (!metaRepo) {
throw new Error("A meta repository URL is required");
}
const branch = answerMap.branch || detectBranch();
await runReleaseChain({
metaRepoUrl: metaRepo,
branch,
currentRepo: answerMap.current,
packageName,
token: answerMap.token,
submoduleFile: answerMap.submoduleFile || undefined,
submodulePath: answerMap.submodulePath || undefined,
targetBaseBranch: answerMap.targetBase || undefined,
});
}
}
export class ReleaseChainDispatchCommand extends Command {
constructor() {
super("ReleaseChainDispatch", Object.assign({}, DefaultCommandOptions, releaseChainArgs));
}
help() {
printCommandHelp(this.log, "release-chain-dispatch", "Dispatch the release-chain GitHub Actions workflow.", "release-chain-dispatch [options]", [
{ flag: "--meta <url>", description: "Meta repository URL" },
{
flag: "--branch <name>",
description: "Branch to evaluate in downstream repositories",
defaultValue: "main or detected branch",
},
{
flag: "--current <owner/repo>",
description: "Repository slug that triggered the release chain",
},
{
flag: "--workflow <file>",
description: "Workflow file name",
defaultValue: "release-chain.yaml",
},
{
flag: "--repo <owner/repo>",
description: "Target repository slug where the workflow lives",
},
{
flag: "--token <token>",
description: "GitHub token for dispatching workflows",
},
{
flag: "--ref <ref>",
description: "Git ref to dispatch the workflow on",
},
{
flag: "--target-base <branch>",
description: "Base branch for downstream pull requests",
},
{
flag: "-h, --help",
description: "Show this help text and exit",
},
], [
"Missing meta or branch values are detected from git and environment variables when possible.",
]);
}
async run(options) {
const answerMap = options;
const metaRepo = answerMap.meta || detectRemoteUrl();
if (!metaRepo) {
throw new Error("A meta repository URL is required");
}
const branch = answerMap.branch || detectBranch();
await dispatchReleaseChainWorkflow({
metaRepoUrl: metaRepo,
branch,
workflowFile: answerMap.workflow || "release-chain.yaml",
repoSlug: answerMap.repo,
currentRepo: answerMap.current,
token: answerMap.token,
ref: answerMap.ref || branch,
targetBaseBranch: answerMap.targetBase || undefined,
});
}
}
function detectRemoteUrl() {
try {
return execSync("git config --get remote.origin.url", {
encoding: "utf8",
}).trim();
}
catch {
return undefined;
}
}
function detectBranch() {
try {
return execSync("git rev-parse --abbrev-ref HEAD", {
encoding: "utf8",
}).trim();
}
catch {
return "main";
}
}
//# sourceMappingURL=release-chain.command.js.map