diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3847d83..f91e2e1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ ### All Submissions: -* [ ] Have you followed the [Newspack Contributing guideline](https://github.com/Automattic/newspack-theme/blob/master/.github/CONTRIBUTING.md)? +* [ ] Have you followed the [Newspack Contributing guideline](https://github.com/Automattic/newspack-theme/blob/trunk/.github/CONTRIBUTING.md)? * [ ] Have you checked to ensure there aren't other open [Pull Requests](../../pulls) for the same update/change? diff --git a/README.md b/README.md index 1281b1e..2ab6256 100644 --- a/README.md +++ b/README.md @@ -53,30 +53,51 @@ Will validate TypeScript code in the project. This requires a `tsconfig.json` fi This package contains a configuration of [`semantic-release`](semantic-release.gitbook.io/), which can be used for automated software releases, published on Github. It's configured to work with the following repository branch setup: -1. `master` – ongoing development +1. `trunk` – ongoing development 1. `alpha` – release candidate +1. `hotfix/*` - for testing urgent bugfixes +1. `epic/*` - for testing large-scale features 1. `release` – the production-ready, released code The following assumes that CI will run: -1. `npm run release` for `release`, `alpha`, and `hotfix/*` branches +1. `npm run release` for `release`, `alpha`, `hotfix/*`, and `epic/*` branches 1. `post-release.sh` script on `release` branch, after the above command completes ### Regular release flow -1. Commit ongoing changes to `master` branch, using [structured commit messages](https://www.conventionalcommits.org/en/v1.0.0/) -1. Merge `master` into `alpha` to create a release candidate (e.g. `1.2.0-alpha.1`) -1. Merge `alpha` into `release` to create a release (e.g. `1.2.0`) -1. `alpha` branch will be reset on top of `release` -1. `master` branch will be updated with the changes from the `release` branch +1. Create a new branch off the `trunk` branch. +1. Commit changes to your branch using [structured commit messages](https://www.conventionalcommits.org/en/v1.0.0/). +1. Open a pull request for review based on `trunk`. Changes must be tested and approved before merging. +1. Merge approved changes to the `trunk` branch. When merging into `trunk`, SQUASH the merge. +1. Merge `trunk` into `alpha` to create a release candidate (e.g. `1.2.0-alpha.1`). When merging `trunk` into `alpha`, DO NOT SQUASH the merge. +1. Merge `alpha` into `release` to create a production release (e.g. `1.2.0`). When merging `alpha` into `release`, DO NOT SQUASH the merge. +1. `alpha` branch will be reset on top of `release`. +1. `trunk` branch will be updated with the changes from the `release` branch. + +### Epic feature release flow + +For large-scale features that require more than one interdependent branch throughout development. + +1. Create a new `epic/*` branch off the `trunk` branch. Push the branch to GitHub so all engineers can work off it simultaneously. **Keep this branch up-to-date with `trunk`, to minimize the risk of merge conflicts.** +1. Create new sub-branches off the epic branch. **Keep sub-branches up-to-date with the `epic/*` branch, to minimize the risk of merge conflicts.** +1. Commit changes to your sub-branches using [structured commit messages](https://www.conventionalcommits.org/en/v1.0.0/). +1. Open pull requests for review based on the `epic/*` branch. Changes must be tested and approved before merging. +1. Merge approved changes to the `epic/*` branch. When merging into `epic/*`, DO NOT SQUASH the merge. +1. A new "epic" pre-release (e.g. `1.2.0-epic-feature.1`) will be tagged and published when changes are merged via PR. Use epic releases for QA and other pre-release testing. +1. Once all features in the `epic/*` branch have been tested and approved, open a pull request for final review based on `trunk`. Final review doesn't require full-scale functional testing, only a review of the changeset (as changes have already been tested in individual PRs). +1. Merge the `epic/*` branch to the `trunk` branch. When merging an epic branch into `trunk`, SQUASH the merge. +1. Once `epic/*` has been merged to `trunk`, follow the regular release flow to generate release candidates and production releases. ### Hotfix release flow -1. Create a new `hotfix/*` branch off the `release` branch +1. Create a new `hotfix/*` branch off the `release` branch. +1. Commit changes to your branch using [structured commit messages](https://www.conventionalcommits.org/en/v1.0.0/). 1. Push the branch to Github, so the CI can process it – _don't create a PR just yet!\*_ -1. A new "hotfix" pre-release (e.g. `1.2.0-hotfix.1`) will be published -1. Merge the hotfix branch into `release` to create a release -1. `alpha` & `master` branches will be updated with the changes from the `release` branch +1. A new "hotfix" pre-release (e.g. `1.2.0-hotfix.1`) will be tagged and published. +1. Open a pull request for review based on `release`. Changes must be tested and approved before merging. +1. Merge the hotfix branch into `release` to create a release. When merging a hotfix into `release`, SQUASH the merge. +1. `alpha` & `trunk` branches will be updated with the changes from the `release` branch. \* `semantic-release` [will not release if the CI job was triggered by a PR](https://github.com/semantic-release/semantic-release/blob/971a5e0d16f1a32e117e9ce382a1618c8256d0d9/index.js#L48-L51) diff --git a/post-release.sh b/post-release.sh index f0f6add..7bac57a 100755 --- a/post-release.sh +++ b/post-release.sh @@ -47,24 +47,24 @@ else fi fi -# Update master branch with latest changes from the release branch, so they are in sync. -echo '[newspack-scripts] Merging the release branch into master.' -git checkout master +# Update trunk branch with latest changes from the release branch, so they are in sync. +echo '[newspack-scripts] Merging the release branch into trunk.' +git checkout trunk -# Merge release branch into master branch, and notify the team if any conflicts arise. +# Merge release branch into trunk branch, and notify the team if any conflicts arise. git merge --no-ff release -m "chore(release): merge in release $LATEST_VERSION_TAG" if [[ $? == 0 ]]; then - echo '[newspack-scripts] Pushing updated master to origin.' + echo '[newspack-scripts] Pushing updated trunk to origin.' git push "https://$GITHUB_TOKEN@github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git" else git merge --abort - echo '[newspack-scripts] Post-release merge to master failed.' + echo '[newspack-scripts] Post-release merge to trunk failed.' if [ -z "$SLACK_CHANNEL_ID" ] || [ -z "$SLACK_AUTH_TOKEN" ]; then echo '[newspack-scripts] Missing Slack channel ID and/or token. Cannot notify.' else echo '[newspack-scripts] Notifying the team on Slack.' curl \ - --data "{\"channel\":\"$SLACK_CHANNEL_ID\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"⚠️ Post-release merge to master failed for: \`$CIRCLE_PROJECT_REPONAME\`. Check <$CIRCLE_BUILD_URL|the build> for details.\"}}]}" \ + --data "{\"channel\":\"$SLACK_CHANNEL_ID\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"⚠️ Post-release merge to \`trunk\` failed for: \`$CIRCLE_PROJECT_REPONAME\`. Check <$CIRCLE_BUILD_URL|the build> for details.\"}}]}" \ -H "Content-type: application/json" \ -H "Authorization: Bearer $SLACK_AUTH_TOKEN" \ -X POST https://slack.com/api/chat.postMessage \ diff --git a/scripts/release.js b/scripts/release.js index 0baff39..383f334 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -41,6 +41,13 @@ const getConfig = ({ gitBranchName }) => { // is not valid, though. See https://semver.org/#spec-item-9. prerelease: '${name.replace(/\\//g, "-")}', }, + // `epic/*` branches – for beta testing/QA pre-release builds. + { + name: "epic/*", + // With `prerelease: true`, the `name` would be used for the pre-release tag. A name with a `/` + // is not valid, though. See https://semver.org/#spec-item-9. + prerelease: '${name.replace(/\\//g, "-")}', + }, ], prepare: ["@semantic-release/changelog", "@semantic-release/npm"], plugins: [ @@ -69,17 +76,19 @@ const getConfig = ({ gitBranchName }) => { ], }; - // Unless on a hotfix branch, add a commit that updates the files. - if (gitBranchName.indexOf("hotfix/") !== 0) { + // Bump the semver and prepare a build package. + config.prepare.push([ + // Increment the version in additional files, and the create the release archive. + "semantic-release-version-bump", + { + files: filesList, + callback: "npm run release:archive", + }, + ]); + + // Unless on a hotfix or epic branch, add a commit that updates the files. + if (gitBranchName.indexOf("hotfix/") !== 0 && gitBranchName.indexOf("epic/") !== 0) { utils.log(`Plugin files and the changelog will be updated.`); - config.prepare.push([ - // Increment the version in additional files, and the create the release archive. - "semantic-release-version-bump", - { - files: filesList, - callback: "npm run release:archive", - }, - ]); config.prepare.push({ path: "@semantic-release/git", // These assets should be added to source control after a release. @@ -93,8 +102,9 @@ const getConfig = ({ gitBranchName }) => { "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}", }); } else { + const branchType = gitBranchName.indexOf("hotfix/") === 0 ? 'hotfix' : 'epic'; utils.log( - `This is a hotfix branch, plugin files and the changelog will *not* be updated.` + `This is a ${branchType} branch, plugin files and the changelog will *not* be updated.` ); } diff --git a/src/@orb.yml b/src/@orb.yml index 9431f45..5270831 100755 --- a/src/@orb.yml +++ b/src/@orb.yml @@ -4,5 +4,5 @@ description: > Newspack shared CI config. display: - home_url: "https://newspack.pub" + home_url: "https://newspack.com" source_url: "https://www.github.com/Automattic/newspack-scripts"