Release Process for ‘‘Core Plugins’’

Before cutting any releases, read the Apache's Releases Policy

If you have not done so already, create a GPG key (see: setting-up-gpg.md).

Core Plugins are released at most weekly (see: versioning-and-release-strategy.md).

A plugins release is performed by a single person each week. We call this person the “Release Manager”. How to select the Release Manager is still TDB.

TODO: We may want to be using signed tags, or at least annotated tags.

TODO: Add step about ensuring plugman owner

TODO: Add step about releasing cordova-plugins

TODO: Should not mention testing other than checking medic

Interactive Plugins Release

Though we are still working out some kinks, it is recommended to try the new coho interactive plugins release command which will handle many of the manual steps listed below.

coho prepare-plugins-release

This will do the following:

  • Create JIRA issue
  • Update repos
  • Let you select which repos to release
  • Let you modify release notes and finalize version to release
  • Branch, tag and push up to master
  • Increment version on master with -dev
  • Create svn dist archives for you to share with the cordova list for voting purposes.

Manual

Try to the interactive plugins release process. If you struggle with, use the manual process which is documented below.

Get Buy-in

  1. Email the dev mailing-list and see if anyone has reason to postpone the release.
  • Subject should be "[DISCUSS] Plugins release
  • If so, agree upon a branching date / time.

Create JIRA issues

  • Create a JIRA issue to track the status of the release.

  • Comments should be added to this bug after each top-level step below is taken

  • Set an environment variable in your terminal for use later on:

    JIRA=“CB-????” # Set this to the release bug.

Make sure you're up-to-date

# Update your repos
coho repo-status -r plugins -b master
coho repo-update -r plugins
coho repo-clone -r plugins
coho foreach -r plugins "git checkout master"

Identify which plugins have changes

ACTIVE=$(for l in cordova-plugin-*; do ( cd $l; last_release=$(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD); git log --pretty=format:'* %s' --topo-order --no-merges $last_release..master | grep -v "Incremented plugin version" > /dev/null && echo $l); done | xargs echo)
echo $ACTIVE

If you don't want to release all plugins, but you have specific plugins you want to release, you need to set ACTIVE equal to them.

ACTIVE="cordova-plugin-camera cordova-plugin-contacts cordova-plugin-device-motion"
echo $ACTIVE

Ensure license headers are present everywhere:

coho audit-license-headers -r active-plugins | less
# Tip: Skim by searching for "Unknown Licenses"

For reference, see this background

Ensure all dependencies and subdependencies have Apache-compatible licenses

coho check-license -r active-plugins

Update RELEASENOTES.md & Version

Remove the ‘‘-dev’’ suffix on the version in plugin.xml.

for l in $ACTIVE; do ( cd $l; v="$(grep version= plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; v2="${v%-dev}"; if [ "$v" != "$v2" ]; then echo "$l: Setting version in plugin.xml to $v2"; sed -i '' -E s:"version=\"$v\":version=\"$v2\":" plugin.xml; fi) ; done

Remove the ‘‘-dev’’ suffix on the version in package.json.

for l in $ACTIVE; do ( cd $l; v="$(grep -m 1 '"version"' package.json | cut -d'"' -f4)"; if [[ $v = *-dev ]]; then v2="${v%-dev}"; echo "$l: Setting version in package.json to $v2"; sed -i '' -E '1,/version":.*/s/version":.*/version": "'$v2'",/' package.json; fi) ; done

If the changes merit it, manually bump the major / minor version instead of the micro. Manual process, but list the changes via:

for l in $ACTIVE; do ( cd $l; echo $l; last_release=$(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD); git log --pretty=format:'* %s' --topo-order --no-merges $last_release..master | grep -v "Incremented plugin version" ); done

For each of the plugins that have a test project inside it, update the version number there (cordova-plugin-*/tests/plugin.xml) to match the version of the plugin itself (cordova-plugin-*/plugin.xml).

for l in $ACTIVE; do ( cd $l; v="$(grep version= plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; vt="$(grep version= tests/plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; if [ "$v" != "$vt" ]; then echo "$l: Setting version to $v"; sed -i '' -E s:"version=\"$vt\":version=\"$v\":" tests/plugin.xml; fi); done

Update its RELEASENOTES.md file with changes.

for l in $ACTIVE; do (coho update-release-notes -r $l); done
# Then curate:
vim ${ACTIVE// //RELEASENOTES.md }/RELEASENOTES.md

Commit these changes together (plugin.xml, RELEASENOTES.md, tests/plugin.xml)

for l in $ACTIVE; do ( cd $l; v="$(grep version= plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; git commit -am "$JIRA Updated version and RELEASENOTES.md for release $v"); done

Reply to the DISCUSS thread with a link to the updated release notes.

Tag

for l in $ACTIVE; do ( cd $l; v="$(grep version= plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; echo "Tagging $l to $v"; git tag "$v" ); done

Test

Create mobilespec and sanity check all plugins on at least one platform (preferably, a released version of the platform and not master). Run through mobilespec, ensuring to do manual tests that relate to changes in the RELEASENOTES.md

cordova-mobile-spec/createmobilespec/createmobilespec.js --android --ios
(cd mobilespec && ./cordova build && ./cordova run android --device)
(cd mobilespec && ./cordova build && ./cordova run ios --device)

Create Release Branch

for l in $ACTIVE; do ( cd $l; v="$(grep version= plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; b=`expr $v : '^\(....\)'`; x="x"; b=$b$x; git branch $b; echo "Creating branch $b for $l"); done

If a branch already exists, you will have to manually checkout the branch, merge master and then checkout master.

Update version to add back -dev suffix

for l in $ACTIVE; do ( cd $l; v="$(grep version= plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; v_no_dev="${v%-dev}"; if [ "$v" = "$v_no_dev" ]; then v2="$(echo $v|awk -F"." '{$NF+=1}{print $0RT}' OFS="." ORS="")-dev"; echo "$l: Setting version in plugin.xml to $v2"; sed -i '' -E s:"version=\"$v\":version=\"$v2\":" plugin.xml; fi) ; done
# update package.json
for l in $ACTIVE; do ( cd $l; v="$(grep -m 1 '"version"' package.json | cut -d'"' -f4)"; if [[ $v != *-dev ]]; then v2="$(echo $v|awk -F"." '{$NF+=1}{print $0RT}' OFS="." ORS="")-dev"; echo "$l: Setting version in package.json to $v2"; sed -i '' -E '1,/version":.*/s/version":.*/version": "'$v2'",/' package.json; fi); done
# update the nested test
for l in $ACTIVE; do ( cd $l; v="$(grep version= plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; vt="$(grep version= tests/plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; if [ "$v" != "$vt" ]; then echo "$l: Setting version to $v"; sed -i '' -E s:"version=\"$vt\":version=\"$v\":" tests/plugin.xml; fi); done
for l in $ACTIVE; do (cd $l; git commit -am "$JIRA Incremented plugin version." ); done

Push tags, branches and changes

# Sanity check:
coho repo-status -r plugins
coho foreach -r plugins "git status -s"
# Push: (assumes "origin" is apache remote)
for l in $ACTIVE; do ( cd $l; tag=$(git describe --tags --abbrev=0); echo $l; set -x; git push origin master && git push origin refs/tags/$tag); done
for l in $ACTIVE; do ( cd $l; v="$(grep version= plugin.xml | grep -v xml | head -n1 | cut -d'"' -f2)"; b=`expr $v : '^\(....\)'`; x="x"; b=$b$x; git push origin $b;); done
# Check that it was all successful:
coho repo-update -r plugins
coho repo-status -r plugins

Publish to dist/dev

Ensure you have the svn repos checked out:

coho repo-clone -r dist -r dist/dev

Create archives from your tags:

coho create-archive -r ${ACTIVE// / -r } --dest cordova-dist-dev/$JIRA

Sanity Check:

# Manually double check version numbers are correct on the file names
# Then run:
coho verify-archive cordova-dist-dev/$JIRA/*.tgz

Upload:

(cd cordova-dist-dev && svn up && svn add $JIRA && svn commit -m "$JIRA Uploading release candidates for plugins release")

Prepare Blog Post

Run the following script to get release notes from RELEASENOTS.md.

for l in $ACTIVE; do (cd $l; current_release=$(git describe --tags --abbrev=0); previous_release=$(git describe --abbrev=0 --tags `git rev-list --tags --skip=1 --max-count=1`); echo "$l@$current_release"; awk '/### '$current_release'.*/,/### '$previous_release'.*/ {temp=match($0,/### '$previous_release'/); title=match($0, /### '$current_release'/); if(temp == 0 && title == 0) print $0}' < RELEASENOTES.md); done
  • Combine the output from above into a Release Announcement blog post
  • Get blog post proof-read.

Start VOTE Thread

Send an email to dev ML with:

Subject:

[VOTE] Plugins Release

Body:

Please review and vote on the release of this plugins release
by replying to this email (and keep discussion on the DISCUSS thread)

Release issue: https://issues.apache.org/jira/browse/CB-XXXX

The plugins have been published to dist/dev:
https://dist.apache.org/repos/dist/dev/cordova/CB-XXXX/

The packages were published from their corresponding git tags:
PASTE OUTPUT OF: coho print-tags -r ${ACTIVE// / -r }

Upon a successful vote I will upload the archives to dist/, upload them to npm, and post the corresponding blog post.

Voting guidelines: https://github.com/apache/cordova-coho/blob/master/docs/release-voting.md
How to vote on a plugins release at https://github.com/apache/cordova-coho/blob/master/docs/plugins-release-process.md#voting

Voting will go on for a minimum of 48 hours.

I vote +1:
* Ran coho audit-license-headers over the relevant repos
* Ran coho check-license to ensure all dependencies and subdependencies have Apache-compatible licenses
* Ensured continuous build was green when repos were tagged

Voting

Steps to verify a plugins release

  1. Setup Repo clone can be skipped if you have cordova-dist-dev. Warning, this requires svn setup.

    coho repo-clone -r cordova-dist-dev (cd cordova-dist-dev && svn up)

  2. Verify

    coho verify-archive cordova-dist-dev/$JIRA/*.tgz coho repo-update -r plugins coho check-license -r active-plugins coho audit-license-headers -r active-plugins | less

    Tip: Skim by searching for “Unknown Licenses”

  3. Test

Review ci.cordova.io.

(Optional locally run mobile-spec)

cordova-mobile-spec/createmobilespec/createmobilespec.js --android --ios
(cd mobilespec && ./cordova build && ./cordova run android --device)
(cd mobilespec && ./cordova build && ./cordova run ios --device)

Email the result of the vote

Respond to the vote thread with:

Subject:

[RESULT][VOTE] Plugins Release

Body:

The vote has now closed. The results are:

Positive Binding Votes: (# of PMC members that +1'ed)

.. names of all +1 PMC members ..

Negative Binding Votes: (# of PMC members that -1'ed)

.. names of all -1 PMC members ..

Other Votes:

.. list any non-binding votes, from non-PMC members ..

The vote has passed.

If there were any votes from non-pmc, include them in an additional Non-Binding section.

Positive Non-Binding Votes: (# that +1'ed)

.. names of all +1 non-PMC members ..

Negative Non-Binding Votes: (# that -1'ed)

.. names of all -1 non-PMC members ..

Note: list of PMC members: http://people.apache.org/phonebook.html?pmc=cordova

If the Vote does not Pass

  • Revert adding of -dev on master branch
  • Address the concerns (on master branch)
  • Re-tag release using git tag -f
  • Add back -dev
  • Start a new vote

Publish to dist/

If you've lost your list of ACTIVE:

ACTIVE=$(cd cordova-dist-dev/$JIRA; ls *.tgz | sed -E 's:-[^-]*$::')

Publish:

cd cordova-dist
svn up
for l in $ACTIVE; do ( svn rm plugins/$l* ); done
cp ../cordova-dist-dev/$JIRA/* plugins/
svn add plugins/*
svn commit -m "$JIRA Published plugins release to dist"

cd ../cordova-dist-dev
svn up
svn rm $JIRA
svn commit -m "$JIRA Removing release candidates from dist/dev"
cd ..

Find your release here: https://dist.apache.org/repos/dist/release/cordova/plugins/

Tell Apache about Release

TODO: Please someone write a coho helper for doing this POST request!

  1. Go to: https://reporter.apache.org/addrelease.html?cordova
  2. Use version “cordova-plugin-$FOO@x.x.x

Publish to npm

cd cordova-dist/plugins
for l in $ACTIVE; do (
    npm publish $l-*.tgz
) done;

Add new apache release tags

Make a copy of your released tag with a prefix of rel\YOURTAG. These are permanent release tags for Apache.

for l in $ACTIVE; do ( cd $l; tag=$(git describe --tags --abbrev=0); git checkout $tag; git tag 'rel/'$tag; git push origin refs/tags/'rel/'$tag; git checkout master); done

Post blog Post

See instructions in the cordova-docs README

Do other announcements

Do the same things regarding announcements as described in cadence-release-process, where they make sense.

Send email to dev list with a subject [ANNOUNCE] Plugin Release and include blog post and tweet links

Subject:

[ANNOUNCE] Plugin Release

Body:

Blog: http://cordova.apache.org/news/YYYY/MM/DD/plugin-release.html
Tweet: https://twitter.com/apachecordova/status/xxxxxxxxxxxx

Close JIRA Issue

  • Double check that the issue has comments that record the steps you took
  • Mark it as fixed

Finally:

  • Update these instructions if they were missing anything.