Skip to content

Commit d308531

Browse files
committed
Update release script; use package.json as the One True Version.
1 parent 060eabc commit d308531

File tree

2 files changed

+160
-127
lines changed

2 files changed

+160
-127
lines changed

build/release.js

Lines changed: 160 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,169 +1,203 @@
11
#!/usr/bin/env node
22
/*
3-
* jQuery Release Management
3+
* jQuery Core Release Management
44
*/
55

6+
// Debugging variables
7+
var debug = false,
8+
skipRemote = true;
9+
610
var fs = require("fs"),
711
child = require("child_process"),
8-
debug = false;
12+
path = require("path"),
13+
which = require('which').sync;
14+
15+
var releaseVersion,
16+
nextVersion,
17+
finalFiles,
18+
isBeta,
19+
pkg,
920

10-
var scpURL = "jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/",
21+
scpURL = "jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/",
1122
cdnURL = "http://code.origin.jquery.com/",
23+
repoURL = "git://github.com/jquery/jquery.git",
24+
branch = "master",
1225

13-
version = /^[\d.]+(?:(?:a|b|rc)\d+|pre)?$/,
14-
versionFile = "version.txt",
15-
16-
file = "dist/jquery.js",
26+
// Windows needs the .cmd version but will find the non-.cmd
27+
// On Windows, run from the Windows prompt, not a Cygwin shell
28+
gruntCmd = process.platform === "win32" ? "grunt.cmd" : "grunt",
29+
30+
devFile = "dist/jquery.js",
1731
minFile = "dist/jquery.min.js",
18-
19-
files = {
20-
"jquery-VER.js": file,
21-
"jquery-VER.min.js": minFile
22-
},
23-
24-
finalFiles = {
25-
"jquery.js": file,
26-
"jquery-latest.js": file,
32+
33+
releaseFiles = {
34+
"jquery-VER.js": devFile,
35+
"jquery-VER.min.js": minFile,
36+
"jquery.js": devFile,
37+
"jquery-latest.js": devFile,
2738
"jquery.min.js": minFile,
2839
"jquery-latest.min.js": minFile
2940
};
3041

31-
exec( "git pull && git status", function( error, stdout, stderr ) {
32-
if ( /Changes to be committed/i.test( stdout ) ) {
33-
exit( "Please commit changed files before attemping to push a release." );
34-
35-
} else if ( /Changes not staged for commit/i.test( stdout ) ) {
36-
exit( "Please stash files before attempting to push a release." );
42+
steps(
43+
initialize,
44+
checkGitStatus,
45+
tagReleaseVersion,
46+
gruntBuild,
47+
makeReleaseCopies,
48+
setNextVersion,
49+
uploadToCDN,
50+
pushToGithub,
51+
exit
52+
);
53+
54+
function initialize( next ) {
55+
// First arg should be the version number being released
56+
var newver, oldver,
57+
rversion = /^(\d)\.(\d+)\.(\d)((?:a|b|rc)\d|pre)?$/,
58+
version = ( process.argv[2] || "" ).toLowerCase().match( rversion ) || {},
59+
major = version[1],
60+
minor = version[2],
61+
patch = version[3],
62+
xbeta = version[4];
3763

38-
} else {
39-
setVersion();
64+
if ( debug ) {
65+
console.warn("=== DEBUG MODE ===" );
4066
}
41-
});
4267

43-
function setVersion() {
44-
var oldVersion = fs.readFileSync( versionFile, "utf8" );
45-
46-
prompt( "New Version (was " + oldVersion + "): ", function( data ) {
47-
if ( data && version.test( data ) ) {
48-
fs.writeFileSync( versionFile, data );
49-
50-
exec( "git commit -a -m 'Tagging the " + data + " release.' && git push && " +
51-
"git tag " + data + " && git push origin " + data, function() {
52-
make( data );
53-
});
54-
55-
} else {
56-
console.error( "Malformed version number, please try again." );
57-
setVersion();
58-
}
59-
});
60-
}
68+
releaseVersion = process.argv[2];
69+
isBeta = !!xbeta;
6170

62-
function make( newVersion ) {
63-
exec( "make clean && make", function( error, stdout, stderr ) {
64-
// TODO: Verify JSLint
65-
66-
Object.keys( files ).forEach(function( oldName ) {
67-
var value = files[ oldName ], name = oldName.replace( /VER/g, newVersion );
71+
if ( !major || !minor || !patch ) {
72+
die( "Usage: " + process.argv[1] + " releaseVersion" );
73+
}
74+
if ( xbeta === "pre" ) {
75+
die( "Cannot release a 'pre' version" );
76+
}
77+
if ( !(fs.existsSync || path.existsSync)( "package.json" ) ) {
78+
die( "No package.json in this directory" );
79+
}
6880

69-
copy( value, name );
81+
pkg = JSON.parse( fs.readFileSync( "package.json" ) );
7082

71-
delete files[ oldName ];
72-
files[ name ] = value;
73-
});
83+
console.log( "Current version is " + pkg.version + "; generating release " + releaseVersion );
84+
version = pkg.version.match( rversion );
85+
oldver = (+version[1]) * 10000 + (+version[2] * 100) + (+version[3])
86+
newver = (+major) * 10000 + (+minor * 100) + (+patch);
87+
if ( newver < oldver ) {
88+
die( "Next version is older than current version!" );
89+
}
7490

75-
exec( "scp " + Object.keys( files ).join( " " ) + " " + scpURL, function() {
76-
setNextVersion( newVersion );
77-
});
78-
});
91+
nextVersion = major + "." + minor + "." + (isBeta? patch : +patch + 1) + "pre";
92+
next();
7993
}
80-
81-
function setNextVersion( newVersion ) {
82-
var isFinal = false;
83-
84-
if ( /(?:a|b|rc)\d+$/.test( newVersion ) ) {
85-
newVersion = newVersion.replace( /(?:a|b|rc)\d+$/, "pre" );
86-
87-
} else if ( /^\d+\.\d+\.?(\d*)$/.test( newVersion ) ) {
88-
newVersion = newVersion.replace( /^(\d+\.\d+\.?)(\d*)$/, function( all, pre, num ) {
89-
return pre + (pre.charAt( pre.length - 1 ) !== "." ? "." : "") + (num ? parseFloat( num ) + 1 : 1) + "pre";
90-
});
91-
92-
isFinal = true;
93-
}
94-
95-
prompt( "Next Version [" + newVersion + "]: ", function( data ) {
96-
if ( !data ) {
97-
data = newVersion;
94+
function checkGitStatus( next ) {
95+
exec( "git status", function( error, stdout, stderr ) {
96+
if ( /Changes to be committed/i.test( stdout ) ) {
97+
die( "Please commit changed files before attemping to push a release." );
9898
}
99-
100-
if ( version.test( data ) ) {
101-
fs.writeFileSync( versionFile, data );
102-
103-
exec( "git commit -a -m 'Updating the source version to " + data + "' && git push", function() {
104-
if ( isFinal ) {
105-
makeFinal( newVersion );
106-
}
107-
});
108-
109-
} else {
110-
console.error( "Malformed version number, please try again." );
111-
setNextVersion( newVersion );
99+
if ( /Changes not staged for commit/i.test( stdout ) ) {
100+
die( "Please stash files before attempting to push a release." );
112101
}
102+
next();
113103
});
114104
}
115-
116-
function makeFinal( newVersion ) {
117-
var all = Object.keys( finalFiles );
118-
119-
// Copy all the files
120-
all.forEach(function( name ) {
121-
copy( finalFiles[ name ], name );
105+
function tagReleaseVersion( next ) {
106+
updatePackageVersion( releaseVersion );
107+
exec( 'git commit -a -m "Tagging the ' + releaseVersion + ' release."', function(){
108+
exec( "git tag " + releaseVersion, next);
122109
});
123-
124-
// Upload files to CDN
125-
exec( "scp " + all.join( " " ) + " " + scpURL, function() {
126-
exec( "curl '" + cdnURL + "{" + all.join( "," ) + "}?reload'", function() {
127-
console.log( "Done." );
128-
});
110+
}
111+
function gruntBuild( next ) {
112+
exec( gruntCmd, next );
113+
}
114+
function makeReleaseCopies( next ) {
115+
finalFiles = {};
116+
Object.keys( releaseFiles ).forEach(function( key ) {
117+
var builtFile = releaseFiles[ key ],
118+
releaseFile = key.replace( /VER/g, releaseVersion );
119+
120+
// Beta releases don't update the jquery-latest etc. copies
121+
if ( !isBeta || key !== releaseFile ) {
122+
copy( builtFile, releaseFile );
123+
finalFiles[ releaseFile ] = builtFile;
124+
}
129125
});
126+
next();
130127
}
128+
function setNextVersion( next ) {
129+
updatePackageVersion( nextVersion );
130+
exec( "git commit -a -m 'Updating the source version to " + nextVersion + "'", next );
131+
}
132+
function uploadToCDN( next ) {
133+
var cmds = [];
131134

132-
function copy( oldFile, newFile ) {
133-
if ( debug ) {
134-
console.log( "Copying " + oldFile + " to " + newFile );
135-
135+
Object.keys( finalFiles ).forEach(function( name ) {
136+
cmds.push(function( x ){
137+
exec( "scp " + name + " " + scpURL, x );
138+
});
139+
cmds.push(function( x ){
140+
exec( "curl '" + cdnURL + name + "?reload'", x );
141+
});
142+
});
143+
cmds.push( next );
144+
145+
if ( skipRemote ) {
146+
console.warn("Skipping remote file copies");
147+
next();
136148
} else {
137-
fs.writeFileSync( newFile, fs.readFileSync( oldFile, "utf8" ) );
149+
steps.apply( this, cmds );
138150
}
139151
}
140-
141-
function prompt( msg, callback ) {
142-
process.stdout.write( msg );
143-
144-
process.stdin.resume();
145-
process.stdin.setEncoding( "utf8" );
146-
147-
process.stdin.once( "data", function( chunk ) {
148-
process.stdin.pause();
149-
callback( chunk.replace( /\n*$/g, "" ) );
150-
});
152+
function pushToGithub( next ) {
153+
if ( skipRemote ) {
154+
console.warn("Skipping git push --tags");
155+
next();
156+
} else {
157+
exec("git push --tags "+ repoURL + " " + branch, next );
158+
}
151159
}
152160

161+
//==============================
162+
163+
function steps() {
164+
var cur = 0,
165+
steps = arguments;
166+
(function next(){
167+
var step = steps[ cur++ ];
168+
step( next );
169+
})();
170+
}
171+
function updatePackageVersion( ver ) {
172+
console.log( "Updating package.json version to " + ver );
173+
pkg.version = ver;
174+
if ( !debug ) {
175+
fs.writeFileSync( "package.json", JSON.stringify( pkg, null, "\t" ) + "\n" );
176+
}
177+
}
178+
function copy( oldFile, newFile ) {
179+
console.log( "Copying " + oldFile + " to " + newFile );
180+
if ( !debug ) {
181+
fs.writeFileSync( newFile, fs.readFileSync( oldFile, "utf8" ) );
182+
}
183+
}
153184
function exec( cmd, fn ) {
185+
console.log( cmd );
154186
if ( debug ) {
155-
console.log( cmd );
156187
fn();
157-
158188
} else {
159-
child.exec( cmd, fn );
189+
child.exec( cmd, { env: process.env }, function( err, stdout, stderr ) {
190+
if ( err ) {
191+
die( stderr || stdout || err );
192+
}
193+
fn();
194+
});
160195
}
161196
}
162-
163-
function exit( msg ) {
164-
if ( msg ) {
165-
console.error( "\nError: " + msg );
166-
}
167-
197+
function die( msg ) {
198+
console.error( "Error: " + msg );
168199
process.exit( 1 );
169200
}
201+
function exit() {
202+
process.exit( 0 );
203+
}

version.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)