@naxodev/gonx
Version:
Modern Nx plugin to use Go in a Nx workspace
165 lines • 7.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = runExecutor;
const devkit_1 = require("@nx/devkit");
const node_child_process_1 = require("node:child_process");
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const npm_run_path_1 = require("npm-run-path");
const chalk = require("chalk");
const LARGE_BUFFER = 1024 * 1000000;
const DEFAULT_TAG_PATTERN = 'v{version}';
function processEnv(color) {
const env = {
...process.env,
...(0, npm_run_path_1.env)(),
};
if (color) {
env.FORCE_COLOR = `${color}`;
}
return env;
}
/**
* Gets the release tag pattern from nx.json configuration
* @param workspaceRoot The root of the workspace
* @param projectName The name of the project
* @returns The tag pattern to use for releases
*/
function getReleaseTagPattern(workspaceRoot, projectName) {
try {
const nxJsonPath = (0, node_path_1.join)(workspaceRoot, 'nx.json');
const nxJson = (0, devkit_1.readJsonFile)(nxJsonPath);
// Check for release configuration in nx.json
if (nxJson.release && nxJson.release.releaseTagPattern) {
// Replace {projectName} with the actual project name in the pattern
const tagPattern = nxJson.release.releaseTagPattern.replace('{projectName}', projectName);
return tagPattern;
}
// Return default pattern if nothing specific is found
return DEFAULT_TAG_PATTERN;
}
catch (err) {
console.warn(`Warning: Could not read nx.json to determine tag pattern: ${err}`);
return DEFAULT_TAG_PATTERN;
}
}
/**
* Gets the latest version from git tags based on the pattern
* @param moduleRoot Root directory of the module
* @param tagPattern Pattern to match tags
* @param projectName Name of the project
* @returns The latest version tag
*/
function getLatestVersionFromGit(moduleRoot, tagPattern) {
try {
// Create a git command that finds the latest tag matching our pattern
// Replace {version} with a wildcard in the pattern for the git command
const gitPattern = tagPattern.replace('{version}', '*');
// Command to get the latest tag matching our pattern
const gitTagCmd = `git tag --sort=-v:refname | grep -E "${gitPattern}" | head -n 1 || echo "${tagPattern.replace('{version}', '0.0.0')}"`;
devkit_1.output.logSingleLine(`Running: ${gitTagCmd}`);
const latestTag = (0, node_child_process_1.execSync)(gitTagCmd, {
env: processEnv(true),
cwd: moduleRoot,
stdio: 'pipe',
})
.toString()
.trim();
return latestTag;
}
catch (err) {
console.warn(`Warning: Failed to get latest version from git: ${err}`);
return tagPattern.replace('{version}', '0.0.0');
}
}
async function runExecutor(options, context) {
var _a, _b;
/**
* We need to check both the env var and the option because the executor may have been triggered
* indirectly via dependsOn, in which case the env var will be set, but the option will not.
*/
const isDryRun = process.env.NX_DRY_RUN === 'true' || options.dryRun || false;
const projectName = context.projectName;
if (!projectName) {
devkit_1.output.error({ title: 'Project name is undefined' });
return { success: false };
}
const projectConfig = (_a = context.projectsConfigurations) === null || _a === void 0 ? void 0 : _a.projects[projectName];
if (!projectConfig) {
devkit_1.output.error({
title: `Project configuration for ${projectName} not found`,
});
return { success: false };
}
const moduleRoot = (0, devkit_1.joinPathFragments)(context.root, (_b = options.moduleRoot) !== null && _b !== void 0 ? _b : projectConfig.root);
const goModPath = (0, devkit_1.joinPathFragments)(moduleRoot, 'go.mod');
const goModContents = (0, node_fs_1.readFileSync)(goModPath, 'utf-8');
const moduleMatch = goModContents.match(/module\s+([^\s]+)/);
if (!moduleMatch) {
devkit_1.output.error({ title: `Could not find module name in ${goModPath}` });
return { success: false };
}
const moduleName = moduleMatch[1];
try {
// Get the release tag pattern from nx.json
const tagPattern = getReleaseTagPattern(context.root, projectName);
devkit_1.output.logSingleLine(`Using release tag pattern: ${tagPattern}`);
// Get the current version (tag) based on the pattern
const currentTag = getLatestVersionFromGit(moduleRoot, tagPattern);
if (!currentTag) {
devkit_1.output.error({
title: `Could not determine current version for ${projectName}. Please make sure there is at least one tag that matches the pattern ${tagPattern}.`,
});
return { success: false };
}
devkit_1.output.logSingleLine(`Found latest version tag: ${currentTag}`);
// Extract the version from the tag using regex based on the tag pattern
let version = currentTag;
// Create a regex pattern from the tag pattern, replacing {version} with a capturing group
if (tagPattern.includes('{version}')) {
// Escape special regex characters in the tag pattern
const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// Create pattern by replacing {projectName} with its value and {version} with a capturing group
const regexPattern = escapeRegex(tagPattern)
.replace(escapeRegex('{projectName}'), escapeRegex(projectName))
.replace(escapeRegex('{version}'), '(.+)');
// Create regex and try to match
const regex = new RegExp(`^${regexPattern}$`);
const match = currentTag.match(regex);
if (match && match[1]) {
version = match[1];
}
}
// Prepare GOPROXY command - ensure version has proper format
const versionForCommand = version.startsWith('v') ? version : `v${version}`;
const goPublishCommand = `GOPROXY=proxy.golang.org go list -m ${moduleName}@${versionForCommand}`;
devkit_1.output.logSingleLine(`Publishing ${chalk.bold(moduleName)} at version ${chalk.bold(versionForCommand)} (from tag ${chalk.bold(currentTag)})...`);
if (isDryRun) {
console.log(`Would run: ${goPublishCommand}`);
console.log(`Would publish module ${chalk.cyan(moduleName)} at version ${chalk.cyan(versionForCommand)} to the Go proxy, but ${chalk.keyword('orange')('[dry-run]')} was set`);
}
else {
devkit_1.output.logSingleLine(`Running "${goPublishCommand}"...`);
(0, node_child_process_1.execSync)(goPublishCommand, {
maxBuffer: LARGE_BUFFER,
env: processEnv(true),
cwd: moduleRoot,
stdio: 'inherit',
});
console.log('');
console.log(`Published ${chalk.cyan(moduleName)}@${chalk.cyan(versionForCommand)} to Go proxy`);
}
return {
success: true,
};
}
catch (err) {
if (err instanceof Error) {
console.error('Publication failed:', err.message);
}
return {
success: false,
};
}
}
//# sourceMappingURL=nx-release-publish.js.map