Skip to content

Commit 2ea74b3

Browse files
committed
Initial commit.
0 parents  commit 2ea74b3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+4482
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/grunt
2+
node_modules/grunt-contrib-jshint

.jshintrc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"boss": true,
3+
"curly": true,
4+
"eqeqeq": true,
5+
"eqnull": true,
6+
"expr": true,
7+
"immed": true,
8+
"noarg": true,
9+
"onevar": true,
10+
"quotmark": "double",
11+
"smarttabs": true,
12+
"trailing": true,
13+
"undef": true,
14+
"unused": true,
15+
16+
"node": true
17+
}

Gruntfile.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = function( grunt ) {
2+
3+
grunt.loadNpmTasks( "grunt-contrib-jshint" );
4+
5+
grunt.initConfig({
6+
jshint: {
7+
options: {
8+
jshintrc: true
9+
},
10+
all: [ "release.js", "lib/*.js" ]
11+
}
12+
});
13+
14+
grunt.registerTask( "default", [ "jshint" ] );
15+
16+
};

README.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# jQuery Project Release Automation
2+
3+
This script automates releases for all jQuery projects. It is designed to create
4+
consistency between projects and reduce the burden of maintaining individual
5+
release scripts.
6+
7+
## Creating a Release
8+
9+
Creating a release is as simple as cloning this repository and telling the
10+
script which project to use. In order to ensure a clean and proper release is
11+
created, you should always start from a new clone of this repository.
12+
13+
```sh
14+
git clone git@github.com:jquery/jquery-release.git
15+
cd jquery-release
16+
node jquery-release.js --remote=jquery/<project-name>
17+
```
18+
19+
### Testing the Release Script
20+
21+
You can do a test run of the release script by using a different remote
22+
repository. The script is smart enough to detect if you're using an
23+
official repository and adjust which actions are taken so that undesired
24+
actions, such as publishing to npm, don't occur for test runs.
25+
26+
### Full Usage Options
27+
28+
See the [usage documenation](/docs/usage.txt) for the full set of options.
29+
You can also run the script with no parameters to see the usage.
30+
31+
32+
33+
## Creating a Project-Specific Release Script
34+
35+
This script only performs the set of common functionality across all projects.
36+
Each project may have additional functionality. Any project-specific
37+
configuration and functionality must be defined in the `build/release.js` file
38+
inside the project's repository.
39+
40+
Here's a minimal example:
41+
42+
```js
43+
module.exports = function( Release ) {
44+
45+
Release.define({
46+
issueTracker: "trac",
47+
contributorReportId: 37,
48+
changelogShell: function() {
49+
return "# Amazing Changelog for v" + Release.newVersion + "\n";
50+
}
51+
});
52+
53+
};
54+
```
55+
56+
### Required/Recommended Configuration
57+
58+
#### checkRepoState()
59+
60+
Performs any project-specific checks to ensure the repository is in a good state
61+
to be released. For example, there is a built-in check to ensure that
62+
AUTHORS.txt is up-to-date.
63+
64+
This method has no return value. If a project-specific check fails, the script
65+
should use `Release.abort()` to prevent the release from continuing.
66+
67+
#### generateArtifacts( callback )
68+
69+
Generates any release artifacts that should be included in the release. The
70+
callback must be invoked with an array of files that should be committed before
71+
creating the tag.
72+
73+
#### changelogShell()
74+
75+
Defines the shell for the changelog. The changelog is created by concatenating
76+
the shell, the commit log, and the issue list.
77+
78+
#### issueTracker
79+
80+
Which type of issue tracker is being used for the project. Must be either
81+
`"trac"` or `"github"`.
82+
83+
#### contributorReportId
84+
85+
If using Trac, this defines which report will produce a list of contributors
86+
for a specific release.
87+
88+
See [docs/track-contributors.sql](docs/track-contributors.sql) for the SQL
89+
necessary to create the Trac report.
90+
91+
### Other Methods
92+
93+
#### define( props )
94+
95+
Defines new properties and methods to add to the `Release` object.
96+
97+
#### abort( msg )
98+
99+
Aborts the release and prints the message.
100+
101+
#### exec( command, options )
102+
103+
Executes the given `command`. You can pass `{ silent: true }` to suppress output
104+
on the command line.
105+
106+
Returns the output.
107+
108+
#### git( command, errorMessage )
109+
110+
Executes the given git `command`. If the command fails, the release will be
111+
aborted and `errorMessage` will be displayed.
112+
113+
#### gitLog( format )
114+
115+
Gets a git log using the specified format. If the log fails, the release will be
116+
aborted.
117+
118+
Returns an array of commits.
119+
120+
#### prompt( callback )
121+
122+
Prompts the user for input.
123+
124+
Passes the input to `callback`.
125+
126+
#### confirm( callback )
127+
128+
Prompts the user to confirm they want to continue with the release script. If
129+
the user decides not to continue, the release will be aborted and `callback`
130+
won't be invoked.
131+
132+
#### confirmReview( callback )
133+
134+
Prompts the user to review the output and confirm they want to continue with the
135+
release script. If the user decides not to continue, the release will be aborted
136+
and `callback` won't be invoked.
137+
138+
#### trac( path )
139+
140+
Gets the results of a Trac query, with tab-delimited results.
141+
142+
Returns the tab-delimited string.
143+
144+
#### readPackage()
145+
146+
Gets the contents of `package.json` as an object.
147+
148+
#### writePackage( package )
149+
150+
Saves `package` to `package.json`, preserving indentation style.
151+
152+
### Other Properties
153+
154+
#### isTest
155+
156+
Whether this is a test release.
157+
158+
#### project
159+
160+
The name of the project being released.
161+
162+
#### remote
163+
164+
The location of the remote repository.
165+
166+
#### preRelease
167+
168+
The version number for a pre-release version, or `false` for stable releases.
169+
170+
#### dir.base
171+
172+
The main directory used for the release script.
173+
174+
#### dir.repo
175+
176+
The directory for the local repository.
177+
178+
#### newVersion
179+
180+
The version being released.
181+
182+
#### prevVersion
183+
184+
The previous release version (used for determining what changed).
185+
186+
#### nextVersion
187+
188+
The version that will be set in `package.json` after the release.
189+
190+
#### tagTime
191+
192+
Timestamp for the release tag.
193+
194+
#### branch
195+
196+
Which branch the release is being generated from.

docs/trac-contributors.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(SELECT DISTINCT `reporter` AS `contributor`
2+
FROM `ticket`
3+
WHERE `resolution` = "fixed"
4+
AND `milestone` = $V)
5+
UNION
6+
(SELECT DISTINCT `author`
7+
FROM `ticket_change`
8+
WHERE `ticket` IN (
9+
SELECT `id`
10+
FROM `ticket`
11+
WHERE `resolution` = "fixed"
12+
AND `milestone` = $V))
13+
ORDER BY CAST(`contributor` AS CHAR)

docs/usage.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Usage: node release.js [--pre-release=version] [--branch=branch] --remote=repo
2+
3+
OPTIONS
4+
--pre-release=version
5+
Creates a pre-release instead of a stable release. Since the
6+
version number can't be determined automatically, it must be
7+
provided, and must be a valid semver.
8+
9+
--branch=branch
10+
Specifies which branch to create the release from.
11+
Defaults to master.
12+
13+
--remote=repo
14+
Specifies the remote repository to work with. There are three
15+
ways to specify the remote:
16+
17+
- GitHub Repository (user/repo)
18+
- File System (/path/to/repo)
19+
- URL (http://mydomain/repo.git)
20+
21+
Regardless of which method is used to specify the remote, the
22+
part after the last slash must match the repo name on GitHub.
23+
24+
TEST RELEASES
25+
To test the release process without affecting any official
26+
repositories, specificy a custom remote, such as your own fork of
27+
the repository.

lib/bootstrap.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
var fs = require( "fs" ),
2+
path = require( "path" );
3+
4+
module.exports = function( Release ) {
5+
6+
Release.define({
7+
isTest: true,
8+
9+
_showUsage: function() {
10+
console.log( fs.readFileSync( path.resolve( __dirname, "../docs/usage.txt" ), "utf8" ) );
11+
},
12+
13+
_parseArguments: function() {
14+
Release.args = {};
15+
16+
process.argv.forEach(function( arg ) {
17+
var name, value,
18+
matches = /--([^=]+)(=(.+))?/.exec( arg );
19+
20+
if ( matches ) {
21+
name = matches[ 1 ].replace( /-([a-z])/gi, function( all, letter ) {
22+
return letter.toUpperCase();
23+
});
24+
value = matches[ 3 ] || true;
25+
Release.args[ name ] = value;
26+
}
27+
});
28+
29+
Release._parseRemote();
30+
Release.branch = Release.args.branch || "master";
31+
Release.preRelease = Release.args.preRelease || false;
32+
33+
console.log();
34+
console.log( "\tProject: " + Release.project );
35+
console.log( "\tRelease type: " + (Release.preRelease ? "pre-release" : "stable") );
36+
console.log( "\tRemote: " + Release.remote );
37+
console.log( "\tBranch: " + Release.branch );
38+
console.log();
39+
40+
if ( Release.isTest ) {
41+
console.log( "This is a test release. npm will not be updated." );
42+
} else {
43+
console.log( "This is a real release. GitHub and npm will be updated." );
44+
}
45+
},
46+
47+
_parseRemote: function() {
48+
var remote = Release.args.remote;
49+
50+
if ( !remote ) {
51+
console.log( "Missing required remote repo." );
52+
console.log();
53+
Release._showUsage();
54+
process.exit( 1 );
55+
}
56+
57+
// URL
58+
if ( /:\/\//.test( remote ) ) {
59+
Release.project = remote.replace( /.+\/([^\/]+)\.git/, "$1" );
60+
61+
// filesystem or GitHub
62+
} else {
63+
Release.project = remote.split( "/" ).pop();
64+
65+
// If it's not a local path, it must be a GitHub repo
66+
if ( !fs.existsSync( remote ) ) {
67+
Release.isTest = !/^jquery\//.test( remote );
68+
remote = "git@github.com:" + remote + ".git";
69+
}
70+
}
71+
72+
Release.remote = remote;
73+
},
74+
75+
_createReleaseDirectory: function() {
76+
console.log( "Determining directories..." );
77+
Release.dir = { base: process.cwd() + "/__release" };
78+
Release.dir.repo = Release.dir.base + "/repo";
79+
80+
if ( fs.existsSync( Release.dir.base ) ) {
81+
console.log( "The directory '" + Release.dir.base + "' already exists." );
82+
console.log( "Aborting." );
83+
process.exit( 1 );
84+
}
85+
86+
console.log( "Creating directory..." );
87+
fs.mkdirSync( Release.dir.base );
88+
}
89+
});
90+
91+
};

0 commit comments

Comments
 (0)