-
Notifications
You must be signed in to change notification settings - Fork 780
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Docs: Automate more of the release process
- Loading branch information
Showing
6 changed files
with
184 additions
and
202 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,106 +15,84 @@ QUnit aims for its releases to be reproducible. Recent releases are automaticall | |
> | ||
> System prerequisites: | ||
> | ||
> * Node.js 12, or later. | ||
> * Node.js 14, or later. | ||
> * Git 2.11, or later. | ||
1. Ensure that all changes for this release have been merged into the main branch. For patch releases, try landing any other bug fixes; for minor releases, ensure new features have been documented and tested. Major releases likely have their own checklist. | ||
Ensure that all changes for this release have been merged into the main branch. For patch releases, try landing any other bug fixes; for minor releases, ensure new features have been documented and tested. Major releases likely have their own checklist. | ||
|
||
2. Create a local `release` branch, and ensure it is up-to-date: | ||
* Verify that the canonical repository is cloned (not a fork): | ||
1. Create a local `release` branch, and ensure it is up-to-date: | ||
Verify that the canonical repository is cloned (not a fork): | ||
``` | ||
git remote -v | ||
# … | ||
# origin [email protected]:qunitjs/qunit.git | ||
``` | ||
* Create or reset the `release` branch: | ||
Create or reset the `release` branch: | ||
``` | ||
git remote update && git checkout -B release -t origin/main | ||
``` | ||
|
||
3. Install dev dependencies and run the tests: | ||
2. Install dev dependencies: | ||
``` | ||
npm ci && npm test | ||
npm ci | ||
``` | ||
Run the tests in various real browsers, either locally or via [BrowserStack](https://www.browserstack.com/): | ||
``` | ||
python3 -m http.server 4000 | ||
# or: | ||
# php -S localhost:4000 | ||
|
||
open http://localhost:4000/test/ | ||
3. Create the release preparation commit: | ||
``` | ||
node build/prep-release.js @VERSION | ||
``` | ||
|
||
4. Create and push the release preparation commit: | ||
* Use `git add -p` to review the changes. | ||
* In `AUTHORS.txt`, if you see duplicate entries, then use the `.mailmap` file to normalize them to a canonical name and e-mail address, and then re-run the above command. | ||
* Edit `History.md` to remove changes not relevant to end-users (e.g. changes relating to tests, build, internal refactoring, doc fixes, etc.). | ||
|
||
Commit your changes with the following message (replace `@VERSION` with the release version): | ||
``` | ||
Build: Prepare @VERSION release | ||
``` | ||
|
||
1. Update the package.json and AUTHORS.txt files, by running the below command (replace `@VERSION` with the release version): | ||
``` | ||
node build/prep-release.js @VERSION | ||
``` | ||
* Use `git add -p` to review the changes. | ||
* In `AUTHORS.txt`, if you see duplicate entries, then use the `.mailmap` file to normalize them to a canonical name and e-mail address, and then re-run the above command. | ||
* Edit `History.md` to remove change not relevant to end-users (e.g. changes relating to tests, build, internal refactoring, doc fixes, etc.). | ||
2. Commit the above changes with the following message (replace `@VERSION` with the release version): | ||
``` | ||
Build: Prepare @VERSION release | ||
``` | ||
3. Push the `release` branch to GitHub. | ||
4. Create a pull request, and merge it once CI is passing. | ||
Push the `release` branch to GitHub. | ||
Once CI is passing, push again, this time to the (protected) `main` branch. | ||
|
||
## Performing the release | ||
|
||
5. Create a local `release` branch, and ensure it is up-to-date: | ||
* Run `git remote -v` and verify the following: | ||
``` | ||
origin [email protected]:qunitjs/qunit.git | ||
``` | ||
* Create or reset the `release` branch: | ||
``` | ||
git remote update && git checkout -B release -t origin/main | ||
``` | ||
* Verify that the latest commit is your release preparation commit: | ||
``` | ||
git show | ||
# Build: Prepare x.y.z release | ||
# … | ||
``` | ||
Verify that your local repo is at the release preparation commit: | ||
|
||
6. Make changes for the release commit: | ||
* Set the release version for npm and Bower metadata (replace `@VERSION` with the release version): | ||
``` | ||
node build/set-release.js @VERSION | ||
``` | ||
This script will edit `package.json` and `bower.json`. It does not need any credentials or permissions, apart from read-write in the project directory. | ||
``` | ||
git show | ||
# Build: Prepare x.y.z release | ||
# … | ||
``` | ||
|
||
* Generate the release artifacts: | ||
4. Build the release: | ||
``` | ||
npm run build | ||
node build/build-release.js @VERSION | ||
``` | ||
This script does not need any credentials or permissions, and may be run in a container that can only read-write the current directory. It will edit `package.json` and `bower.json`, and then execute `npm run build` to generate the release artifacts. | ||
|
||
* Review the changes to the package and library files, compared to the previous release. | ||
Review the changes to the package, compared to the previous release. | ||
``` | ||
node build/review-package.js @LAST_VERSION | ||
# … reviews package.json, qunit.js, and qunit.css | ||
``` | ||
|
||
7. Commit and publish the release to GitHub.<br>⚠️ Do not push to the main branch! | ||
5. Publish to GitHub.<br>⚠️ Do not push to the main branch! | ||
``` | ||
git add -f package.json bower.json qunit/ | ||
git commit -m "Release @VERSION" | ||
git tag -s "@VERSION" -m "Release @VERSION" | ||
git push --tags | ||
``` | ||
|
||
8. Verify that Bower sees the release, by running `npx bower info qunit` and checking that the latest | ||
version is indeed the version we just published. | ||
|
||
9. Publish the release to npm: | ||
* Use `git status` to confirm once more that you have a clean working copy, apart from release artifacts in `qunit/`. | ||
* Run `npm publish`, this will bundle the current directory and publish it to npm with the name and version specified in `package.json`. | ||
* Verify that the release is displayed at <https://www.npmjs.com/package/qunit>. | ||
6. Publish to npm: | ||
``` | ||
npm publish | ||
```` | ||
This will bundle the current directory and publish it to npm with the name and version specified in `package.json`. | ||
Verify that the release is displayed at <https://www.npmjs.com/package/qunit>. | ||
|
||
10. Publish the release to the jQuery CDN: | ||
7. Publish to the jQuery CDN: | ||
* Prepare the commit locally: | ||
``` | ||
node build/auth-cdn-commit.js real @VERSION | ||
|
@@ -124,7 +102,6 @@ QUnit aims for its releases to be reproducible. Recent releases are automaticall | |
``` | ||
cd __codeorigin | ||
git show | ||
# … | ||
git push | ||
``` | ||
* Verify that the release is listed at <https://code.jquery.com/qunit/> and accessible via <https://code.jquery.com/qunit/qunit-x.y.z.js> | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
// Helper to set the QUnit release version in various places, | ||
// and prepare a local commit in a codeorigin.git clone. | ||
// | ||
// To test the local commit step, with an alternate remote | ||
// pass "test" as the second argument. | ||
// | ||
// See also RELEASE.md. | ||
// | ||
// Inspired by <https://github.com/jquery/jquery-release>. | ||
|
||
const cp = require('child_process'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
|
||
const cdnRemotes = { | ||
anonymous: 'https://github.com/jquery/codeorigin.jquery.com.git', | ||
auth: '[email protected]:jquery/codeorigin.jquery.com.git' | ||
}; | ||
const cdnFiles = { | ||
'qunit/qunit.js': 'cdn/qunit/[email protected]', | ||
'qunit/qunit.css': 'cdn/qunit/[email protected]' | ||
}; | ||
const cdnCommitMessage = 'qunit: Added version @VERSION'; | ||
|
||
const Repo = { | ||
buildFiles (version) { | ||
if (typeof version !== 'string' || !/^\d+\.\d+\.\d+$/.test(version)) { | ||
throw new Error('Invalid or missing version argument'); | ||
} | ||
{ | ||
const file = 'bower.json'; | ||
console.log(`Updating ${file}...`); | ||
const filePath = path.join(__dirname, '..', file); | ||
const json = fs.readFileSync(filePath, 'utf8'); | ||
const packageIndentation = json.match(/\n([\t\s]+)/)[1]; | ||
const data = JSON.parse(json); | ||
|
||
data.version = version; | ||
|
||
fs.writeFileSync( | ||
filePath, | ||
JSON.stringify(data, null, packageIndentation) + '\n' | ||
); | ||
} | ||
{ | ||
const file = 'package.json'; | ||
console.log(`Updating ${file}...`); | ||
const filePath = path.join(__dirname, '..', file); | ||
const json = fs.readFileSync(filePath, 'utf8'); | ||
const packageIndentation = json.match(/\n([\t\s]+)/)[1]; | ||
const data = JSON.parse(json); | ||
|
||
data.version = version; | ||
data.author.url = data.author.url.replace('main', version); | ||
|
||
fs.writeFileSync( | ||
filePath, | ||
JSON.stringify(data, null, packageIndentation) + '\n' | ||
); | ||
} | ||
{ | ||
console.log('Running `npm run build`...'); | ||
cp.execFileSync('npm', [ | ||
'run', | ||
'build' | ||
], { encoding: 'utf8' }); | ||
} | ||
}, | ||
cdnClone (repoPath) { | ||
const remote = cdnRemotes.anonymous; | ||
console.log('... cloning ' + remote); | ||
if (fs.existsSync(repoPath)) { | ||
fs.rmdirSync(repoPath, { recursive: true }); | ||
} | ||
cp.execFileSync('git', [ | ||
'clone', | ||
'--depth=5', | ||
'-q', | ||
remote, | ||
repoPath | ||
]); | ||
}, | ||
cdnCommit (version) { | ||
if (!version) { | ||
throw new Error('Missing parameters'); | ||
} | ||
const repoPath = path.join(__dirname, '..', '__codeorigin'); | ||
Repo.cdnClone(repoPath); | ||
|
||
const toCommit = []; | ||
for (const src in cdnFiles) { | ||
const srcPath = path.join(__dirname, '..', src); | ||
const dest = cdnFiles[src].replace('@VERSION', version); | ||
const destPath = path.join(repoPath, dest); | ||
console.log('... copying ' + src + ' to ' + dest); | ||
fs.copyFileSync(srcPath, destPath, fs.constants.COPYFILE_EXCL); | ||
toCommit.push(dest); | ||
} | ||
|
||
console.log('... creating commit'); | ||
|
||
const author = cp.execSync('git log -1 --format=%aN%n%aE', | ||
{ encoding: 'utf8', cwd: path.join(__dirname, '..') } | ||
) | ||
.trim() | ||
.split('\n'); | ||
|
||
cp.execFileSync('git', ['add', ...toCommit], | ||
{ cwd: repoPath } | ||
); | ||
|
||
cp.execFileSync('git', | ||
['commit', '-m', cdnCommitMessage.replace('@VERSION', version)], | ||
{ | ||
cwd: repoPath, | ||
env: { | ||
GIT_AUTHOR_NAME: author[0], | ||
GIT_AUTHOR_EMAIL: author[1], | ||
GIT_COMMITTER_NAME: author[0], | ||
GIT_COMMITTER_EMAIL: author[1] | ||
} | ||
} | ||
); | ||
|
||
// prepre for user to push from the host shell after review | ||
cp.execFileSync('git', ['remote', 'set-url', 'origin', cdnRemotes.auth], | ||
{ cwd: repoPath } | ||
); | ||
} | ||
}; | ||
|
||
const [version, remote] = process.argv.slice(2); | ||
|
||
try { | ||
Repo.buildFiles(version); | ||
Repo.cdnCommit(version, remote || 'real'); | ||
} catch (e) { | ||
if (e.stderr) { | ||
e.stdout = e.stdout.toString(); | ||
e.stderr = e.stderr.toString(); | ||
} | ||
console.error(e); | ||
process.exit(1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.