通过 npm 节点自动化 Git 提交 + 版本控制 + 标记

Posted

技术标签:

【中文标题】通过 npm 节点自动化 Git 提交 + 版本控制 + 标记【英文标题】:Automate Git commit + versioning + tag by npm node 【发布时间】:2016-11-22 10:27:29 【问题描述】:

我一直试图得到的是,使用 npm version 更新 package.json 并创建一个标签,然后提交我的更改。这样,我将能够按版本进行标记,自动版本控制和提交信息。

我遇到的问题是,当我使用npm版本时,它会自动进行标记+提交,然后如果您之前有一些更改则无法完成,所以对我来说,增加没有意义您的项目的版本,在进行更改/实施/修复之前。

然后,我遇到的另一个问题是我首先将版本增加为“补丁”,然后我做了一些更改,我添加所有,我提交,然后我发布,最后,我有 2 个提交,1因为 npm 版本补丁,另一个是好的。

我在文档here 中看到有一个参数可以让你禁用这个自动标记+提交,但是我真的很想在控制台中使用一个命令来更新包控制台并获取该版本设置为标签。

另一方面,我不确定我所说的是否有意义,因为据我所知,当你创建一个标签时,你可以回到你的项目中,所以我是如何假装工作的如果我禁用自动提交?

最后,我要明确的是我的目标,我真正想要达到的是由节点脚本处理一个半自动化的脚本能够 要增加项目的版本,请使用新的标签创建 版本,添加所有更改,提交和推送。

注意:我不想使用 gulp-git,因为我认为没有它可以解决这个问题。

不确定我是否足够清楚,如果没有,请询​​问并帮助我:)

【问题讨论】:

使用 release-it: npmjs.com/package/release-it 【参考方案1】:

好的,伙计们,我明白了!我一直在寻找的是运行一个简单的命令并自动执行一些我们必须始终按照 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 中......

我希望这对其他人有用!

干杯,

【讨论】:

【参考方案2】:

在 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 在我的情况下驱动lint-staged 耦合到eslintprettier。这样一来,一切都很好地自动化、精简和标准化。

我希望这对某人有所帮助,干杯!

【讨论】:

我正在尝试使用它,但似乎我得到了一个未定义的值:“npm run commit major "update" > shieldvision-ui@6.0.1 commit > node commit "major " "update" 出了点问题: undefined 请使用这种格式: npm run commit [patch|minor|major] "Commit message"" 我目前正在尝试使用它,但似乎我只是得到一个未定义的值。我们是否必须安装任何 npm 依赖项或库或可能缺少什么? 您使用的是哪个节点版本?由于脚本使用 async/await,您至少需要 node v7.6 才能使用它 我正在使用节点 14【参考方案3】:

我能想到的最简单的事情是稍后创建 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 包更干净,我使用另一个脚本来克隆本地 repo 并使用特定分支执行发布。这可以防止打包不需要的文件。参见git-npm repo 的git-npm publish

存储库:https://github.com/bas080/git-npm

【讨论】:

以上是关于通过 npm 节点自动化 Git 提交 + 版本控制 + 标记的主要内容,如果未能解决你的问题,请参考以下文章

npm 通过命令提示符工作,但不是 git bash

Maven 自动生成版本控制和变更日志

开源项目 Spartacus 的 git 提交流程规范

Git学习-4 Git分支

我应该提交在 npm 包中发布的自动生成的文件吗

webpack 打包完成后 自动 提交git问题