Azure DevOps Build Best Practices for Multiple YMLS - azure-devops

I have a question on general best practices for Azure DevOps. When building a project, we have two build configs, debug or release. At some point in the deployment pipeline across a multi-stage environments, these need to be changed, which means two builds from what I can understand.
Is it better to have one yml, with the build config being set as a condition from the source branch (i.e. if source branch contains "release" build config is Release, if source branch isn't from release, then config is Debug, or should I be having multiple builds and a pipeline triggered by two different artifacts?

It is much better to have one yml. By having only the one build pipeline and using a simple condition, you limit the possibility of bugs arising due to differences in the separate yml definitions. Additionally, it is more maintainable as changes are only made in one place.

Related

Azure DevOps: Why does new pipeline commit the yaml file to default branch

I created a new pipeline in Azure DevOps, and created a new branch for it.
As a result, DevOps automatically committed the YAML file for the new pipeline to my 'development' branch.
None of the other pipelines I've created have YAML files committed into the repo...
Why does it do this?
Do we have to keep the YAML file there?
It has nothing to do with the source code of the application, so doesn't seem to make sense why its stored there.
YAML is code for how your application is deployed, thus it is part of the source code. By putting it under source control it can keep track of version changes and any additional changes to parameters or variables that are determined or inserted in the build process.
This is opposed to the older ways of doing things where it was updated via UI and not source control and did not have peer reviews, branching merging, and additional polices that can be applied.
This on top of the the YAML Pipelines for Releases going GA the other week will make YAML under a repo even more powerful as the YAMLs will not only build but also release code.
In Azure Devops Service we define pipelines using the YAML syntax or through the user interface (Classic). So there're two kinds of pipelines, Yaml pipelines and Classic UI(Classic build and release) pipelines.
None of the other pipelines I've created have YAML files committed
into the repo...
Why does it do this?
It's expected behavior when defining pipelines using Yaml syntax: The pipeline is versioned with your code. It follows the same branching structure.
And one advantage for this is: A change to the build process might cause a break or result in an unexpected outcome. Because the change is in version control with the rest of your codebase, you can more easily identify the issue.
To sum up, the yaml pipeline will be added into version control and it's by-design behavior. If you don't want this behavior, you can feel free to use Classic Build and Classic Release pipelines. It's also a good choice! About the differences between these formats you can check Feature availability. Hope it helps :)

Deployment configured as YAML as part of a Pipeline

We have been using a YAML file to do our CI in Azure DevOps for a few months with the idea that we would get our release configured using YAML in the future.
Well that time is now and I'm confused by how you would introduce a CD process. With the MyProject-CI.yml being a Build Pipeline and our Releases being Classic Pipelines I assumed that when the time came to get the CD process down as YAML we would create a MyProject-CD.yml. That would be triggered by the dropping of an Artifact within the MyProject-CI.yml CI.
However I think that was just a misunderstanding on my behalf and what we are supposed to do is convert the original MyProject-CI.yml into a multi-stage pipeline that has the following stages
Build and Run Unit Tests
Deploy to Development and run WebTests
Deploy to Production and run WebTests
Is the switch to a multi stage CI/CD in one file correct rtaher than Release and Build in separate files?
The short answer is yes, you got the idea. A single multi-stage pipeline yml is the way to do both build and deploy, and that is the base intention. Here is an exercise that parallels your case that might help.
As your pipelines get more complex, you will likely get into scenarios with multiple files, as you can template parts of your pipeline for reuse in multiple places, or to enforce conventions from a central location.

Deploy many apps through ONE release process via Azure DevOps

I need to deploy many similar apps to the same environments with Azure DevOps.
What are some ways to share and maintain the release process for these apps....
to avoid updating every app's Release process when it changes?
Background
I have dozens of similar apps with identical release processes.
Each app (in its own repo) will have its own Azure Pipeline.
I'm fine with a custom solution to this problem.
Options
Make a Release for every Pipeline -- not a fan!
CON: Azure seems to want a 1-to-1 relationship between Pipelines and Releases.
CON: I want to avoid many Releases at all costs, since changes would be nearly unmaintainable.
Use custom stage templates -- doesn't work for what I need
CON: Releases do not share custom stage templates.
Custom templates that you create are scoped to the project that you created them in. [Azure Documentation]
CON: Custom stage templates cannot be updated (as of this post).
To update an stage template, delete the existing template in a release pipeline and then save the stage as a template with the same name. [Azure Documentation]
Put the release process in the Pipeline .yml file -- seems possible, but....
PRO: The process would be stored in a shared "common" repo.
PRO: Each app will have a minimal Pipeline .yml file, setting some parameters before running the shared process.
CON: How would I track and manually deploy releases without the Release portal UI? Am I missing something?
Trigger the same Release with artifacts from different apps -- not sure this will work....
PRO: One release process, easy to track and deploy as needed via the Release portal UI.
CON: How would I track releases for different apps? Would I name Releases with the app name?
CON: I don't see how to set it up, since a Release is tied to a primary Pipeline.
At the time of linking an artifact source to a release pipeline.... [Azure Documentation]
CON: Though multiple artifact sources can be used, Releases need a default artifact Pipeline or source repo. Would I need to setup the artifact source programmatically?
When you link multiple artifact sources to a release pipeline, one of them is designated as the primary artifact source. The primary artifact source is used to set a number of pre-defined variables. It can also be used in naming releases. [Azure Documentation]
Use multiple artifact sources and artifact variables -- not sure this will work....
When there are multiple artifact sources linked to a release pipeline, you can access information about each of these. [Azure Documentation]
Bottom Line
I was able to solve many of these problems in Octopus Deploy. However, I'm having significant trouble seeing how to move my DevOps process into Azure DevOps. How would you handle this situation?
There is no perfect solution to meet your requirements.
Generally deploy multiple apps to multiple environments, we recommend that Make a Release for every Pipeline. But just as you mentioned it has 1-to-1 relationship between build pipelines and Releases and it has many releases.
We can deploy multiple apps to multiple environments through ONE release with customized Template as you mentioned, we can also use the Task Groups to combine a set of tasks together, then reuse them in different stages. But we still need to update the definitions accordingly (change the Task Group version) once the specific task group is updated.
Another way is Clone Stage, you mentioned they are the same environments, so you can config one stage, then clone stages from the existing one, just name the stages with the specific App names accordingly. But you still need to change the settings accordingly, for example the Artifact filters (see Release triggers) to determine the condition to trigger the specific stage. But in this way it will download all the artifacts first when you add multiple artifact sources, this will take long time to get sources...

confusion on Azure DevOps pipelines

I've recently been working on switching from On premise TFS to Azure DevOps, and trying to learn more about the different pipelines and I think I may have had my Build pipeline do too much.
Currently I have my Build Pipeline do
Get Source code from Repo
Run database scripts/deploy dacpacs
Copy files over to virtual machines that have web application set up already
Run unit/integration tests
Publish the test results
I repeat these steps closely multiple times, one for develop branch, one for current and previous release branch.
But if I want to take advantage of the Releases and Deployments areas what would that really get me?
It looks like it would be easier to say yes this code did make it out to this dev/beta environment.
I'm working with ColdFusion code that includes some .NET webservices within the repo, would I have to make an artifact that zips up the repo and then deploys it, or is there a better way to take advantage of the release pipeline?
It's not necessary to make an artifact that zips up the repo and then deploys it. There are several types of tools you might use in your application lifecycle process to produce or store artifacts. For example, you might use version control systems such as Git or TFVC to store your artifacts. You can configure Azure Pipelines to deploy artifacts from multiple sources. Check the following link for more details:
https://learn.microsoft.com/en-us/azure/devops/pipelines/release/artifacts?view=azure-devops#sources

Visual Studio Team Services: Single Build Definition for Multiple Branches

We are using Visual Studio Team Services.
We have a Prod-Branch which is builded by our Prod-Build-Definition and deployed by our Prod-Release-Definition to our Test / Integration and Production Environments.
With each Prod-Release deployed to the customer, we create a Prod-Rel-Version-x.x.x Branch from the Prod-Branch (in Case we need that for a Hotfix).
During the Sprint we are developping on a Dev-Branch which is builded by our Dev-Build-Definition and deployed by our Dev-Release-Definition to our DEV Environment for Developer Tests.
After the Sprint (or from time to time) the Dev-Branch is merged to the Main-Branch and then to the Prod-Branch. From there it is deployed to the different Stages for Testing by the customer.
When there is a Hotfix-Case, we fix the bug on the Prod-Rel-Version-x.x.x Branch and would like to reuse our existing Prod-Build-Definition to build this Hotfix-Version and deploy to the different stages by the existing Prod-Release-Definition for testing and going live with this version.
How can we reuse our Prod-Build-Definition with this different Branch (Prod-Rel-Version-x.x.x Branch instead of the Prod-Branch)?
When I look at the build definition, I think i would be possible, just be editing the Server Path (Repository > Mappings) from $/NameOfOurApp/Prod to $/NameOfOurApp/Prod-Rel-Version-x.x.x)...that should do the trick or not? But from what I read, it's not possible to use Build-Variables in Server Mappings, so I cannot change this variable for example in the Queue new Build Dialog...
What's the best way to accomplish my scenario?
The only way to do this is to create a single build definition which downloads all the branches. Then use variables in the tasks to select the version to build. This will become very messy (and slow) very fast.
Instead it's much easier to clone the build definition. Alternatively you can create a Build Definition Template from an existing build definition and use that to create a new Build Definition.
A much, much better solution however, is not to rely on so many branches.You only need the branch when you really need to make a hotfix, and you only need the stages branches when you have a lot of findings in higher stages. By improving teh way you work, you'll be able to get rid of the branches, simplifying the work for all.
Update
VSTS and TFS 2018 now support the use of variables in the workspace definition.