Skip to content

Branches and releases

Alexander Thomas edited this page Apr 29, 2020 · 23 revisions

Branches and work flows

We have a rather simple branch setup for the dart project. Normally, everything is developed on the master branch. Features that are not yet ready for prime time are hidden under a flag, and enabled when sufficient stability has been proven. We occasionally create feature branches for landing big and disruptive changes. In addition to that, we have our dev, beta, and stable branches used for releasing the sdk.

In summary, we have in four main branches:

  • master: Used for "everyday" development; land your CLs here.

  • dev: Populated from the master branch via full pushes, usually twice a week. Only in emergencies are cherry picks landed on the dev channel. Don't land CLs here. Released via dev channel builds.

  • beta: Populated from the dev branch via full pushes, usually once a month, or via cherry picks. Don't land CLs here. Released via beta channel builds.

  • stable: Our main release branch, populated from the beta branch via full pushes when a release is ready, or via cherry picks. Don't land CLs here. Released via stable channel builds.

Release cycle

Our normal release cycle is roughly 2 months long, but we don't make any guarantees, i.e., we may ship early if we feel that the stability is good or we may ship late if it is not. We don't normally follow a feature driven release cycle, but in some cases for larger changes to the language we may postpone a release to get all tools in sync.

During the entire cycle we do full merges of master to dev, basically releasing a green build from master on dev roughly twice a week. In case of bugs found quickly we do another full push.

We spend the last ~2 weeks of the cycle stabilizing the beta channel, starting with a full push of the latest dev release to beta. We only cherry picking critical fixes to the beta channel. People continue working on the master branch and dev releases will continue to be released. In this 2 week period we do multiple batches of cherry picks a week, and release those on the beta channel. We call this cherry-pick season.

Once we have something that looks good we merge it to stable and release it there. During the 2 months we do patch security, crash and critical bug releases on stable based on the latest stable version.

Dev branch

Pushing to dev

Find a suitable commit with green builds on master, we call this #MASTER_HASH_TO_BASE_RELEASE_OFF. We call the version we are pushing $THE_VERSION_BEING_PUSHED, this is based on the actual values in tools/VERSION, but looks like this "2.9.0-3.0.dev".

git new-branch --upstream origin/dev dev
git merge --no-commit #MASTER_HASH_TO_BASE_RELEASE_OFF

Update tools/VERSION (for these full pushes reset PRERELEASE_PATCH to 0, increase PRERELEASE by 1, the updated version is your $THE_VERSION_BEING_PUSHED)

git commit -a

Update the commit message, it should read like:

Version $THE_VERSION_BEING_PUSHED

Merge commit '#MASTER_HASH_TO_BASE_RELEASE_OFF' into dev

Sanity check:

git diff #MASTER_HASH_TO_BASE_RELEASE_OFF

should only give differences in the tools/VERSION file.

Push the changes:

git push

Tag the new release:

git tag -a $THE_VERSION_BEING_PUSHED -m $THE_VERSION_BEING_PUSHED
git push --tags

Beta branch

Getting your changes to beta channel during cherry pick season

See the cherry pick to beta page for all the details on how to get a change cherry picked.

Pushing to beta

Assume that the dev channel build we want to base this of is #DEV_HASH_TO_BASE_RELEASE_OFF

git new-branch --upstream origin/beta release
git merge --no-commit #DEV_HASH_TO_BASE_RELEASE_OFF

There may very well be merge conflicts if we did patch releases on beta in the prior release. Always just solve these by taking the dev version. Because of this, always do a sanity check:

git diff #DEV_HASH_TO_BASE_RELEASE_OFF

This should only give a difference in the version file. If not, checkout the file(s) from #DEV_HASH_TO_BASE_RELEASE_OFF.

Update tools/VERSION (for these full pushes reset PRERELEASE_PATCH to 1, and CHANNEL to beta; all other values must match the tool/VERSION in #DEV_HASH_TO_BASE_RELEASE_OFF). As before, we call the version $THE_VERSION_BEING_PUSHED. On beta, versions look almost like dev versions but with a ".beta" suffix, e.g., 2.9.0-3.1.beta.

git push

Tag the new release:

git tag -a $THE_VERSION_BEING_PUSHED -m $THE_VERSION_BEING_PUSHED
git push --tags

Cherry picking to beta

Please don't just cherry pick your changes to beta, we normally batch these up. Instead file a merge request (see above).

We do this using two branches to get a nice looking history on the beta branch, and to not trigger builds with non working versions on the bots (the bot git poller will do git log --first-parent when figuring out commits.

$THE_VERSION_BEING_PUSHED has the same meaning as above. The #HASH_1 ... #HASH_N are the commits we want to cherry pick

git new-branch --upstream origin/beta cherry
git cherry-pick #HASH_1
.
.
.
git cherry-pick #HASH_N

Now, we have all the cherry picks on the cherry branch, create the branch we will use for pushing, merge the cherry picks in (to get a merge node similar to what we have for normal full pushes). We use --no-ff to get the merge node instead of fast forward commits.

git new-branch --upstream origin/beta beta
git merge --no-ff --no-commit cherry

Edit tools/VERSION, increase PRERELEASE_PATCH by N where N is the number of commits that are cherry-picked.

git commit -a

Commit message should read:

Version $THE_VERSION_BEING_PUSHED

Cherry-pick #HASH_1 to beta
.
.
.
Cherry-pick #HASH_N to beta

Sanity check the log, make sure all the cherry picks are there and that the Version commit has the right structure.

Push the changes:

git push

Tag the new release:

git tag -a $THE_VERSION_BEING_PUSHED -m $THE_VERSION_BEING_PUSHED
git push --tags

Stable branch

The way we handle stable releases is more or less equal to the way we handle beta. When we have a good beta channel build after 2 weeks of cherry-picking, we merge that over to the stable branch:

Getting your changes to a new stable patch release

First of, before doing any patch releases on stable the commits should already have been on dev (and ideally beta) for a number of days without reported issues (preferably more than a week). Also, before releasing it, we need more manual validation and sanity checking. Please send out a mail internally requesting for feedback and ask the people responsible for the patches going in to validate functionality.

We normally simply cherry pick the changes from master, and there is no difference in how we do this compared to beta channel, except, we don't increase PRERELEASE_PATCH, we increment PATCH in the tools/VERSION file.

Once you are ready, create a cherry pick issue, see Cherry picks to stable.

Doing a new full stable build

Assume that the beta channel build we want to base this of is #BETA_HASH_TO_BASE_RELEASE_OFF

git new-branch --upstream origin/stable stable
git merge --no-commit #BETA_HASH_TO_BASE_RELEASE_OFF

There may very well be merge conflicts if we did patch releases on stable in the prior release. Always just solve these by taking the beta version. Because of this, always do a sanity check:

git diff #BETA_HASH_TO_BASE_RELEASE_OFF

This should only give a difference in the version file. If not, checkout the file(s) from #BETA_HASH_TO_BASE_RELEASE_OFF.

Update tools/VERSION (for these full pushes reset PRERELEASE_PATCH to 0, reset PRERELEASE to 0, reset PATCH to 0, set MINOR to the version from DEV (i.e., if we are doing this to release 2.9.0 set it to 9). As before, we call the version $THE_VERSION_BEING_PUSHED, on stable this is more simple, e.g., 2.9.0.

git push

Tag the new release:

git tag -a $THE_VERSION_BEING_PUSHED -m $THE_VERSION_BEING_PUSHED
git push --tags

Finally, make sure everything on the release checklist is completed.

Clone this wiki locally