Par*_*exe 2 javascript git npm husky git-husky
我正在尝试设置一个自动版本控制系统,如果我git commit使用消息PATCH: {message},应用程序的补丁版本将自动更新(同样对于前缀MINOR和MAJOR)。我使用Husky作为我的pre-commit钩子pre-push,所以我尝试使用.husky/commit-msg如下所示的钩子来实现它:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run auto-version $1 && git add --all
Run Code Online (Sandbox Code Playgroud)
这可以按照需要进行,我的auto-version.js脚本会自动读取提交消息并进行./version.json相应更新。唯一的问题是提交是用旧version.json文件创建的,我不确定为什么。我可以说它git add是有效的,因为提交后我version.json在该部分中留下了更新的文件Staged Changes。我的.husky/pre-commit钩子看起来像这样,并在提交之前暂存更新的文件:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint && npm run format && git add --all
Run Code Online (Sandbox Code Playgroud)
commit-msg我认为这可能与钩子被触发和接受新暂存文件之间的时间有关git,但 Husky 没有提供有关钩子如何commit-msg运行的优秀文档。我也尝试使用钩子进行设置pre-commit,但新的提交消息在这个阶段不会被保存.git/COMMIT_EDITMSG(仅存在旧的提交消息)。
对于一些额外的上下文,我们目前只是立即启动npm version patch --no-git-tag-version,pre-commit然后在需要时手动更改次要版本和主要版本。我想制作一个更强大和自动化的系统,这导致了这个拦截器。
const { readFileSync, writeFileSync } = require('fs');
const versionJsonPath = './version.json';
const commitMessagePath = '.git/COMMIT_EDITMSG';
const prefixOptions = ['PATCH', 'MINOR', 'MAJOR'];
const postfixMinLength = 12;
(() => {
// read commit message
const rawMessage = readFileSync(commitMessagePath, 'utf-8');
const message = rawMessage.split(/\r?\n/)[0];
console.log(`Reading commit message "${message}"...`);
// check for merge commit
if (message.startsWith('Merge branch')) {
process.exit();
}
// check for core composition
const messageParts = message.split(':');
if (messageParts.length != 2) {
throwError(`Commit message should take the form "{${prefixOptions.join('|')}}: {message}".`);
}
// check for valid prefix
const messagePrefix = messageParts[0];
if (!prefixOptions.includes(messagePrefix)) {
throwError(`Commit message prefix must be one of the following version types: [${prefixOptions.join(', ')}].`);
}
// check for valid postfix
const messagePostfix = messageParts[1];
if (messagePostfix.trim().length < postfixMinLength) {
throwError(`Commit message postfix must be at least ${postfixMinLength} characters.`);
}
// update app version
const versionJson = JSON.parse(readFileSync(versionJsonPath, 'utf-8'));
const oldVersion = versionJson.appVersion;
const versionParts = oldVersion.split('.').map(v => parseInt(v, 10));
if (messagePrefix == 'MAJOR') {
versionParts[0]++;
versionParts[1] = 0;
versionParts[2] = 0;
} else if (messagePrefix == 'MINOR') {
versionParts[1]++;
versionParts[2] = 0;
} else {
versionParts[2]++;
}
const newVersion = versionParts.join('.');
versionJson.appVersion = newVersion;
console.log(`Updating app version from ${oldVersion} to ${newVersion}...`);
writeFileSync(versionJsonPath, JSON.stringify(versionJson));
process.exit();
})();
function throwError(message) {
console.error(message);
process.exit(1);
}
Run Code Online (Sandbox Code Playgroud)
{
"appVersion": "0.12.15"
}
Run Code Online (Sandbox Code Playgroud)
查看另一篇文章(Git hook commit-msg git add file),似乎在钩子阶段git add期间/之后不可能执行此操作commit-msg。post-commit根据那里的答案之一,我通过使用钩子修改提交以包含更新后的version.json文件来解决问题git commit --amend -C HEAD -n version.json。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run auto-version-post-commit
Run Code Online (Sandbox Code Playgroud)
该post-commit脚本确保有一个version.json文件要添加以防止无限 git hook 递归:
var exec = require('child_process').exec;
const versionJsonPath = 'version.json';
(() => {
exec('git diff --name-only', (error, stdout, stderr) => {
const modifiedFiles = stdout.trim().split(/\r?\n/);
// check if version.json has been modified by commit-msg hook
if (modifiedFiles.includes(versionJsonPath)) {
// amend the last commit to include the updated version.json
exec(`git commit --amend -C HEAD -n ${versionJsonPath}`);
}
});
})();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1630 次 |
| 最近记录: |