├── .node-version ├── .gitignore ├── src ├── ora.js ├── logger.js ├── tag.js ├── exec.js ├── commit.js ├── bumpVersion.js ├── mainLifeCycle.js ├── changelog.js └── utils.js ├── .vscode └── settings.json ├── .npmignore ├── conventional-changelog-picgo ├── templates │ ├── footer.hbs │ ├── template.hbs │ ├── header.hbs │ └── commit.hbs ├── parser-opts.js ├── conventional-changelog.js ├── index.js ├── conventional-recommended-bump.js ├── LICENSE.md └── writer-opts.js ├── commitlint-picgo ├── types.js └── index.js ├── eslint.config.js ├── .github └── workflows │ └── publish.yml ├── License ├── package.json ├── CHANGELOG.md ├── .cz-config.js ├── bin └── bump-version └── README.md /.node-version: -------------------------------------------------------------------------------- 1 | 22 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn-error.log 3 | .serena/ 4 | .vscode/ 5 | -------------------------------------------------------------------------------- /src/ora.js: -------------------------------------------------------------------------------- 1 | const Ora = require('ora') 2 | module.exports = new Ora({ 3 | text: '' 4 | }) 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": "explicit" 4 | } 5 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | yarn-error.log 3 | package-lock.json 4 | tsconfig.json 5 | tslint.json 6 | .vscode/ 7 | .travis.yml 8 | .serena/ 9 | pnpm-lock.yaml 10 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/templates/footer.hbs: -------------------------------------------------------------------------------- 1 | {{#if noteGroups}} 2 | {{#each noteGroups}} 3 | 4 | ### {{title}} 5 | 6 | {{#each notes}} 7 | * {{#if commit.scope}}**{{commit.scope}}:** {{/if}}{{text}} 8 | {{/each}} 9 | {{/each}} 10 | 11 | {{/if}} 12 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/templates/template.hbs: -------------------------------------------------------------------------------- 1 | {{> header}} 2 | 3 | {{#each commitGroups}} 4 | 5 | {{#if title}} 6 | ### {{title}} 7 | 8 | {{/if}} 9 | {{#each commits}} 10 | {{> commit root=@root}} 11 | {{/each}} 12 | 13 | {{/each}} 14 | {{> footer}} 15 | 16 | 17 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/parser-opts.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = { 4 | headerPattern: /^(:.*: \w*)(?:\((.*)\))?: (.*)$/, 5 | headerCorrespondence: [ 6 | `type`, 7 | `scope`, 8 | `subject` 9 | ], 10 | noteKeywords: [`BREAKING CHANGE`] 11 | } 12 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/templates/header.hbs: -------------------------------------------------------------------------------- 1 | {{#if isPatch~}} 2 | ## 3 | {{~else~}} 4 | # 5 | {{~/if}} {{#if @root.linkCompare~}} 6 | :tada: {{version}} 7 | {{~else}} 8 | :tada: {{version}} 9 | {{~/if}} 10 | {{~#if title}} "{{title}}" 11 | {{~/if}} 12 | {{~#if date}} ({{date}}) 13 | {{/if}} 14 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/conventional-changelog.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Q = require(`q`) 4 | const parserOpts = require(`./parser-opts`) 5 | const writerOpts = require(`./writer-opts`) 6 | 7 | module.exports = Q.all([parserOpts, writerOpts]) 8 | .spread((parserOpts, writerOpts) => { 9 | return { parserOpts, writerOpts } 10 | }) 11 | -------------------------------------------------------------------------------- /src/logger.js: -------------------------------------------------------------------------------- 1 | const ora = require('./ora') 2 | const chalk = require('chalk') 3 | const level = { 4 | success: 'green', 5 | info: 'blue', 6 | warn: 'yellow', 7 | error: 'red' 8 | } 9 | module.exports = (msg, type) => { 10 | let log = chalk[level[type]](`[Bump ${type.toUpperCase()}]: `) 11 | log += msg 12 | ora.clear() 13 | ora.frame() 14 | console.log(log) 15 | } 16 | -------------------------------------------------------------------------------- /commitlint-picgo/types.js: -------------------------------------------------------------------------------- 1 | const types = [ 2 | ':sparkles: Feature', 3 | ':bug: Fix', 4 | ':construction: WIP', 5 | ':hammer: Refactor', 6 | ':package: Chore', 7 | ':art: Style', 8 | ':arrow_up: Upgrade', 9 | ':zap: Perf', 10 | ':pencil: Docs', 11 | ':white_check_mark: Test', 12 | ':back: Revert', 13 | ':tada: Release', 14 | ':pushpin: Init' 15 | ] 16 | 17 | module.exports = types 18 | -------------------------------------------------------------------------------- /src/tag.js: -------------------------------------------------------------------------------- 1 | const exec = require('./exec') 2 | module.exports = (argv, newVersion) => { 3 | if (argv.dry) { 4 | return Promise.resolve() 5 | } 6 | let flow 7 | if (argv.tag === false) { 8 | flow = Promise.resolve() 9 | } else { 10 | flow = exec(argv, `git tag -a v${newVersion} -m v${newVersion}`) 11 | } 12 | return flow.then(async () => { 13 | if (argv.push) { 14 | await exec(`git push --follow-tags origin master`) 15 | } 16 | return null 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const Q = require(`q`) 3 | const conventionalChangelog = require(`./conventional-changelog`) 4 | const parserOpts = require(`./parser-opts`) 5 | const recommendedBumpOpts = require(`./conventional-recommended-bump`) 6 | const writerOpts = require(`./writer-opts`) 7 | 8 | module.exports = Q.all([conventionalChangelog, parserOpts, recommendedBumpOpts, writerOpts]) 9 | .spread((conventionalChangelog, parserOpts, recommendedBumpOpts, writerOpts) => { 10 | return { conventionalChangelog, parserOpts, recommendedBumpOpts, writerOpts } 11 | }) 12 | -------------------------------------------------------------------------------- /src/exec.js: -------------------------------------------------------------------------------- 1 | const exec = require('child_process').exec 2 | const logger = require('./logger') 3 | 4 | module.exports = (argv, cmd) => { 5 | return new Promise((resolve, reject) => { 6 | // Exec given cmd and handle possible errors 7 | exec(cmd, { cwd: argv.path }, function (err, stdout, stderr) { 8 | // If exec returns content in stderr, but no error, print it as a warning 9 | // If exec returns an error, print it and exit with return code 1 10 | if (err) { 11 | logger(stderr || err.message, 'error') 12 | return reject(err) 13 | } else if (stderr) { 14 | logger(stderr, 'warn') 15 | } 16 | return resolve(stdout) 17 | }) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /src/commit.js: -------------------------------------------------------------------------------- 1 | const utils = require('./utils') 2 | const exec = require('./exec') 3 | let changedFiles = [ 4 | 'package.json', 5 | 'package-lock.json' 6 | ] 7 | module.exports = (argv, newVersion) => { 8 | if (argv.changelog !== false) { 9 | changedFiles.push(argv.file) 10 | } 11 | const releaseMsg = `:tada: Release: v${newVersion}` 12 | if (argv.skipCommit) return Promise.resolve() 13 | changedFiles = utils.checkFileAndGetPath(argv, changedFiles).join(' ') 14 | if (changedFiles === '' || argv.dry) { 15 | return Promise.resolve() 16 | } 17 | return exec(argv, `git add ${changedFiles}`) 18 | .then(() => { 19 | return exec(argv, `git commit ${changedFiles} -m "${releaseMsg}"`) 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /commitlint-picgo/index.js: -------------------------------------------------------------------------------- 1 | const typeEnum = require('./types') 2 | 3 | module.exports = { 4 | parserPreset: '../conventional-changelog-picgo/parser-opts', 5 | rules: { 6 | 'body-leading-blank': [1, 'always'], 7 | 'footer-leading-blank': [1, 'always'], 8 | 'header-max-length': [2, 'always', 100], 9 | 'scope-case': [ 10 | 2, 11 | 'always', 12 | ['lower-case', 'kebab-case'] 13 | ], 14 | 'subject-case': [ 15 | 2, 16 | 'never', 17 | ['sentence-case'] 18 | ], 19 | 'subject-empty': [2, 'never'], 20 | 'subject-full-stop': [2, 'never', '.'], 21 | 'type-case': [0, 'always', 'lower-case'], 22 | 'type-empty': [2, 'never'], 23 | 'type-enum': [2, 'always', typeEnum] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | const { FlatCompat } = require('@eslint/eslintrc') 2 | const js = require('@eslint/js') 3 | 4 | const compat = new FlatCompat({ 5 | baseDirectory: __dirname, 6 | recommendedConfig: js.configs.recommended, 7 | allConfig: js.configs.all 8 | }) 9 | 10 | module.exports = [ 11 | { 12 | ignores: ['node_modules', 'dist'] 13 | }, 14 | ...compat.extends( 15 | 'eslint:recommended', 16 | 'plugin:import/recommended', 17 | 'plugin:n/recommended', 18 | 'plugin:promise/recommended' 19 | ), 20 | { 21 | languageOptions: { 22 | ecmaVersion: 2022, 23 | sourceType: 'script' 24 | } 25 | }, 26 | { 27 | files: ['eslint.config.js'], 28 | rules: { 29 | 'n/no-unpublished-require': 'off' 30 | } 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/conventional-recommended-bump.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const parserOpts = require(`./parser-opts`) 4 | 5 | module.exports = { 6 | parserOpts, 7 | 8 | whatBump: (commits) => { 9 | let level = 2 10 | let breakings = 0 11 | let features = 0 12 | 13 | commits.forEach(commit => { 14 | if (commit.notes.length > 0) { 15 | breakings += commit.notes.length 16 | level = 0 17 | } else if (commit.type === `feat`) { 18 | features += 1 19 | if (level === 2) { 20 | level = 1 21 | } 22 | } 23 | }) 24 | 25 | return { 26 | level: level, 27 | reason: breakings === 1 28 | ? `There is ${breakings} BREAKING CHANGE and ${features} features` 29 | : `There are ${breakings} BREAKING CHANGES and ${features} features` 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/bumpVersion.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const checkFileAndGetPath = require('./utils').checkFileAndGetPath 3 | let versionFiles = ['package.json', 'package-lock.json'] 4 | module.exports = (argv, version) => { 5 | if (argv.dry === false) { 6 | return Promise.resolve() 7 | } 8 | versionFiles = checkFileAndGetPath(argv, versionFiles) 9 | 10 | for (let file of versionFiles) { 11 | let content = fs.readFileSync(file, 'utf8') 12 | try { 13 | content = JSON.parse(content) 14 | content.version = version 15 | content = JSON.stringify(content, null, 2) + '\n' 16 | if (argv.dry) { 17 | console.log('bump version to:', version) 18 | } else { 19 | fs.writeFileSync(file, content, 'utf8') 20 | } 21 | } catch (e) { 22 | return Promise.reject(e) 23 | } 24 | } 25 | return Promise.resolve() 26 | } 27 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/LICENSE.md: -------------------------------------------------------------------------------- 1 | ### ISC License 2 | 3 | Copyright © [conventional-changelog team](https://github.com/conventional-changelog) 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 11 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 14 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | jobs: 10 | publish: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v4 15 | 16 | - name: Setup pnpm 17 | uses: pnpm/action-setup@v4 18 | with: 19 | version: 10 20 | 21 | - name: Setup Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: 20 25 | registry-url: https://registry.npmjs.org 26 | cache: pnpm 27 | 28 | - name: Install dependencies 29 | run: pnpm install --frozen-lockfile 30 | 31 | - name: Lint 32 | run: pnpm run lint 33 | 34 | - name: Publish 35 | run: pnpm publish --access public --no-git-checks 36 | env: 37 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 38 | -------------------------------------------------------------------------------- /src/mainLifeCycle.js: -------------------------------------------------------------------------------- 1 | const bumpVersion = require('./bumpVersion') 2 | const commit = require('./commit') 3 | const changeLog = require('./changelog') 4 | const tag = require('./tag') 5 | const spinner = require('./ora') 6 | module.exports = (argv, currentVersion, newVersion) => { 7 | spinner.start() 8 | return Promise.resolve() 9 | .then(() => { 10 | spinner.text = 'Bumping version...' 11 | return bumpVersion(argv, newVersion) 12 | }) 13 | .then(() => { 14 | spinner.text = 'Generating changelog...' 15 | return changeLog(argv, newVersion) 16 | }) 17 | .then(() => { 18 | spinner.text = 'Commiting changes...' 19 | return commit(argv, newVersion) 20 | }) 21 | .then(() => { 22 | spinner.text = 'Creating tag...' 23 | return tag(argv, newVersion) 24 | }) 25 | .then(() => { 26 | return spinner.succeed('Done!') 27 | }) 28 | .catch(err => { 29 | spinner.fail('Failed!') 30 | throw err 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 PicGo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/changelog.js: -------------------------------------------------------------------------------- 1 | const cc = require('conventional-changelog') 2 | const config = require('../conventional-changelog-picgo') 3 | const fs = require('fs') 4 | 5 | module.exports = (argv, newVersion) => { 6 | if (argv.changelog === false) { 7 | return Promise.resolve() 8 | } 9 | return new Promise((resolve, reject) => { 10 | let content = '' 11 | let oldContent = '' 12 | try { 13 | oldContent = fs.readFileSync(argv.file, 'utf8') 14 | } catch { 15 | oldContent = '' 16 | } 17 | let context = '' 18 | if (argv.dry) { 19 | context = { 20 | version: newVersion 21 | } 22 | } 23 | let changeLogStream = cc({ 24 | config 25 | }, context, { merges: null, path: argv.path }).on('error', (err) => { 26 | return reject(err) 27 | }) 28 | changeLogStream.on('data', (buffer) => { 29 | content += buffer.toString() 30 | }) 31 | changeLogStream.on('end', () => { 32 | if (argv.dry) { 33 | console.log('Changelog is:') 34 | console.log(content + oldContent) 35 | } else { 36 | fs.writeFileSync(argv.file, content + oldContent) 37 | } 38 | return resolve() 39 | }) 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/templates/commit.hbs: -------------------------------------------------------------------------------- 1 | *{{#if scope}} **{{scope}}:** 2 | {{~/if}} {{#if subject}} 3 | {{~subject}} 4 | {{~else}} 5 | {{~header}} 6 | {{~/if}} 7 | 8 | {{~!-- commit link --}} {{#if @root.linkReferences~}} 9 | ([{{hash}}]( 10 | {{~#if @root.repository}} 11 | {{~#if @root.host}} 12 | {{~@root.host}}/ 13 | {{~/if}} 14 | {{~#if @root.owner}} 15 | {{~@root.owner}}/ 16 | {{~/if}} 17 | {{~@root.repository}} 18 | {{~else}} 19 | {{~@root.repoUrl}} 20 | {{~/if}}/ 21 | {{~@root.commit}}/{{hash}})) 22 | {{~else}} 23 | {{~hash}} 24 | {{~/if}} 25 | 26 | {{~!-- commit references --}} 27 | {{~#if references~}} 28 | , closes 29 | {{~#each references}} {{#if @root.linkReferences~}} 30 | [ 31 | {{~#if this.owner}} 32 | {{~this.owner}}/ 33 | {{~/if}} 34 | {{~this.repository}}#{{this.issue}}]( 35 | {{~#if @root.repository}} 36 | {{~#if @root.host}} 37 | {{~@root.host}}/ 38 | {{~/if}} 39 | {{~#if this.repository}} 40 | {{~#if this.owner}} 41 | {{~this.owner}}/ 42 | {{~/if}} 43 | {{~this.repository}} 44 | {{~else}} 45 | {{~#if @root.owner}} 46 | {{~@root.owner}}/ 47 | {{~/if}} 48 | {{~@root.repository}} 49 | {{~/if}} 50 | {{~else}} 51 | {{~@root.repoUrl}} 52 | {{~/if}}/ 53 | {{~@root.issue}}/{{this.issue}}) 54 | {{~else}} 55 | {{~#if this.owner}} 56 | {{~this.owner}}/ 57 | {{~/if}} 58 | {{~this.repository}}#{{this.issue}} 59 | {{~/if}}{{/each}} 60 | {{~/if}} 61 | 62 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fs = require('fs') 3 | const checkFileAndGetPath = (argv, files) => { 4 | return files.map(item => { 5 | if (path.isAbsolute(item)) { 6 | return item 7 | } 8 | return path.join(argv.path, item) 9 | }).filter(item => { 10 | return fs.existsSync(item) 11 | }) 12 | } 13 | const helperMsg = ` 14 | BumpVersion -- By PicGo Group 15 | 16 | Usage 17 | bump-version 18 | 19 | Example 20 | bump-version -t major 21 | 22 | Options 23 | -a, --preid-alpha Prerelease id: alpha. Exp. 1.0.0.alpha-0 24 | 25 | -b, --preid-beta Prerelease id: beta. Exp. 1.0.0.beta-0 26 | 27 | -d, --dry Run bump version without change anything & output the log in console 28 | 29 | -f, --file Read and write the CHANGELOG file, relative to package.json's path 30 | Default: CHANGELOG.md 31 | 32 | -p, --path A filepath of where your package.json is located 33 | Default: ./ 34 | 35 | -h, --help Display help message 36 | 37 | -t, --type Release type. [major, minor, patch, premajor, preminor, prepatch, prerelease] 38 | Default: patch 39 | 40 | --push Auto push commits to origin master 41 | Default: false 42 | 43 | --no-tag Tag won't be created 44 | Default: tag will be created 45 | 46 | --no-changelog Changelog won't be created 47 | Default: changelog will be created 48 | ` 49 | 50 | module.exports = { 51 | checkFileAndGetPath, 52 | helperMsg 53 | } 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@picgo/bump-version", 3 | "version": "2.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "bin": { 7 | "bump-version": "./bin/bump-version" 8 | }, 9 | "publishConfig": { 10 | "access": "public" 11 | }, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\"", 14 | "cz": "git-cz", 15 | "release": "node ./bin/bump-version", 16 | "lint": "eslint --ext .js .", 17 | "lint:fix": "eslint --ext .js --fix ." 18 | }, 19 | "husky": { 20 | "hooks": { 21 | "pre-commit": "npm run lint", 22 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 23 | } 24 | }, 25 | "repository": { 26 | "type": "git", 27 | "url": "git+https://github.com/PicGo/bump-version.git" 28 | }, 29 | "author": "Molunerfinn", 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/PicGo/bump-version/issues" 33 | }, 34 | "homepage": "https://github.com/PicGo/bump-version#readme", 35 | "devDependencies": { 36 | "@eslint/eslintrc": "^3.3.3", 37 | "@eslint/js": "^9.39.1", 38 | "eslint": "^9.39.1", 39 | "eslint-plugin-import": "^2.32.0", 40 | "eslint-plugin-n": "^17.23.1", 41 | "eslint-plugin-promise": "^7.2.1" 42 | }, 43 | "config": { 44 | "commitizen": { 45 | "path": "node_modules/cz-customizable" 46 | }, 47 | "cz-customizable": { 48 | "config": ".cz-config.js" 49 | } 50 | }, 51 | "commitlint": { 52 | "extends": [ 53 | "./commitlint-picgo" 54 | ] 55 | }, 56 | "dependencies": { 57 | "@commitlint/cli": "^7.5.2", 58 | "chalk": "^4.1.2", 59 | "commitizen": "^4.2.3", 60 | "compare-func": "^2.0.0", 61 | "conventional-changelog": "^3.0.6", 62 | "cz-customizable": "^7.5.1", 63 | "husky": "^1.3.1", 64 | "inquirer": "^13.0.2", 65 | "minimist": "^1.2.8", 66 | "ora": "^3.4.0", 67 | "q": "^1.5.1", 68 | "semver": "^7.7.3" 69 | }, 70 | "engines": { 71 | "node": ">=20.0.0" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # :tada: 2.0.0 (2025-12-10) 2 | 3 | 4 | ### :bug: Bug Fixes 5 | 6 | * some deps not installed ([f2a4f74](https://github.com/PicGo/bump-version/commit/f2a4f74)) 7 | 8 | 9 | ### :package: Chore 10 | 11 | * add pnpm-lock to npmignore ([6de1b65](https://github.com/PicGo/bump-version/commit/6de1b65)) 12 | * update deps \&\& add node 20 limit ([d2d96e9](https://github.com/PicGo/bump-version/commit/d2d96e9)) 13 | 14 | 15 | 16 | ## :tada: 1.1.2 (2021-09-16) 17 | 18 | 19 | ### :package: Chore 20 | 21 | * change travis-ci -> github actions ([d3c896f](https://github.com/PicGo/bump-version/commit/d3c896f)) 22 | 23 | 24 | 25 | ## :tada: 1.1.1 (2021-04-10) 26 | 27 | 28 | 29 | # :tada: 1.1.0 (2020-04-30) 30 | 31 | 32 | ### :sparkles: Features 33 | 34 | * change some dev deps to deps ([12bd7b0](https://github.com/PicGo/bump-version/commit/12bd7b0)) 35 | 36 | 37 | 38 | ## :tada: 1.0.3 (2019-05-11) 39 | 40 | 41 | ### :sparkles: Features 42 | 43 | * **header:** add header-max-length from 72 to 100 ([7a5ec79](https://github.com/PicGo/bump-version/commit/7a5ec79)) 44 | 45 | 46 | ### :bug: Bug Fixes 47 | 48 | * **lint:** subject case can't be sentence-case ([860a327](https://github.com/PicGo/bump-version/commit/860a327)) 49 | 50 | 51 | ### :pencil: Documentation 52 | 53 | * refine readme ([#1](https://github.com/PicGo/bump-version/issues/1)) ([1984de2](https://github.com/PicGo/bump-version/commit/1984de2)) 54 | * remove a comma ([f484287](https://github.com/PicGo/bump-version/commit/f484287)) 55 | 56 | 57 | 58 | ## :tada: 1.0.2 (2019-04-10) 59 | 60 | 61 | ### :bug: Bug Fixes 62 | 63 | * preid command from 'pa' to 'a' && eslint error ([cf989fa](https://github.com/PicGo/bump-version/commit/cf989fa)) 64 | 65 | 66 | ### :pencil: Documentation 67 | 68 | * fix word error && change version badge ([0cbeb79](https://github.com/PicGo/bump-version/commit/0cbeb79)) 69 | 70 | 71 | 72 | ## :tada: 1.0.1 (2019-04-09) 73 | 74 | 75 | ### :bug: Bug Fixes 76 | 77 | * npm test command missed ([0c5301f](https://github.com/PicGo/bump-version/commit/0c5301f)) 78 | * symbolic links bug ([1a95111](https://github.com/PicGo/bump-version/commit/1a95111)) 79 | * travis yarn test bug ([77e97d4](https://github.com/PicGo/bump-version/commit/77e97d4)) 80 | 81 | 82 | 83 | # :tada: 1.0.0 (2019-04-09) 84 | 85 | 86 | ### :pushpin: Init 87 | 88 | * picgo bump-version init commit ([b04432f](https://github.com/PicGo/bump-version/commit/b04432f)) 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /.cz-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // types, 3 | types: [ 4 | { 5 | value: ":sparkles: Feature", 6 | name: "Feature: when adding new features" 7 | }, 8 | { 9 | value: ":bug: Fix", 10 | name: "Fix: when fixing bugs" 11 | }, 12 | { 13 | value: ":construction: WIP", 14 | name: "WIP: when working in progress" 15 | }, 16 | { 17 | value: ":hammer: Refactor", 18 | name: "Refactor: when changing the code without adding features or fixing bugs" 19 | }, 20 | { 21 | value: ":package: Chore", 22 | name: "Chore: when changing the build process or auxiliary tools and libraries such as documentation generation" 23 | }, 24 | { 25 | value: ":art: Style", 26 | name: "Style: when improving the format/structure of the code" 27 | }, 28 | { 29 | value: ":arrow_up: Upgrade", 30 | name: "Upgrade: when upgrading dependencies" 31 | }, 32 | { 33 | value: ":zap: Perf", 34 | name: "Perf: when improving performance" 35 | }, 36 | { 37 | value: ":pencil: Docs", 38 | name: "Docs: when wrting docs" 39 | }, 40 | { 41 | value: ":white_check_mark: Test", 42 | name: "Test: when adding or updating tests" 43 | }, 44 | { 45 | value: ":back: Revert", 46 | name: "Revert: when reverting some commits" 47 | }, 48 | { 49 | value: ":tada: Release", 50 | name: "Release: when releasing a new version" 51 | }, 52 | { 53 | value: ":pushpin: Init", 54 | name: "Init: when initializing a project" 55 | } 56 | ], 57 | 58 | // override the messages, defaults are as follows 59 | messages: { 60 | type: "Select the type of change that you're committing:", 61 | scope: "\nDenote the SCOPE of this change (optional):", 62 | // used if allowCustomScopes is true 63 | customScope: "Denote the SCOPE of this change:", 64 | subject: "[subject] Write a SHORT, IMPERATIVE tense description of the change:\n", 65 | body: 66 | '[body] Provide a LONGER description of the change (optional). Use "|" to break new line:\n', 67 | breaking: "List any BREAKING CHANGES (optional):\n", 68 | footer: 69 | "[footer] List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n", 70 | confirmCommit: "Are you sure you want to proceed with the commit above?" 71 | }, 72 | 73 | allowCustomScopes: false, 74 | allowBreakingChanges: [":sparkles: Feature", ":bug: Fix"] 75 | }; 76 | -------------------------------------------------------------------------------- /bin/bump-version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const minimist = require('minimist') 3 | const semver = require('semver') 4 | const path = require('path') 5 | const inquirer = require('inquirer').default 6 | const logger = require('../src/logger') 7 | const mainLifeCycle = require('../src/mainLifeCycle') 8 | const utils = require('../src/utils') 9 | 10 | let pkg 11 | try { 12 | pkg = require(path.join(process.cwd(), 'package.json')) 13 | } catch (e) { 14 | logger('package.json not found!', 'error') 15 | process.exit(0) 16 | } 17 | let argv = minimist(process.argv.slice(2), { 18 | alias: { 19 | 'preid-alpha': 'a', // alpha 20 | 'preid-beta': 'b', // beta 21 | 'dry': 'd', // dry run mode 22 | 'file': 'f', // changelog file, 23 | 'path': 'p', // package.json's path 24 | 'help': 'h', // help message 25 | 'type': 't' // bump type 26 | } 27 | }) 28 | 29 | if (argv.h) { 30 | console.log(utils.helperMsg) 31 | process.exit(0) 32 | } 33 | 34 | let releaseType = typeof argv.t === 'string' ? argv.t : 'patch' 35 | let currentVersion = pkg.version 36 | if (currentVersion === undefined) { 37 | logger('Version field is not found in package.json!', 'error') 38 | process.exit(0) 39 | } 40 | let preid = argv.a ? 'alpha' : argv.b ? 'beta' : '' 41 | let nextVersion = semver.inc(currentVersion, releaseType, preid) 42 | let releaseTypes = ['major', 'minor', 'patch', 'premajor', 'preminor', 'prepatch', 'prerelease'] 43 | 44 | function generateReleaseTypes (types) { 45 | return types.map(item => { 46 | let version = semver.inc(currentVersion, item, (preid || 'alpha')) 47 | return { 48 | name: `${item} - ${version}`, 49 | value: version 50 | } 51 | }) 52 | } 53 | 54 | let defaultObj = { 55 | path: process.cwd(), 56 | file: 'CHANGELOG.md' 57 | } 58 | 59 | argv = Object.assign({}, defaultObj, argv) 60 | 61 | let promptList = [ 62 | { 63 | type: 'confirm', 64 | name: 'confirmVersion', 65 | message: `The next version is ${nextVersion}, is it right?` 66 | } 67 | ] 68 | console.log( 69 | ` 70 | BumpVersion -- By PicGo Group 71 | ` 72 | ); 73 | (async () => { 74 | let answer = await inquirer.prompt(promptList) 75 | if (answer.confirmVersion) { 76 | await mainLifeCycle(argv, currentVersion, nextVersion) 77 | } else { 78 | promptList = [ 79 | { 80 | type: 'select', 81 | name: 'version', 82 | message: `The current version is ${currentVersion}\n Which version would you like to bump it?`, 83 | choices: [ 84 | ...generateReleaseTypes(releaseTypes), 85 | new inquirer.Separator(), 86 | 'custom version', 87 | 'never mind~' 88 | ], 89 | pageSize: 10 90 | } 91 | ] 92 | let answer = await inquirer.prompt(promptList) 93 | if (answer.version === 'never mind~') { 94 | return console.log('Bye~') 95 | } else if (answer.version === 'custom version') { 96 | promptList = [ 97 | { 98 | type: 'input', 99 | name: 'version', 100 | message: 'Write down your custom version:' 101 | } 102 | ] 103 | let result = await inquirer.prompt(promptList) 104 | if (semver.valid(result.version) && semver.gte(result.version, currentVersion)) { 105 | await mainLifeCycle(argv, currentVersion, result.version) 106 | } else { 107 | return logger('Invalid version!', 'error') 108 | } 109 | } else { 110 | await mainLifeCycle(argv, currentVersion, answer.version) 111 | } 112 | } 113 | })() 114 | -------------------------------------------------------------------------------- /conventional-changelog-picgo/writer-opts.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const compareFunc = require(`compare-func`) 4 | const Q = require(`q`) 5 | const readFile = Q.denodeify(require(`fs`).readFile) 6 | const resolve = require(`path`).resolve 7 | const headerPattern = /^(:.*: (.*))$/ 8 | 9 | const compareTitleFunc = (a, b) => { 10 | let sortMap = { 11 | 'Features': 10, 12 | 'Bug Fixes': 9, 13 | 'BREAKING CHANGES': 8 14 | } 15 | let typeA = a.title.match(headerPattern)[2] 16 | let typeB = b.title.match(headerPattern)[2] 17 | 18 | return (sortMap[typeB] || 0) - (sortMap[typeA] || 0) 19 | } 20 | 21 | module.exports = Q.all([ 22 | readFile(resolve(__dirname, `./templates/template.hbs`), `utf-8`), 23 | readFile(resolve(__dirname, `./templates/header.hbs`), `utf-8`), 24 | readFile(resolve(__dirname, `./templates/commit.hbs`), `utf-8`), 25 | readFile(resolve(__dirname, `./templates/footer.hbs`), `utf-8`) 26 | ]) 27 | .spread((template, header, commit, footer) => { 28 | const writerOpts = getWriterOpts() 29 | 30 | writerOpts.mainTemplate = template 31 | writerOpts.headerPartial = header 32 | writerOpts.commitPartial = commit 33 | writerOpts.footerPartial = footer 34 | 35 | return writerOpts 36 | }) 37 | 38 | function getWriterOpts () { 39 | return { 40 | transform: (commit, context) => { 41 | let discard = true 42 | const issues = [] 43 | 44 | commit.notes.forEach(note => { 45 | note.title = `BREAKING CHANGES` 46 | discard = false 47 | }) 48 | 49 | if (commit.type === `:sparkles: Feature`) { 50 | commit.type = `:sparkles: Features` 51 | } else if (commit.type === `:bug: Fix`) { 52 | commit.type = `:bug: Bug Fixes` 53 | } else if (commit.type === `:zap: Perf`) { 54 | commit.type = `:zap: Performance Improvements` 55 | } else if (commit.type === `:back: Revert`) { 56 | commit.type = `:back: Revert` 57 | } else if (commit.type === `:pencil: Docs`) { 58 | commit.type = `:pencil: Documentation` 59 | } else if (commit.type === `:package: Chore`) { 60 | commit.type = `:package: Chore` 61 | } else if (commit.type === `:pushpin: Init`) { 62 | commit.type = `:pushpin: Init` 63 | } else if (discard) { 64 | return 65 | } else if (commit.type === `:arrow_up: Upgrade`) { 66 | commit.type = `:arrow_up: Dependencies Upgrade` 67 | } else if (commit.type === `:art: Style`) { 68 | commit.type = `:art: Styles` 69 | } else if (commit.type === `:hammer: Refactor`) { 70 | commit.type = `:hammer: Code Refactoring` 71 | } else if (commit.type === `:white_check_mark: Test`) { 72 | commit.type = `:white_check_mark: Tests` 73 | } else if (commit.type === `:construction: WIP` || commit.type === ':tada: Release') { 74 | return 75 | } 76 | 77 | if (commit.scope === `*`) { 78 | commit.scope = `` 79 | } 80 | 81 | if (typeof commit.hash === `string`) { 82 | commit.hash = commit.hash.substring(0, 7) 83 | } 84 | 85 | if (typeof commit.subject === `string`) { 86 | let url = context.repository 87 | ? `${context.host}/${context.owner}/${context.repository}` 88 | : context.repoUrl 89 | if (url) { 90 | url = `${url}/issues/` 91 | // Issue URLs. 92 | commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => { 93 | issues.push(issue) 94 | return `[#${issue}](${url}${issue})` 95 | }) 96 | } 97 | if (context.host) { 98 | // User URLs. 99 | commit.subject = commit.subject.replace(/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, (_, username) => { 100 | if (username.includes('/')) { 101 | return `@${username}` 102 | } 103 | 104 | return `[@${username}](${context.host}/${username})` 105 | }) 106 | } 107 | } 108 | 109 | // remove references that already appear in the subject 110 | commit.references = commit.references.filter(reference => { 111 | if (issues.indexOf(reference.issue) === -1) { 112 | return true 113 | } 114 | 115 | return false 116 | }) 117 | 118 | return commit 119 | }, 120 | groupBy: `type`, 121 | commitGroupsSort: compareTitleFunc, 122 | commitsSort: [`scope`, `subject`], 123 | noteGroupsSort: `title`, 124 | notesSort: compareFunc 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PicGo BumpVersion 2 | 3 | A full `git commit` -> `changelog` -> `release` workflow & convention. 4 | 5 | It's now only available for Node.js projects. Thanks [standard-version](https://github.com/conventional-changelog/standard-version) for the inspiration. 6 | 7 | > Starting from v1.2.0, bump-version requires Node.js 20 or higher. 8 | 9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |