使用npm node自动化Git提交、版本控制和打标签

12
我想做的是使用npm版本来更新package.json并创建一个标签,然后提交我的更改。这样,我就能够按版本拥有标签,自动版本化并记录提交信息。
我的问题是,当我使用npm版本时,它会自动进行标记和提交,如果之前有一些更改,则无法完成此操作。因此,对我来说,在进行更改/实现/修复之前增加项目版本没有意义。
另一个问题是,我首先将版本号提高为“patch”,然后进行一些更改,添加所有内容,提交并发布后,最后我会有两个提交,一个是因为npm版本补丁,另一个才是我想要的正常提交。
我在文档中看到这里有一个参数可以禁用标记+提交自动行为,但我仍然想在控制台中使用命令来更新包并将该版本设置为标签。
另一方面,我不确定我所说的是否有意义,因为据我所知,当您创建标签时,可以返回到该点的项目状态。如果我禁用自动提交,我如何打算像那样工作呢?
最终,我的目标很明确:通过节点脚本处理半自动化脚本,以便能够提高项目版本、创建带有新版本的标签、添加所有更改、提交并推送。
注意:我不想使用gulp-git,因为我认为有一种方法可以在没有它的情况下处理这个问题。
如果我表述不清楚,请问我并帮助我 :)

使用 release-it: https://www.npmjs.com/package/release-it - James Gentes
3个回答

11

好的,大家听我说!我明白了!我想要做的是运行一个简单的命令并自动化我们必须按照相同顺序执行的一些无聊任务,用于Git。

所以,我在这里做的第一步是运行以下命令:

$> npm run commit -- 'v.1.0.1: Fixes'

发生的情况是我首先清理了不需要/不想要的文件夹/文件,然后运行:

$> npm version patch -no-git-tag-version --force

那个命令只是增加了我的package.json版本,没有提交和打标签,所以我像平常一样添加了所有更改,然后提交了我的更改,之后,我使用tag:commit的gulp任务创建标签。

在下面附上的gulp任务中,我使用require获取包的版本,并将其视为对象。

"scripts": {
   "start": "gulp start",
   "initialize": "npm install & typings install",
   "clean": "gulp clean:folders",
   "commit:example": "echo 'npm run commit -- 'v.1.0.1: Fixes'",
   "commit:patch": "npm version patch --no-git-tag-version --force",
   "commit:minor": "npm version minor --no-git-tag-version --force",
   "commit:major": "npm version major --no-git-tag-version --force",
   "precommit": "npm run clean && npm run commit:patch && git add --all",
   "postcommit": "gulp tag:commit && git push origin master && git status && gulp commit:done",
   "commit": "git commit -m "
},

然后,在我的gulp文件中,我有这个:

///// ***** GIT ***** /////


gulp.task('tag:commit', function () {
    var version = pjson.version;
    console.log(colors.bgWhite.black.bold(' \nTagging the version ' + version + ' \n'));
    return run('git tag ' + version).exec();
});

我不想使用gulp-git,因为我知道有其他方法可以做到这一点。如果需要合并、创建分支或者其他操作,我会在控制台中运行命令并进行修复。但是对于每日提交来说,记得打标签、更新包版本、将其放入git commit中等过程非常繁琐...

希望这对其他人有所帮助!

谢谢!


发现这个特别有用,因为我正在使用一个package.json来管理仓库和electron项目子文件夹 - 让这两个保持同步真是让人头疼。 - klreeher

8

如何在package.json中添加一个名为commit的npm脚本:

"scripts": {
    ...
    "commit": "node commit"
    ...
},

使用方法如下:

$> npm run commit patch "Your commit message goes here"

在这里,patch 可以替换为 minormajor ,具体取决于您想要的版本升级。

./commit.js 脚本的内容如下:

#!/usr/bin/env node
'use strict';

const util = require('util');
const exec = util.promisify(require('child_process').exec);
const spawn = require('child_process').spawnSync;

async function version(versionType) {
    const { stdout, stderr } = await exec(`npm version ${versionType} --no-git-tag-version --force`);
    if (stderr) throw stderr;
    return stdout;
}

async function branch() {
  const { stdout, stderr } = await exec(`git rev-parse --abbrev-ref HEAD`);
  if (stderr) throw stderr;
  return stdout;
}

const run = async () => {
  try {
    const versionType = process.argv[2];
    const gitMessage = process.argv[3];

    if (versionType !== 'patch' && versionType !== 'minor' && versionType !== 'major') throw new Error('You need to specify npm version! [patch|minor|major]');
    if (!gitMessage) throw new Error('You need to provide a git commit message!');

    const npmVersion = await version(versionType);
    await spawn('git', ['add', 'package.json', 'package-lock.json'], { stdio: 'inherit' });
    await spawn('git', ['commit', '-m', gitMessage.trim()], { stdio: 'inherit' });
    await spawn('git', ['tag', npmVersion.trim()], { stdio: 'inherit' });
    await spawn('git', ['status'], { stdio: 'inherit' });
    const currentBranch = await branch();
    await spawn('git', ['push', 'origin', currentBranch.trim()], { stdio: 'inherit' });

  } catch (err) {
    console.log('Something went wrong:');
    console.error(err.message);
    console.error('\nPlease use this format: \nnpm run commit [patch|minor|major] "Commit message"');
  }
};

run();

请注意,我没有添加git add --all,因为我更喜欢对我的提交进行更有选择性的操作,但是这个脚本的格式应该足够简单,以便任何人都可以理解并扩展。不过我确实使用了git add package.json,所以每次执行此脚本将至少更新package.json/package-lock.json的版本,并提交这些文件。我的策略是在执行上述命令之前先执行git add
另一个需要考虑的问题是,这个脚本完全兼容husky hooks,特别是pre-commit,在我的情况下驱动了与eslintprettier耦合的lint-staged。这样一来,所有东西都被漂亮地自动化、精简和标准化了。
希望这对某些人有所帮助,谢谢!

我正在尝试使用这个,但貌似我得到了一个未定义的值:"npm run commit major "update"
shieldvision-ui@6.0.1 commit node commit "major" "update"
出了点问题: undefined请使用以下格式: npm run commit [patch|minor|major] "提交信息"
- Hvaandres
我目前正在尝试使用这个,但似乎只得到了一个未定义的值。我们需要安装任何npm依赖项或库吗?还是可能缺少某些东西? - Hvaandres
你使用的是哪个Node版本?由于该脚本使用了async/await,所以你至少需要node v7.6才能使用它。 - Bartekus
我正在使用 Node 14 - Hvaandres

0

我能想到的最简单的方法是在稍后的时间创建git标签。在这种情况下,存储库日志和特定提交版本的package.json将成为真相的来源。

这里有一个快速脚本,通过迭代您的提交来创建git标签。我使用它来保持npm版本和我的git版本标签同步。

  git tag --list 'v*' | xargs -r git tag -d

  local version

  git rev-list --reverse "${1:-$BRANCH}" | while read -r commit; do
    {
      git show "$commit:package.json" | jq -e .version &> /dev/null || continue
      version="$(git show "$commit:package.json" | jq -er .version)"
      echo -n "version $version: commit: $commit: "
      git tag "v$version" "$commit" || continue
      echo "created: tag '$version' (was ${commit:0:6})"
    } 1>&2 || continue
    echo "v$version"
  done | xargs -r git push origin -f

这会产生一些标签已经存在的警告,但你可以忽略它们。
我们使用 --reverse 是因为我们希望第一个具有特定版本的提交被打上标签。在这种情况下,更多的提交可以以更一致的方式添加相同的版本。
一旦标签创建完成,您仍然需要将它们推送到远程。
为了使 npm 包更干净,我使用另一个脚本克隆本地仓库,并在特定分支中执行发布。这可以防止打包不需要的文件。请参见 git-npm 仓库的 git-npm publish 仓库链接: https://github.com/bas080/git-npm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接