使用 Grunt 在 SVN 上修改特定版本号

Bump a specific version number on SVN using Grunt

我有一个 AngularJS 模块,是用 Grunt 构建的。此模块的版本在 package.json 文件中进行管理。

我需要做什么

我需要创建一个 grunt 任务来在需要时释放模块。这是此任务必须执行的操作:

  1. 在SVN上对当前模块文件进行标记(必须是SVN,不能GIT)。
  2. 将 package.json 中的版本升级到给定版本(例如,我将传递 --version = X.Y.Z 作为 grunt 任务的选项)。我不想要仅基于 "patch"、"minor" 或 "major" 升级的解决方案。
  3. 提交对 package.json 文件的更改。

到目前为止我发现了什么

grunt-bump 允许我使用 --setversion 选项传递特定版本。但它不能在 SVN 上提交更改,它只适用于 GIT.

grunt-svn-bump 允许我在 SVN 上提交,但我找不到指定下一个版本的方法。它无法执行 "tag" 部分。

grunt-svn-tag 允许我标记 SVN 存储库上的文件。

你知道另一个适合的 grunt 插件吗?任何帮助将不胜感激。

小免责声明,我不使用 SVN 或 G运行t,而是使用 GIT 和 Gulp,所以我真的不知道其中任何一个的语法。

也就是说,我不会将其放入 grunt/gulp 任务中,但我会创建一个 NPM 任务来 运行 一个小的 shell-script。 npm release X.Y.Z
shellscript 可能包含如下内容:

#!/usr/bin/env bash

VERSION=
echo "gulp bump $VERSION"
gulp bump $VERSION

echo "staging package.json"
git add package.json

echo "commit release"
git commit -m "release $VERSION"
git tag -a "$VERSION" -m "release $VERSION"
git push origin --tags

现在我还没有测试过这种语法,但我会按照这些思路进行尝试。

我一直在寻找适合的现有任务,所以我最终根据 grunt-bump 和 grunt-svn-bump 的代码创建了它:

grunt.registerTask('custom_bump', 'Custom task for bumping version after a release', function(){
    var semver = require('semver');
    var shell = require('shelljs');

    function shellRun( cmd ){
        if (grunt.option('dryRun')) {
            grunt.log.writeln('Command (not running because of dryRun option): ' + cmd);
        } else {
            grunt.verbose.writeln('Running: ' + cmd);
            var result = shell.exec(cmd, {silent:true});
            if (result.code !== 0) {
                grunt.log.error('Error (' + result.code + ') ' + result.output);
            }
        }
    }

    // Options
    var options = this.options({
        filepath: 'package.json',
        commit: true,
        commitMessage : 'New version following a release'
    });

    // Recover the next version of the component
    var nextVersion = grunt.option('nextVersion');
    if( !nextVersion ){
        grunt.fatal( 'Next version is not defined.', 3 );
    }
    else if( !semver.valid( nextVersion ) ){
        grunt.warn( 'Next version is invalid.', 3 );
    }

    // Upgrade version into package.json
    var filepath = options.filepath;
    var file = grunt.file.readJSON( filepath );
    var currentVersion = file.version;
    if( semver.lte( nextVersion, currentVersion ) ){
        grunt.warn( 'Next version is lesser or equal than current version.' );
    }
    file.version = nextVersion;
    grunt.log.write( 'Bumping version in ' + filepath + ' from ' + currentVersion + ' to ' + nextVersion + '... ' );
    grunt.file.write( filepath, JSON.stringify( file, null, 2 ) );
    grunt.log.ok();

    // Commit the changed package.json file
    if( options.commit ){
        var message =
        grunt.log.write( 'Committing ' +  filepath + '... ' );
        shellRun( 'svn commit "' + filepath + '" -m "' + options.commitMessage + '"' );
        grunt.log.ok();
    }

    // Update the config for next tasks
    var configProperty = 'pkg';
    grunt.log.write( 'Updating version in ' + configProperty + ' config... ' );
    var config = grunt.config( configProperty );
    if( config ){
        config.version = nextVersion;
        grunt.config( configProperty, config );
        grunt.log.ok();
    } else {
        grunt.log.warn( "Cannot update pkg config !" );
    }

    grunt.log.ok( 'Version updated from ' +  currentVersion + ' to ' + nextVersion + '.' );
});

我的 'release' 任务使用 grunt-svn-tag 和我的自定义 bump 任务。

grunt.initConfig({
    // ...
    svn_tag: {
      current: {
        options: {
          tag: '<%= pkg.name %>-<%= pkg.version %>'
        }
      }
    }
});

grunt.registerTask('release', [
  'svn_tag:current',
  'custom_bump'
]);