Skip to content

Commit

Permalink
ci: rework release workflow making dev the default branch (#9514)
Browse files Browse the repository at this point in the history
**Related Issue:** #9469 will be closed in favor of this PR

## Summary

Make CI changes for a new release workflow that supports hotfixes as
patch bumps without causing friction with the versioning and changelog
generation setup.

- All PRs are switched to target the `dev` branch instead of `main`
- When it's time for a release, create a branch off of `dev`, open a PR
targeting `main`, and use the [rebase
merge](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/about-merge-methods-on-github#rebasing-and-merging-your-commits)
method when installing.
- Install the Release Please PR generated via the step above, which
creates the github releases and git tags on `main` (where they currently
are for all previous releases) and deploys to NPM.
- Checkout a branch off of and create/install a PR to `dev` containing
the cherry-picked the release commit (changelog and package.json version
modifications) from `main`.
- Continue development on `dev`, where `next` releases are deployed
from.
- Commits for a hotfix get cherry-picked from `dev` to `main` as needed.
- When its time for a hotfix release, install the Release Please PR into
`main` and cherry-pick the release commit back to `dev`
- Cycle continues...

## Notes

- The default branch will be changed to `dev` and `main` will be our
release branch, since that's where all of the tags already exist.
- We need to rebase merge `dev` to `main` due to our changelog
generation and versioning setup:
  - squashing won't work, since all of the commits need to be on `main`
  - a normal merge won't work, since a linear history is required
- There won't be duplicate commits from syncing back and forth because
rebasing automatically drops cherry-picked commits.
- Unfortunately, GitHub doesn't support per-branch merge methods, so we
will need to remember to:
  - enable rebase-merge method in the repo settings
  

![image](https://github.com/Esri/calcite-design-system/assets/10986395/9fa8be42-7923-47f9-b2d8-df65416e88cc)

- switch the method to rebase-merge in the PR when installing changes
from `dev` to `main`
  

![image](https://github.com/Esri/calcite-design-system/assets/10986395/fcbfa86d-950f-459f-8ecd-e468d4373415)

  - disable rebase-merge in the repo settings
  • Loading branch information
benelan authored Jun 10, 2024
1 parent 8edeb36 commit d8d1629
Show file tree
Hide file tree
Showing 16 changed files with 165 additions and 115 deletions.
57 changes: 57 additions & 0 deletions .github/scripts/publishPrerelease.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash

if [ "$BRANCH" = "dev" ]; then
if [ "$NEXT_RELEASE_ENABLED" != "true" ]; then
echo "Next release is disabled"
exit 0
fi

if ! npm run util:is-next-deployable; then
echo "No deployable changes in dev"
exit 0
fi
fi

npm install

# version the packages with lerna before building to ensure the version in
# Calcite components' source code preamble is correct for deployment
if [ "$BRANCH" = "dev" ]; then
npm run version:next
elif [ "$BRANCH" = "main" ]; then
npm run version:hotfix
elif [ "$BRANCH" = "rc" ]; then
npm run version:rc
fi

npm run build
npm test

git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"

# make sure the committed, autogenerated files are up to date before releasing.
# The "|| true" prevents failure if there are no changes.
git add packages/calcite-components/src/components.d.ts package-lock.json || true
git commit -m "build: update types and package-lock" || true

# try deploying storybook, but still release next if it fails with "|| true"
if [ "$BRANCH" = "main" ]; then
{ npm run --workspace=@esri/calcite-components build-storybook &&
npx --workspace=@esri/calcite-components storybook-to-ghpages \
--host-token-env-variable=GH_TOKEN_FOR_STORYBOOK \
--existing-output-dir=docs --ci; } || true

# remove the built docs after storybook deploys to gh-pages
git reset --hard
fi

if [ "$BRANCH" = "main" ]; then
npm run publish:next
elif [ "$BRANCH" = "dev" ]; then
npm run publish:hotfix
elif [ "$BRANCH" = "rc" ]; then
npm run publish:rc
fi

npm run util:push-tags
4 changes: 2 additions & 2 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Chromatic
on:
push:
branches: [main, hotfix, rc]
branches: [main, rc, dev]
pull_request:
branches: [main, hotfix, rc]
branches: [main, rc, dev]
types: [labeled, synchronize]
jobs:
run:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ name: "CodeQL"

on:
push:
branches: [main, rc]
branches: [main, rc, dev]
pull_request:
# The branches below must be a subset of the branches above
branches: [main, rc]
branches: [main, rc, dev]
schedule:
- cron: "19 2 * * 4"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Deploy Latest
on:
workflow_dispatch:
push:
branches: [main, hotfix]
branches: [main]
permissions:
contents: write
pull-requests: write
Expand Down
68 changes: 0 additions & 68 deletions .github/workflows/deploy-next.yml

This file was deleted.

45 changes: 45 additions & 0 deletions .github/workflows/deploy-prerelease.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Deploy Prerelease
concurrency:
group: deploy_prerelease
cancel-in-progress: true
on:
# `next` versions are automatically released when deployabled commits are pushed to dev
push:
branches: [dev]
# `hotfix` and `rc` versions must be manually released:
# https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.ADMIN_TOKEN }}
ref: ${{ github.base_ref || github.ref_name }}
- uses: actions/setup-node@v4
with:
node-version-file: package.json
registry-url: "https://registry.npmjs.org"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Deploy prerelease and storybook
env:
NEXT_RELEASE_ENABLED: ${{ secrets.NEXT_RELEASE_ENABLED }}
# https://github.com/storybookjs/storybook-deployer/issues/77#issuecomment-618560481
GH_TOKEN_FOR_STORYBOOK: ${{ github.actor }}:${{ secrets.ADMIN_TOKEN }}
NPM_CONFIG_PROVENANCE: true
BRANCH: ${{ github.base_ref || github.ref_name }}
run: ../scripts/publishPrerelease.sh
- name: notify teams
uses: toko-bifrost/[email protected]
if: ${{ !cancelled() && github.event_name == 'push' }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
webhook-uri: ${{ secrets.TEAMS_WEBHOOK_URI_BUILD }}
show-on-start: false
card-layout-exit: complete
timezone: America/Los_Angeles
2 changes: 1 addition & 1 deletion .github/workflows/pr-bot.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: PR Bot
on:
pull_request:
branches: [main, rc, hotfix]
branches: [main, rc, dev]
permissions:
pull-requests: write
issues: write
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: E2E
on:
workflow_dispatch:
pull_request:
branches: [main, rc, hotfix]
branches: [main, rc, dev]
jobs:
e2e:
runs-on: ubuntu-20.04
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-milestone.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: PR Merged
on:
pull_request:
branches: [main, rc]
branches: [main, rc, dev]
types: [closed]
jobs:
milestone:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/remove-prerelease-changelog-entries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ on:
push:
branches:
- release-please--branches--main
- release-please--branches--hotfix
permissions:
contents: write
pull-requests: write
Expand Down
2 changes: 1 addition & 1 deletion documentation/monorepo.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,4 @@ A `remove-prerelease-changelog-entries.yml` GitHub Action runs the `removePrerel

### Steps to release

For the most part the releases are automated in the CI (see the sections above). However, there are a few manual steps, which are described in the [releasing documentation](/Releasing.md).
For the most part the releases are automated in the CI (see the sections above). However, there are a few manual steps, which are described in the [releasing documentation](./releasing.md).
66 changes: 40 additions & 26 deletions documentation/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,65 +12,77 @@ When releasing during normal work hours, you should block people from merging PR

1. Let the team know via Teams in the `Core - Releases` 🔒 channel (@ the channel for visibility)
1. Go to the repo settings -> "Branches"
1. Under "Branch protection rules" edit the entry for `main`
1. Under "Branch protection rules" edit the entry for `dev`
1. Under "Require approvals" change the number from 1 to 6 and save the changes.

![image](https://user-images.githubusercontent.com/10986395/167955616-c796d1ff-5c1a-4332-a6d5-5288f9d20992.png)

### Release steps

The `latest` release process is mostly automated, but a few manual steps are required:
Follow these steps to release a major, minor, or patch version:

1. Follow the steps above to [prevent merging pull requests](#prevent-merging-pull-requests).
2. Make sure all of the workflows for the [most recent commit on `main`](https://github.com/Esri/calcite-design-system/commits/main) are completed.
1. If time is short, you can cancel the `Build` workflow, which releases `next` and deploys storybook. We just want to make sure it doesn't deploy the `next` version after `latest` is released. If the most recent commit is a next release (titled `chore: release next`) then you can definitely cancel the `Build` workflow since it will be intentionally cancelled by the CI anyway.
3. Review the PR created by `release-please` (titled `chore: release main`) to make sure the changelog(s) and package versioning looks correct.
1. There should be a commit on the PR's branch named `docs: remove prerelease changelog entries` that occurred **after** the most recent commit on `main`.
4. Add the `skip visual snapshots` label. <!-- TODO: automate this in the release-please config -->
5. Make sure the rest of the PR checks are passing.
6. Approve and install the PR once all checks are passing. You will need to use Admin privilege to override the 6 approval rule [added above](#prevent-merging-pull-requests).
7. Wait for the release's [Deploy Latest](https://github.com/Esri/calcite-design-system/actions/workflows/deploy-latest.yml) action to finish.
8. Ensure the released package(s) were deployed to NPM and that [GitHub Releases were created](https://github.com/Esri/calcite-design-system/releases).
1. [Create a new branch](https://github.com/Esri/calcite-design-system/branches) off of `dev`.
1. Create a pull request from the new branch with `main` as the target.
1. Once the pull request is ready to install, enable "Allow rebase merging" under the Pull Requests section of the [repo settings](https://github.com/Esri/calcite-design-system/settings).
![image](https://github.com/Esri/calcite-design-system/assets/10986395/9fa8be42-7923-47f9-b2d8-df65416e88cc)
1. In the pull request created in step 3, switch the merge method to "Rebase and merge" and install.
![image](https://github.com/Esri/calcite-design-system/assets/10986395/fcbfa86d-950f-459f-8ecd-e468d4373415)
1. Disable the "Allow rebase merging" option from step 4.
1. Wait for the [Deploy Latest](https://github.com/Esri/calcite-design-system/actions/workflows/deploy-latest.yml) workflow run on `main` to complete.
1. Review the PR created by `release-please` (titled `chore: release main`) to make sure the changelog(s) and package versioning looks correct.
- There should be a commit on the PR's branch named `docs: remove prerelease changelog entries` that occurred **after** the most recent commit on `main`.
1. Make sure the rest of the PR checks are passing.
1. Approve and install the PR once all checks are passing. You will need to use Admin privilege to override the 6 approval rule.
1. Wait for the release's [Deploy Latest](https://github.com/Esri/calcite-design-system/actions/workflows/deploy-latest.yml) workflow run to finish.
1. Ensure the released package(s) were deployed to NPM and that [GitHub Releases were created](https://github.com/Esri/calcite-design-system/releases).

- You can check the NPM version(s) on the website (e.g., [calcite-components](https://www.npmjs.com/package/@esri/calcite-components?activeTab=versions)) or with the CLI:

```sh
npm view @esri/calcite-components version
```
```sh
npm view @esri/calcite-components version
```

1. See the [troubleshooting](#troubleshooting) section if something went wrong, or reach out to Ben or Franco for help.
1. Create a new branch off of `dev` and cherry-pick the release commit from `main` (the version bumps and changelog sections).

```sh
git checkout dev && git pull && git checkout -b cherry-pick-release && git cherry-pick main && git push -u HEAD
```

9. See the [troubleshooting](#troubleshooting) section if something went wrong, or reach out to Ben or Franco for help.
10. Change the `main` branch's required approvals back to 1 and save the changes (see the [Prevent merging PRs](#prevent-merging-pull-requests) section)
11. Let the team know via Teams merging is now unblocked in the initial `Core - Releases` message from earlier.
1. Create a pull request from the new branch to `dev`, and install it by squash merging.
1. Change the `dev` branch's required approvals back to 1 and save the changes (see the [Prevent merging PRs](#prevent-merging-pull-requests) section)
1. Let the team know via Teams merging is now unblocked in the initial `Core - Releases` message from earlier.

### Troubleshooting

The following are some troubleshooting steps you can take if a release is unsuccessful.

1. Find the workflow run for the release [here](https://github.com/Esri/calcite-design-system/actions/workflows/deploy-latest.yml), and view the logs to find the error message.
2. Fix the error. In some cases you can resolve the issue with a temporary solution, and then fix the CI after the release is completed. For example, if the `components.d.ts` file is outdated and breaks releases due to an unclean working tree, the [temporary solution](https://github.com/Esri/calcite-design-system/pull/9008) would be to build locally and submit a PR with the updated file. That way you won't be so time crunched when determining an [actual fix](https://github.com/Esri/calcite-design-system/pull/9011) to prevent the same error from occurring in the future. Reach out to Ben or Franco if a solution to the error isn't clear.
3. Once the PR with the fix is installed, make sure the new workflow run is passing.
4. **IMPORTANT:** If the new release is showing up in the [GitHub releases](https://github.com/Esri/calcite-design-system/releases) but not on NPM, you'll need to release locally. This signifies the error involved publishing to NPM, which happens after the releases and tags are created on GitHub. To release locally, run the following commands:
1. Fix the error. In some cases you can resolve the issue with a temporary solution, and then fix the CI after the release is completed. For example, if the `components.d.ts` file is outdated and breaks releases due to an unclean working tree, the [temporary solution](https://github.com/Esri/calcite-design-system/pull/9008) would be to build locally and submit a PR with the updated file. That way you won't be so time crunched when determining an [actual fix](https://github.com/Esri/calcite-design-system/pull/9011) to prevent the same error from occurring in the future. Reach out to Ben or Franco if a solution to the error isn't clear.
1. Once the PR with the fix is installed, make sure the new workflow run is passing.
1. **IMPORTANT:** If the new release is showing up in the [GitHub releases](https://github.com/Esri/calcite-design-system/releases) but not on NPM, you'll need to release locally. This signifies the error involved publishing to NPM, which happens after the releases and tags are created on GitHub. To release locally, run the following commands:

```sh
npm install && npm run build && npm test && npm run publish:latest
```
```sh
npm install && npm run build && npm test && npm run publish:latest
```

### Bumping the examples

A [GitHub Action](https://github.com/Esri/calcite-components-examples/blob/master/.github/workflows/bump-examples.yml) will automatically bump the versions in [`calcite-components-examples`](https://github.com/Esri/calcite-components-examples) and open a PR on Wednesday night after the release. Make sure to test the samples when there are major changes. [Here](https://github.com/Esri/calcite-components-examples/blob/master/.github/scripts/bump-examples.js) is the script if any changes are needed.

## next releases

`next` releases are useful for testing incoming changes between releases. They are [released by the CI](/Monorepo.md#ci-for-next-releases) after 'deployable' commits are installed to `main`. A deployable commit is:
`next` releases are useful for testing incoming changes between releases. They are [released by the CI](./monorepo.md#ci-for-next-releases) after 'deployable' commits are installed to `dev`. A deployable commit is:

1. a commit of type `feat` or `fix`
2. a commit that introduces a breaking change
1. a commit that introduces a breaking change

If you need to disable `next` releases, you can do so by setting the `NEXT_RELEASE_ENABLED` GitHub Secret to anything but `true`. If you need to manually release `next`, you can run the following commands from the monorepo's root directory:

```sh
# make sure you don't have any unsaved work
git checkout main
git checkout dev
npm run clean
npm install
npm test
Expand All @@ -88,8 +100,10 @@ git add packages/*/CHANGELOG.md
git commit amend --no-edit
git tag -d "@esri/[email protected]"
git tag -d "@esri/[email protected]"
git tag -d "@esri/[email protected]"
git tag -a "@esri/[email protected]" -m "@esri/[email protected]" HEAD
git tag -a "@esri/[email protected]" -m "@esri/[email protected]" HEAD
git tag -a "@esri/[email protected]" -m "@esri/[email protected]" HEAD
# now you can publish and push tags
```

Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"command": {
"version": {
"conventionalCommits": true,
"allowBranch": ["main", "rc", "hotfix"]
"allowBranch": ["main", "rc", "dev"]
}
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"start": "turbo run start --log-order=stream",
"test": "turbo run test --log-order=stream",
"util:is-next-deployable": "tsx support/isNextDeployable.ts",
"util:push-tags": "git push origin main --follow-tags",
"util:push-tags": "git push origin HEAD --follow-tags",
"util:upload-release-assets": "tsx support/uploadReleaseAssets.ts",
"util:remove-prerelease-changelog-entries": "tsx support/removePrereleaseChangelogEntries.ts",
"util:sync-linked-package-versions": "tsx support/syncLinkedPackageVersions.ts"
Expand Down
6 changes: 3 additions & 3 deletions support/isNextDeployable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
throw new Error("No deployable changes since the previous release, skipping ⛔");
}

await runGit("checkout", "main", "--quiet");
await runGit("checkout", "dev", "--quiet");
await runGit("fetch", "--tags", "--quiet");

if (
(await latestCommit("main")) != (await latestCommit("origin/main")) &&
(await deployable("main", "origin/main"))
(await latestCommit("dev")) != (await latestCommit("origin/dev")) &&
(await deployable("dev", "origin/dev"))
) {
throw new Error("There is a more recent deployable install, aborting ⛔️");
}
Expand Down
Loading

0 comments on commit d8d1629

Please sign in to comment.