Git
校驗你記得此次打包是否是當前調試的代碼麼?
const sh = require('shelljs') const chalk = require('chalk') const uncommit = sh.exec('git status --porcelain').stdout const lines = uncommit.toString().split('\n').filter(item => item).length if (lines) { console.log(chalk.red('note: 有代碼未提交或緩存,請慎重發版!!!')) console.log('----------------------------------------------------') console.log('recommend: 使用git push提交 或 git stash緩存後再發版.') process.exit(1) } process.exit(0)
每次打包沒有日誌,強制開發者必須上傳或緩存後才能打包,利用Git爲打包作日誌服務。
const sh = require('shelljs') const chalk = require('chalk') const inquirer = require('inquirer') const log = console.log async function permission () { const uncommit = sh.exec('git status --porcelain').stdout const lines = uncommit.toString().split('\n').filter(item => item).length if (lines) { log(chalk.redBright(chalk.bold('note: ') + '有代碼未提交或緩存,請慎重發版!!!')) log('----------------------------------------------------') log(chalk.blueBright('recommend: ') + '使用git push提交 或 git stash緩存後再發版.') const { isSkip } = (await inquirer.prompt({ type: 'expand', name: 'isSkip', choices: [ { key: 'y', name: 'Yes', value: true }, { key: 'n', name: 'No', value: false } ], message: '是否獨斷獨行?' })) if (isSkip) { process.env.custom_uncommit_skip = isSkip process.exit(0) } process.exit(1) } process.exit(0) } permission()
使用場景
"prerelease": "node bin/index.js"
const fs = require('fs') const path = require('path') const handleFile = path.resolve(process.cwd(), 'src', 'manifest.json') const rawText = fs.readFileSync(handleFile) const manifestJson = JSON.parse(rawText) console.log(manifestJson) manifestJson.versionCode++ fs.writeFileSync(handleFile, JSON.stringify(manifestJson, '', 2))
JSON.stringify
的使用JSON.stringify()
接受三個參數node
\t
、\n
之類使用場景
"prerelease": "node bin/git-uncommit.js && node bin/auto-version.js",
參考
lerna version
semver.inc
升級版本const fs = require('fs') const path = require('path') const sh = require('shelljs') const chalk = require('chalk') const semver = require('semver') const inquirer = require('inquirer') const terminal = inquirer.prompt const quickJSONFile = path.resolve(process.cwd(), 'src', 'manifest.json') const manifestJson = JSON.parse(fs.readFileSync(quickJSONFile)) function customVersion(message, { filter, validate } = {}) { return terminal([ { type: "input", name: "input", message, filter, validate, }, ]) .then(answers => { return answers.input; }); } /** * @param {PackageGraphNode|Object} node The metadata to process * @property {String} currentVersion * @property {String} name (Only used in independent mode) * @property {String} prereleaseId */ function promptVersion(currentVersion, name, prereleaseId) { const patch = semver.inc(currentVersion, "patch"); const minor = semver.inc(currentVersion, "minor"); const major = semver.inc(currentVersion, "major"); const prepatch = semver.inc(currentVersion, "prepatch", prereleaseId); const preminor = semver.inc(currentVersion, "preminor", prereleaseId); const premajor = semver.inc(currentVersion, "premajor", prereleaseId); const message = `Select a new version ${name ? `for ${name} ` : ""}(currently ${currentVersion})`; return terminal({ type: 'list', message, name: 'choice', choices: [ { value: patch, name: `Patch (${patch})` }, { value: minor, name: `Minor (${minor})` }, { value: major, name: `Major (${major})` }, { value: prepatch, name: `Prepatch (${prepatch})` }, { value: preminor, name: `Preminor (${preminor})` }, { value: premajor, name: `Premajor (${premajor})` }, { value: "PRERELEASE", name: "Custom Prerelease" }, { value: "CUSTOM", name: "Custom Version" }, ] }).then(({choice}) => { if (choice === "CUSTOM") { return customVersion("Enter a custom version", { filter: semver.valid, // semver.valid() always returns null with invalid input validate: v => v !== null || "Must be a valid semver version", }); } if (choice === "PRERELEASE") { const defaultVersion = semver.inc(currentVersion, "prerelease", prereleaseId); const prompt = `(default: "${prereleaseId}", yielding ${defaultVersion})`; return customVersion(`Enter a prerelease identifier ${prompt}`, { filter: v => semver.inc(currentVersion, "prerelease", v || prereleaseId), }); } return choice; }); } promptVersion(manifestJson.versionName).then(nextVersion => { try { manifestJson.versionName = nextVersion manifestJson.versionCode++ fs.writeFileSync(quickJSONFile, JSON.stringify(manifestJson, '', 2)) console.log(chalk.whiteBright(`--------------path:${quickJSONFile}--------------------`)) console.log(`${chalk.whiteBright(chalk.bold('Has been configured a new version:'))}${chalk.blueBright(nextVersion)}`) console.log(chalk.whiteBright(`--------------releasing-releasing-releasing------------------`)) if (!process.env.custom_uncommit_skip) { sh.exec('git commit --amend --no-edit') } process.exit(0) } catch (e) { console.log(chalk.redBright(JSON.stringify(e))) process.exit(1) } })
執行npx standard-version
,會進行如下步驟:git
packageFiles
文件中查詢當前版本號commit
(的type
)升級bumpFiles & packageFiles
文件中的版本號conventional-changelog
)bumpFiles vs. packageFiles概念介紹:能夠藉助文章後續的定製化理解,簡單來講,packageFiles
是輸入,packageFiles
+ bumpFiles
是輸出github
基礎用法
npx standard-version
指定Tag前綴
默認是'v-*'shell
standard-version -t <prefix>
首次提交
指定首次提交,不會自動升級版本號npm
npx standard-version --first-release
指定預發版及Tag前綴
格式json
standard-version --prerelease <prefix>
示例緩存
# npm run script npm run release -- --prerelease alpha
指定版本號
忽略自動升級版本功能async
# npm run script npm run release -- --release-as minor # Or npm run release -- --release-as 1.1.0
忽略Git鉤子校驗
standard-version --no-verify
默認配置
在項目根目錄下建立.versionrc | .versionrc.js | .versionrc.json
定製使用standard-version
。ide
在這以前,須要瞭解默認配置,默認項是如下的合集函數
以package.json
文件爲例:standard-version
默認修改的是頂層的version
字段,若是想要修改其它結構中的其它字段,除了配置bumpFiles & packageFiles
,還須要自定義updater
。
快應用場景示例:
// .versionrc.js const handleFile = [ { "filename": "src/manifest.json", "type": "json", "updater": require('./bin/custom-version-updater') } ] module.exports = { "packageFiles": handleFile, "bumpFiles": handleFile }
// bin/custom-version-updater.js const stringifyPackage = require('stringify-package') const detectIndent = require('detect-indent') const detectNewline = require('detect-newline') module.exports.readVersion = function (contents) { return JSON.parse(contents).versionName } module.exports.writeVersion = function (contents, version) { const json = JSON.parse(contents) let indent = detectIndent(contents).indent let newline = detectNewline(contents) json.versionCode++ json.versionName = version return stringifyPackage(json, indent, newline) }