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

ci: deploy hotfixes as prerelease #9469

Closed
wants to merge 2 commits into from

Conversation

benelan
Copy link
Member

@benelan benelan commented May 30, 2024

Summary

Change the hotfix deployment CI to use pre-releases, e.g. 2.9.0-hotfix.0.

Why though?

The need to publish hotfixes as pre-releases is related to Calcite's continuous integration setup. Calcite uses Release Please, which requires a linear git history to properly handle versioning and changelog generation. Release Please finds the most recent GitHub release's tag and uses it to determine the version bump (major, minor, patch) and which commits to add to the changelog.

In Calcite's workflow, the commits on the hotfix branch are synced to main after a hotfix is released. If hotfixes are released as semver patch bumps, Release Please will ignore all the commits that happened before the hotfix landed on main, which will omit items from the changelog and potentially release as the wrong version.

For example, let's say a v2.8.0 latest release was deployed, a v2.8.1 hotfix was needed/deployed, and then a new latest release is ready to deploy. This is the state of the git history in the example:

  * 0757be0 (HEAD -> main) fix: number sanitization
  * 14e9a92 (tag: v2.8.1) chore: release hotfix v2.8.1
  * 04e2a2c fix: types related build error
  * 1eee108 fix: focus style
  * 4062654 feat: add component
  | * 5253edd (hotfix) chore: release hotfix v2.8.1
  | * 25dff34 fix: types related build error
  |/
  * 302c41b (tag: v2.8.0) chore: release latest v2.8.0
  * a502c34 ...
Git history generation script for example
mkdir hotfix-example
cd hotfix-example || return
git init --initial-branch main

# install to and release from main branch
echo "truncated" >one
git add --all
git commit --message "..."
echo "latest release" >two
git add --all
git commit --message "chore: release latest v2.8.0"
git tag -m v2.8.0 -a v2.8.0 HEAD
echo "feat" >three
git add --all
git commit --message "feat: add component"

# install to and release from hotfix branch
git checkout -b hotfix v2.8.0
echo "hotfix" >four
git add --all
git commit --message "fix: types related build error"
echo "hotfix release" >six
git add --all
git commit --message "chore: release hotfix v2.8.1"
git tag -m v2.8.1 -a v2.8.1 HEAD

# sync hotfix -> main
git checkout main
git cherry-pick ..hotfix
sleep 1 # fix timing issue

# GitHub's rebase merge option creates new commit SHAs, meaning the hotfix tag
# won't exist on main. Release Please will abort if it finds a GitHub release
# without a release tag on the branch its running on, so the tag needs to be
# recreated on main.
# 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
git tag -f -m v2.8.1 -a v2.8.1 HEAD

# install fix to main branch
echo "fix" >seven
git add --all
git commit --message "fix: number sanitization"

# visualize history
git log --all --decorate --oneline --graph

The upcoming latest release should be deployed as v2.9.0 and the changelog section should have entries for the commits that landed on main but not hotfix.

The changelog should look like this
## v2.9.0

### Fix

- fix: focus style
- fix: number sanitization

### Feature

- feat: add component

## v2.8.1

### Fix

- fix: types related build error

However, Release Please will stop looking at commits once it finds the most recent latest release tag, in this case the v2.8.1 hotfix. This means the release will be deployed as v2.8.2, since there is one "fix" commit since hotfix was synced to main.

The changelog will incorrectly look like this
## v2.8.2

### Fix

- fix: number sanitization

## v2.8.1

### Fix

- fix: types related build error

Calcite's solution to this issue is deploying hotfix v2.8.1-hotfix.0 instead of v2.8.1, v2.8.1-hotfix.1 instead of v2.8.2, etc., because GitHub Releases aren't created for pre-releases. This means Release Please will ignore their tags, so the version bump and changelog generation will be correct.

@github-actions github-actions bot added the chore Issues with changes that don't modify src or test files. label May 30, 2024
Copy link
Member

@jcfranco jcfranco left a comment

Choose a reason for hiding this comment

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

✨🦾🤖✨

@jcfranco jcfranco added the skip visual snapshots Pull requests that do not need visual regression testing. label May 31, 2024
@benelan
Copy link
Member Author

benelan commented Jun 4, 2024

Closing in favor of #9514

@benelan benelan closed this Jun 4, 2024
@benelan benelan deleted the benelan/use-prerelease-for-hotfix branch June 4, 2024 20:05
benelan added a commit that referenced this pull request Jun 10, 2024
**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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore Issues with changes that don't modify src or test files. skip visual snapshots Pull requests that do not need visual regression testing.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants