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...
Related
I've been fighting with this for a while. I've been able to get it working with two separate release pipelines, but not with one. It seems that in one pipeline the PR trigger for releases fires for all environments, even with separate build artifacts.
Goal is to have the following in one release pipeline:
PR to dev and merge to dev deploys to dev environment
PR to main deploys to QA environment
Merge to main of said PR releases to prod (with manual approval step).
It would be great to get this one one release pipeline, as that would reduce overhead and management, etc.
I've tried all sorts of variations with artifact release triggers and the environment pre-deployment conditions, but to no avail.
I've even tried using 2 separate build pipelines (one for main, one for develop) and then loading both as artifacts and trying to separate that way, but even when only 1 build pipeline runs, it triggers the PR release condition for both environments.
You should be able to achieve this if you implement your release pipeline with the new YAML pipelines.
The simplest option (which is not quite what you are asking for but should get the same outcome) would be to create a template with your core deployment logic, then create separate pipelines that reuse this template. That should allow you to replicate the triggers that you already had working for two release pipelines without needing to duplicate the deployment code.
Alternatively, you could set up a single YAML pipeline with Stages for Dev, QA and Prod, and set conditions on the stages, based on the source branch and/or build reason.
I am trying to find the most correct and simplest deployment process for each application release we have. The difficulties are the following:
It is Azure DevOps Releases.
Application has more than one artifact that should be delivered as a whole. Application distro, Its modules, and some configuration for servers that are not directly linked with the application, and of course automation scripts (which is versioned). All of them have their own build process and can be versioned separately.
All those components (App, separate server config, automation) are delivered as one product version. However, they could have different versions, for example: 12.2.1 (app), 12.2.3 (server), 12.2.1 (automation).
The question is how to build the process when after release (official), we can stick all of the final versions together (i mean not specifying them manually during pipeline release creation for each) taking into account that one of the component's version can be increased and we should be able to increase the version for release in terms of hotfixes for example.
Release Pipelines and 3 Artifacts: ok, there are 3 artifacts and a user has to specify all 3 versions manually during creation - quite a high risk to misclick. Unfortunately, there are 10 of them... 10 multiply 3 = 30 times to do a mistake.
Release Pipeline and 1 Artifact (app): Consider only one version of the application and automatically obtain automation scripts and configuration from feed by using app version. Could work, but no observability on what artifacts are going to be used, no way to downgrade, the only the latest version of artifacts (12.2.3.*).
Specify the version in the variable group connected to the stage (environments). Can easily make a mistake because release uses the baken version of the variable group. If you update VG, but not create a release - it will be epic fail. Moreover, there is no vision of what it is going to install/update, etc.
Please, share your ideas on how to manage multiple artifact versions within one product release to make the process more robust and clear with a little of flexibility.
That's how it works for me via this simple approach:-
A single build pipeline with many Agent Jobs where each one represents an artifact.
So here you will publish the different artifacts under separate folders and automatically increase versions "If needed", using a script per each and at the end all will be under the same BuildId.
Another variety if separation isn't needed that all be under the same Agent Job.
A single release pipeline that is linked to this big nested artifact that will perform the deploy.
Here also if separation is needed, could have multi stages or multi Agent Jobs as before.
Versions increasing either will happen manually at commits or scripts will automatically increase each build.
I would prefer the first as the 2nd doesn't indicate that there was any change.
The possibility of developer forgetting to update the version will be the same as developer introduces a bug so that can be fixed later.
Then at the end, you have a Single Release => Single Build => Many versions => A commit.
I've configured Release Pipeline with two artifacts linked to it and each artifacts has set to create release whenever new build is available. These two artifact come from two different modules on separate GIT repo's.
In this case, release pipeline will get triggered twice(one per artifact). But I wanted it to get triggered only after all the linked artifact builds are succeeded. Tried finding solution in the docs, but couldn't find it much helpful. Any suggestions please.
I am afraid it is not possible to trigger a release only after all the linked artifact builds are succeeded. Azure devops doesnot have such a feature to configure this yet. A new release will now be triggered when either of the linked artifacts build is succeeded.
You will have to create two different release pipelines, one for each artifact. Or you will have to find a way to put BuildA and BuildB in one artifact.
You can submit a feature request to Microsoft Development team. Hope they will consider implementing this feature in the future sprint. Or you can vote on this existing user voice.
This is not possible to configure it out of the box. It will trigger release just after one of artifact become available. If you want to overcome this, you need to create some custom app to monitor artifacts and trigger release once both artifacts meet some condition.
There is topic in developer community to implement this.
I'm new to Aure DevOps. Trying to create build and release pipelines there's one thing I don't understand:
Commonly, every kind of build finally results in some output, called artifacts.
With Azure DevOps it seems like there is always a final copy or publish task necessary to copy the created artifact from A to B, so the release task may then access the compiled artifacts.
Why aren't these artifacts plain accessible to a release pipeline right from the location where they have been built? Why don't the build tasks automatically set a variable pointing to the right folder, so the release pipeline may access the files right from there?
Or is this already happening and I'm just missing something from the tutorials I watched?
There are so many reasons.
Two easy ones:
There is no guarantee that the agent's working folder still contains the files. Agents are reused from build to build and release to release, and a given build or release will always use the same working folder. The working folder is cleaned up between builds.
Releases may run on different agents. On different machines. In different domains. Or any combination. There's no guarantee that the agent where the build ran is accessible by the agent where the release is running. Publishing the artifact allows a guarantee: As long as the machine the release is running on has the ability to talk to Azure DevOps (which is a requirement for the agent to function in the first place), it can get the artifacts it needs.
Why aren't these artifacts plain accessible to a release pipeline
right from the location where they have been built?
Agree with Daniel.
The main reason for me is because we can't hold the hosted agent all the time. Since MS wants to protect resources efficiently, it is not occupied for a long time.
When we queue a build, MS will assign us a brand new clean agent to execute our task, and after the build is complete, the MS will reclaim the agent assigned to our build and restore the agent to its initial state in preparation for accepting the assignment of the next task.
So, we could not keep hold the hosted agent to use it in next release pipeline. We have to store the artifacts in the cloud/server, then we could download it in the release pipeline. Otherwise, we could not get the artifact we need from an agent that has been restored.
Besides, MS is randomly assigned to the agent, and we cannot guarantee that the same agent will be allocated and built during the release pipeline.
That is the main reason why we need to copy or publish the artifacts.
If you do not want to copy or publish the artifacts, you could setup your own private agent, and do not clean the agent before you execute the release pipeline.
Update:
why is the user, well, bothered to find a place for the artifacts
manually? I would have expected every build pipeline to come with a
personal space to store the latest build artifacts. A space where
Azure DevOps automatically copies the build artifacts to. To me it
looks like things have to be manually copied from A to B and then
later from B to C.
That because not all output is needed, for example, the test project, what we need is test result/Code coverage for the test project, not the output for the solution. In this case, we do not need to copy the output to the artifacts. On the other hand, we need to copy some special files to artfacts, then automatically copy the build artifacts will not meet your requirements.
That is also the reason why we provide the task to copy files to artifacts, so that we could customize our personality needs.
Of course, if you think that manual copying is superfluous, you can use the MSBuild parameter /p:output=$(build.artifactstagingdirectory) to set the output directly to artifacts.
If I need to copy things from A to B in the Build pipeline, then what
should keep me from copying it to C right away? Then a separate
Release pipeline would be, well, rather optional, if not redundant.
If you are in the build pipeline, there is another task Download build artifacts, which could download the build artifacts.
if you are in the release pipeline, you just need select the build artifacts as source, release pipeline will download that artifact automatically:
Check this document for some more details.
Hope this helps.
We are trying to set up an Azure DevOps Pipeline (fka VSTS Release Definition) to accomplish the following flow:
The Production stage (environment) will be triggered if the artifact's build includes a special tag named "Production". This is easily done by adding a artifact filter like so:
The Dev/Test stages (environments) will be triggered if the artifact's build does NOT include the "Production" tag. We are unable to accomplish this since the Exclude filter doesn't allow excluding tags.
The reason we want to skip Dev/Test stages when it's time for us to deploy to Production is because there might be a long time gap between when a build has been validated in Dev/Test and when it's actually Production deployment time. We tag our good build with the "Production" tag and we allow our development to keep going in the master branch. Therefore, when it's time for Production deployment, we don't necessarily want to re-deploy that build to Dev/Test again since Dev/Test might be already several versions ahead.
We know we could also create a Release branch from master to accomplish this goal. However, we'd rather not create Release branches if we could skip Dev/Test deployments using build tags instead.
Please advise. Thanks!
You may be able to achieve the outcome you are looking for but in a different way.
When you create a new release for your pipeline you can change automated triggers to manual triggers.
If you want to skip non production environments so an old version isn't deployed to them, change the automated trigger to manual for those environments.