Gutenberg Release Process
Edit
This Repository is used to perform several types of releases. This document serves as a checklist for each one of these. It is helpful if you’d like to understand the different workflows.
To release Gutenberg, you need commit access to the WordPress.org plugin repository as well as being part of the WordPress organization at npm. 🙂
Plugin Releases Plugin Releases
Schedule Schedule
We release a new major version approximately every two weeks. The current and next versions are tracked in GitHub milestones, along with each version’s tagging date (the day when the release candidate is to be tagged).
- On the date of the current milestone, we publish a release candidate and make it available for plugin authors and users to test. If any regressions are found with a release candidate, a new one can be published. On this date, all remaining PRs on the milestone are moved automatically to the next release. Release candidates should be versioned incrementally, starting with
-rc.1
, then-rc.2
, and so on. -
Two days after the first release candidate, the stable version is created based on the last release candidate and any necessary regression fixes. Once the stable version is released, a post like this describing the changes and performing a performance audit is published.
If critical bugs are discovered on stable versions of the plugin, patch versions can be released at any time.
Release Tool Release Tool
Note that at the time of writing, the tool doesn’t support releasing consecutive RC releases. However, it is possible to use the tool for patch releases following the first stable release.
The plugin release process is entirely automated. To release the RC version of the plugin, run the following command and follow the instructions:
./bin/plugin/cli.js rc
To release a stable version, run:
./bin/plugin/cli.js stable
During the release process, you’ll be asked to provide:
- A changelog: prepare one beforehand by following the instructions below.
- A personal access token: have one ready beforehand by visiting this page, if you haven’t got one yet.
- User and password for your GitHub account: if 2FA is enabled for your account (it should), you need to provide a personal access token instead of password (you can use the one necessary for the release).
Manual Release Process Manual Release Process
Creating the first Release Candidate Creating the first Release Candidate
Releasing the first release candidate for this milestone (x.x
) involves:
- writing a release blog post and changelog
- creating the release branch
- bumping the version and tagging the release
- building the plugin
- publishing the release to GitHub
- publishing the call for testing
Writing the Release Post and Changelog
To generate a changelog for a release, use the changelog generator tool:
npm run changelog
By default, this will search for and organize all pull requests associated with the milestone for the next version of the project.
To override the default behavior, you can pass one or both of the following options. Remember to use --
to let NPM pass the options to the script.
--milestone <milestone>
: Provide the title of the milestone for which the changelog should be generated. This should exactly match the title as shown on the milestones page.- Example:
npm run changelog -- --milestone="Gutenberg 8.1"
- Example:
--token <token>
: Provide a GitHub personal access token for authenticating requests. This should only be necessary if you run the script frequently enough to been blocked by rate limiting.- Example:
npm run changelog -- --token="..."
- Example:
The script will output a generated changelog, grouped by pull request label. Note that this is intended to be a starting point for release notes. You will still want to manually review and curate the changelog entries.
Guidelines for proof-reading include:
- Fix spelling errors or clarify wording. Phrasing should be easy to understand where the intended audience are those who use the plugin or are keeping up with ongoing development.
- Create new groupings as applicable, and move pull requests between.
- When multiple pull requests relate to the same task (such as a follow-up pull request), try to combine them to a single entry.
- If subtasks of a related set of pull requests are substantial, consider organizing as entries in a nested list.
- Remove mobile app pull request entries.
Once you have cleaned up the changelog, choose a few features to highlight in the release post and record an animation of them in use.
You should also include a performance audit at the end of the release post. You can use bin/plugin/cli.js perf
to automatically do this.
Compile this to a draft post on make.wordpress.org/core; this post should be published after the actual release.
Creating the Release Branch
For each milestone (let’s assume it’s x.x
here), a release branch is used to release all RCs and minor releases. For the first RC of the milestone, a release branch is created from master.
git checkout master git checkout -b release/x.x git push origin release/x.x
Bumping the Version and Tagging the Release
- Checkout the
release/x.x
branch. - Create a commit like this, bumping the version number in
gutenberg.php
,package.json
, andpackage-lock.json
tox.x.0-rc.1
. - Create a Pull Request from the release branch into
master
using the changelog as a description and ensure the tests pass properly. - Tag the RC version.
git tag vx.x.0-rc.1
from the release branch. - Push the tag
git push --tags
. - Merge the version bump pull request and avoid removing the release branch.
Build the Plugin
- Run
git fetch --tags
. - Check out the tag for this release, you should run
git checkout vx.x.0-rc.1
. - Run
npm run build:plugin-zip
from the root of project. This packages a zip file with a release build ofgutenberg.zip
.
Publish the Release on GitHub
- Create a new release on GitHub.
- If you were releasing the
x.x.0-rc.1
release candidate, label itx.x.0-rc.1
and use thevx.x.x-rc.1
as a tag. - Upload the
gutenberg.zip
file into the release. - Use the changelog as a description of the release.
- Publish the release.
Here’s an example release candidate page; yours should look like that when you’re finished.
Creating Release Candidate Patches (done via git cherry-pick
) Creating Release Candidate Patches (done via git cherry-pick
)
If a bug is found in a release candidate and a fix is committed to master
, we should include that fix in a new release candidate. To do this you’ll need to use git cherry-pick
to add these changes to the milestone’s release branch. This way only fixes are added to the release candidate and not all the new code that has landed on master
since tagging:
- Checkout the corresponding release branch with:
git checkout release/x.x
. - Cherry-pick fix commits (in chronological order) with
git cherry-pick [SHA]
. - Create a commit like this, bumping the version number in
gutenberg.php
,package.json
, andpackage-lock.json
tox.x.0-rc.2
. - Create a Pull Request from the release branch into
master
using the changelog as a description and ensure the tests pass properly. Note that if there there are merge conflicts, Travis CI will not run on the PR. Run tests locally usingnpm run test
andnpm run test-e2e
if this happens. - Tag the RC version.
git tag vx.x.0-rc.2
from the release branch. - Push the tag
git push --tags
. - Create a branch for bumping the version number.
git checkout -b bump/x.x
. - Create a Pull Request from the
bump/x.x
branch intomaster
using the
changelog as a description. - Merge the version bump pull request.
- Follow the steps in build the plugin and publish the release on GitHub.
You can copy the existing changelog from the previous release candidate. Let other contributors know that a new release candidate has been released in the #core-editor
channel and the call for testing post.
Official Gutenberg Releases™ Official Gutenberg Releases™
The process of releasing Gutenberg is similar to creating a release candidate, except we don’t use the -rc.X
in the git
tag and we publish a new branch in the subversion repository. This updates the version available in the WordPress plugin repository and will cause WordPress sites around the world to prompt users to update to this new version.
Creating a Release Creating a Release
Creating a release involves:
- verifying the release blog post and changelog
- bumping the version
- building the plugin
- publishing the new release to GitHub
- committing to the plugin repository
- publishing the release blog post
Verifying the Release Post and Changelog
- Check the draft post on make.wordpress.org/core; make sure the changelog reflects what’s shipping in the release.
Bumping the Version
- Checkout the release branch
git checkout release/x.x
.
Note: This branch should never be removed or rebased. When we want to merge something from it to master and conflicts exist/may exist we use a temporary branch bump/x.x
.
- Create a commit like this, removing the
-rc.X
from the version number ingutenberg.php
,package.json
, andpackage-lock.json
. - Create a new branch called
bump/x.x
fromrelease/x.x
and switch to it:git checkout -b bump/x.x
. - Create a pull request from
bump/x.x
tomaster
. Verify the continuous integrations tests pass, before continuing to the next step even if conflicts exist. - Rebase
bump/x.x
againstorigin/master
usinggit fetch origin && git rebase origin/master
. - Force push the branch
bump/x.x
usinggit push --force-with-lease
. - Switch to the
release/x.x
branch. Tag the version from the release branchgit tag vx.x.0
. - Push the tag
git push --tags
. - Merge the version bump pull request.
Build the Plugin
- Run
git fetch --tags
. - Check out the tag for this release, you should run
git checkout vx.x.0
. - Run
npm run build:plugin-zip
from the root of project. This packages a zip file with a release build ofgutenberg.zip
.
Publish the Release on GitHub
- Create a new release on GitHub.
- If you were releasing the
x.x.0
release candidate, label itx.x.0
and use thevx.x.x
as a tag. - Upload the a
gutenberg.zip
file into the release. - Use the changelog as a description of the release.
- Publish the release.
Commit to the Plugin Repository
You’ll need to use Subversion to publish the plugin to WordPress.org.
- Do an SVN checkout of
https://wordpress.org/plugins/gutenberg/trunk
:- If this is your first checkout, run:
svn checkout https://plugins.svn.wordpress.org/gutenberg/trunk
- If you already have a copy, run:
svn up
- If this is your first checkout, run:
- Delete the contents except for the
readme.txt
andchangelog.txt
files (these files don’t exist in thegit
repo, only in Subversion). - Extract the contents of the zip file.
- Edit
readme.txt
, replacing the changelog for the previous version with the current release’s changelog. - Add the changelog for the current release to
changelog.txt
. - Add new files/remove deleted files from the repository:
# Add new files: svn st | grep '^\?' | awk '{print $2}' | xargs svn add # add the -r option to xargs if you use a linux-based OS # Delete old files: svn st | grep '^!' | awk '{print $2}' | xargs svn rm # add the -r option to xargs if you use a linux-based OS
- Commit the new version:
# Replace X.X.X with your version: svn ci -m "Committing Gutenberg version X.X.X"
- Tag the new version:
svn cp https://plugins.svn.wordpress.org/gutenberg/trunk https://plugins.svn.wordpress.org/gutenberg/tags/X.X.X -m "Tagging Gutenberg version X.X.X"
- Edit
readme.txt
to point to the new tag. The Stable version header inreadme.txt
should be updated to match the new release version number. After updating and committing that, the new version should be released:
svn ci -m "Releasing Gutenberg version X.X.X"
This will cause the new version to be available to users of WordPress all over the globe! 💃
You should check that folks are able to install the new version from their Dashboard.
Publish the Release Blog Post Publish the Release Blog Post
- Publish the make/core release blog post drafted earlier.
- Pat yourself on the back! 👍
If you don’t have access to make.wordpress.org/core, ping someone on the Gutenberg Core team in the WordPress #core-editor Slack channel to publish the post.
Packages Releases and WordPress Core Updates Packages Releases and WordPress Core Updates
The Gutenberg repository mirrors the WordPress SVN repository in terms of branching for each SVN branch, a corresponding Gutenberg wp/*
branch is created:
- The
wp/trunk
branch contains all the packages that are published and used in thetrunk
branch of WordPress. - A Gutenberg branch targeting a specific WordPress major release (including its further minor increments) is created (example
wp/5.2
) based on thewp/trunk
Gutenberg branch when the corresponding WordPress release branch is created. (This usually happens when the firstRC
of the next WordPress major version is released).
Synchronizing WordPress Trunk Synchronizing WordPress Trunk
For each Gutenberg plugin release, WordPress trunk should be synchronized. Note that the WordPress trunk
branch can be closed or in “feature-freeze” mode. Usually, this happens between the first beta
and the first RC
of the WordPress release cycle. During this period, the Gutenberg plugin releases should not be synchronized with WordPress Core.
The process has three steps: 1) update the wp/trunk
branch within the Gutenberg repo 2) publish the new package versions to npm 3) update the WordPress trunk
branch.
The first step is automated via ./bin/plugin/cli.js npm-stable
command. You only have to run the command, but, for the record, the manual process would look like this:
- Ensure the WordPress
trunk
branch is open for enhancements. - Get the last published Gutenberg release branch with
git fetch
. - Check out the
wp/trunk
branch. - Remove all files from the current branch:
git rm -r .
. - Check out all the files from the release branch:
git checkout release/x.x -- .
. - Commit all changes to the
wp/trunk
branch withgit commit -m "Merge changes published in the Gutenberg plugin vX.X release"
and push to the repository. - Update the
CHANGELOG.md
files of the packages with the new publish version calculated and commit to thewp/trunk
branch. Assuming the package versions are written using this formatmajor.minor.patch
, make sure to bump at least theminor
version number. For example, if the CHANGELOG of the package to be released indicates that the next unreleased version is5.6.1
, choose5.7.0
as a version in case ofminor
version. This is important as the patch version numbers should be reserved in case bug fixes are needed for a minor WordPress release (see below).
Once the command is finished, you can start the second part: publishing the npm packages.
- Update your local
wp/trunk
branch with the latest changes pushed to GitHub. - Log-in to npm via the console:
npm login
. Note that you should have 2FA enabled. - From the
wp/trunk
branch, run the scriptnpm run publish:prod
.- When asked for the version numbers to choose for each package pick the values of the updated CHANGELOG files.
- You’ll be asked for your One-Time Password (OTP) a couple of times. This is the code from the 2FA authenticator app you use. Depending on how many packages are to be released you may be asked for more than one OTP, as they tend to expire before all packages are released.
- If the publishing process ends up incomplete (perhaps because it timed-out or an bad OTP was introduce) you can resume it via
lerna publish from-package
.
- Cherry-pick the commits created by lerna (“Publish” and the CHANGELOG update) into the
master
branch of Gutenberg.
Finally, now that the npm packages are ready, a patch can be created and committed into WordPress trunk
.
Minor WordPress Releases Minor WordPress Releases
The following workflow is needed when bug fixes or security releases need to be backported into WordPress Core. This can happen in a few use-cases:
- During the
beta
and theRC
period of the WordPress release cycle. - For WordPress minor releases and WordPress security releases (example
5.1.1
).
- Check out the relevant WordPress major branch (If the minor release is 5.2.1, check out
wp/5.2
). - Create a feature branch from that branch, and cherry-pick the merge commits for the needed bug fixes onto it.
- Create a Pull Request from this branch targeting the WordPress major branch used above.
- Merge the Pull Request using the “Rebase and Merge” button to keep the history of the commits.
Now, the branch is ready to be used to publish the npm packages.
- Check out the WordPress branch used before (Example
wp/5.2
). git pull
.- Run the package release process but when asked for the version numbers to choose for each package, (assuming the package versions are written using this format
major.minor.patch
) make sure to bump only thepatch
version number. For example, if the last published package version for this WordPress branch was5.6.0
, choose5.6.1
as a version.
Note: For WordPress 5.0
and WordPress 5.1
, a different release process was used. This means that when choosing npm package versions targeting these two releases, you won’t be able to use the next patch
version number as it may have been already used. You should use the “metadata” modifier for these. For example, if the last published package version for this WordPress branch was 5.6.1
, choose 5.6.1+patch.1
as a version.
- Update the
CHANGELOG.md
files of the published packages with the new released versions and commit to the corresponding branch (Examplewp/5.2
). - Cherry-pick the CHANGELOG update commits into the
master
branch of Gutenberg.
Now, the npm packages should be ready and a patch can be created and committed into the corresponding WordPress SVN branch.
Standalone Package Releases Standalone Package Releases
The following workflow is needed when packages require bug fixes or security releases to be published to npm outside of a WordPress release cycle.
Note: Both the master
and wp/trunk
branches are restricted and can only be pushed to by the Gutenberg Core team.
Identify the commit hashes from the pull requests that need to be ported from the repo master
branch to wp/trunk
The wp/trunk
branch now needs to be prepared to release and publish the packages to npm.
Open a terminal and perform the following steps:
1. git checkout master
2. git pull
3. git checkout wp/trunk
4. git pull
Before porting commits check that the wp/trunk
branch does not have any outstanding packages waiting to be published:
1. git checkout wp/trunk
2. npm run publish:check
Now cherry-pick the commits from master
to wp/trunk
, use -m 1 commithash
if the commit was a pull request merge commit:
1. git cherry-pick -m 1 cb150a2
2. git push
Whilst waiting for the GitHub actions build for wp/trunk
branch to pass, identify and begin updating the CHANGELOG.md
files:
1. git checkout wp/trunk
2. npm run publish:check
Example
npm run publish:check @wordpress/e2e-tests @wordpress/jest-preset-default @wordpress/scripts lerna success found 3 packages ready to publish
Check the versions listed in the current CHANGELOG.md
file, looking through the commit history of a package e.g @wordpress/scripts and look out for “chore(release): publish” and “Update changelogs” commits to determine recent version bumps, then looking at the commits since the most recent release should aid with discovering what changes have occurred since the last release.
Note: You may discover the current version of each package is not up to date, if so updating the previous released versions would be appreciated.
Begin updating the changelogs based on the Maintaining Changelogs documentation and commit the changes:
git checkout wp/trunk
- Update each of the
CHANGELOG.md
files - Stage the changelog changes
git add packages/
git commit -m "Update changelogs"
- Make a note of the commit hash of this commit
> Example
>> [master 278f524f16] Update changelogs` 278f524
> git push
Now that the changes have been committed to the wp/trunk
branch and the Travis CI builds for the wp/trunk
branch are passing it’s time to publish the packages to npm:
1. Once again run npm run publish:check
to confirm there are no unexpected packages ready to be published:
Example
npm run publish:check @wordpress/e2e-tests @wordpress/jest-preset-default @wordpress/scripts lerna success found 3 packages ready to publish
- Run the package release process but when asked for the version numbers to choose for each package use the versions you made note of above when updating each packages
CHANGELOG.md
file.
Truncated example of publishing process output npm run publish:prod Build Progress: [==============================] 100% lerna notice cli v3.18.2 lerna info versioning independent ? Select a new version for @wordpress/e2e-tests (currently 1.9.0) Patch (1.9.1) ? Select a new version for @wordpress/jest-preset-default (currently 5.3.0) Patch (5.3.1) ? Select a new version for @wordpress/scripts (currently 6.1.0) Patch (6.1.1) Changes: - @wordpress/e2e-tests: 1.9.0 => 1.9.1 - @wordpress/jest-preset-default: 5.3.0 => 5.3.1 - @wordpress/scripts: 6.1.0 => 6.1.1 ? Are you sure you want to publish these packages? Yes lerna info execute Skipping releases lerna info git Pushing tags... lerna info publish Publishing packages to npm... lerna info Verifying npm credentials lerna info Checking two-factor auth mode ? Enter OTP: 753566 lerna success published @wordpress/jest-preset-default 5.3.1 lerna success published @wordpress/scripts 6.1.1 lerna success published @wordpress/e2e-tests 1.9.1 Successfully published: - @wordpress/e2e-tests@1.9.1 - @wordpress/jest-preset-default@5.3.1 - @wordpress/scripts@6.1.1 lerna success published 3 packages
Now that the packages have been published the “chore(release): publish” and “Update changelogs” commits to wp/trunk
need to be ported to the master
branch:
1. git checkout master
2. git pull
3. Cherry-pick the 278f524
hash you noted above from the “Update changelogs” commit made to wp/trunk
4. git cherry-pick 278f524
5. Get the commit hash from the the lerna publish commit either from the terminal or wp/trunk commits
6. Cherry-pick the fe6ae0d
“chore(release): publish”_ commit made to wp/trunk
7. git cherry-pick fe6ae0d
8. git push
Confirm the packages dependencies do not contain file://
links in the dependencies
or devdependencies
section of the packages released, e.g:
https://unpkg.com/browse/@wordpress/jest-preset-default@5.3.1/package.json
https://unpkg.com/browse/@wordpress/scripts@6.1.1/package.json
https://unpkg.com/browse/@wordpress/jest-preset-default@5.3.1/package.json
Time to announce the published changes in the #core-js and #core-editor Slack channels
📣 Successfully published: • @wordpress/e2e-tests@1.9.1 • @wordpress/jest-preset-default@5.3.1 • @wordpress/scripts@6.1.1 Lerna success published 3 packages
Ta-da! 🎉