Last active
March 29, 2018 05:57
-
-
Save ronapelbaum/17642d12b63825b6cd2b1dd09e089af3 to your computer and use it in GitHub Desktop.
NPM Version Management Auto-Patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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", | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
npm install | |
npm test | |
# on master only! | |
npm run relsase |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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