Azure DevOps CI/CD for Windows Desktop Apps – Part 2

Controlling the Build Pipeline

As stated in the “My Goal” section of my previous post, I want to start a build only when a commit message has some predefined tag or identifier. This is useful if you want to make sure that only the solution/projects you are interested in are built in a larger “mono-repo”.


There are more parts available:
Azure DevOps CI/CD for Windows Desktop Apps – Part 1
Azure DevOps CI/CD for Windows Desktop Apps – Part 2 (this post)
Azure DevOps CI/CD for Windows Desktop Apps – Part 3
Azure DevOps CI/CD for Windows Desktop Apps – Part 4
Azure DevOps CI/CD for Windows Desktop Apps – Part 5


Control Options – Custom conditions

The important piece here is the “Custom condition” at the bottom of the build task properties. The section is collapsed by default, so you have to click on the caption to expand it.

and(succeeded(), contains(variables['Build.SourceVersionMessage'], '[win]'))

You may have to scroll to the right to see the complete condition.

So when I include [win] in my commit message (available in the Build.SourceVersionMessage variable), this task should be performed. Click on the information symbol next to the “Custom condition” caption to view the documentation and syntax of the conditions.

Make sure you add this condition to all the build tasks you want to run on that condition.

The above condition is used for all tasks in the build pipeline up until the Run Unit Tests. All the tasks after the Run Unit Tests task have a different condition because I only want them to run when I intend to further process my build in the release pipeline. All the other tasks, especially the file copy tasks should not really run if I’m not interested in publishing. This is the condition I use for the tasks after the Run Unit Tests:

and(succeeded(), contains(variables['Build.SourceVersionMessage'], '[win]'), contains(variables['Build.SourceVersionMessage'], '#PUBLISH'))

You may have to scroll to the right to see the complete condition.

As you can see, this condition requires a successful state of the previous task AND the ‘[win]’ tag as well as the ‘#PUBLISH’ tag in my commit message. You can learn more about the syntax here and here.

Why not Task Groups or Agent Jobs?

I’ve tried using task groups and dedicated agent jobs to make it easier and apply the custom condition only once for a group of tasks but for whatever reason they did not work as I expected (at least at the time of writing this blog post). I even created a github issue about this.

About the Build Pipeline

As you can see in the screenshot above, the build pipeline is pretty simple. Nothing fancy here but I try to quickly explain what each task is used for.

  • Use NuGet 4.4.1
    This is a standard task which is created for you with the new pipeline based on Azure Git and .NET Desktop app.
  • Manual NuGet Task
    By default you get a simple to configure “NuGet Restore” task but I had to replace that with a custom command. In my csproj/solution I have special conditions which nuget packages to use and when, so I had to come up with my own command. Maybe stuff for a dedicated blog post.
  • Build solution
    Nothing special here.
  • Run Unit Tests
    Nothing special here.
  • Add Icon Resources to Executable
    This tasks allows me to embed more than one icon resource to an executable (VS does not support this). Maybe also something for a dedicated blog post.
  • Copy Release Build Output
    This task copies the output directory (where the release build with all depending files reside) to a special staging directory on my build server. Since I’m using Release Pipelines to further process my build, I need those files later on.
  • Copy Release Pipeline Scripts
    This task copies all the scripts which are used to a special staging directory for the release pipeline. My scripts are all checked in the repo and in the release pipeline I basically have to take care that all the files for further processing are available.
  • Publish Artifact drop
    I’m publishing my artifacts to a local file share on the build agent for performance reasons. Pushing it into the cloud and pulling it in the release pipeline takes quite a long time and isn’t really necessary in my case since all my stuff happens on the agent.
  • Set Publish Tag
    This is the last missing piece and quite important for controlling the release pipeline. But this will be discussed in Part 3. Stay tuned…

Leave a Reply