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

Packages: Finalize the revised strategy for npm publishing #39389

Merged
merged 4 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
40 changes: 40 additions & 0 deletions .github/workflows/build-plugin-zip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,43 @@ jobs:
asset_path: ./gutenberg.zip
asset_name: gutenberg.zip
asset_content_type: application/zip

npm-publish:
name: Publish WordPress packages to npm
runs-on: ubuntu-latest
environment: WordPress packages
needs: [bump-version, build]
if: ${{ endsWith( needs.bump-version.outputs.new_version, '-rc.1' ) }}
steps:
- name: Checkout (for CLI)
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
with:
path: main
ref: trunk

- name: Checkout (for publishing)
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
with:
path: publish
ref: trunk
token: ${{ secrets.GUTENBERG_TOKEN }}

- name: Configure git user name and email (for publishing)
run: |
cd publish
git config user.name "Gutenberg Repository Automation"
git config user.email gutenberg@wordpress.org

- name: Setup Node
uses: actions/setup-node@38d90ce44d5275ad62cc48384b3d8a58c500bb5f # v2.2.2
with:
node-version: 14
registry-url: 'https://registry.npmjs.org'

- name: Publish packages to npm ("latest" dist-tag)
run: |
cd main
npm ci
./bin/plugin/cli.js npm-latest --semver minor --ci --repository-path ../publish
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note, that it's going to be a regular npm publishing from now on. Not the test one like last week 😄

env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/create-block.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Create Block
on:
pull_request:
push:
branches: [trunk, wp/trunk]
branches: [trunk, wp/latest]

# Cancels all previous workflow runs for pull requests that have not completed.
concurrency:
Expand Down
39 changes: 0 additions & 39 deletions .github/workflows/upload-release-to-plugin-repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,45 +94,6 @@ jobs:
name: changelog ${{ matrix.label }}
path: ./changelog.txt

npm-publish:
name: Publish WordPress packages to npm
runs-on: ubuntu-latest
needs: update-changelog
if: ${{ github.event.release.prerelease && endsWith( github.event.release.tag_name, '-rc.1' ) && github.event.release.assets[0] }}
steps:
- name: Checkout (for CLI)
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
with:
path: main
ref: trunk

- name: Checkout (for publishing)
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
with:
path: publish
ref: trunk
token: ${{ secrets.GUTENBERG_TOKEN }}

- name: Configure git user name and email (for publishing)
run: |
cd publish
git config user.name "Gutenberg Repository Automation"
git config user.email gutenberg@wordpress.org

- name: Setup Node
uses: actions/setup-node@38d90ce44d5275ad62cc48384b3d8a58c500bb5f # v2.2.2
with:
node-version: 14
registry-url: 'https://registry.npmjs.org'

- name: Publish packages to npm ("next" dist-tag)
run: |
cd main
npm ci
./bin/plugin/cli.js npm-next --semver minor --ci --repository-path ../publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

upload:
name: Upload Gutenberg Plugin
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion bin/plugin/commands/packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ function getConfig( releaseType, { ci, repositoryPath, semver } ) {
repositoryPath && join( process.cwd(), repositoryPath ),
interactive: ! ci,
minimumVersionBump: semver,
npmReleaseBranch: releaseType === 'next' ? 'wp/next' : 'wp/trunk',
npmReleaseBranch: releaseType === 'next' ? 'wp/next' : 'wp/latest',
releaseType,
};
}
Expand Down
48 changes: 24 additions & 24 deletions docs/contributors/code/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,16 @@ Yes. The method for this is identical to the main Plugin release process. You wi

## Packages Releases to npm and WordPress Core Updates

The Gutenberg repository mirrors the [WordPress SVN repository](https://make.wordpress.org/core/handbook/about/release-cycle/) in terms of branching for each SVN branch, a corresponding Gutenberg `wp/*` branch is created:
The Gutenberg repository follows the [WordPress SVN repository's](https://make.wordpress.org/core/handbook/about/release-cycle/) branching strategy for every major WordPress release. In addition to that, it also contains two other special branches that control npm publishing workflows:

- The `wp/trunk` branch contains the same version of packages published to npm with the `latest` distribution tag. The WordPress core consumes those packages directly in the `trunk` branch and uses them for public releases.
- The `wp/next` branch contains the same version of packages published to npm with the `next` distribution tag. Projects should use those packages for development purposes only.
- A Gutenberg branch targeting a specific WordPress major release (including its further minor increments) is created (example `wp/5.2`) based on the `wp/trunk` Gutenberg branch when the corresponding WordPress release branch is created. (This usually happens when the `beta` or `RC` of the next WordPress major version is released).
- The `wp/latest` branch contains the same version of packages as those published to npm with the `latest` distribution tag. The goal here is to have this branch synchronized with the last Gutenberg plugin release, and the only exception would be an unplanned [bugfix release](#standalone-bugfix-package-releases).
- The `wp/next` branch contains the same version of packages as those published to npm with the `next` distribution tag. It always gets synchronized with the `trunk` branch. Projects should use those packages for development or testing purposes only.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this branch and "next" packages become less important if we do wp/latest release on each plugin RC

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's true. However, we might make it more useful in the future, too. I used it recently for testing purposes of the publishing workflow. At the moment, publishing with the next dist-tag is a bit noisy in the repository because it creates a git tag for every package published. This is the default behavior in npm and the only way to work around it would be to use canary releases from Lerna and publish changes even daily. I remember having some issues with the broken version bumps with --canary flag so we would have to ignore the excessive number of git tags created or work around it somehow.

- A Gutenberg branch `wp/*` (example `wp/6.0`) targeting a specific WordPress major release (including its further minor increments) gets created based on the `wp/latest` Gutenberg branch just after the last Gutenberg release planned for inclusion in the next major WordPress release.

Release types and their schedule:

- [Synchronizing Gutenberg Plugin](#synchronizing-gutenberg-plugin) (`latest` dist tag) – publishing happens every two weeks based on the newly created RC1 version of the Gutenberg plugin.
- [WordPress Releases](#wordpress-releases) (`patch` dist tag) – only when bug or security fixes need to be backported into WordPress Core.
- [Synchronizing Gutenberg Plugin](#synchronizing-gutenberg-plugin) (`latest` dist tag) – publishing happens automatically every two weeks based on the newly created `release/*` (example `release/12.8`) branch with the RC1 version of the Gutenberg plugin.
- [WordPress Releases](#wordpress-releases) (`patch` dist tag) – publishing gets triggered manually from the `wp/*` (example `wp/6.0`) branch. Once we reach the point in the WordPress major release cycle (usually after Beta 1) where we only cherry-pick commits from the Gutenberg repository to the WordPress core, we use `wp/*` branch (created from `wp/latest`) for npm publishing with the `patch` dist-tag. It's also possible to use older branches to backport bug or security fixes to the corresponding older versions of WordPress Core.
- [Development Releases](#development-releases) (`next` dist tag) – it is also possible to perform development releases at any time when there is a need to test the upcoming changes.

There is also an option to perform [Standalone Bugfix Package Releases](#standalone-bugfix-package-releases) at will. It should be reserved only for critical bug fixes or security releases that must be published to _npm_ outside of regular cycles.
Expand All @@ -206,19 +206,19 @@ There is also an option to perform [Standalone Bugfix Package Releases](#standal

For each Gutenberg plugin release, we also publish to npm an updated version of WordPress packages. This is automated with the [Release Tool](#release-tool) that handles releases for the Gutenberg plugin.

We deliberately update the `wp/trunk` branch within the Gutenberg repo with the content from the Gutenberg release `release/*` (example `release/12.7`) branch at the time of the Gutenberg RC1 release. This is done to ensure that the `wp/trunk` branch is as close as possible to the latest version of the Gutenberg plugin. It also practically removes the chances of conflicts while backporting to `trunk` commits with updates applied during publishing to `package.json` and `CHANGELOG.md` files. In the past, we had many issues in that aspect when doing npm publishing after the regular Gutenberg release a week later. When publishing the new package versions to npm, we pick at least the `minor` version bump to account for future bugfix or security releases.
We deliberately update the `wp/latest` branch within the Gutenberg repo with the content from the Gutenberg release `release/*` (example `release/12.7`) branch at the time of the Gutenberg RC1 release. This is done to ensure that the `wp/latest` branch is as close as possible to the latest version of the Gutenberg plugin. It also practically removes the chances of conflicts while backporting to `trunk` commits with updates applied during publishing to `package.json` and `CHANGELOG.md` files. In the past, we had many issues in that aspect when doing npm publishing after the regular Gutenberg release a week later. When publishing the new package versions to npm, we pick at least the `minor` version bump to account for future bugfix or security releases.

All steps are automated via `./bin/plugin/cli.js npm-latest` command. For the record, the manual process would look very close to the following steps:

1. Ensure the WordPress `trunk` branch is open for enhancements.
2. Get the last published Gutenberg release branch with `git fetch`.
3. Check out the `wp/trunk` branch.
3. Check out the `wp/latest` branch.
4. Remove all files from the current branch: `git rm -r .`.
5. Check out all the files from the release branch: `git checkout release/x.x -- .`.
6. Commit all changes to the `wp/trunk` branch with `git commit -m "Merge changes published in the Gutenberg plugin vX.X release"` and push to the repository.
7. Update the `CHANGELOG.md` files of the packages with the new publish version calculated and commit to the `wp/trunk` branch. Assuming the package versions are written using this format `major.minor.patch`, make sure to bump at least the `minor` version bumps gets applied. For example, if the CHANGELOG of the package to be released indicates that the next unreleased version is `5.6.1`, choose `5.7.0` as a version in case of `minor` 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).
6. Commit all changes to the `wp/latest` branch with `git commit -m "Merge changes published in the Gutenberg plugin vX.X release"` and push to the repository.
7. Update the `CHANGELOG.md` files of the packages with the new publish version calculated and commit to the `wp/latest` branch. Assuming the package versions are written using this format `major.minor.patch`, make sure to bump at least the `minor` version bumps gets applied. For example, if the CHANGELOG of the package to be released indicates that the next unreleased version is `5.6.1`, choose `5.7.0` as a version in case of `minor` 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).
8. Log-in to npm via the console: `npm login`. Note that you should have 2FA enabled.
9. From the `wp/trunk` branch, install npm dependencies with `npm ci`.
9. From the `wp/latest` branch, install npm dependencies with `npm ci`.
10. Run the script `npm run publish:latest`.
- 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.
Expand Down Expand Up @@ -254,32 +254,32 @@ Now, the npm packages should be ready and a patch can be created and committed i

The following workflow is needed when packages require bug fixes or security releases to be published to _npm_ outside of a regular release cycle.

Note: Both the `trunk` and `wp/trunk` branches are restricted and can only be _pushed_ to by the Gutenberg Core team.
Note: Both the `trunk` and `wp/latest` 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 `trunk` branch to `wp/trunk`
Identify the commit hashes from the pull requests that need to be ported from the repo `trunk` branch to `wp/latest`

The `wp/trunk` branch now needs to be prepared to release and publish the packages to _npm_.
The `wp/latest` 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 trunk`
2. `git pull`
3. `git checkout wp/trunk`
3. `git checkout wp/latest`
4. `git pull`

Before porting commits check that the `wp/trunk` branch does not have any outstanding packages waiting to be published:
Before porting commits check that the `wp/latest` branch does not have any outstanding packages waiting to be published:

1. `git checkout wp/trunk`
1. `git checkout wp/latest`
2. `npm run publish:check`

Now _cherry-pick_ the commits from `trunk` to `wp/trunk`, use `-m 1 commithash` if the commit was a pull request merge commit:
Now _cherry-pick_ the commits from `trunk` to `wp/latest`, 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](https://github.com/WordPress/gutenberg/actions?query=branch%3Awp%2Ftrunk), identify and begin updating the `CHANGELOG.md` files:
Whilst waiting for the GitHub actions build for `wp/latest`[branch to pass](https://github.com/WordPress/gutenberg/actions?query=branch%3Awp%2Ftrunk), identify and begin updating the `CHANGELOG.md` files:

1. `git checkout wp/trunk`
1. `git checkout wp/latest`
2. `npm run publish:check`
> Example
>
Expand All @@ -297,10 +297,10 @@ Note: You may discover the current version of each package is not up to date, if

The good news is that the rest of the process is automated with `./bin/plugin/cli.js npm-bugfix` command. For the record, the manual process would look very close to the following steps:

1. Check out the `wp/trunk` branch.
2. Update the `CHANGELOG.md` files of the packages with the new publish version calculated and commit to the `wp/trunk` branch.
1. Check out the `wp/latest` branch.
2. Update the `CHANGELOG.md` files of the packages with the new publish version calculated and commit to the `wp/latest` branch.
3. Log-in to npm via the console: `npm login`. Note that you should have 2FA enabled.
4. From the `wp/trunk` branch, install npm dependencies with `npm ci`.
4. From the `wp/latest` branch, install npm dependencies with `npm ci`.
5. Run the script `npm run publish:latest`.
- 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.
Expand All @@ -309,7 +309,7 @@ The good news is that the rest of the process is automated with `./bin/plugin/cl

### Development Releases

As noted in the [Synchronizing Gutenberg Plugin](#synchronizing-gutenberg-plugin) section, packages publishing happens every two weeks from the `wp/trunk` branch. It's also possible to use the development release to test the upcoming changes present in the `trunk` branch at any time. We are taking advantage of [package distribution tags](https://docs.npmjs.com/cli/v7/commands/npm-dist-tag) that make it possible to consume the future version of the codebase according to npm guidelines:
As noted in the [Synchronizing Gutenberg Plugin](#synchronizing-gutenberg-plugin) section, packages publishing happens every two weeks from the `wp/latest` branch. It's also possible to use the development release to test the upcoming changes present in the `trunk` branch at any time. We are taking advantage of [package distribution tags](https://docs.npmjs.com/cli/v7/commands/npm-dist-tag) that make it possible to consume the future version of the codebase according to npm guidelines:

> By default, the `latest` tag is used by npm to identify the current version of a package, and `npm install <pkg>` (without any `@<version>` or `@<tag>` specifier) installs the `latest` tag. Typically, projects only use the `latest` tag for stable release versions, and use other tags for unstable versions such as prereleases.

Expand Down