conditionnally select nuget package during build - azure-devops

Our build environment is VSTS pipeline and our development environment is visual studio.
We are using dev branches (or feature branches) and we have a main branch (master branch).
As piece of code are getting stable and don't need much debug, We are now willing to split our projects into nuget packages.
As long as we are in dev or feature branch, we want to generate and use the -alpha nuget package to test and use the latest code.
But as soon as we are doing a pull request to the master branch, we want to use the stable nuget package.
Of course, without having to manually go to the nuget package manager and update every nuget package before committing;
Said differently, every project in a dev branch should automatically build with the -alpha version of each nuget package and the build of the master branch should be with the stable version of the package.
How can we create a vsts pipeline to achieve this

conditionnally select nuget package during build
You could add a task (powershell or batch) to modify the nuget.config or the project file to update the package version with condition.
steps:
- powershell: |
# Write your PowerShell commands here.
update the package version in the nuget.config or project file.
displayName: 'Update package version'
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))

You create two (build) pipelines:
Dev / Feature you name it -> gets triggered by your feature/* branches and publishes your -aplpha nuget package
Stable / Prod -> gets triggered by pull requests into the main branch and publishes the stable nuget package
I personally don't have much experience with YAML, yet, but in the classic pipeline editor you can easily add tasks. Each pipeline should roughly be looking like this:
Some more details:
Missing on the screen shot is the important trigger part. You can also edit that in the classic pipeline editor in the "trigger" tab. There you choose your feature branch setting (e.g. feature/*) and exclude the master on the feature pipeline.
Converting all to YAML should be straight forward via the "View YAML" feature in the classic web editor.
Depending on your private setup you might need extra steps like NuGet auth if you use a private NuGet server etc..

Related

How should c# references be handled when working with DevOps artifacts?

I am new to DevOps. I will explain my structure first.
Project 1>
Repo 1
Repo 2
I am trying to make two build pipelines one that will build Repo 1 and a second that will build repo 2.
Repo 2 has a dependency on Repo1.dll.
I understand that I can publish the Repo1.dll and then download the artifact in repo2's pipeline.
My trouble is, our developers normal workflow is to have both repo's running in debug on their machines using a project reference. I am having trouble understanding how to reference Repo 1 from Repo 2 in a way that the artifact can be used in DevOps and project reference can be used on the developers machines.
How should c# references be handled when working with DevOps artifacts?
The best way to do this is using the NuGet.
When you build Repo 1 and create the nuget package Package1. Then publish this package Package1 to the Azure devops feed.
Now, add this package Package1 to the solution2 in the Visual Studio from the feed.
When we update the repo1, we need to build the NuGet package, publish it to the feed, then update the refernces package version to refer to the package you just publish.

Only build the project that has changed

I have a single .NET solution with multiple class library projects, each one is published as a nuget feed using azure-devops.
Then I have an azure-devops build pipeline, with steps to Restore, Build, Publish, Pack and Push.
The first 4 steps are setup for **/.csproj and the last is a $(Build.ArtifactStagingDirectory)/.nupkg with the target feed.
I have everything set up and working, except if you make a change to just one project, it builds ALL projects because of the **/*.csproj.
This is no good for nuget packages, as it increments every project's version number and they all appear as having an update available in the nuget package manager.
My Question: Is there a way to do this so that only the project(s) with changes go through the process?
Is there a way to do this so that only the project(s) with changes go through the process?
The answer is yes.
The solution is use the private agent to build your solution instead of the hosted agent.
That because every time the hosted agent assigned to us is a clean machine, VS/MSbuild will build all the projects for the setting **/* csproj. So, to resolve this issue, we must save the results of the last build to achieve incremental builds.
So, to resolve this issue, we need to set up a private agent to build those projects and do not clean the working directory of your private agent before the build is run:
Set the Clean option to false on the Get sources:
Note: Since you also set the **/*.csproj for the task nuget push, if the project not modified, this command will push the same version to the feed, it will throw the conflict error, you need enable Allow duplicates to be skipped on the nuget push task:
Hope this helps.

Is there a way to validate a package is built off a particular branch as part of build in VSTS DevOps?

As part of a project we are using some in-house npm packages. These have a simple branching strategy of 'develop', 'release' and 'master'. Our project will reference this package, but we want a way to make sure that when we go to release, that the package referenced has been built off the release branch for that package and not the develop one.
Is there a way to fail a build if the package hasn't been built of a given branch?
So you want some way to tag your builds as "release candidate" when they come from specific release branch. There are many different ways to do this.
For example, Azure Pipelines has some built in variables:
https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml
You see we have a variable : Build.SourceBranchName
You can use this in a number of ways. For example you could write this into a build-notes.txt and package it into your artifact. Or depending on how you package your artifacts, you may be able to tag this information in somewhere.
e.g. NPM supports something called dist-tag : https://docs.npmjs.com/cli/dist-tag
Your release pipeline then just needs some logic to read this and validate.

Azure DevOps - Private NuGet feed doesn't update stable release

I created a private NuGet feed in Azure DevOps following this guide and created a build pipeline with dotnet pack and dotnet nuget push steps. After running the build a few times, the new versions are displayed under Artifacts >> MyFeed >> Versions. I promoted some of the versions by hand to #Release.
Here's the view in DevOps:
But when I connect to the feed in Visual Studio, I only see version 1.0.0 as stable release, but all later versions (which are published via my build pipeline), are only shown if I check the "include pre-release" option. Here's a screenshot:
My questions are:
1 - how can I manually promote a version to stable?
2 - how can I promote a version to stable via a build or release pipeline?
Azure DevOps - Private NuGet feed doesn't update stable release
Just like zivkan said "anything after a - character signals pre-release information.". You can check the nuget document Package versioning for some details.
1 - how can I manually promote a version to stable?
You can download that package from your nuget feed, then change the package version to stable, then re-push it to the feed.
2 - how can I promote a version to stable via a build or release pipeline?
To promote a version to stable via a build or release, you could change the build number. When you use dotnet pack task to create the nuget package, there is an option Automatic package versioning:
Update:
So, try to use the option Use the build number option on the Automatic package versioning.
Then, in the Build number format option, you can set it to $(Major).$(Minor).$(Patch)$(Rev:.r):
The value of $(Major), $(Minor), $(Patch) are custom variables in the Variables tab, the value of $(Rev:.r) is the build number.
In this case, the package will be TestSample.1.0.0.5.nupkg.
Hope this helps.
NuGet uses Semantic Versioning 2.0, which says that anything after a - character signals pre-release information. Therefore 1.0.1-CI is prerelease, whereas 1.0.1 would be a release version. If you want build metadata in the version string, you should use the + character, again as defined by SemVer2.
edit: note that SemVer metadata does not contribute to version comparisons, so 1.2.3+CI.1 is considered the SAME version as 1.2.3+CI.2

VSTS Release Management: filter by branch on artifact source

I am using VSTS build to run a CI build. This build definition is the same for all my git branches (master, develop, features, etc).
I am now trying to implement a deployment pipeline using VSTS release management. I plan to have two distinct release definitions. One for feature branches and one for the more important branches like develop and master. The release definition for feature branches would be more lightweight.
I think this is pretty basic and usual. In fact, that's pretty much what is documented in Microsoft's typical use case for Release Management.
For both of these pipelines, I want to configure them to start automatically using the 'Continuous Deployment' trigger. When I select this trigger, I must select an artifact source.
Unfortunately, an artifact source takes all artifacts (regardless of the branch) coming from a given build definition (my CI build). Since I use the same CI build definition for all my branches, it looks like I can't configure my two release pipelines in 'Continuous Deployment' and still use the same build definition as an artifact source.
Anybody knows how to share the same build definition for multiple release definitions but only start a release for a specific branch? Anybody knows of a way to filter by branch when we define an artifact source?
Configure branch specific release deployment
Go to release management in VSTS
Go to the definition of the release
Go to tab triggers
Add Continuous Deployment trigger
Here you can select a specific branch (for branch)
Availability of feature
This feature is available in VSTS
In the TFS on-premise version it was supposed to be available in version Server 2017.1 but it is still not available in version 2018.1
Currently there is no way in VSTS Release Management to do conditional deployment based on branch.
An alternate would be to create separate BDs for different branches and then configure them as artifact sources for the RDs.
This will also give users a clarity about the artifact from its name itself.