Versioning per different project (feed) in Azure Pipelines - .net-core

I have a .Net Core repo, that consists of various smaller projects, and a pipeline that builds it, tests it, and publishes the nugets on the feed.
My problem is that all different nugets that get published have the same version.
What I want to accomplish is to have for each nuget published a different version according to how it is developed/pushed (I cannot just split the repo). Is this possible?

You could try to pack the project on by one:
steps:
- task: DotNetCoreCLI#2
displayName: 'dotnet build'
inputs:
projects: '**/*.csproj'
- task: DotNetCoreCLI#2
displayName: 'dotnet pack'
inputs:
command: pack
packagesToPack: 'ConsoleAppCore/ConsoleApp1/ConsoleApp1.csproj'
versioningScheme: byPrereleaseNumber
majorVersion: 2
minorVersion: 1
patchVersion: 1
- task: DotNetCoreCLI#2
displayName: 'dotnet pack'
inputs:
command: pack
packagesToPack: 'ConsoleAppCore/ConsoleAppCore/ConsoleAppCore.csproj'
versioningScheme: byPrereleaseNumber
majorVersion: 3
minorVersion: 1
patchVersion: 1
- task: DotNetCoreCLI#2
displayName: 'dotnet pack'
inputs:
command: pack
packagesToPack: 'ConsoleAppCore/ConsoleApp2/ConsoleApp2.csproj'
versioningScheme: byPrereleaseNumber
majorVersion: 1
minorVersion: 1
patchVersion: 1

Related

How to pass projects as parameter while using dotnet publish command in DotNetCoreCLI#2 task

I have dotnet core project and using 'DotNetCoreCLI#2' task in Azure Pipeline to publish the code. My 'DotNetCoreCLI#2' task looks like this:
- task: DotNetCoreCLI#2
displayName: 'Dotnet Publish'
inputs:
command: 'publish'
publishWebProjects: false
projects: |
**/*.csproj
!**/*Blazor.csproj
arguments: '-o $(Build.ArtifactStagingDirectory)'
This works when used. Now I am trying to build template and want to pass projects values as variables or parameters but failing to do so.
Here is what I tried (I am using variable here)
variables:
projectsToPublish: '**/*.csproj;!**/*Blazor.csproj'
steps:
- task: DotNetCoreCLI#2
displayName: 'Dotnet Publish'
inputs:
command: 'publish'
publishWebProjects: false
projects: $(projectsToPublish)
arguments: '-o $(Build.ArtifactStagingDirectory)'
I also tried using variables like this, but it didn't work and keep getting this error message: ##[error]Project file(s) matching the specified pattern were not found.
variables:
projectsToPublish: '|
**/*.csproj
!**/*Blazor.csproj'
or
variables:
projectsToPublish: '**/*.csproj
!**/*Blazor.csproj'
Any idea how I can set projects values in variables and use it in publish task?
how I can set projects values in variables and use it in publish task?
To solve this issue, you can define multiple line variable in Azure Pipeline.
For example:
variables:
projectsToPublish: |
**/*.csproj
!**/*Blazor.csproj
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: echo "$(projectsToPublish)"
- task: DotNetCoreCLI#2
inputs:
command: 'publish'
publishWebProjects: false
projects: |
$(projectsToPublish)
Result:
You could use parameters for a try.
Firstly, ensure in your repo the '/*.csproj;!/*Blazor.csproj' files do exist.
Then you could try this:
parameters:
- name: projectsToPublish
type: string
values:
- '**/*.csproj'
- '!**/*Blazor.csproj'
steps:
- task: DotNetCoreCLI#2
displayName: 'Dotnet Publish'
inputs:
command: 'publish'
publishWebProjects: false
projects: ${{ parameters.projectsToPublish}}
arguments: '-o $(Build.ArtifactStagingDirectory)'
For parameters execute in runtime, you will need to choose the value after click run:
[![enter image description here][1]][1]
Choose one then click 'run', then you are supposed to run the task.
[1]: https://i.stack.imgur.com/2uoPk.png

First time Azure DevOps user, tips on what I could do better in my build pipeline

I work for a small company and we are just starting to get our DevOps pipeline setup. The codebase is about 20 projects in a Visual Studio Solution. Some of these projects' frameworks are .Net 5 and others are .Net Framework 4.8. We are currently in the process of updating but for now we need to use what we have. The following is my attempt at a build pipeline. It runs and I think it works. But I wanted to get more professional opinions on what I can do better because I feel like it is pretty newb.
Here is my yml file:
# ASP.NET Core (.NET Framework)
# Build and test ASP.NET Core projects targeting the full .NET Framework.
# Add steps that publish symbols, save build artifacts, and more:
# https://learn.microsoft.com/azure/devops/pipelines/languages/dotnet-core
trigger:
- develop
pool:
vmImage: 'windows-latest'
variables:
solution: '**/MySolution.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#1
displayName: 'Install NuGet'
- task: NuGetCommand#2
displayName: 'NuGet restore'
inputs:
command: 'restore'
restoreSolution: '$(solution)'
feedsToUse: 'select'
vstsFeed: '6010f35a-7ea3-4aa2-8264-60e3a5f02e6f'
- task: UseDotNet#2
displayName: 'Use .NET Core sdk 5.0.404'
inputs:
packageType: 'sdk'
version: '5.0.404'
includePreviewVersions: true
#Using DotNet and NuGet restore because without doing both the build breaks.
- task: DotNetCoreCLI#2
displayName: 'DotNet Restore'
inputs:
command: 'restore'
projects: '**/*.csproj'
feedsToUse: 'select'
vstsFeed: '6010f35a-7ea3-4aa2-8264-60e3a5f02e6f'
#Specifying older version to work with our older project dependencies.
- task: NodeTool#0
displayName: 'Use Node version 14.x'
inputs:
versionSpec: '14.x'
#The CleanWebsitesPackage lines are weird, I added them because the build was deleting most of the .Net Framework 4.8 project outputs
#when I looked in the logs it showed these steps were the ones doing the deleting.
#By pointing them at nothing it doesn't delete.
- task: VSBuild#1
displayName: 'VS Build'
inputs:
solution: '$(solution)'
msbuildArgs: '
/p:DeployOnBuild=true
/p:WebPublishMethod=package
/p:PackageAsSingleFile=true
/p:SkipInvalidConfigurations=true
/p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip"
/p:DeployIisAppPath="Default Web Site"
/p:CleanWebsitesPackageCoreDependsOn=""
/p:CleanWebsitesPackageDependsOn=""'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: ExtractFiles#1
inputs:
archiveFilePatterns: '$(build.artifactStagingDirectory)\WebApp.zip'
destinationFolder: '$(build.artifactStagingDirectory)\WebApp'
cleanDestinationFolder: true
overwriteExistingFiles: true
- task: DeleteFiles#1
inputs:
SourceFolder:
Contents: '(build.artifactStagingDirectory)\WebApp.zip'
- task: PublishPipelineArtifact#1
inputs:
targetPath: '$(build.artifactStagingDirectory)'
# targetPath: '$(Pipeline.Workspace)' #Uncomment to publish entire directory
artifact: 'drop'
publishLocation: 'pipeline'
I would probably keep things simple but here are few suggestions i can think off.
If the scope of this pipeline is to become a multi-stage pipeline in the future then you could utilize stages to define multiple stages of your pipeline
stages:
stage: A
jobs:
job: A1
job: A2
stage: B
jobs:
job: B1
job: B2
Reference: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/stages?view=azure-devops&tabs=yaml
You can use templates to define reusable content, logic, and parameters.
Reference: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops

Build Asp.Net website project using Azure Devops

I am trying to build a solution using CI pipeline. It is an old ASP.NET Web Forms Site. The yaml file is as follows
trigger:
- main
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#1
- task: NuGetCommand#2
inputs:
restoreSolution: '$(solution)'
- task: VSBuild#1
inputs:
solution: '$(solution)'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: '$(build.artifactStagingDirectory)'
ArtifactName: 'PublishBuildArtifacts'
After build nothing is copied to artifact 'PublishBuildArtifacts' and I see a message "Directory 'D:\a\1\a' is empty. Nothing will be added to build artifact 'PublishBuildArtifacts'."
My understanding is that via PackageLocation property the package would be in artifactstagingdirectory folder which should be published in the next step. What am I missing here? Do I need to use copyfile task? If so what would be the source and target folders? Thanks
You may add CopyFiles task before PublishBuildArtifacts task :
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
inputs:
SourceFolder: '$(agent.builddirectory)'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: '$(build.artifactStagingDirectory)'
ArtifactName: 'PublishBuildArtifacts'

How to ignore some files when generating test coverage with VSTest and reportgenerator tools on Azure pipelines

I have a problem that I have failed to resolve.
I have a .NET core project that I want to run tests and publish the test coverage on Azure Pipelines.
The problem is: I'm using EF to generate Migrations files. I want to ignore these files from test
but I can't.
Anyone how to do add some arguments to the pipe-lines command to ignore these files? like --exclude Migrations/*.cs
Here is the job in my azure-pipelines.yaml
- job: Testing
steps:
- task: UseDotNet#2
displayName: 'Use .Net Core sdk 3.1.x'
inputs:
version: 3.1.x
- task: DotNetCoreCLI#2
inputs:
command: 'test'
projects: '$(build.sourcesDirectory)/tests/*Tests/*.csproj'
arguments: -c $(BuildConfiguration) --logger trx --collect:"XPlat Code Coverage" --settings:$(build.sourcesDirectory)/src/test.runsettings -- RunConfiguration.DisableAppDomain=true
displayName: 'run tests'
- task: DotNetCoreCLI#2
inputs:
command: custom
custom: tool
arguments: install --tool-path . dotnet-reportgenerator-globaltool
displayName: Install ReportGenerator tool
- script: ./reportgenerator -reports:$(Agent.TempDirectory)/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/coverlet/reports -reporttypes:"Cobertura"
displayName: Create reports
- task: PublishCodeCoverageResults#1
displayName: 'Publish code coverage'
inputs:
codeCoverageTool: Cobertura
summaryFileLocation: $(Build.SourcesDirectory)/coverlet/reports/Cobertura.xml
You're probably looking for -classfilters or -filefilters.
https://github.com/danielpalme/ReportGenerator
I use -classfilter like this, where Foo.Bar.* and Foo.Baz.* is the namespace i want to exclude in the report:
variables:
...
classes-to-exclude-from-coverage: "-Foo.Bar.*;-Foo.Baz.*"
...
- script: ./reportgenerator -reports:$(Agent.TempDirectory)/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/coverlet/reports -reporttypes:"HtmlInline_AzurePipelines;Cobertura;Badges" -assemblyfilters:"-xunit*;" -classfilters:'$(classes-to-exclude-from-coverage)'
displayName: Create reports

Azure DevOps Xamarin.iOS simulator build output

Here is my build pipeline:
pool:
vmImage: 'macOS-latest'
variables:
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#0
- task: NuGetCommand#2
displayName: 'Restoring nuget for the solution'
inputs:
restoreSolution: '**/*.sln'
- task: XamariniOS#2
displayName: 'Building iOS for simulator'
inputs:
solutionFile: '**/*iOS*.csproj'
configuration: '$(buildConfiguration)'
buildForSimulator: true
packageApp: false
- task: CopyFiles#2
displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
inputs:
SourceFolder: $(build.SourcesDirectory)
Contents: '**/*.app'
TargetFolder: '$(build.artifactstagingdirectory)'
condition: succeededOrFailed()
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: Mobile-BackReporting iOS'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
condition: succeededOrFailed()
The important part is task: CopyFiles#2
I am trying to copy the iOS simulator package i.e. SampleToDo.iOS.app to the staging directory. I can see that in build output, the file gets generated here:
/Users/runner/runners/2.171.1/work/1/s/MobileBackReporting.iOS/bin/iPhoneSimulator/Release/SampleToDo.iOS.app
To get to this path, I have tried all the possible combination of Build and Agent environment variable paths found here:
https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml
I still can't copy the SampleToDo.iOS.app file to staging area as copy file task gives warning as:
##[warning]Directory '/Users/runner/work/1/a' is empty. Nothing will be added to build artifact 'drop'.
##[warning]Directory '/Users/runner/work/1/s' is empty. Nothing will be added to build artifact 'drop'.
If you enable system.debug (set system.debug=true variable in your pipeline) in your pipeline. You can see from the copy file task log, the .app is actually a directory. That is why the copy file task showed error that file was not found.
Since .app is a directory, you need to configure the copy file task like below. The copy file task will copy all the contents in this directory to folder $(build.artifactstagingdirectory)/SampleToDo.iOS.app.
If you want to generate .ipa file, you can set packageApp=true
- task: CopyFiles#2
displayName: 'Copy Files'
inputs:
SourceFolder: $(build.SourcesDirectory)
Contents: '**/SampleToDo.iOS.app/**'
TargetFolder: '$(build.artifactstagingdirectory)/SampleToDo.iOS.app'
flattenFolders: true
condition: succeededOrFailed()
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: Mobile-BackReporting iOS'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
condition: succeededOrFailed()

Resources