I'm looking for the correct branching and merging strategy for the situation I'm currently in. A few weeks ago I created a new Dev branch from Main for version 1.6 of an application. This version is now being tested and will go live in the coming weeks.
Starting today I need to begin development for version 1.7, but I'm unsure how to proceed in TFS. I think there are 2 scenario's:
1. The dev branch for 1.7 is created from Main (as usual), and I integrate all 1.6 changes into the 1.7 branch and start my development. Any changes in the 1.6 will be merged into the 1.7 branch as soon as they are ready to be tested.
2. The dev branch for 1.7 is created by branching the 1.6 dev branch, any future changes in 1.6 will again be merged as per point 1.
The problem with #1 is the fact there is no direct relation between 1.6 and 1.7 according to TFS, which results in baseless merges.
The problem with #2 is the fact there is no direct relation between 1.7 and Main, which results in a baseless merge later on, when 1.7 is completed and merged with Main.
Is this a situation where baseless merges can't be avoided, or is my entire strategy wrong?
I'm assuming Main represents your last stable release and may be open to receiving hotfixes and the like to resolve critical issues. I'm also assuming that the typical workflow is that you begin developing a "vNext" version -- in this case, 1.6, and then work on that branch until you've completed work on it, then merge it into Main. The problem is that you're using ever-shifting development branches for your next release. You don't want to branch off of 1.6 to 1.7, because then you'd have to merge from 1.7 to 1.6 eventually, and then that 1.6 branch no longer accurately reflects what version 1.6 was.
I'd simplify things a bit. Create two "permanent" branches:
Main - your current stable "production" version
Dev - your in-development version (1.6, in this case)
Developers can work against Dev normally. When it's "done-done" and becomes the current stable version, it's merged to Main.
Now you have the ability to make feature branches (for longer-running, isolated features that aren't necessarily going out in the next release) or "vNext" branches (for stuff slated for the next release that you've discovered you have capacity to start working on earlier than anticipated).
Now you can create a branch off of Dev for your 1.7 work, and reverse-integrate your 1.6 changes into 1.7. When 1.7 becomes the new development target, merge 1.7 into Dev, and delete the 1.7 branch.
If you want to maintain older versions, you can use labels on the Main branch to represent each stable version, or you can create release branches to represent them.
Related
Environment:
TFS 2018 with source code in TFS Git
developers are using gitflow-like workflow (main, develop and short-lived feature branches)
there is a build definition used for CI (off of develop branch)
... and another one for releases (off of main branch)
as project evolves build definitions get updated (new steps, etc)
What is the best approach that allows reproduction of previous builds (or, at minimum, release builds)? (in case if previously made build was lost in boating accident)
Ideally I need to be able to plug in version (e.g. 8.5.12345.1) somewhere, press OK and eventually receive data identical to that produced by corresponding build in the past.
Your best approach is to switch to YAML builds and releases. That way your pipeline is versioned together with the code.
If you don't do that, you may need to clone your build and releases every time you make breaking changes.
Alternatively, use the version diff view in your pipeline to go back to an older version or use the json to create a new definition using the API.
Upgrading to Azure DevOps Servers 2020 will give you more advanced YAML features not yet available in Team Foundation Server 2018.
Note: for truly reproducible builds, you'll need to also find a way to lock the build tasks themselves, TFS and Azure DevOps will automatically roll forward to the latest minor version of a given build task. While task authors should try to prevent any breaking changes in those minor upgrades there are no guarantees. You can also never rely on any tool installers that use a v2.x notation or a task that relies on latest. Azure DevOps isn't ideally suited for full reproducible builds.
You can pin task versions in YAML now, if I remember correctly, this was added in Azure DevOps 2020.
You can set which minor version gets used by specifying the full version number of a task after the # sign (example: GoTool#0.3.1). You can only use task versions that exist for your organization.
See: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/tasks?view=azure-devops&tabs=yaml#task-versions
The Tasks docs offer special scripts to pin the versions of out-of-the-box tasks as well.
We currently have the following structure in one of our projects.
Trunk (Version 1)
Version 2
Version 3
Version 1 has become legacy
Version 2 is something which never got released and isn't needed anymore. But Version 3 is a branch from it.
Version 3 is the future and should be the new trunk.
So what I want to do is the following:
Make Version 3 the new trunk but without loosing anything from the current trunk.
So I stumbled upon "Reparenting with no parent" and from what I read it seems to do what I need, but I couldn't find anything about what would happen to the current trunk. Will there be two trunks?
Or would it be better to create a new tfs project from Version 3?
Thanks
Reparenting is when you want to move a branches parent from an old branch to a new branch for example. You want to create a new trunk to branch off of.
In general I would suggest to add a label of "Version 1" to the current trunk as a way to go back to the current version in the future if necessary. This is how you will "keep" the current trunk. Then you will probably need a baseless merge from version 3 to trunk. Then trunk is the latest and you can start branching new versions again.
Here is a good post with more details.
We have 9-10 applications in our project. Until now, there wasn't a defined TFS structure and no release management. We need to setup one.
We are stuck in middle of it right now with some issues about the process to be followed for every release.
This is what we have planned till now. We create a main branch which will have the current production source code.
For managing the releases, we will create a "releases" folder where we will create a separate branch for every release. All the bug fixes and developer check ins will be done on this branch.
Currently, for deployment purpose, we are deploying the developed/bug fixed code to QA. After QA validation, we copy the published code from the QA environment to the Staging Servers. After stage validation, the published code is copied to production.
Now, We are unable to figure out how/merge do we merge the release code to main line. The client's requirement is that mainline code should be the one from where we published and deployed to QA.
We were earlier planning to deploy from the release branch and merge the release branch to main once all the validation and the production move is complete.
But this means that if we incur any merging issues, the main line code could be buggy or unreliable and we could face major issues in case of any hot fixes/further releases.
Please suggest a strategy that would be suitable for my requirements.
Thanks in advance.
You should be lookin towards more of a binary release model than a source release model. If you have to merge code then everything needs retested, which can be expensive.
If you were in Git I would recommend Git Flow but since you seam to be in TFVC you should look at branch by release.
Create a branch for your current codeline, say R1. Then work on there untill R1 is code complete. Branch to R2 to continue adding new features.
R1 can now be stabalised, released, and then supported at your measure maintining one continuous branch with one continuous build creating binaries. You create a binary release pipeline in Release Management and off you go.
R2 is then where new features are added and you create a separate build and binary pipleine for you new version untill you are code complete there.
We're updating a large project from VSS to TFS2010, and we need to establish good branching/merging strategies. We are in favour of feature-branches but I have no idea if we should branch only the sub-projects/files affected in each feature (like we would in VSS) or should always branch the whole code-base and rely on lazy copying and good merging (like in git/mercurial).
The guides I've found so far online talk about branching strategies (branch by release, feature, etc) but not about which files/sub-projects you should perform the branch on.
Is there a "right way" to do it? Say we have a setup like this:
Code
|
|- ModuleA
|- ModuleB
|- ModuleC
|- ModuleD
And we have a feature F which impacts ModuleA and ModuleD. Would we be better to branch Code, or ModuleA and ModuleD only?
If your feature is impacting something that is used throughout your codebase, branch your entire codebase. You still want to have CI builds running on your feature branch, and thus you want all of your automated tests to run, same as always.
Even if a feature only affects one small segment of your application, you still want to be able to test the application as a whole to make sure you haven't introduced any breaking changes.
I recommend reading the ALM Rangers' branching/merging guide, which you can download from CodePlex.
I read lot on this subject (Techdays, videos, etc.), on my project apply this strategy, it's recommended as best practise.
The implementation requires performing the following tasks:
1 . Create a truncated development , trunk reads XYZ
Note: developments are not directly on the trunk, but are about a girl called Service Pack branch .
2 . Create from the trunk a new child branch service pack, language 1.YZ
Note: This branch will host the first dedicated development functionality.
Event Project: End of first iteration ( The development team believes that the developments are completed).
3 . Create from Service Pack 1.YZ a new child branch Fix denominated 1.0.Z.
Note: This branch contains all developments dedicated to future bug fixes following the delivery of the target feature.
4 . Create from Fix 1.0.Z. a new child branch Release denominated 1.0.0 .
Note:
This branch will remain read-only.
This branch is the only branch deployed in a production environment .
This branch is a picture of our delivery.
It allows you to draw different deliveries made .
It allows to perform operations on the Rollback version if the need arises ( Avoid conflicts file version ) .
Event Project : Delivery of production
Deliver Release 1.0.0 branch on the production environment .
6 . Merge Service Pack 1.Y.Z to X.Y.Z trunk
Note : At this point all branches are at the same level of evolution .
Event Project: bug occurs on the Release 1.0.0
7 . The treatment of bugs can be done in two ways as possible :
■ If it is determined that the version is not stable
Carry - on patches Fix branch 1.0.Z.
Create a new branch Release 1.0.1
Deliver the branch Release 1.0.1
Merge Fix 1.0.Z to Service Pack 1.Y.Z.
Merge Service Pack 1.Y.Z. to trunk X.Y.Z.
Note: You can iterate many times : 1.0,1 , 1.0.2 , 1.0.3 etc. .
■ If it is determined that the version is stable and we decided to fix bugs on a new delivery.
- Create from Service Pack 1.Y.Z. Fix a new child branch 1.1.Z
Make corrections on Fix branch 1.1.Z
Create from Fix 1.1.Z. a new child branch Release denominated 1.1.0 .
Deliver the 1.1.0 branch
Event Project: An important new feature comes
8 . Create from the trunk a new child branch service pack, language 2.YZ
Reproduce the same organization ...
Remark : on my blog i writted post
When making a deployment to production, should I mark my code with a label or create a branch for the code that's in production?
In TFS, I would have a Release branch with a label identifying the specific version being released to production.
Which would imply you have other branches may I suggest the following
Three major branches: Main, Develop, & Release.
One Hotfix branch for your current fire.
0 to N Major-Feature branches to contain the disruption of development.
Details
Main Branch
Contains the latest stable builds
Tag/Label each release
Develop Branch
Branched from the Main
Where most of the work is done
Merge back to Main before release
Release Branch
Branched from one of the following:
The Develop branch
OR the Main branch (this may be better since it is "stable")
Bug fixes are done here
After fixes are tested and released,
merge to Develop branch
OR merge to Main branch and then forward integrate (FI - which is a merge from parent to child) to Develop
Tag/Label each release or bug fix
Hotfix Branch
Branched from Main
Merged back into Main
Forward integrate merge to Develop
Used to allow Main to remain "stable"
Major Feature Branches
Branched from Develop
Merged back into Develop
Used for major features that would possibly disrupt the regular development path
References:
another stack overflow question: when-to-use-a-tag-label-and-when-to-branch especially Martin Woodward's answer
Source Control How To by Eric Sink
A successful Git branching model by Vincent Driessen
This contains a very good graphic of a branching model
Ideally, both.
You probably want to have a label so that you know exactly what you delivered for a specific release. However, you probably also want to create a branch so that you can perform minor bug fixing to what was released and create a new release.
In practice, you could approach it in one of two ways:
Have a continuous developmental timeline that gets branched for each of your production releases:
example:
------------------------->dev
| | |
| | |
| | |
v1.0 v2.0 v3.0
Have your production releases "cascade" off of one another:
example:
---->v1.0---->v2.0---->v3.0
Ultimately, up to you in deciding what architecture to adopt, as long as it's consistent and makes sense to you.
You can use a combination of both. Here is how we do this internally for all projects.
We have structure with folder Branches and sub folder for each minor and major version. We also use labels that we set on individual sub folders so we can easily rebuild any specific version any time in the future.
$\Branches
\2012.01
\2012.02 (branched from 2012.01)
\2012.03 (branched from 2012.02)
\2013.01 (branched from 2012.03)
You can also check out Visual Studio Team Foundation Server Branching and Merging Guide for more details.
I have seen both done, Labeling is more lightweight and to me easier. But, it has been pointed out that labels can be deleted rather easily. A branch protects against this by not actually being deleted unless "destroyed". The reason I prefer not use branches is I hate having to cloak them as I tend to do get latest from the root and don't want all those branches filling up my hard drive
For the record, since it was pointed out to me about label's being deleted I have removed permissions for Labeling from everyone but Admins and the build service accounts to help mitigate this.