Missing artifacts from triggering build - azure-devops

To set the stage, I have two pipelines created in yaml, call them Build-CI and Release-CD. Release-CD has a pipeline resource dependency on Build-CI so when Build-CI completes, Release-CD is triggered.
The problem I am having is specific to build artifacts. In order to make my Release-CD jobs more efficient I am only downloading the build artifact that is necessary to complete the job, rather than having all jobs download all artifacts. I do this using the following syntax
- download: triggeredBy
artifact: 'drop'
patterns: '**/ArtifactSubFolder/*'
In this case "triggeredBy" is the name of the pipeline resource.
My understanding is this will download the artifacts from the build that triggered the release. And this works when the build and release occur back-to-back. However, the Release-CD pipeline contains multiple stages (dev, test, stage, prod). And as much is the case, the release will go to "test" and sit there waiting approval for a day or so before being promoted to "stage".
When this delay occurs and we approve the release to the next environment we get errors saying that the build artifacts are not found, and the build id it refers to is not the build id of the triggering build, but rather the build id of a build that occurred between the deploy to "test" and the approval to "stage"
How do I ensure that when approving these release pipelines to subsequent stages that they are indeed downloading artifacts from the original triggering branch?

Related

Download only artifacts I need in release pipeline and run tasks conditionnally

I have created a release pipeline that has multiple artifacts to be downloaded from multiple repositories.
Now, when I want to start the release I want to introduce a condition so that when the condition is met I download only the artifact I need and then run the task to deploy it otherwise when there is no condition all of the artifacts are downloaded thus all tasks are run.
How can I achieve that with azure DevOps ?
For conditions, I tried to look into
but for downloading only an artifact from multiple one I can't unless I specify a release pipeline for every project I have.
By default, build artifacts are downloaded to the agent. You can configure an option in the stage to skip the download of artifacts. https://learn.microsoft.com/en-us/azure/devops/pipelines/release/artifacts?view=azure-devops#artifact-sources---azure-pipelines
And use "Download Pipeline Artifact" task to specify your target Artifact. Set "Custom condition" within this task: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=classic
You can customize this behavior by forcing a stage to run by specifying a custom condition.

Azure DevOps Classic Release - Artifact Filter always triggering release

I have an Azure DevOps classic release pipeline
There are 2 artifacts (type build) with continuous deployment trigger enabled, and 2 stages
Each stage has an "after release" trigger with an artifact filter, to the respective build artifact.
The builds are for different repos.
However, both stage are being triggered when every build artifact is created, even when I manually create a release...
Expected behavior is:
Build A completes, only stage A is triggered
Build B completes, only stage B is triggered
When I manually create a release, I would like to choose which stage will be triggered. If this is not possible, the trigger both stages
Is this a bug or am I missing something?
Azure DevOps Classic Release - Artifact Filter always triggering release
For this issue ,I am afraid that it is currently not supported in azure devops. If you want different artifacts to trigger the deployment of different rows of stages respectively, it is better to create two pipelines, set the artifact in each pipeline to trigger the deployment on the required stages.
And you could check this topic on developer community
Sorry I should have clarified a bit more. I don't think that triggers will solve all use cases, but having triggers on stages would at least allow you to have the following:
Stage A has trigger /src/appA
Stage B has trigger /src/appB
If you commited (script, code, etc.) to /src/appB, it should use previous artifacts and only build appB and further if requested.
If you think that two artifacts only trigger a part of the pipeline is necessary, you could submit a feature request in our Develop Community site. Our PM and product team will kindly review your suggestion.

Devops CI pipeline exclude publish on pre release build

We have a pre build check on our PR's as a requirement to be completed.
We also have a CD release pipeline setup to release the app once new artifacts are published.
The problem is that once the pre release build is run, it publoshes artifacts and releases them.
Is there a way to restrict the publishing only when the code is merged and built?
Try adding the following condition clause to your publish step(s):
condition: and(succeeded(), ne(variables['build.reason'], 'PullRequest'))
This causes the step to be triggered if the previous step succeeded AND the reason for the build is not a pull request.

Execute a stage in DevOps Release pipeline every night on scheduler

I have an Azure DevOps CI Build and Release pipeline in following setup:
CI Build runs with each new commit in develop branch and creates a Build Drop (Artifact)
Release pipeline runs with each new Artifact and deploys to INT and eventually to PROD (after manual approval)
I would like to add a 3rd stage (called eg. MONITOR) which would run after the PROD release every night using the same drop as the PROD stage used, with following schema:
[Build Drop] -> [INT] -> manual approval: [PROD] -> nightly scheduler: [MONITOR]
This seems to be impossible to me, do you know how to achieve this goal?
Following is crucial for me:
the MONITOR and PROD run always from exactly the same Artifact
MONITOR is executed only if the PROD was successful
if there is a newer PROD release, the old MONITOR is not executed any more and instead the newest one is executed using the newest Artifact which made it to PROD
I tried so far following:
merge develop to master when the commit made it to PROD. And then used scheduled nightly Build from master with MONITOR stage - it works, but MONITOR uses different Artifact than PROD, so not usable for me
used scheduled trigger for MONITOR after PROD - does not work, the MONITOR is executed only once at scheduled time and never again
created extra release pipeline based on specific Artifact version with a scheduled trigger - this works, but I have to maintain the specific Artifact version manually with each successful PROD release. Another caveat is that I have to use 2 separate pipelines which makes the overview not so nice. (but, so far the best solution I achieved)
do you have better ideas? many thanks
What I would do is have 2 separate Release Pipelines.
This allows you to schedule the release without producing a new artifact (scheduled build).
Then, I would do some of what #Soccerjoshj07 suggested in that I would invoke the REST api in a task on the MONITOR pipeline/stage.
I would make the REST api call to the Releases endpoint to get the top=1 releases for releasedefinitionid=x. Then use the Release Environment endpoint to get the PROD environment for that latest release id. With the environment in hand, check the status for succeeded. If not, fail the release.
Edit as per new requirement outlined in comment
Given PROD.1 is succeeded and PROD.2 is failed when MONITOR is triggered, then the artifact from PROD.1 should be used for MONITOR.
With this criteria I would change some things. Rather than have the MONITOR go digging for the latest PROD release and fail if the latest is failed, I would make the successful PROD stage tag its build artifact and employ artifact filters on the Monitor pipeline.
The tagging can occur via the REST api or using the Tag Build or Release Task from Colin's ALM Corner Build & Release Tools and might look like this:
Are you using a YAML template, and if so have you played with the cron schedules? https://learn.microsoft.com/en-us/azure/devops/pipelines/build/triggers?view=azure-devops&tabs=yaml#scheduled-triggers
If using classic Release UI, I think you can have the definition trigger be on a schedule but that would queue the entire definition. You might have to get creative with variables and maybe create 'isScheduled=true' and use that to determine if it should skip tasks.
Other ideas:
Create a logic app or function app that calls the REST API? Sample app and github link here: https://oshamrai.wordpress.com/2019/04/22/azure-devops-rest-api-19-queue-builds-and-download-build-results/
The Azure-Devops AZ CLI extension might be easier, though: https://learn.microsoft.com/en-us/cli/azure/ext/azure-devops/pipelines/build?view=azure-cli-latest#ext-azure-devops-az-pipelines-build-queue
Beside setting up two release pipelines, if you want to use scheduled trigger for only one Stage, I am afraid there is no such out of box way to achieve that, scheduled trigger is only for entire pipeline.
As a workaround, you can add a custom condition for the job of MONITOR stage.
For example in yaml:
- stage: MONITOR
jobs:
- job:
condition: and(always(), eq(variables['Release.Reason'], 'Schedule'))
steps:
In UI , you can set this in Run this job of agent job:
In this case, the stage only executed when the release triggered by scheduled trigger. If the release is triggered by other reasons, the MONITOR stage will be skipped .
The limitation of this workaround is that when your pipeline is triggered by a scheduled trigger, two other stages are also executed.
Or write a script with powershell task (in INT/PROD stages) to determine whether Release.Reason is Schedule. If yes , skip the current stage.
For how to obtain the latest artifact version of PROD and determine the deployment status of PROD, you can refer to the two answers above.

Release is triggered even though build does not publish artifact

Last week, our team decided to move all separate .NET projects into a single solution. Because we were already using Azure DevOps with separate build pipelines for each project, we looked into the possibility to only trigger builds whenever there are changes to a specific project. This, to prevent the build agents from rebuilding the entire solution on every commit.
Because our source repository is a locally hosted Git one, we do not have the niceties of using path filters, so we resorted to using a Powershell task to determine if all upcoming tasks should be skipped, using a custom condition (explained in this SO question).
Now, on every commit, all builds are triggered, but the builds resolve for themselves if they should continue to build and (more importantly) if they should publish a build artifact at the end. An example of such a skipped build is below:
However, every time such a build 'succeeds', a new artifact is created, even though the publish artifact task is skipped. The problem is that all our release pipelines are triggered when a build pipeline creates an artifact. So every time a build is skipped like shown above, the release pipeline triggers and tries to deploy the artifact. But it fails, because the artifact it uses to deploy does not really exist (it seems like it is empty, and the build pipeline actually doesn't mention an artifact on the Summary tab), so any operations on the artifact fail in the release pipeline.
Our release pipelines are set to trigger on source type build artifact, for the corresponding build pipeline, with the default version parameter set to latest.
How is it possible that, even though the publish artifact task is skipped, the release pipeline still triggers and tries to deploy an empty artifact?
I assuming you enable the Continues Delivery in the Releases pipelines, this option is not related to build artifacts. this option means that Release will be triggered when the build succeeded (not matter if he has artifacts or no).
So this is the reason why after each build a new release started.
As workaround, you can add a task in the build that add "build tag" only when there is a artifacts, and in the release artifacts options, instead of choose Latest you can choose Latest from the build pipeline default branch with tags and specify the tag you put in the build.
Another option is in the "Stages" click on the triggers and then it's configured to "After release" so enable the "Artifact filters" and specify there the build tag.
How do you add a build tag? add a PowerShell task with this command:
Write-Host "##vso[build.addbuildtag]test-tag"