Release is triggered even though build does not publish artifact - azure-devops

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"

Related

How To Group Azure DevOps Build Artifacts From Multiple Projects Into One Release Pipeline By Just Build Artifact Tag

All the project builds for release 3 have been tagged with relese3. Out of 100 projects I'm not sure which ones are release3. I need to group all the build artifacts from each project tagged with release3 into one release pipeline. Is there a way to add build artifacts to a release by just build artifact tag?
Don't know which projects are tagged release3:
Is there any way to group build artifacts from multiple projects into one release pipeline by just build artifact tag?
Or can one release pipeline just use the Azure Trigger Pipeline task to trigger all project release pipelines with a build tag of release3?
How To Group Azure DevOps Build Artifacts From Multiple Projects Into One Release Pipeline By Just Build Artifact Tag
I am afraid there is no such way to do this at this moment.
As we know, in the release pipeline, we need to specify the pipeline which need to be deployed.
We cannot leave the option source(build definition) blank (it is required). in addition,
If this function is supported, there will be a certain risk, because the release pipeline is directly related to production, and tags are used to bind all related build pipelines, which makes if our development engineers accidentally use the wrong tag, or in the wrong If the tag is added to the pipeline, the wrong build artifact will be released to the actual production environment because the pipeline is not clearly specified in the release pipeline. will cause losses.
If you feel this feature is important to you, you could add your request for this feature on our UserVoice site (https://developercommunity.visualstudio.com/report?space=21&entry=suggestion), which is our main forum for product suggestions. Thank you for helping us build a better Azure DevOps.

The $(Build.ArtifactStagingDirectory) variable's value changes when deploying a build in Azure DevOps Pipelines

I have a DACPAC deployment task which is failing, because for some reason the value of the $(Build.ArtifactStagingDirectory) pipeline variable is changing between the build pipeline and the release pipeline. In the build pipeline, the variable is set to C:\agent\_work\2\a, but in the release pipeline it's C:\agent\_work\r2\a. This is causing the release pipeline to fail when it tries to deploy the DACPAC artifact, because the folder it's looking in is empty; the folder where the artifact actually is is ignored. How do I make these variables consistent between the build and release pipelines so that the artifact is retrieved from the same folder it's generated in? These variables appear to be built in, so I don't see any way to change them. I could always hardcode a path, but that seems a bit kludgy...
In releases you have System.ArtifactsDirectory which is
The directory to which artifacts are downloaded during deployment of a release. The directory is cleared before every deployment if it requires artifacts to be downloaded to the agent. Same as Agent.ReleaseDirectory and System.DefaultWorkingDirectory.
Example: C:\agent_work\r1\a
and in pipelines/builds Build.ArtifactStagingDirectory
The local path on the agent where any artifacts are copied to before being pushed to their destination. For example: c:\agent_work\1\a
A typical way to use this folder is to publish your build artifacts with the Copy files and Publish build artifacts tasks.
Note: Build.ArtifactStagingDirectory and Build.StagingDirectory are interchangeable. This directory is purged before each new build, so you don't have to clean it up yourself.
See Artifacts in Azure Pipelines.
This variable is agent-scoped, and can be used as an environment variable in a script and as a parameter in a build task, but not as part of the build number or as a version control tag.
This is in line with your experience. And you cannot change it, as they are predefined. But can you clarify why this is a problem for you?
In the release pipeline, you can't directly access the files in the build pipeline, not only because the working directory is different, but also because they do not use the same agent. You need to download the artifacts first, and then use them in the release pipeline.
You can use the following ways to download artifacts:
Use the Download Build Artifacts task.
Go to the edit release pipeline page -> Select Add artifact -> Select Build -> Fill in the information related to the build pipeline (Notice the value of Source alias)-> Add it. You will find your artifacts are downloaded in $(System.ArtifactsDirectory)/${Source alias}
For more information about consuming artifacts in release pipelines, you can click this document.
Oh, I think I figured it out. Each release pipeline stage has an option called "Artifact download" which lets you specify which artifacts out of all those linked in the pipeline are actually used by that stage. I needed to check the appropriate checkboxes there in order to use the artifacts in the stage's tasks.

VSTS - Download triggering artifact

I currently have a release defined for pushing clients to an internal nuget server.
Each release is identical in terms of steps, the only thing that changes is the triggering artifact.
However when I add another artifact to a "generic" release, so that there are now ClientA and ClientB artifacts on the release, both artifacts are downloaded when the release is triggered and they are both then pushed.
What I would like to know is if it is possible to have the release only download the triggering artifact.
Example:
A release is triggered on both ClientA and ClientB.
ClientB is released. The build triggers and only uses the ClientB artifact during the deployment.
I don't think this is possible at the moment, but something similar is possible though.
Create a task group from the current release definition as described here: https://learn.microsoft.com/en-us/vsts/pipelines/library/task-groups?view=vsts
There clone the release definition and change the artifact from ClientA to ClientB.
You'll end up having two release definition, both sharing the steps but the artifacts will be different.
EDIT: PowerShell script to download Build artifacts
Eddie suggested a nice workaround. Here's how you can pull down an artifact manually.
You need to enable Allow scripts to access OAuth token
Add a PowerShell task to each phase and reference the DownloadBuildArtifacts.ps1 script
If the release is triggered by build artifacts, the value of the pre-defined variable "$(RELEASE.TRIGGERINGARTIFACT.ALIAS)" will be the triggered artifacts alias. You can get the value of this variable to determine which artifact trigger the release.
There isn't any way to achieve this out of box. But you can disable auto download artifacts and add a powershell script in your release definition to get the triggered artifact and download it.
There isn't the way to just download the triggered artifacts, but you can identify which artifact trigger this release through RELEASE_TRIGGERINGARTIFACT_ALIAS variable.
So, you can push corresponding one per to that variable.

Release definition to publish nuget packages for multiple artifacts

I have a VSTS release definition that I want to use for publishing nuget packages for multiple artifacts. The artifacts for the different nuget packages are supplied to the release definition from different build definitions. Only artifacts from the build that triggered the release shall be downloaded and published. The pipeline is setup according to the picture below.
That is, when a build triggers a new release, only artifacts from that build should be published in the release. All artifacts from the other build definitions should be ignored since the version number on those nuget packages are not updated and will fail to push.
Can this be accomplished?
Take a look at this link https://learn.microsoft.com/en-us/vsts/release-notes/2018/mar-05-vsts#improve-release-times-by-partially-downloading-artifacts
And then on that same link see Deploy selectively based on the artifact triggering a release
It will basically explain VSTS new features. The first one is to specify what you want to download on a release phase. The second one is to add a custom condition on a phase to define if it should be executed.
So you could create two phases, one for each of your artifacts. Each phase would only download the corresponding artifact and only run if the custom conditional evaluates true, using the new release variable Release.TriggeringArtifact.Alias.
Note that this release variable is only present if the release is continuous deployment.

VSTS: Unable to add Build Tag which trigger release

In VSTS online, I have in my Release process (Under Triggers) the Continuous Deployment checked. On the Set trigger on artifact source, I put a Tag condition (with tags) set to Automated.
I also have a tag in the Build Process. (Correctly adds the Tag to the build)
But my release is not triggered automatically? In the Deployments status (In my Build) it says "Tags set for release trigger did not match the tags in build branch". But they match (See pictures). What could be the issue?
This is because you added the tag Automated after the build is finished (by label source or manually). This can’t trigger CD release. Tags should be add during a build (not a build is finished). So you can add a power shell task with inline script in your build definition:
Write-Host "##vso[build.addbuildtag]Automatd"
Then the release will be trigger after build is finished.
I do this a different way very similar to:
How to trigger VSTS build and release when pushing tags?
In my Release Pipeline I add a branch filter to 'refs/tags/' or 'refs/tags/v' for the Continuous Deployment Trigger, or anywhere else where I want to filter action in my Release Pipeline. The good thing is that you can apply your Git Tag AFTER your build is complete, just like you prefer. This is optional, but I use Git in conjunction with GitVersion.
Also, please be aware that Git Tags and Build Tags are not the same. Git Tags are stored in the Git repository while Build Tags are associated with a VSTS/Azure build summary. Don't get confused with the two.
For future readers it looks like you can now trigger a release even when a tag is added to a build at any time (not just during a build).
Create a release when tags are added to an existing build. Upon enabling this option, a release gets created when tags are added to an existing build that has not been released. This could lead to deployment of an older build to the environments.