I think that it's good idea to build artifact and then deploy it across all environment, test, preprod, prod.
But according to Gitflow we use "release" branches for tests and we merge it to main, develop and delete release branch. So we have "release" artifact and we test it, but as I understand we deploy to prod artifact from tagged main branch. And for me it's strange.
What could be the objective reasons of this?
main <=> prod
The reason for this is simple, however, the usual name of the main branch is master. One needs to have an easy way to refer back to whatever prod contains, because, in the case of hotfixes, you want to branch out from prod, because the issue is reproducible there. It is another matter that there is usually a branch for hotfixes as well.
release branches
Basically, you may have many different things that are being developed at the same time. You probably want to create well-separated partitions of problem-spaces to define your tasks, each such partition would represent a release. So, if you are optimizing some business logic on the one hand and you are polishing the UI on the other hand, then you not necessarily know which one will be released first, so you will have some named branches for those. Having "release" branches is a convention for this. Now, when you are deploying a release to prod, you can merge master into your release branch and perform automatic and/or manual tests. When this is successful, your release branch is merged into your master branch.
Deleting a release branch
Once the work represented by a release branch is successfully completed, it makes sense to remove it after it was merged to avoid wasting storage space on things that are unlikely to change (because they were accepted). Note that if a problem arises with a release later on, you can always checkout the commit hash of the tagged commit that represents the release merge in order to see whether the problem you have seen was already manifesting when the release branch was released.
Related
I'm working with git flow and a doubt arouse about the master branch. I have development and user acceptance working on develop branch and when I finish the test, I merge the develop with master branch and put into production. My question is if something goes wrong after this merge with master branch, I will not have tested it. What should I do to have the master branch tested? How to ensure that the master is not broken? Is there any pattern?
tl;dr: No, you already tested it.
Details:
In a properly implemented Git-Flow strategy, anything you merge into master should be fully ahead of master 1, so you would never need to test what you'll get after merging into master, as it will be the identical state before and after the merge. (And presumably you have fully tested the branch before merging into master!) The reason this is true is that when hotfix branches are merged into master, they should be immediately merged back down into develop too (or into a release branch if one currently exists). This means there should never be any code that is only on master and not yet in the branch you're about to merge into master. As documented by Git Flow regarding completing hotfix branches:
When finished, the bugfix needs to be merged back into master, but also needs to be merged back into develop, in order to safeguard that the bugfix is included in the next release as well. This is completely similar to how release branches are finished.
And also,
The one exception to the rule here is that, when a release branch currently exists, the hotfix changes need to be merged into that release branch, instead of develop.
Side Note: You mentioned that you are merging develop directly into master, and you can do that if it's working for you, but I just want to point out that typically in Git Flow you use a release branch instead. Doing so enables simultaneous development on develop while you are hardening a release as it awaits deployment. Here's a question that discusses this, and my answer there provides some tips for how to avoid creating release branches in Git Flow, if you normally don't need them.
1 In Git we oftentimes say that one branch is "fully ahead" of another branch when the first branch can reach the tip commit of the second branch. For example, develop is ahead of master if the tip commit of master is in the history of the develop branch. In this case however what we actually mean is that all commits with state changes in master are present on develop, and this distinction exists only because of the --no-ff requirement when merging into master, so it's possible that master might have some merge commits that don't yet exist on develop. Those merge commits do not contain any new state though, so we can say from a practical point of view that develop is fully ahead of master.
From a purity standpoint, my personal preference is to always have every commit on master be present in develop or release before merging into master, so that we can say "fully ahead" and mean it from a commit ID standpoint as well. To achieve this, you can slightly tweak the documented Git Flow by, instead of merging release and hotfix branches back to develop after merging into master, merge master back down into develop. This achieves the identical state but also achieves the "fully ahead" meaning that we like to see in Git. It also means anytime you merge anything into master, you could do a fast forward merge, but we choose to use --no-ff instead to maintain a historical record of when the merge occurred, and exactly what was merged. Using this tweak, the fact that you could have done a fast-forward merge is the proof you need that you don't have re-test master after the merge.
If the master branch changed since you forked the develop branch, you certainly could break master after merging develop (especially if you had to sift through merge conflicts), even if develop was working fine on its own. The way to make sure that master isn't broken after merging is to have good unit tests for master to make sure no existing functionality is broken, and then add and run additional unit tests for develop which test the new feature works after its merged.
We are using visualstudio.com TFS to store the source code. We have DEV, STG and PROD branches. now I want to automate build and release to IIS server.
But it looks like to me that TFS compiles the code from the branch where I commit to, and that's the only build, after that I can install the same binary on all the servers.
But it doesn't seem to be ok, because what if we find a bug on the live code, so we need to fix it, but we already have new code in DEV, and we don't want to revert, and install the old code with the fix on the dev server?
What I think we should do is to merge the code from DEV to STG, from STG to PROD, but I couldn't find any module for that. And it looks strange, I would be surprised if I am the only person whats to do this, especially because it is doable with Jenkins.
thanks
I typically discourage automating merging of code between branches; merging should be a deliberate action. When someone expresses that desire, it's usually a sign of a problem with the branching model and deployment model they're using.
Code promotion branching (where you have one branch that corresponds to each environment, as in the scenario you described) is a bad practice because it encourages you to build different sets of binaries for each environment. You build something for a lower environment, test it, validate it, then totally disregard that testing and rebuild from source. That should terrify you, especially for production branches -- you have no idea if what you just built is going to work properly.
Current thinking is to minimize the number of branches you have, and instead isolate in-progress work behind feature toggles so that features that aren't ready for production can simply be disabled, but still allow deployments to take place. With sufficiently mature feature toggling practices and testing practices in place, you can actually eliminate branching entirely and work out of a single branch, promoting binaries to production whenever your automated and manual QA process deems the version they're testing is good.
Assuming you're using TFVC, if you want to maintain a code promotion branching strategy, then you'll need to maintain multiple builds and releases, one for each branch/environment. Typically, in this kind of scenario, I'd eliminate the stage branch entirely. Anything that goes to the Dev branch is built and deployed to Dev. Anything that goes into the Prod branch is built and follows a deployment pipeline from staging->production. Hotfixes can go directly into the prod branch and be merged backwards. There are tons of strategies for branching; you'll need to read up on the subject and design a branching and release strategy that works best for your team.
The Microsoft ALM Team describe the Basic Branch Plan as needing a MAIN, DEV, and RELEASE branch.
I am working on introducing branching/merging to a new team who currently uses source control with no branches whatsoever.
I was wondering how the RELEASE branch is actually used.
Can changes be made in the DEV branch then be merged up to the MAIN branch without needing a RELEASE branch? MAIN would still be read-only. It would basically be the RELEASE branch in essence. The reason I say this is because we don't have that many changes but I want to isolate the stable code from new changes. Our concept of a "release" per say is not yet well defined. I am still working on that.
I just don't know if my team needs a RELEASE branch (considering our needs specifically).
I would appreciate some comment about the strategy of just having a MAIN and DEV branch.
Typically the release branch(es) are used for "safekeeping". Basically the same as a label.
Releases to production are usually a pretty important event, and you want to know exactly what source you released (in case you ever need to go back to it). Way back when people used to create Labels to track this, but creating Release branches is better for a couple reasons:
Labels are mutable in TFS, meaning somebody could change a label and there would be no audit trail
Branches are also mutable of course (changes can be checked in), but this can be locked down via branch specific permissions
Also if a change is made to a Release branch (which it never should be), at least you have an audit trail through history
Even though a branch looks like a heavy-weight operation creating a copy of your entire code base, in reality TFS just creates a new pointer to the same files, so the storage cost is trivial
I went the other way when I implemented TFS at a client (replaced SVN). What I did was introduce a MAIN branch and a RELEASE branch and not a DEV branch initially as that seemed very confusing to the team. It is also hard to convey the purpose of a DEV branch to an SVN familiar team initially.
The main purpose of our RELEASE branch was to preserve a historical placeholder as said in another answer. Currently we are using Git and we have a CI server that does the release process and branches to release/$version_number. I think that concept might be easier to understand and convey to your team. i.e. automatically create release branches when you actually release.
We are trying to implement the "Basic Dual Branch Plan" as described by the ALM Rangers in the latest Visual Studio TFS Branching and Merging Guide. From the guidance:
The basic branch plan with a MAIN, DEV, and RELEASE branch enables concurrent development for your next release, a stable MAIN branch for testing and a RELEASE branch for any ship blocking bug fixes. Multiple development areas are supported by creating additional development branches from MAIN. These are peers to each other and children of MAIN.
Additional releases are supported by creating release branches for each product release. Each release branch is a child of MAIN and a peer to each other (e.g. release 2.0 branch is peer to release 3.0 and both are children of MAIN). If supporting only a single release in production at a time, you may consider a single release branch, and make bug fixes directly on this branch. Once the RELEASE branch is created MAIN and the development branches can start taking changes approved for the next product release.
We are undecided as to whether we want to use a single Release branch (and label releases), or create a new release branch per release. However, there are some questions that apply either way, that don't seem to be addressed by the guidance.
My main question is: At what point in time should we create a RELEASE branch (or move tested code to the single RELEASE branch if that's the way we go)?
My first reaction was to create it only when ready to do the release, but then you have the problem of creating a deadlock for development and testing of the next sprint's work; you cannot check these changes into MAIN until the RELEASE branch has been created (if you do, it's more difficult to separate out the changes you only want to go to RELEASE).
Second idea is to create the RELEASE branch at the beginning of the sprint, and as changes pass testing in MAIN, merge them down to the current RELEASE branch. Once we reach the end of the sprint, we can lock that RELEASE branch down, and create a new one for the next sprint. This sounds like it would work, but I see no discussion of it anywhere, so I just wanted to see what people are doing.
I would give the same advice as Adarsh Shah in that 2 branches (MAIN, RELEASE) are sufficient in most cases, and using feature branches for things that you don't want to commit into MAIN immediately because it would take a while to be fully ready for testing. And by RELEASE I mean a branch per actual release.
Keep in mind though that, in theory, MAIN should in a release-ready state at any moment. This means using feature branches for a lot of small changes too and not merging things into MAIN as long as the feature is not considered ready. Now, this is something that you should experiment with and see what works best in your environment. If you find that it is too hard to keep MAIN into a release-ready state, by all means, create a separate DEV branch to commit the daily work. In my experience however, with some good guidelines, automated and manual testing you quickly can get into a flow where MAIN can be considered quite stable. I've worked in environments where we had a DEV branch which was highly unstable and a stable MAIN branch, and environments where we didn't have a DEV branch. Sometimes the DEV branch was needed, sometimes it became a burden to keep them in sync as both DEV and MAIN were fairly stable and essentially just a copy of each other.
Now, when should you create the release branch. It depends on the type of development you are doing. For small desktop projects or websites which have a fairly steady release cycle (a single release per sprint, for example) I find it easiest to create a release branch at the end of a sprint, and only pushing it to production the sprint after.
S1 - - S2 - - S3 - - S4 // Each sprint
\ R1 - \ R2 - \ R3 // Release branch created at the end of a sprint
\ P1 - \ P2 // Pushed to production at the start of the next sprint
So, at the end of S1 I create the release branch R1 from MAIN but it's not pushed to production just yet. During S2 both new features are implemented on MAIN and critical bugs are fixed on R1. If a fix on R1 is approved, it gets merged back into MAIN too, if it's required. At the end of S2, a new R2 is created, and R1 is pushed into production. I have found this approach to work quite well. You basically have a full sprint to work out the last issues in a release branch.
Of course, if a serious critical bug appears on production this bug gets priority above all else. An RXa, RXb, ... branch can then be created of the existing R-branch that's in production, implement the hot-fix and push that hot-fix into production. You can then consider whether it's needed to merge the changes from the hot-fix into your MAIN branch. Don't create a hot-fix on the MAIN branch and merge it down though, you'll find that it quickly becomes too complex because on MAIN a lot of the surrounding code might have already changed.
Here is what I would suggest:
1) Do all development on the Main branch until Code Complete. Code complete is the time when developers stop working on new features for that sprint but can fix regression bugs. Code complete can be few days before the release or up to a week based on how long is your sprint).
2) Create a new RELEASE branch from the MAIN at that point . Deploy the branch to QA/Staging environment to do a smoke test. After that point QA team will use RELEASE branch to do the testing for the release.
3) Developers can start working on the new features for next sprint at that point and start checking-in changes to MAIN branch. Any regression issues found during testing will be fixed in RELEASE branch first and then merged back to MAIN.
4) Any changes to code in RELEASE branch will then be pushed to QA/Staging for further testing.
5) One the Release is done any bug found in production will be fixed in RELEASE branch and hot-fixed to Prod and also merged back to MAIN.
No. 1 will be too late and no. 2 will be too early IMO.
I would suggest to create a new branch for every RELEASE and then get rid of old RELEASE branches periodically instead of using labels.
Also, I prefer having only 2 branches MAIN(which is also DEV) and RELEASE except any branch developers need to any specific feature/framework change etc. Under the root folder I usually create MAIN, RELEASES(all release branches) and BRANCHES(all branches specific to a feature/framework changes etc. but these are created only in special cases not always)
We have 3 environments: dev, test, and staging.
I want to check in and out of TFS. When we make changes, I want to promote the code to the dev web server. Next I want to promote the changes to test, then to staging. Would it be possible to do this with Team Foundation Server?
Why on earth are people suggesting branching? You branch for different features or static branches for release snapshots.
Surely the differences between these environments are configuration items/files and settings within these. All you need to do is get your deployment and release management process in order.
Create appropriate MSBuild tasks and use TFSBuild (Continuous Integration) to call these to take care of outputting the correct config files for the Environment/Configuration you are building. You can trivially add another MSBuild target that deals with the appropriate deployment to the respective target environments.
You can manually checkout the code from each branch, make your changes subsequently to each branch, and checkin. Very carefully.
Much better is to have these 3 environments be branches of each other. (Typically you start with dev, and branch to the other 2 in turn). Then you can use the Merge functionality to merge (for example) your dev changesets directly to test, etc. At this point your Test modules (that need to be changed to match dev) are checked out, with the changes. Then simply commit the changes. Then repeat for staging and rinse. This is the suggested methodology for this common scenerio.
Two important notes:
Even though TFS if very server-centric (compared to SVN, for example), this merging functionality happens on the client. You need to have each branch mapped to your machine. After the Merge process is completed, you'll have uncommitted changes in the target branch until you check in.
In Microsoft's vision and in the example I give here, these branches are permanent. This was a change from my previous practice using SVN, where whole branches were created/promoted/retired all the time. In the TFS way, you create the Test branch and it remains, indefinately, the Test branch. It's never promoted; its changes are merged elsewhere.
Building is a separate action. You need to set up a separate build for each situation, though of course once you set up the first one the other two will be trivial. After your merge to staging, you'll then run the staging build. (From Team Explorer or in the Build menu). TFS is a bit heavy but once it is set up it does handle this situation very well, easy for a distributed team to merge and build quickly (with automated build tests, etc.).
Yes, this is possible, but you must manually check them in from one branch to another.