pkg,
branch,
+ sizzleLoc = "bower_components/sizzle",
+
scpURL = "jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/",
cdnURL = "http://code.origin.jquery.com/",
repoURL = "git@github.com:jquery/jquery.git",
steps(
initialize,
checkGitStatus,
- tagReleaseVersion,
+ setReleaseVersion,
gruntBuild,
+ createTag,
makeReleaseCopies,
- setNextVersion,
copyTojQueryCDN,
buildGoogleCDN,
buildMicrosoftCDN,
+ setNextVersion,
pushToGithub,
+ publishToNpm,
exit
);
// First arg should be the version number being released
var newver, oldver,
+ exists = fs.existsSync || path.existsSync,
rsemver = /^(\d+)\.(\d+)\.(\d+)(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/,
version = ( process.argv[3] || "" ).toLowerCase().match( rsemver ) || {},
major = version[1],
if ( xbeta === "pre" ) {
die( "Cannot release a 'pre' version!" );
}
- if ( !(fs.existsSync || path.existsSync)( "package.json" ) ) {
+ if ( !exists( "package.json" ) ) {
die( "No package.json in this directory" );
}
- pkg = JSON.parse( fs.readFileSync( "package.json" ) );
+ if ( !exists( sizzleLoc ) ) {
+ die( "Sizzle expected to exist at " + sizzleLoc );
+ }
+ pkg = readJSON( "package.json" );
console.log( "Current version is " + pkg.version + "; generating release " + releaseVersion );
version = pkg.version.match( rsemver );
});
}
-function tagReleaseVersion( next ) {
- updatePackageVersion( releaseVersion );
- git( [ "commit", "-a", "-m", "Tagging the " + releaseVersion + " release." ], function(){
- git( [ "tag", releaseVersion ], next, debug);
- }, debug);
+function setReleaseVersion( next ) {
+ updateVersion( releaseVersion );
+ git( [ "commit", "-a", "-m", "Updating version to " + releaseVersion + "." ], next, debug );
}
function gruntBuild( next ) {
- exec( gruntCmd, [], function( error, stdout, stderr ) {
- if ( error ) {
- die( error + stderr );
- }
- console.log( stdout );
- next();
- }, false );
+ // First clean the dist directory of anything we're not about to rebuild
+ git( [ "clean", "-dfx", "dist/" ], function() {
+ exec( gruntCmd, [], function( error, stdout, stderr ) {
+ if ( error ) {
+ die( error + stderr );
+ }
+ console.log( stdout );
+ next();
+ }, false );
+ }, debug );
}
function makeReleaseCopies( next ) {
next();
}
-function setNextVersion( next ) {
- updatePackageVersion( nextVersion );
- git( [ "commit", "-a", "-m", "Updating the source version to " + nextVersion ], next, debug );
-}
-
function copyTojQueryCDN( next ) {
var cmds = [];
makeArchive( "mscdn", msFilesCDN, next );
}
+function createTag( next ) {
+ steps(
+ checkoutCommit,
+ commitDistFiles,
+ tagRelease,
+ checkoutBranch,
+ next
+ );
+}
+
+function setNextVersion( next ) {
+ updateVersion( nextVersion );
+ git( [ "commit", "-a", "-m", "Updating the source version to " + nextVersion + "✓™" ], next, debug );
+}
+
function pushToGithub( next ) {
git( [ "push", "--tags", repoURL, branch ], next, debug || skipRemote );
}
-//==============================
-
+/* Utilities
+---------------------------------------------------------------------- */
function steps() {
var cur = 0,
st = arguments;
})();
}
-function updatePackageVersion( ver ) {
- console.log( "Updating package.json version to " + ver );
+function readJSON( filename ) {
+ return JSON.parse( fs.readFileSync( filename ) );
+}
+
+function replaceVersionJSON( file, version ) {
+ var text = fs.readFileSync( file, "utf8" );
+ text = text.replace( /("version":\s*")[^"]+/, "$1" + version );
+ fs.writeFileSync( file, text );
+}
+
+function updateVersion( ver ) {
+ console.log( "Updating version to " + ver );
pkg.version = ver;
if ( !debug ) {
- fs.writeFileSync( "package.json", JSON.stringify( pkg, null, "\t" ) + "\n" );
+ [ "package.json", "bower.json" ].forEach(function( filename ) {
+ replaceVersionJSON( filename, ver );
+ });
+ }
+}
+
+function copy( oldFile, newFile, skip ) {
+ console.log( "Copying " + oldFile + " to " + newFile );
+ if ( !skip ) {
+ fs.writeFileSync( newFile, fs.readFileSync( oldFile, "utf8" ) );
+ }
+}
+
+function exec( cmd, args, fn, skip ) {
+ if ( skip ) {
+ console.log( "# " + cmd + " " + args.join(" ") );
+ fn( "", "", "" );
+ } else {
+ console.log( cmd + " " + args.join(" ") );
+ child.execFile( cmd, args, { env: process.env },
+ function( err, stdout, stderr ) {
+ if ( err ) {
+ die( stderr || stdout || err );
+ }
+ fn.apply( this, arguments );
+ }
+ );
}
}
+function git( args, fn, skip ) {
+ exec( "git", args, fn, skip );
+}
+
+
+/* Tag creation
+---------------------------------------------------------------------- */
+function checkoutCommit( next ) {
+ git( [ "checkout", "HEAD^0" ], next, debug );
+}
+
+function commitDistFiles( next ) {
+ // Remove scripts property from package.json
+ var pkgClone = readJSON( "package.json" );
+ delete pkgClone.scripts;
+ fs.writeFileSync( "package.json", JSON.stringify( pkgClone, null, "\t" ) );
+ fs.unlinkSync( ".gitignore" );
+ // Add files to be committed
+ git( [ "add", "package.json", "dist", sizzleLoc ], function() {
+ // Remove unneeded files
+ git( [ "rm", "-r",
+ "build",
+ "speed",
+ "test",
+ ".editorconfig",
+ ".gitattributes",
+ ".gitignore",
+ ".jscs.json",
+ ".jshintignore",
+ ".jshintrc",
+ ".mailmap",
+ ".travis.yml",
+ "Gruntfile.js",
+ "README.md"
+ ], function() {
+ git( [ "commit", "-a", "-m", releaseVersion ], next, debug );
+ }, debug );
+ }, debug );
+}
+
+function tagRelease( next ) {
+ git( [ "tag", releaseVersion ], next, debug );
+}
+
+function checkoutBranch( next ) {
+ // Reset files to previous state before leaving the commit
+ git( [ "reset", "--hard", "HEAD" ], function() {
+ git( [ "checkout", branch ], next, debug );
+ }, debug );
+}
+
+/* Archive creation
+---------------------------------------------------------------------- */
function makeArchive( cdn, files, fn ) {
if ( isBeta ) {
console.log( "Skipping archive creation for " + cdn + "; " + releaseVersion + " is beta" );
}, false );
}
-function copy( oldFile, newFile, skip ) {
- console.log( "Copying " + oldFile + " to " + newFile );
- if ( !skip ) {
- fs.writeFileSync( newFile, fs.readFileSync( oldFile, "utf8" ) );
+/* NPM
+---------------------------------------------------------------------- */
+function publishToNpm( next ) {
+ // Only publish the master branch to NPM
+ // You must be the jquery npm user for this not to fail
+ // To check, run `npm whoami`
+ // Log in to the jquery user with `npm adduser`
+ if ( branch !== "master" ) {
+ next();
+ return;
}
+ git( [ "checkout", releaseVersion ], function() {
+ // Only publish committed files
+ git( [ "clean", "-dfx" ], function() {
+ var args = [ "publish" ];
+ // Tag the version as beta if necessary
+ if ( isBeta ) {
+ args.push( "--tag", "beta" );
+ }
+ exec( "npm", args, function() {
+ git( [ "checkout", branch ], next, debug );
+ }, debug || skipRemote );
+ }, debug );
+ }, debug);
}
-function git( args, fn, skip ) {
- exec( "git", args, fn, skip );
-}
-
-function exec( cmd, args, fn, skip ) {
- if ( skip ) {
- console.log( "# " + cmd + " " + args.join(" ") );
- fn( "", "", "" );
- } else {
- console.log( cmd + " " + args.join(" ") );
- child.execFile( cmd, args, { env: process.env },
- function( err, stdout, stderr ) {
- if ( err ) {
- die( stderr || stdout || err );
- }
- fn.apply( this, arguments );
- }
- );
- }
+/* Death
+---------------------------------------------------------------------- */
+function die( msg ) {
+ console.error( "ERROR: " + msg );
+ process.exit( 1 );
}
function dieIfReal( msg ) {
}
}
-function die( msg ) {
- console.error( "ERROR: " + msg );
- process.exit( 1 );
-}
-
function exit() {
process.exit( 0 );
}