Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Platform Release: Improve patch and dev version support #188

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
978cf05
Fix prepare-platform-release-branch usage
Jul 3, 2018
7b54e27
Prepare CDVAvailability.h after updating JS
Jul 3, 2018
aefb169
Additional output for prepare-platform-release-branch
Jul 3, 2018
0b715dc
WORKAROUND for local grunt issue in cordova-js
Jun 22, 2018
a411022
Updates to improve support for patch releases
Jul 3, 2018
57d32c3
add --tag-only option to tag-release command
Jul 23, 2018
fcf0195
EXTRA GIT WORKAROUND for package.json
Jul 6, 2018
4f42966
Show if version was updated in package.json
Jul 27, 2018
dfc4ec0
platforms-release-process doc updates
Jul 27, 2018
f5b6e2c
skip extra -dev version if not final release
Aug 1, 2018
c440794
prepare-platform-release-branch commit prefix opt
Aug 1, 2018
9d51d1a
remove extra from commit messages
Aug 1, 2018
674ed41
Merge remote-tracking branch 'origin/master' into improve-patch-and-d…
Nov 14, 2018
50bfbd8
Update docs/platforms-release-process.md
May 21, 2019
89d80f8
update comment in src/platform-release.js
May 21, 2019
ab591b7
REVERT changes for iOS for now
May 21, 2019
f58af4f
Add XXX TODO comments to src/platform-release.js
May 21, 2019
a494d16
Merge branch 'master' of github.com:apache/cordova-coho into improve-…
May 21, 2019
0916886
XXX TODO comments for code to update CDVAvailability.h
May 21, 2019
7862dab
XXX TODO comments to raise issues
May 21, 2019
e1fe50a
Merge branch 'master' of github.com:apache/cordova-coho into improve-…
May 21, 2019
89c84f2
npx eslint --fix src
May 21, 2019
05136c5
QUICK SQUASH FIXUP for eb6e72bb - commit prefix opt in src/versionuti…
May 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions docs/platforms-release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,19 @@ Create and prepare your release branch by using `coho prepare-platform-release-b
3. Propagates version number from `--version` argument (or from `package.json` if there is no `--version` argument) to all other files (`VERSION` and similar [e.g. `build.gradle` for Android]) on the release branch `5.0.x`
4. Prepares `master` for future development already: It gives version (`package.json`, `VERSION` and similar) a minor bump and adds `-dev` (=> `5.1.0-dev`) again

Run the following command (make sure to replace the version below with what is listed inside `package.json`).
Run the following command (make sure to replace the version below with what is listed inside `package.json`) in case of release from the `master`:

coho prepare-platform-release-branch --version 5.0.0 -r android
coho prepare-platform-release-branch --version 7.2.0 -r android

or in case of release from another release branch:

coho prepare-platform-release-branch --version 7.1.1 -r android -b 7.1.x

Then ensure commits look okay on both branches

coho repo-status -r android -b master -b 5.0.x
coho repo-status -r android -b master -b 7.1.x

or use git tool to verify manually.
brodycj marked this conversation as resolved.
Show resolved Hide resolved

## Testing

Expand Down Expand Up @@ -346,25 +352,31 @@ Create a JIRA issue for it, and mark it as a blocker.

All good? Have another look at the changes:

coho repo-status -r android -b master -b 5.0.x
coho repo-status -r android -b master -b 7.1.x

If changes look right:

coho repo-push -r android -b master -b 5.0.x

This pushes the commits in both `master` and `5.0.x` (the release branch) to the remote.
This pushes the commits in both `master` and `7.1.x` (the release branch) to the remote.

### Tag and push tag

Before you tag, run this command:

coho tag-platform-release --version 5.0.0 -r android --pretend
coho tag-platform-release --version 7.1.0 -r android --pretend

Seems okay? Then execute it by running:

coho tag-platform-release --version 5.0.0 -r android
coho tag-platform-release --version 7.1.0 -r android

This command also tags `cordova-js` with `android-7.1.0` and pushes it.

To tag without automatic push:
janpio marked this conversation as resolved.
Show resolved Hide resolved

coho tag-platform-release --version 7.1.0 -r android --tag-only

This command also tags `cordova-js` with `android-5.0.0` and pushes it.
and then manually push the new tags.

## Publish Release Candidate to `dist/dev`

Expand Down
4 changes: 4 additions & 0 deletions src/gitutil.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ exports.pendingChangesExist = function * () {
exports.gitCheckout = function * (branchName) {
var curBranch = yield gitutil.retrieveCurrentBranchName(true);
if (curBranch !== branchName) {
// EXTRA WORKAROUND SOLUTION for package.json,
janpio marked this conversation as resolved.
Show resolved Hide resolved
// as needed for cordova-osx & Windows
// FUTURE TBD better solution for package.json?
yield executil.execHelper(executil.ARGS('git checkout -- package.json'));
return yield executil.execHelper(executil.ARGS('git checkout -q ', branchName));
}
};
Expand Down
111 changes: 77 additions & 34 deletions src/platform-release.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function * updateCDVAvailabilityFile (version) {
fs.writeFileSync(iosFile, iosFileContents.join('\n'));
}

function * updateJsSnapshot (repo, version, commit) {
function * updateJsSnapshot (repo, version, commit, branch, commitPrefixOrUndefined) {
function * ensureJsIsBuilt () {
var cordovaJsRepo = repoutil.getRepoById('js');
if (repo.id === 'blackberry') {
Expand All @@ -139,10 +139,19 @@ function * updateJsSnapshot (repo, version, commit) {
if (hasBuiltJs !== version) {
yield repoutil.forEachRepo([cordovaJsRepo], function * () {
yield gitutil.stashAndPop(cordovaJsRepo, function * () {
// git fetch and update master for cordovajs
yield repoupdate.updateRepos([cordovaJsRepo], ['master'], false);
yield gitutil.gitCheckout('master');
// git fetch and update master (or fetch other branch) for cordova-js
if (branch === 'master') {
yield repoupdate.updateRepos([cordovaJsRepo], [branch], false);
}
// EXTRA WORKAROUND SOLUTION for package.json,
// as needed for cordova-osx & Windows
// FUTURE TBD better solution for package.json?
yield executil.execHelper(executil.ARGS('git checkout -- package.json'));
yield executil.execHelper(executil.ARGS('git checkout -q ' + branch));
yield gitutil.gitCheckout(branch);
yield executil.execHelper(executil.ARGS('npm install'), false, true); // WORKAROUND PART 1 for local grunt issue in cordova-js
yield executil.execHelper(executil.ARGS('grunt compile:' + repo.id + ' --platformVersion=' + version), false, true);
shelljs.rm('-fr', 'node_modules'); // WORKAROUND PART 2 for local grunt issue in cordova-js
janpio marked this conversation as resolved.
Show resolved Hide resolved
hasBuiltJs = version;
});
});
Expand All @@ -161,7 +170,8 @@ function * updateJsSnapshot (repo, version, commit) {
});
if (commit === true) {
if (yield gitutil.pendingChangesExist()) {
yield executil.execHelper(executil.ARGS('git commit -am', 'Update JS snapshot to version ' + version + ' (via coho)'));
var pre = !!commitPrefixOrUndefined ? commitPrefixOrUndefined : '';
yield executil.execHelper(executil.ARGS('git commit -am', pre + 'Update JS to version ' + version + ' (via coho)'));
}
}
} else if (repoutil.repoGroups.all.indexOf(repo) !== -1) {
Expand All @@ -175,13 +185,16 @@ exports.createAndCopyCordovaJSCommand = function * () {
' 1. Generates a new cordova.js.\n' +
' 2. Replaces platform\'s cordova.js file.\n' +
'\n' +
'Usage: $0 copy-js -r platform')
'Usage: $0 copy-js -r platform [--js <cordova-js branch or tag name>]')
);

var repos = flagutil.computeReposFromFlag(argv.r);

var jsBranchName = argv.js ? argv.js : 'master';

yield repoutil.forEachRepo(repos, function * (repo) {
var version = yield handleVersion(repo, argv.version, false);
yield updateJsSnapshot(repo, version, false);
yield updateJsSnapshot(repo, version, false, jsBranchName);
});
};

Expand All @@ -197,64 +210,87 @@ exports.prepareReleaseBranchCommand = function * () {
'Command can also be used to update the JS snapshot after release \n' +
'branches have been created.\n' +
'\n' +
'Usage: $0 prepare-release-branch -r platform [--version=3.6.0]')
'Usage: $0 prepare-platform-release-branch -r platform [--version=3.6.0] [-b <platform branch name>] [--js <cordova-js branch or tag name>] [--pre <COMMIT-PREFIX (with space at the end if needed)>')
);

var repos = flagutil.computeReposFromFlag(argv.r);

// XXX TBD ???:
janpio marked this conversation as resolved.
Show resolved Hide resolved
var branchName = null;

var isOtherRepoBranch = !!argv.b;
var repoBranchName = isOtherRepoBranch ? argv.b : 'master';
var jsBranchName = argv.js ? argv.js : 'master';
var pre = argv.pre ? argv.pre : '';

// First - perform precondition checks.
yield repoupdate.updateRepos(repos, [], true);

yield repoutil.forEachRepo(repos, function * (repo) {
var platform = repo.id;
var version = yield handleVersion(repo, argv.version, true);
var branchName = versionutil.getReleaseBranchNameFromVersion(version);
var releaseBranchName = isOtherRepoBranch ? repoBranchName :
versionutil.getReleaseBranchNameFromVersion(version);

yield gitutil.stashAndPop(repo, function * () {
// git fetch + update master
yield repoupdate.updateRepos([repo], ['master'], false);
if (platform === 'ios') {
// Updates version in CDVAvailability.h file
yield updateCDVAvailabilityFile(version);
// Git commit changes
if (yield gitutil.pendingChangesExist()) {
yield executil.execHelper(executil.ARGS('git commit -am', 'Added ' + version + ' to CDVAvailability.h (via coho).'));
}
}
yield repoupdate.updateRepos([repo], [repoBranchName], false);

// Either create or pull down the branch.
if (yield gitutil.remoteBranchExists(repo, branchName)) {
if (yield gitutil.remoteBranchExists(repo, releaseBranchName)) {
print('Remote branch already exists for repo: ' + repo.repoName);
// Check out and rebase.
yield repoupdate.updateRepos([repo], [branchName], true);
yield gitutil.gitCheckout(branchName);
} else if (yield gitutil.localBranchExists(branchName)) {
yield executil.execHelper(executil.ARGS('git checkout ' + branchName));
yield repoupdate.updateRepos([repo], [releaseBranchName], true);
yield gitutil.gitCheckout(releaseBranchName);
} else if (yield gitutil.localBranchExists(releaseBranchName)) {
yield executil.execHelper(executil.ARGS('git checkout ' + releaseBranchName));
} else if (isOtherRepoBranch) {
yield executil.execHelper(executil.ARGS('git checkout ' + repoBranchName));
} else {
yield gitutil.gitCheckout('master');
yield executil.execHelper(executil.ARGS('git checkout -b ' + branchName));
yield executil.execHelper(executil.ARGS('git checkout -b ' + releaseBranchName));
}

yield updateJsSnapshot(repo, version, true);
print(repo.repoName + ': Setting VERSION to "' + version + '" on branch "' + branchName + '".');
yield versionutil.updateRepoVersion(repo, version);
yield updateJsSnapshot(repo, version, true, jsBranchName, pre);

if (platform === 'ios' && /\d$/.test(version)) {
// Updates version in CDVAvailability.h file
yield updateCDVAvailabilityFile(version);
// Git commit changes
if (yield gitutil.pendingChangesExist()) {
yield executil.execHelper(executil.ARGS('git commit -am', pre + 'Add ' + version + ' to CDVAvailability.h (via coho).'));
}
}

print(repo.repoName + ': Setting VERSION to "' + version + '" on branch "' + releaseBranchName + '".');
yield versionutil.updateRepoVersion(repo, version, {commitChanges:true, pre:pre});

// skip remaining steps for this repo if other repo branch was specified:
if (isOtherRepoBranch) return;

// or skip remaining steps if not a final release version:
if (version.indexOf('-') !== -1) return;

yield gitutil.gitCheckout('master');
var devVersion = createPlatformDevVersion(version);
print(repo.repoName + ': Setting VERSION to "' + devVersion + '" on branch "master".');
yield versionutil.updateRepoVersion(repo, devVersion);
yield updateJsSnapshot(repo, devVersion, true);
yield gitutil.gitCheckout(branchName);
yield versionutil.updateRepoVersion(repo, devVersion, {commitChanges:true, pre:pre});
yield updateJsSnapshot(repo, devVersion, true, jsBranchName);
yield gitutil.gitCheckout(releaseBranchName);
});
});
executil.reportGitPushResult(repos, ['master', branchName]);

// XXX TBD ???:
executil.reportGitPushResult(repos, [repoBranchName, branchName]);
};

function * tagJs (repo, version, pretend) {
function * tagJs (repo, version, pretend, tagOnly) {

function * execOrPretend (cmd) {
if (pretend) {
print('PRETENDING TO RUN: ' + cmd.join(' '));
} else if (tagOnly && cmd[1] === 'push') {
print('SKIP: ' + cmd.join(' '));
} else {
yield executil.execHelper(cmd);
}
Expand All @@ -281,23 +317,30 @@ exports.tagReleaseBranchCommand = function * (argv) {
var argv = configureReleaseCommandFlags(optimist // eslint-disable-line
.usage('Tags a release branches.\n' +
'\n' +
'Usage: $0 tag-release --version=2.8.0-rc1 -r platform')
'Usage: $0 tag-release --version=2.8.0-rc1 -r platform [--pretend] [--tag-only]')
.options('pretend', {
desc: 'Don\'t actually run git commands, just print out what would be run.',
type: 'boolean'
})
.options('tag-only', {
desc: 'Don\'t actually push to origin, just print out what would be pushed.',
type: 'boolean'
})
);
var repos = flagutil.computeReposFromFlag(argv.r);
var version = flagutil.validateVersionString(argv.version);
var pretend = argv.pretend;
var branchName = versionutil.getReleaseBranchNameFromVersion(version);
var tagOnly = argv['tag-only'];

// First - perform precondition checks.
yield repoupdate.updateRepos(repos, [], true);

function * execOrPretend (cmd) {
if (pretend) {
print('PRETENDING TO RUN: ' + cmd.join(' '));
} else if (tagOnly && cmd[1] === 'push') {
print('SKIP: ' + cmd.join(' '));
} else {
yield executil.execHelper(cmd);
}
Expand Down Expand Up @@ -329,7 +372,7 @@ exports.tagReleaseBranchCommand = function * (argv) {
} else {
print('Repo ' + repo.repoName + ' is already tagged.');
}
yield tagJs(repo, version, pretend);
yield tagJs(repo, version, pretend, tagOnly);

});
});
Expand Down
10 changes: 8 additions & 2 deletions src/versionutil.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ exports.getReleaseBranchNameFromVersion = function (version) {
* @param {Object} [opts] An options object
* @param {Boolean} [opts.commitChanges=true] Specifies whether to commit changes
* to the repo after update is done.
* @param {String} [opts.pre=''] Optional commit prefix
*/
exports.updateRepoVersion = function * updateRepoVersion (repo, version, opts) {
// Update the VERSION files.
Expand Down Expand Up @@ -130,13 +131,15 @@ exports.updateRepoVersion = function * updateRepoVersion (repo, version, opts) {

// Update the package.json VERSION.
var packageFilePaths = repo.packageFilePaths || ['package.json'];
var pendingChangesExistInJSON = false;
if (fs.existsSync(packageFilePaths[0])) {
var data = fs.readFileSync(packageFilePaths[0], {encoding: 'utf-8'});
var packageJSON = JSON.parse(data);
packageJSON.version = version;
// use 2 spaces indent similar to npm
fs.writeFileSync(packageFilePaths[0], JSON.stringify(packageJSON, null, 2) + '\n');
if (!(yield gitutil.pendingChangesExist())) {
pendingChangesExistInJSON = yield gitutil.pendingChangesExist();
if (!pendingChangesExistInJSON) {
apputil.print('package.json file was already up-to-date.');
}
} else {
Expand Down Expand Up @@ -166,6 +169,9 @@ exports.updateRepoVersion = function * updateRepoVersion (repo, version, opts) {

var commitChanges = !!(opts ? opts.commitChanges : true);
if (commitChanges && (yield gitutil.pendingChangesExist())) {
yield gitutil.commitChanges('Set VERSION to ' + version + ' (via coho)');
var versionDescription = pendingChangesExistInJSON ?
'version & VERSION' : 'VERSION';
var pre = opts.pre || '';
yield gitutil.commitChanges(pre + 'Set ' + versionDescription + ' to ' + version + ' (coho)');
}
};