@storm-software/workspace-tools
Version:
Tools for managing a Storm workspace, including various Nx generators and executors for common development tasks.
268 lines (256 loc) • 9.04 kB
JavaScript
import {
pnpmCatalogUpdate
} from "./chunk-AD4BVP7F.mjs";
import {
joinPaths
} from "./chunk-ATIBREWM.mjs";
import {
__name
} from "./chunk-2BPV2XV2.mjs";
// src/executors/npm-publish/executor.ts
import { execSync } from "node:child_process";
import { readFile } from "node:fs/promises";
var LARGE_BUFFER = 1024 * 1e6;
async function npmPublishExecutorFn(options, context) {
const isDryRun = process.env.NX_DRY_RUN === "true" || options.dryRun || false;
if (!context.projectName) {
throw new Error("The `npm-publish` executor requires a `projectName`.");
}
const projectConfig = context.projectsConfigurations?.projects?.[context.projectName];
if (!projectConfig) {
throw new Error(`Could not find project configuration for \`${context.projectName}\``);
}
const packageRoot = joinPaths(context.root, options.packageRoot || joinPaths("dist", projectConfig.root));
const packageJsonPath = joinPaths(packageRoot, "package.json");
const packageJsonFile = await readFile(packageJsonPath, "utf8");
if (!packageJsonFile) {
throw new Error(`Could not find \`package.json\` at ${packageJsonPath}`);
}
const packageJson = JSON.parse(packageJsonFile);
const packageName = packageJson.name;
console.info(`\u{1F680} Running Storm NPM Publish executor on the ${packageName} package`);
const packageTxt = packageName === context.projectName ? `package "${packageName}"` : `package "${packageName}" from project "${context.projectName}"`;
if (packageJson.private === true) {
console.warn(`Skipped ${packageTxt}, because it has \`"private": true\` in ${packageJsonPath}`);
return {
success: true
};
}
await pnpmCatalogUpdate(packageRoot, context.root);
const npmPublishCommandSegments = [
`npm publish --json`
];
const npmViewCommandSegments = [
`npm view ${packageName} versions dist-tags --json`
];
const registry = options.registry ? options.registry : execSync("npm config get registry", {
cwd: packageRoot,
env: {
...process.env,
FORCE_COLOR: "true"
},
maxBuffer: LARGE_BUFFER,
killSignal: "SIGTERM"
}).toString().trim();
if (registry) {
npmPublishCommandSegments.push(`--registry="${registry}" `);
npmViewCommandSegments.push(`--registry="${registry}" `);
}
if (options.otp) {
npmPublishCommandSegments.push(`--otp="${options.otp}" `);
}
if (isDryRun) {
npmPublishCommandSegments.push("--dry-run");
}
npmPublishCommandSegments.push("--provenance --access=public ");
const tag = options.tag || execSync("npm config get tag", {
cwd: packageRoot,
env: {
...process.env,
FORCE_COLOR: "true"
},
maxBuffer: LARGE_BUFFER,
killSignal: "SIGTERM"
}).toString().trim();
if (tag) {
npmPublishCommandSegments.push(`--tag="${tag}" `);
}
if (!isDryRun) {
const currentVersion = packageJson.version;
try {
try {
const result = execSync(npmViewCommandSegments.join(" "), {
cwd: packageRoot,
env: {
...process.env,
FORCE_COLOR: "true"
},
maxBuffer: LARGE_BUFFER,
killSignal: "SIGTERM"
});
const resultJson = JSON.parse(result.toString());
const distTags = resultJson["dist-tags"] || {};
if (distTags[tag] === currentVersion) {
console.warn(`Skipped ${packageTxt} because v${currentVersion} already exists in ${registry} with tag "${tag}"`);
return {
success: true
};
}
} catch (err) {
console.warn("\n ********************** \n");
console.warn(`An error occurred while checking for existing dist-tags
${JSON.stringify(err)}
Note: If this is the first time this package has been published to NPM, this can be ignored.
`);
console.info("");
}
try {
if (!isDryRun) {
const command = `npm dist-tag add ${packageName}@${currentVersion} ${tag} --registry="${registry}" `;
console.info(`Adding the dist-tag ${tag} - preparing to run the following:
${command}
`);
const result = execSync(command, {
cwd: packageRoot,
env: {
...process.env,
FORCE_COLOR: "true"
},
maxBuffer: LARGE_BUFFER,
killSignal: "SIGTERM"
});
console.info(`Added the dist-tag ${tag} to v${currentVersion} for registry "${registry}"
Execution response: ${result.toString()}
`);
} else {
console.info(`Would add the dist-tag ${tag} to v${currentVersion} for registry "${registry}", but [dry-run] was set.
`);
}
return {
success: true
};
} catch (err) {
try {
console.warn("\n ********************** \n");
let error = err;
if (Buffer.isBuffer(error)) {
error = error.toString();
}
console.warn(`An error occurred while adding dist-tags:
${error}
Note: If this is the first time this package has been published to NPM, this can be ignored.
`);
console.info("");
const stdoutData = JSON.parse(err.stdout?.toString() || "{}");
if (stdoutData?.error && !(stdoutData.error?.code?.includes("E404") && stdoutData.error?.summary?.includes("no such package available")) && !(err.stderr?.toString().includes("E404") && err.stderr?.toString().includes("no such package available"))) {
console.error("npm dist-tag add error please see below for more information:");
if (stdoutData.error.summary) {
console.error(stdoutData.error?.summary);
}
if (stdoutData.error.detail) {
console.error(stdoutData.error?.detail);
}
if (context.isVerbose) {
console.error(`npm dist-tag add stdout: ${JSON.stringify(stdoutData, null, 2)}`);
}
return {
success: false
};
}
} catch (err2) {
console.error(`Something unexpected went wrong when processing the npm dist-tag add output
${JSON.stringify(err2)}`);
return {
success: false
};
}
}
} catch (err) {
let error = err;
if (Buffer.isBuffer(error)) {
error = error.toString();
}
console.error("\n ********************** \n");
console.info("");
console.error("An error occured trying to run the npm dist-tag add command.");
console.error(error);
console.info("");
const stdoutData = JSON.parse(err.stdout?.toString() || "{}");
if (!(stdoutData.error?.code?.includes("E404") && stdoutData.error?.summary?.toLowerCase().includes("not found")) && !(err.stderr?.toString().includes("E404") && err.stderr?.toString().toLowerCase().includes("not found"))) {
console.error(`Something unexpected went wrong when checking for existing dist-tags.
Error: ${JSON.stringify(err)}
`);
return {
success: false
};
}
}
}
try {
const cwd = packageRoot;
const command = npmPublishCommandSegments.join(" ");
console.info(`Running publish command "${command}" in current working directory: "${cwd}" `);
const result = execSync(command, {
cwd,
env: {
...process.env,
FORCE_COLOR: "true"
},
maxBuffer: LARGE_BUFFER,
killSignal: "SIGTERM"
});
if (isDryRun) {
console.info(`Would publish to ${registry} with tag "${tag}", but [dry-run] was set ${result ? `
Execution response: ${result.toString()}` : ""}
`);
} else {
console.info(`Published to ${registry} with tag "${tag}" ${result ? `
Execution response: ${result.toString()}` : ""}
`);
}
return {
success: true
};
} catch (err) {
try {
console.error("\n ********************** \n");
console.info("");
console.error("An error occured running pnpm publish.");
console.error("Please see below for more information:");
console.info("");
const stdoutData = JSON.parse(err.stdout?.toString() || "{}");
if (stdoutData.error.summary) {
console.error(stdoutData.error.summary);
console.error(stdoutData.error.summary);
}
if (stdoutData.error.detail) {
console.error(stdoutData.error.detail);
}
if (context.isVerbose) {
console.error(`npm publish stdout:
${JSON.stringify(stdoutData, null, 2)}`);
}
console.error("\n ********************** \n");
return {
success: false
};
} catch (err2) {
let error = err2;
if (Buffer.isBuffer(error)) {
error = error.toString();
}
console.error(`Something unexpected went wrong when processing the npm publish output
Error: ${JSON.stringify(error)}
`);
console.error("\n ********************** \n");
return {
success: false
};
}
}
}
__name(npmPublishExecutorFn, "npmPublishExecutorFn");
export {
LARGE_BUFFER,
npmPublishExecutorFn
};