How to handle release candidates in git-flow - workflow

We're working by the git-flow workflow. Typically we release some release candidates (RC, v1.0.0-rc.0) before we ship the final release (v1.0.0).
To do so, we have a release branch (release/1.0.0). The release candidates are just tags within that branch. The release branch is not merged into main until we have a final release.
Today we discussed whether we should open a release branch for every release candidate (e.g. `release/1.0.0-rc.0) and merge these into main whenever the candidate is released.
Any opinions on this one?

Generally, if each of the previous release candidates are reachable by the newest one, then they could be on the same branch, and therefore there isn't any benefit to having separate branches for each.
If you wish to make a new release candidate that does not start from the current release candidate (e.g. perhaps you need to back up a few commits, or even start over), then that would be a good time to consider creating a new branch.
I assume once you merge into main you can delete all of the release branches, whether they were fully merged into main or not. Since you still have the old release versions tagged that you didn't use, you could always go back to them if you wish, even without the branches.

Related

Avoid including all workitems on first build on new branch

Our CI/CD is currently set up so we continually produce installers when PR's are completed. However that is for our internal pipeline. When we are ready to release, we open up a stabilization branch (release branch) where we do various things, like flicking a switch in the binaries so they no longer present them as being internal test binaries, but regular production binaries.
The problem is then in the WorkItem tracking. The first build on the release branch shows up as including every workitem included since day 0, and even adds the build to the work items. But we are only interested in marking work items that are in PR's targeting the new release branch, rather than the entire history up till the point of branch creation.
Here's an overview of how we branched out. "4.9.6" only contains one PR (2 commits and 1 merge commit), and the master branch continued ahead:
This is then the first CI build triggered on the release branch:
For some reason it seems to have just included the latest 50 commits (I believe it just capped out there), which also results in a long list of "Linked work items". However, there was only 1 work item included in the only PR in the lifetime of the "4.9.6" branch.
Is it possible somehow to avoid that, or even just a way to work around the issue?

Merge a fix from main to branch or vice versa?

In version control, we have a main branch and recently created a release branch. We were dicussing, where to fix an issue and where to merge it (fix in main and forward integrate to release or fix in release and reverse integrate to main).
Microsoft states in their "Branching and Merging Primer" (https://learn.microsoft.com/de-de/vsts/repos/tfvc/branching-strategies-with-tfvc?view=vsts) that one should never forward integrate from main to release. But they don't present I reason, nor can I think of one.
Is there a reason for this?
A lot depends on your particular way to use a SCM - independently of which one you use.
It makes a difference if you are a company with 1000 committers working on one single
product or if you are talking about a tiny project with just 3 people.
However in general it is indeed not a good idea to merge changes from a main line to
a release line.
Imagine your mainline frequently gets commits (either directly or merged from other branches).
Now we assume that the main branch got some bugfixes that you also want in your release branch.
If you attempt to merge the bugfixes from main to release you probably run into problems, because the bugfixes are entangled with other changes that you don't want in your release branch (possibly because they implement new features for the next release).
Also the merging process might result in new mistakes/errors and break the release which you probably do not want.
See:
This also depends on the question if you want to alter an existing release at all.
You could instead create a new release based on the previous one and then merge
the desired changes from main and subsequently fix them.
This is more or less the same, but with the difference that you never touch an existing release (which may be of importance for you or may be not).
See:
A clean way to update the existing release would be to branch off a temporary branch
from your release branch, then merge the relevant changes from main. After subsequently fixing the temporary branch you can merge it to the release which should now be a simple copy operation without the risk of breaking anything.
See:
Update:
After reading your question again I found that you're thinking about changing in the release and then merging to main.
IMHO a release branch should never ever be used for developing any changes. It should always only pick up changes that were developed and tested in other branches. After all the reason of having release branches is that they are stable and reliable. Any development ruins that.

Branch-per-feature workflow using Mercurial

We have team of 10 developers who works parallel for different features, sometimes these features use common code sometime no.
And now we're changing our process to branch-per-feature and it seems mercurial is more suitable for such development.
I see this process so:
1. make release branch (r-b) from default(trunk)
2. make feature branch (f-b) from default(trunk)
When developer thinks his feature is done he can merge f-b to r-b. When it's time to go to QA we merge all finished f-b to r-b and create release for our QAs.
Questions:
When QA finds a bug developer should modify his f-b and merge it again to r-b. Does it mean that developer just switch to his f-b and start fixing the bug and then makes simple merge f-b to r-b again?
When release is passed QA it goes to PROD - how can we freeze changes? "hg tag" is good choice but someone can update tag if he really wants it.
Thanks
If you're going to merging into specific release branches then your feature branches should be branched from the release branch, not the trunk. It is simpler to merge with the parent branch than a non-parent branch.
1) If you really want to do feature branches then each bug would have its own branch. This will help keep bug fixes separate from new features. After all, it's branch-per-feature not branch-per-developer.
2) Hg tag is what I have used. You are right that someone change move a tag if they really want to, but tags are versioned and you can install hooks on the main hg repo to throw alerts if a tag is moved. I really wouldn't worry about tags being moved unless you can't trust your developers, in which case you are screwed.
The answer to your first question is 'yes'.
The best way to freeze for release is to have a separate release clone that only the release manager can push/pull changesets to. Just because you're using branches doesn't mean multiple-clones don't have a place in your workflow. Have a clone that QA does final pre-flight testing on to which developers can't push changes makes for a great firewall.
Also, consider using bookmarks for your feature branches. Since, as I'm sure you know, Mercurial named branch names never go away the git-like bookmarks work well for sort lived concepts like features and bugs.

Branching and Merging Strategies

I have been tasked with coming up with a strategy for branching, merging and releasing over the next 6 months.
The complication comes from the fact the we will be running multiple projects all with different code changes and different release dates but approximately the same development start dates.
At present we are using VSS for code management, but are aware that it will probably cause some issues and will be migrating to TFS before new development starts.
What strategies should I be employing and what things should I be considering before setting a plan down?
Sorry if this is vague, feel free to ask questions and I will update with more information if required.
This is the single best source control pattern that I have come across. It emphasizes the importance of leaving the trunk free of any junk (no junk in the trunk). Development should be done in development branches, and regular merges (after the code has been tested) should be made back into the trunk (Pic 1), but the model also allows for source to be patched while still under development (Pic 2). I definitely recommend reading the post in its entirety, to completely understand.
Pic 1
Pic 2
Edit: The pictures are definitely confusing without words. I could explain, but I would basically be copying the original author. Having said that, I probably should have selected a better picture to describe the merge process, so hopefully this helps. I'd still recommend reading the post, however:
The simplest and most usual way I've seen branching work is off two premises. Trunk and Release. I think this is known as the "Unstable trunk, stable branch" philosophy.
Trunk is your main source. This contains the "latest and the greatest" code and is forward looking. It generally isn't always stable.
Release is a one-to-many association with trunk. There is one trunk but many releases that derive from the trunk. Releases generally start with a branch of the trunk once a particular functionality milestone has been hit so the "only" things left to go in for a particular deployment should just be bug fixes. You then branch the trunk, give it a label (e.g. 1.6 Release is our current latest Release), build and send the release to QA. We also push the version number (usually the minor number) of the trunk up at this point to ensure we don't have two releases with the same number.
Then you begin the testing cycle on your release branch. When sufficient testing has been perfomed you apply bug fixes to the release branch, merge these back to the trunk (to ensure bug fixes are carried forward!) and then re-release a build of the branch. This cycle with QA continues until you are both happy and the release is finally given to the customer(s). Any bug reports from the customer(s) that are accurate (i.e. they are a bug!) start another QA cycle with the branch in question.
As you create future releases it is a good idea to also try to move older customers onto newer branches to reduce the potential number of branches you might have to back-patch a bug fix into.
Using this technique you can deploy solutions using your technology to a variety of customers that require different levels of service (starting with least first), you can isolate your existing deployments from "dangerous" new code in the trunk and the worst merge scenario is one branch.
My first recommendation would be to read Eric Sink's Source Control HOWTO - specifically the branches and branch merge chapters.
We have 3 containers - DEV, MAIN, and RELEASE for our work. MAIN contains all our "ready-to-release" code and we tend to think of it as "basically stable." DEV/Iteration (or DEV/Feature, or DEV/RiskyFeatureThatMightBreakSomeoneElse) are branches from MAIN and are merged up when the Iteration/Feature is ready to promote up past the DEV environment. We also have TFS builds set up from the DEV/Iteration branch and the MAIN branch.
Our RELEASE container contains numbered releases (similar to the "tags" container used in many Subversion repositories). We simply take a branch from MAIN each time - I like to say we're "cutting" a RELEASE branch to signify this shouldn't have a lot of activity going on once the merge is finished.
As for VSS->TFS - Microsoft supports an upgrade path which should keep your version history, but if you don't need it the history, I would just get the latest version from VSS, check it into TFS and archive the VSS repository.
One final tip - get your team members familiar with source control. They must understand branching and merging or you will be stuck doing a lot of cleanup work :).
Good luck!
The subversion book describes some common branching patterns. Maybe you can also apply these to TFS.

Pros and cons of version promotion vs. version branches

In my current project I have to decide which technique to use when branching. I have two options (we'll assume that we already have decided to develop in the trunk):
Version branches
Make a branch whenever a new version is put on the test machines and tag it like "release0.1". Bugs are fixed in this branch (and then merged to the trunk of course) and when this release finally goes live it's tagged "release0.1.1". This leads to having a branch for every major version and a tag for every minor version. If a bug has to be fixed in the live-version, it's fixed in it's appropriate branch and then merged down to the trunk.
Version promotion
Have only three branches "trunk" (for development), "test" and "live". When a version is put on the test machines, the trunk is merged (promoted) into the "test" branch, bugs are fixed in that branch and when the version is released, the "test" branch is merged into the "live" branch. If we find a bug in the "live" branch, it's fixed there and then merged down to the trunk.
What are the pros and cons of these two philosophies? What are your own experiences? Are there any other - possibly better - methods available?
It depends on your maintenance policy.
If you choose to maintain more than the latest release (XP in parallel to Vista for instance), version branches is a better choice.
From my experience version promotion has much smaller overhead on merging changes from different branches and trying to remember what was fixed on which branch, etc. so whenever possible I prefer to work this way. Unfortunately, if you use version promotion it is often not possible to do small quick fixes on the released version (because there are big chunks of code checked in to the "test" branch) -> so we and up having version branches.
To sum up I think (for me at least) usually the best way is to do something in-between the two - do all development on trunk (main branch), tag all builds/releases, and create a version branch only if needed (e.g. there is a critical bug in production, and there are changes in trunk that can't be released).
In my opinion, the two are note exclusive.
The version branches mecanism is needed if you have to maintain different RELEASED versions. But I think it is a best-practice to always prepare a branching point (depending on your gestion version system) after releasing a version.
The "promotion" mecanism is needed if you have to release test version. This is usefull if you have, for example, a validation team distinct to development team and/or large team where development goes fast. In these cases, you need a specific branch to stabilize the next "stable" release while trunk stay "unstable".