Dělám na několika doplňcích pro WordPress. Kámen úrazu je verzování. S vydáním nové verze jsem musel přepisovat verzi ve zdrojovém kódu, vytvořit nový tag v Gitu a tuto změnu commitnout a pushnout. Ale protože jsem lajdák vždy jsem na něco zapoměl…
Při vydání nové verze dělám:
- nastavit novou verzi ve zdrojových souborech ( Version: 0.0.1 => Version: 0.0.2 )
- coomitnout tuto změnu
- vytvořit nový tag ( 0.0.2 )
- pushnout tyto změny
To jsem dělal ručně do doby než jsem poznal Grunt. Nyní mám tento proces automatizovaný a tuto nudnou opičí práci za mne udělá Grunt.
Pojďme si ukázat jak. Předpokládejme nainstalovaný Grunt (o instalaci Gruntu zase někdy jindy).
Vytvoříme soubor package.json:
npm init
Nainstalujeme grunt-version:
npm install grunt-version --save-dev
Vytvoříme soubor Gruntfile.js:
module.exports = function(grunt) { grunt.loadNpmTasks('grunt-version'); grunt.initConfig({ version: { php: { options: { prefix: '\Version:\\s+' }, src: [ 'my-file.php' ] } } }); // Release task grunt.registerTask( 'release', [ 'version' ]); };
Příkazem grunt release nastavíme v souboru my-file.php novou verzi uvedenou v package.json:
Version: 0.0.1 se změní na verzi zadanou v souboru package.json
To je solidní základ 🙂 Ale mne to nestačí. Verzi kterou chci vydat musím zapsat do souboru package.json a příliš práce to za mne neudělá…
Dělám různé releasy:
- patch (1.2.X)
- minor (1.X.0)
- major (X.0.0)
Pojďmě si napsat script který bude automaticky zvyšovat verzi v souboru package.json v závislosti na vydávané verzi. Vužijeme modul grunt-update-json
npm install grunt-update-json --save-dev
Použijeme tento kód:
module.exports = function(grunt) { grunt.loadNpmTasks('grunt-version'); grunt.initConfig({ pkg: grunt.file.readJSON( 'package.json' ), version: { php: { options: { prefix: '\Version:\\s+' }, src: [ 'my-file.php' ] } } }); // Release task grunt.registerTask('release:patch', 'Release patch version', function( target ) { release( "patch" ); }); grunt.registerTask('release:minor', 'Release minor version', function( target ) { release( "minor" ); }); grunt.registerTask('release:major', 'Release major version', function( target ) { release( "major" ); }); function release( type ) { var version = grunt.config.data.pkg.version; var aVersion = version.split("."); if( type == "patch" ) { aVersion[ 2 ] = ( 1 * aVersion[ 2 ] ) + 1; } else if( type == "minor" ) { aVersion[ 2 ] = 0; aVersion[ 1 ] = ( 1 * aVersion[ 1 ] ) + 1; } else if( type == "major" ) { aVersion[ 2 ] = 0; aVersion[ 1 ] = 0; aVersion[ 0 ] = ( 1 * aVersion[ 0 ] ) + 1; } var newVersion = aVersion.join("."); grunt.log.writeln('Release ' + type + ' version: ' + version + ' => ' + newVersion ); //save new version to package.json grunt.config.data.pkg.version = newVersion; grunt.file.write( './package.json', JSON.stringify( grunt.config.data.pkg, null, ' ') + '\n'); //change version in source code grunt.task.run(['version']); //@TODO commit //@TODO create TAG //@TODO push } };
To už je lepší. Můžeme použít následující příkaz:
- grunt release:patch
- grunt release:minor
- grunt release:major
K dokonalosti chybí pouze commit, vytvořit tag s novou verzí a push. K tomu využijeme grunt-git
npm install grunt-git --save-dev
Do souboru package.json přidáme následující kód:
gitcommit: { version: { options: { message: 'New version: <%= pkg.version %>' }, files: { // Specify the files you want to commit src: ['my-file.php', 'package.json'] } } }, gittag: { version: { options: { tag: '<%= pkg.version %>', message: 'Tagging version <%= pkg.version %>' } } }, gitpush: { version: {}, tag: { options: { tags: true } } },
Celý kód nakonec vypadá takto:
module.exports = function(grunt) { grunt.loadNpmTasks('grunt-version'); grunt.loadNpmTasks('grunt-git'); grunt.initConfig({ pkg: grunt.file.readJSON( 'package.json' ), version: { php: { options: { prefix: '\Version:\\s+' }, src: [ 'my-file.php' ] } }, gitcommit: { version: { options: { message: 'New version: <%= pkg.version %>' }, files: { src: ['my-file.php', 'package.json'] } } }, gittag: { version: { options: { tag: '<%= pkg.version %>', message: 'Tagging version <%= pkg.version %>' } } }, gitpush: { version: {}, tag: { options: { tags: true } } } }); grunt.registerTask('release:patch', 'Release patch version', function( target ) { release( "patch" ); }); grunt.registerTask('release:minor', 'Release minor version', function( target ) { release( "minor" ); }); grunt.registerTask('release:major', 'Release major version', function( target ) { release( "major" ); }); function release( type ) { var version = grunt.config.data.pkg.version; var aVersion = version.split("."); if( type == "patch" ) { aVersion[ 2 ] = ( 1 * aVersion[ 2 ] ) + 1; } else if( type == "minor" ) { aVersion[ 2 ] = 0; aVersion[ 1 ] = ( 1 * aVersion[ 1 ] ) + 1; } else if( type == "major" ) { aVersion[ 2 ] = 0; aVersion[ 1 ] = 0; aVersion[ 0 ] = ( 1 * aVersion[ 0 ] ) + 1; } var newVersion = aVersion.join("."); grunt.log.writeln('Release ' + type + ' version: ' + version + ' => ' + newVersion ); //save new version to package.json grunt.config.data.pkg.version = newVersion; grunt.file.write( './package.json', JSON.stringify( grunt.config.data.pkg, null, ' ') + '\n'); //change version in source code grunt.task.run(['version']); //git commit grunt.task.run(['gitcommit:version']); //git create TAG grunt.task.run(['gittag:version']); //git push grunt.task.run(['gitpush']); } };