@decaf-ts/utils
Version:
module management utils for decaf-ts
214 lines • 8.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TagReleaseCommand = void 0;
const node_child_process_1 = require("node:child_process");
const command_js_1 = require("./../command.cjs");
const input_js_1 = require("./../../input/input.cjs");
const constants_js_1 = require("./../../utils/constants.cjs");
const help_command_js_1 = require("./help.command.cjs");
const credentials_command_js_1 = require("./credentials.command.cjs");
const options = {
public: {
type: "boolean",
default: false,
},
private: {
type: "boolean",
default: false,
},
gitToken: {
type: "string",
default: "github",
},
npmToken: {
type: "string",
default: "npm",
},
gitUser: {
type: "string",
default: undefined,
},
allowFromBranch: {
type: "boolean",
default: false,
},
tag: {
type: "string",
default: undefined,
},
message: {
type: "string",
default: undefined,
},
};
class TagReleaseCommand extends command_js_1.Command {
constructor() {
super("TagReleaseCommand", options);
}
async ensureReleaseBranch(allowFromBranch = false) {
if (allowFromBranch)
return;
const currentBranch = (0, node_child_process_1.execSync)("git rev-parse --abbrev-ref HEAD", {
cwd: process.cwd(),
encoding: "utf8",
}).trim();
if (currentBranch !== "master" && currentBranch !== "main") {
throw new Error(`release must be run from 'master' or 'main' branch. Current branch: ${currentBranch}`);
}
}
async prepareTag(tag) {
tag = `${tag || ""}`.trim();
if (tag.length > 0) {
return tag;
}
(0, node_child_process_1.execSync)("git tag --sort=-taggerdate | head -n 5", {
cwd: process.cwd(),
stdio: "inherit",
});
return input_js_1.UserInput.insistForText("tag", "What should be the new tag? (accepts v*.*.*[-...])", (val) => !!val.toString().match(/^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9a-zA-Z-]+)?$/));
}
async prepareMessage(message) {
message = `${message || ""}`.trim();
if (message.length > 0) {
return message;
}
return input_js_1.UserInput.insistForText("message", "Tag Message", (val) => !!val && val.toString().length > 0);
}
help() {
(0, help_command_js_1.printCommandHelp)(this.log, "tag-release", "Prepare a release, create a git tag, push, and optionally publish to npm.", "tag-release [options] [tag] [message]", [
{
flag: "--public",
description: "Publish to the public npm registry",
defaultValue: "false",
},
{
flag: "--private",
description: "Publish to the restricted npm registry",
defaultValue: "false",
},
{
flag: "--git-token <name>",
description: "Secret name for the git push token",
defaultValue: "github",
},
{
flag: "--npm-token <name>",
description: "Secret name for the npm publish token",
defaultValue: "npm",
},
{
flag: "--git-user <name>",
description: "Git user name embedded in authenticated pushes",
},
{
flag: "--allow-from-branch",
description: "Skip the master/main branch guard",
defaultValue: "false",
},
{
flag: "--tag <version>",
description: "Release tag to create",
},
{
flag: "--message <text>",
description: "Release message to use",
},
{
flag: "-h, --help",
description: "Show this help text and exit",
},
], [
"If tag or message are omitted, the command prompts interactively.",
"Tokens are resolved via the credentials command (env var → OS keychain → legacy file).",
], [
"tag-release --public --tag v1.2.3 --message \"Release 1.2.3\"",
"tag-release --private --allow-from-branch --tag v1.2.3",
]);
}
async run(answers) {
await this.ensureReleaseBranch(answers.allowFromBranch === true);
const publishAccessFlag = answers.private === true ? "private" : "public";
const tag = await this.prepareTag(answers.tag);
const message = await this.prepareMessage(answers.message);
const gitTokenName = `${answers.gitToken || "github"}`;
const npmTokenName = `${answers.npmToken || "npm"}`;
const gitUser = typeof answers.gitUser === "string" && answers.gitUser.trim().length > 0
? answers.gitUser.trim()
: (0, node_child_process_1.execSync)("git config user.name", {
cwd: process.cwd(),
encoding: "utf8",
}).trim();
(0, node_child_process_1.execSync)("npm run prepare-release", {
cwd: process.cwd(),
stdio: "inherit",
});
const status = (0, node_child_process_1.execSync)("git status --porcelain", {
cwd: process.cwd(),
encoding: "utf8",
});
if (status.trim().length > 0) {
(0, node_child_process_1.execSync)("git add .", { cwd: process.cwd(), stdio: "inherit" });
(0, node_child_process_1.execSync)(`git commit -m "${tag} - ${message} - after release preparation"`, {
cwd: process.cwd(),
stdio: "inherit",
});
}
(0, node_child_process_1.execSync)(`npm version "${tag}" -m "${message}"`, {
cwd: process.cwd(),
stdio: "inherit",
});
const remoteUrl = (0, node_child_process_1.execSync)("git remote get-url origin", {
cwd: process.cwd(),
encoding: "utf8",
}).trim();
if ((0, credentials_command_js_1.hasSecret)(gitTokenName)) {
const currentBranch = (0, node_child_process_1.execSync)("git rev-parse --abbrev-ref HEAD", {
cwd: process.cwd(),
encoding: "utf8",
});
let upstream = "";
try {
upstream = (0, node_child_process_1.execSync)("git rev-parse --abbrev-ref --symbolic-full-name '@{u}'", {
cwd: process.cwd(),
encoding: "utf8",
});
}
catch {
upstream = "";
}
const token = (0, credentials_command_js_1.resolveSecret)(gitTokenName);
(0, node_child_process_1.execSync)(`git push "https://${gitUser}:${token}@${remoteUrl.replace(/^https:\/\//, "")}" --follow-tags`, {
cwd: process.cwd(),
stdio: "inherit",
});
if (upstream.trim().length > 0) {
try {
(0, node_child_process_1.execSync)(`git branch --set-upstream-to="${upstream.trim()}" "${currentBranch.trim()}"`, {
cwd: process.cwd(),
stdio: "inherit",
});
}
catch {
// ignore restore failures
}
}
}
else {
(0, node_child_process_1.execSync)("git push --follow-tags", {
cwd: process.cwd(),
stdio: "inherit",
});
}
const npmAccessValue = publishAccessFlag === "public" ? "public" : "restricted";
if (message.endsWith(constants_js_1.NoCIFLag) && (0, credentials_command_js_1.hasSecret)(npmTokenName)) {
const npmToken = (0, credentials_command_js_1.resolveSecret)(npmTokenName);
(0, node_child_process_1.execSync)(`NPM_TOKEN="${npmToken}" npm publish --ignore-scripts --access "${npmAccessValue}"`, {
cwd: process.cwd(),
stdio: "inherit",
});
}
}
}
exports.TagReleaseCommand = TagReleaseCommand;
//# sourceMappingURL=tag-release-shell.command.js.map
//# sourceMappingURL=tag-release-shell.command.cjs.map