alvamind-tools
Version:
CLI tools for generating source code documentation and git automation
131 lines (105 loc) โข 4.33 kB
text/typescript
import { execSync } from 'child_process';
import * as readline from 'readline';
import chalk from 'chalk';
import * as fs from 'fs';
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const [, , versionArg, commitMessageArg] = process.argv;
async function askQuestion(query: string): Promise<string> {
return new Promise((resolve) => {
rl.question(query, resolve);
});
}
function getCurrentBranch(): string {
return execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
}
function validatePackageJson(): void {
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const requiredFields = ['name', 'version', 'description', 'main', 'types'];
for (const field of requiredFields) {
if (!packageJson[field]) {
throw new Error(`Missing required field in package.json: ${field}`);
}
}
}
async function selectVersionType(): Promise<string> {
if (versionArg && ['patch', 'minor', 'major'].includes(versionArg)) {
return versionArg;
}
console.log(chalk.cyan('\nSelect version increment type:'));
console.log(chalk.gray('1. patch (1.0.0 -> 1.0.1)'));
console.log(chalk.gray('2. minor (1.0.0 -> 1.1.0)'));
console.log(chalk.gray('3. major (1.0.0 -> 2.0.0)'));
const answer = await askQuestion('Enter your choice (1-3): ');
const versionMap: { [key: string]: string } = {
'1': 'patch',
'2': 'minor',
'3': 'major',
};
return versionMap[answer] || 'patch';
}
async function getCommitMessage(version: string): Promise<string> {
if (commitMessageArg) {
return commitMessageArg;
}
const defaultMessage = `chore: release v${version}`;
const message = await askQuestion(
chalk.cyan(`Enter commit message (default: "${defaultMessage}"): `)
);
return message.trim() || defaultMessage;
}
async function publishPackage() {
try {
console.log(chalk.cyan('\n๐ Running pre-publish checks...\n'));
console.log(chalk.cyan('๐ Validating package.json...'));
validatePackageJson();
console.log(chalk.green('โ
package.json is valid'));
const currentBranch = getCurrentBranch();
if (currentBranch !== 'main' && currentBranch !== 'master') {
console.log(chalk.yellow(`โ ๏ธ You're on branch '${currentBranch}'.`));
}
console.log(chalk.cyan('\n๐งน Cleaning project...'));
execSync('bun clean', { stdio: 'inherit' });
console.log(chalk.cyan('\n๐ฆ Installing dependencies...'));
execSync('bun install', { stdio: 'inherit' });
console.log(chalk.cyan('\n๐จ Building project...'));
execSync('bun run build', { stdio: 'inherit' });
try {
console.log(chalk.cyan('\n๐งช Running tests...'));
execSync('bun test', { stdio: 'inherit' });
console.log(chalk.green('โ
Tests passed'));
} catch (error) {
console.log(chalk.yellow('โ ๏ธ No tests found or tests failed'));
}
const versionType = await selectVersionType();
console.log(chalk.cyan(`\n๐ Incrementing ${versionType} version...`));
execSync(`npm version ${versionType} --no-git-tag-version`, { stdio: 'inherit' });
console.log(chalk.cyan('\n๐ Publishing to npm...'));
execSync('npm publish', { stdio: 'inherit' });
// Get the new version after publishing
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const newVersion = packageJson.version;
const tagName = `v${newVersion}`;
// Get commit message and commit changes
const commitMessage = await getCommitMessage(newVersion);
console.log(chalk.cyan('\n๐ Committing changes...'));
execSync(`bun commit "${commitMessage}"`, { stdio: 'inherit' });
// Create and push tag
console.log(chalk.cyan('\n๐ท๏ธ Creating and pushing tag...'));
execSync(`git tag ${tagName}`, { stdio: 'inherit' });
execSync('git push --tags', { stdio: 'inherit' });
console.log(chalk.green('\nโจ Package successfully published to npm!'));
console.log(chalk.gray(`Version: ${newVersion}`));
console.log(chalk.gray(`Tag: ${tagName}`));
console.log(chalk.gray(`Commit: ${commitMessage}`));
} catch (error) {
console.error(chalk.red('\nโ Error during publish process:'), error);
process.exit(1);
} finally {
rl.close();
}
}
publishPackage();