How to avoid codefreeze when deployments past QA are in progress - bitbucket

We normally merge feature branches to the development branch(Development branch is deployed to QA) and from there RELEASE tags are created subsequently followed by deployments to staging and production. All has been implemented through AWS codepipeline. Problem we are facing is that once RELEASE branch is created, we go into code freeze and we cant merge more into development branch i.e. get things into QA till production deployment is completed successfully(Think about scenario, if hotfix is needed in production, we need our development branch to be exactly what was deployed into production, prior to applying the hotfix). We are trying to figureout a way on how to avoid codefreeze while release is in progress. This is a high level description of our issue, would love to provide more details, if needed.
Thank you.

Related

Image promotion strategy

How is image promotion handled with 'dev' images?
Like many others, we have three environments for deployments – Dev, Stage, Production.
Stage always tracks the latest master, and production deploys are triggered when releases are tagged in Github. It's easy enough to promote images between stage and production.
Where I'm having trouble understanding this is with Dev. Dev images are built on pull requests in our case, but there's a good chance the branch behind the PR is some number of commits behind master, so promoting this image through the ranks would cause outdated code to end up on stage and prod.
What is the typical practice here? Are dev images kept separate, in a separate image repository and never mixed with the stage/production images? Is there some way to promote them that I'm missing?
Stage always tracks the latest master, and production deploys are triggered when releases are tagged in Github
Dev images are built on pull requests in our case, but there's a good chance the branch behind the PR is some number of commits behind master
This is all a bit confusing to me. I like to keep things simple, and I usually advocate for one branch per environment.
In this scenario, I would advise you to have the following branches:
dev
stage
production
This will allow you to make changes to one environment at a time, progressively. So first you would push your changes to the dev branch, and if they are successful, you would then push the same changes to staging; likewise, if the changes are successful in staging, you would then push the changes to production. The pushing to the branch can and should be done via merge requests.
Each branch would have its own pipeline associated to it, which would build, test and release the image to the environment specific registry. Keeping registries separate amongst environments may seem overkill but it would make your life easier when it comes down to permissions management.
Having one branch per environment also has the added benefit that you will be able to restrict access to certain branches, e.g. everyone should be able to merge to dev but not everyone should be able to merge to prod.

Gitflow, QA, CI/CD deploy the same artifact across all environments

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.

TFS merge during build and release

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.

TFS Release Management

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.

How can I branch my code in a way that makes testing possible without contaminating the baseline?

Using TFS, we have the following:
A main baseline
A development branch for each development effort. These get merged back to the baseline.
A release branch that is created with each release. Bug fixes are made here, released, and merged back to the baseline.
Using shelvesets, we can share code across development branches if needed without contaminating the baseline. Useful for code reviews.
When we deliver our development changes to baseline we have an automated build that kicks off and automatically places our changes on the test server.
The problem is that the business analysts can't see our changes until they're on the test server, and currently the only way to get our changes on the test server is to check them into baseline. So if the BA's find something wrong, the code is, unfortunately, already in baseline and we would have to go through the trouble of taking it back out.
Is there a way we can change our branching strategy or process to get the BA's what they want to see without contaminating our baseline?
Your branching strategy sounds exactly what we decided on at my company. I don't think the issue is with your branching strategy, I think the issue is that you have to check changes into the baseline in order to apply them to the test server.
At my company, changes aren't checked into the baseline until they are promoted and running in production. Release branches are what are deployed to the test servers... if bugs are found, or the BAs want to change something, we don't have to go through the pain of removing the changes from the baseline.
However, if you have a lot of concurrent releases, this can become a pain to merge all of the releases together before moving them to production, since you aren't merging into the baseline until later in the process. At my company, we have a very strict release schedule, and try to only have a single release working its way to production at a time. Because of this, waiting to merge the release into the baseline until the release has been promoted into production hasn't created any issues for us, or extra work so far...
How often do you do releases? Would you be able to deploy release branches onto your test servers, and have the baseline represent what is currently deployed in production?
(I'd make this a comment, but I'm still working on earning that privilege...)
I would not prefer this approach, I would suggest:
A main baseline which contains stabilized code. The code will be merged into this branch from respective release branch only after successful release.
A Release branch which gets created from Main for each release. This branch will be used to generate Release Builds and will be deployed to test environment.
A Development Branch created from Release Branch, it will be used for Development efforts and will be merged to Release when I'm ready to give my build to test.

Resources