Skip to content

Instantly share code, notes, and snippets.

@ronapelbaum
Last active March 29, 2018 05:57
Show Gist options
  • Save ronapelbaum/17642d12b63825b6cd2b1dd09e089af3 to your computer and use it in GitHub Desktop.
Save ronapelbaum/17642d12b63825b6cd2b1dd09e089af3 to your computer and use it in GitHub Desktop.
NPM Version Management Auto-Patch
{
"name": "my-package",
"version": "1.2.0",
"scripts": {
"patch-version": "node patch-version.js",
"tag-version": "node tag-version.js \"release-tag\"",
"prerelease": "npm run patch-version && npm run tag-version",
"release": "npm publish",
}
}
const proc = require('child_process');
const jf = require('jsonfile');
const semver = require('semver');
const run = (command) => {
const args = command.split(' ');
const file = args.shift();
let res = '';
try {
res = proc.execFileSync(file, args, { encoding: 'utf8' }).trim();
} catch (e) {
// do nothing
}
return res;
};
const readJson = file => jf.readFileSync(file);
const writeJson = (file, data) => jf.writeFileSync(file, data, { spaces: 2 });
const patch = version => version.split(/\./)[2];
const minor = version => version.split(/\./)[1];
const getModuleVersions = module => JSON.parse(utils.run(`npm view ${module} versions --json`)) || [];
function getIncrementPatchNumber(module, currentVersion) {
const lastVersion = getModuleVersions(module).pop();
let patchNumber;
if (lastVersion && minor(lastVersion) === minor(currentVersion)) {
patchNumber = +patch(lastVersion) + 1;
} else {
patchNumber = +patch(currentVersion);
}
return patchNumber;
}
function getVersion(packageJson) {
const currentVersion = packageJson.version;
if (!currentVersion) {
throw new Error('Can\'t read \'version\' from package.json');
}
const patchNumber = getIncrementPatchNumber(packageJson.name, currentVersion);
const newVersion = currentVersion.replace(getRegex(options), `.${patchNumber}`);
if (!semver.valid(newVersion)) {
throw new Error(`Can't apply patch version ${patchNumber} to version template ${currentVersion}.`);
}
return newVersion;
}
function patchVersion() {
const packageJsonPath = `${process.cwd()}/package.json`;
const packageJson = readJson(packageJsonPath);
packageJson.version = getVersion(options);
writeJson(packageJsonPath, packageJson);
console.log(`Version bumped to ${packageJson.version}`);
}
// ---------
patchVersion();
npm install
npm test
# on master only!
npm run relsase
const proc = require('child_process');
const jf = require('jsonfile');
const run = (command) => {
const args = command.split(' ');
const file = args.shift();
let res = '';
try {
res = proc.execFileSync(file, args, { encoding: 'utf8' }).trim();
} catch (e) {
// do nothing
}
return res;
};
const gitOrigin = () => run('git config remote.origin.url') || 'origin';
const readJson = file => jf.readFileSync(file);
const getVersion = () => readJson(`${process.cwd()}/package.json`).version;
const gitTag = (a, m, cb) => {
const cmd = `git tag -a ${a} -m "${m}"`;
return proc.exec(cmd, (err) => {
if (err) {
console.error('Error: can\'t tag git', err);// eslint-disable-line no-console
} else {
console.log(`Tagged git ${a}`); // eslint-disable-line no-console
cb(a);
}
});
};
const gitPushTag = (tg) => {
const cmd = `git push ${gitOrigin()} ${tg}`;
return proc.exec(cmd, (err) => {
if (err) {
console.error('Error: can\'t push git', err); // eslint-disable-line no-console
} else {
console.log(`Pushed tag ${tg}`); // eslint-disable-line no-console
}
});
};
function tag(msg) {
const ann = getVersion();
gitTag(ann, msg, (tg) => {
gitPushTag(tg);
});
}
// ------
tag(process.argv.slice(2));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment