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']);
}
};