I have a DevOps team and have very less experience with C# and .NET.
I have code written by dev team.
This is the folder structure of the project:
Now when I built the software using visual studio community edition. It creates this folder structure.
Global.asax
Web.config
app_data
bin
Properties
But when i am running the build via Azure Devops Pipeline, then folder structure is changed.
- task: NuGetToolInstaller#1
displayName: Installing nuget
- task: NuGetCommand#2
displayName: nuget restore
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
feedsToUse: config
nugetConfigPath: NuGet.config
- task: VSBuild#1
inputs:
solution: '**\*.sln'
msbuildArgs: '/p:OutDir=$(Build.ArtifactStagingDirectory)'
createLogFile: true
logFileVerbosity: diagnostic
name: BulidingSolutionTask
- task: PublishBuildArtifacts#1
displayName: 'Publish Build Artifacts'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
Below is folder structure.
_PublishedWebsites/Mainproject/Global.asax
_PublishedWebsites/Mainproject/Properties
_PublishedWebsites/Mainproject/Web.config
_PublishedWebsites/Mainproject/bin
_PublishedWebsites/webjob1/bin/FileSandDirecotriesOfWebJob
_PublishedWebsites/webjob2/bin/FileSandDirecotriesOfWebJob
Why am I getting extra folder created _PublishedWebsites/Mainproject and why Webjob1 and 2 has bin folder inside? Is it a development problem or build problem and how to fix it?
Your first screenshot is the structure of the "solution" in .NET, which is where your SLN file lives. Your second screenshot is of your "project" in .NET, which is where your CSPROJ file lives. If you only want to build the project but not the solution you would want to specify that in your DevOps tasks as **/XYZ.csproj (where "XYZ" is the name of the CSPROJ file in the Mainproject folder) rather then building the entire solution, which likely houses those other projects that you're getting in your build output.
Alternatively, you could leave the SLN build, and then use the following build args:
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
And then simply this for your publish:
- publish: '$(Build.ArtifactStagingDirectory)'
artifact: drop
This will put your individual projects into ZIP files that can then be deployed independently (i.e. if you were to want to deploy webjob1 or webjob2 later, you would have that option in your release pipeline).
Related
I have a project using .net core 3.1 with Windows Forms and a Windows Application Packaging project in the same solution. I had this pipeline working for the past couple of months and now it seems to have stopped working.
I'm not sure, but it seems to be failing to find a .target file from within the hosted agent I'm using to run the pipeline.
I tried using the VS Msbuild step and the MSBuild standalone one, also tried specific NuGet versions(5.2.0,5.8.0,5.10.0) with Nuget Restore step. But nothing seems to help.
Does anyone have some clue where to start looking?
The error:
...
CopyFilesToOutputDirectory:
Copying file from "D:\a\1\s\PrinterAgent\PrinterAgent\obj\Release\netcoreapp3.1\PrinterAgent.dll" to "D:\a\1\s\PrinterAgent\PrinterAgent\bin\Release\netcoreapp3.1\PrinterAgent.dll".
PrinterAgent -> D:\a\1\s\PrinterAgent\PrinterAgent\bin\Release\netcoreapp3.1\PrinterAgent.dll
Copying file from "D:\a\1\s\PrinterAgent\PrinterAgent\obj\Release\netcoreapp3.1\PrinterAgent.pdb" to "D:\a\1\s\PrinterAgent\PrinterAgent\bin\Release\netcoreapp3.1\PrinterAgent.pdb".
Done Building Project "D:\a\1\s\PrinterAgent\PrinterAgent\PrinterAgent.csproj" (default targets).
##[error]C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\DesktopBridge\Microsoft.DesktopBridge.targets(16,3): Error MSB4019: The imported project "C:\hostedtoolcache\windows\dotnet\sdk\3.1.411\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.NuGet.targets" was not found. Confirm that the expression in the Import declaration "C:\hostedtoolcache\windows\dotnet\sdk\3.1.411\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.NuGet.targets" is correct, and that the file exists on disk.
Project "D:\a\1\s\PrinterAgent\PrinterAgent.sln" (1) is building "D:\a\1\s\PrinterAgent\PrinterAgent.Package\PrinterAgent.Package.wapproj" (3) on node 1 (default targets).
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\DesktopBridge\Microsoft.DesktopBridge.targets(16,3): error MSB4019: The imported project "C:\hostedtoolcache\windows\dotnet\sdk\3.1.411\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.NuGet.targets" was not found. Confirm that the expression in the Import declaration "C:\hostedtoolcache\windows\dotnet\sdk\3.1.411\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.NuGet.targets" is correct, and that the file exists on disk. [D:\a\1\s\PrinterAgent\PrinterAgent.Package\PrinterAgent.Package.wapproj]
Done Building Project "D:\a\1\s\PrinterAgent\PrinterAgent.Package\PrinterAgent.Package.wapproj" (default targets) -- FAILED.
Done Building Project "D:\a\1\s\PrinterAgent\PrinterAgent.sln" (default targets) -- FAILED.
Build FAILED.
"D:\a\1\s\PrinterAgent\PrinterAgent.sln" (default target) (1) ->
"D:\a\1\s\PrinterAgent\PrinterAgent.Package\PrinterAgent.Package.wapproj" (default target) (3) ->
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\DesktopBridge\Microsoft.DesktopBridge.targets(16,3): error MSB4019: The imported project "C:\hostedtoolcache\windows\dotnet\sdk\3.1.411\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.NuGet.targets" was not found. Confirm that the expression in the Import declaration "C:\hostedtoolcache\windows\dotnet\sdk\3.1.411\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.NuGet.targets" is correct, and that the file exists on disk. [D:\a\1\s\PrinterAgent\PrinterAgent.Package\PrinterAgent.Package.wapproj]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:07.08
##[error]Process 'msbuild.exe' exited with code '1'.
Pipeline Definition:
Using windows-2019 agent
pool:
name: Azure Pipelines
demands:
- msbuild
- azureps
#Your build pipeline references the ‘packageName’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
#Your build pipeline references the ‘packageName’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
#Your build pipeline references the ‘BuildPlatform’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
#Your build pipeline references the ‘BuildConfiguration’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
#Your build pipeline references the ‘msixInstallUrl’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
#Your build pipeline references an undefined variable named ‘signingCert.password’. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab. See https://go.microsoft.com/fwlink/?linkid=865972
#Your build pipeline references an undefined variable named ‘mySecureFile.secureFilePath’. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab. See https://go.microsoft.com/fwlink/?linkid=865972
variables:
packageVersion: '1.0.0'
steps:
- task: UseDotNet#2
displayName: 'Use .NET Core sdk 3.1.411'
inputs:
version: 3.1.411
- powershell: |
[xml]$manifest= get-content ".\PrinterAgent\PrinterAgent.Package\Package.appxmanifest"
$manifest.Package.Identity.Version = "$(packageVersion).$(Build.BuildId)"
$manifest.Package.Identity.Name = "demo-864d9095-955f-4d3c-adb0-6574a5acb88b"
$manifest.Package.Properties.DisplayName = "$(packageName)"
$manifest.Package.Applications.Application.VisualElements.DisplayName = "$(packageName)"
$manifest.save(".\PrinterAgent\PrinterAgent.Package\Package.appxmanifest")
displayName: 'PowerShell Script'
- task: DotNetCoreCLI#2
displayName: 'dotnet restore'
inputs:
command: restore
projects: '**/*.csproj'
- task: DownloadSecureFile#1
displayName: 'Download secure file'
inputs:
secureFile: <fileId>
#Fails here
- task: MSBuild#1
displayName: 'Build solution **/*.sln'
inputs:
msbuildVersion: 16.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArguments: '/p:AppInstallerUri=$(msixInstallUrl) /p:AppxPackageDir="$(Build.ArtifactStagingDirectory)" /p:UapAppxPackageBuildMode=SideLoadOnly /p:GenerateAppInstallerFile=true /p:PackageCertificatePassword="$(signingCert.password)" /p:PackageCertificateKeyFile="$(mySecureFile.secureFilePath)" /p:AppInstallerCheckForUpdateFrequency=OnApplicationRun /p:AppInstallerUpdateFrequency=1 /p:AppInstallerShowPrompt=true'
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: drop'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
condition: succeededOrFailed()
- task: AzureCLI#2
displayName: 'Azure CLI CleanUp blob'
inputs:
azureSubscription: <azureSubscription>
scriptType: ps
scriptLocation: inlineScript
inlineScript: 'az storage blob delete-batch --account-name <storage> --source ''$web'''
- task: AzureFileCopy#4
displayName: 'AzureBlob File Copy'
inputs:
SourcePath: '$(build.artifactstagingdirectory)/*'
azureSubscription: <azureSubscription>
Destination: AzureBlob
storage: <storageName>
ContainerName: '$web'
I finally fixed it myself.
You need the latest .NET SDK to get rid of MSB4019:
- task: UseDotNet#2
displayName: 'Use .NET Core sdk 3.1.x'
inputs:
version: 3.1.x
This will introduce another issue (NETSDK1004, see my comments), that can be fixed by restoring the packaging project explicitly, but that requires msbuild, try something like:
- task: MSBuild#1
inputs:
solution: PrinterAgent.Package\PrinterAgent.Package.wapproj
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArguments: '/t:restore'
You might also try to modify the existing msbuildArguments by adding: /t:restore;build
I created an Azure CI pipeline through Visual Studio 2019. The project target framework is .net core 3.1. However, during the NuGet Restore it fails.
I have .Net Core 2.2.2017 and 3.1.101 installed on my computer and my Visual Studio 2019 community version is 16.4. My environment variables paths are in place.
I also tried creating an app service manually that uses .net core 3.1 LTS stack but I still get the same error.
##[error]The nuget command failed with exit code(1) and error(C:\Program Files\dotnet\sdk\2.2.110\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.TargetFrameworkInference.targets(137,5):
error NETSDK1045: The current .NET SDK does not support targeting .NET Core 3.1. Either target .NET Core 2.2 or lower, or use a version of the .NET SDK that supports .NET Core 3.1.
This is the YAML file generated by Visual Studio
pool:
name: Hosted VS2017
demands:
- msbuild
- visualstudio
- vstest
steps:
- task: NuGetToolInstaller#1
displayName: 'Use NuGet 5.0.0'
inputs:
versionSpec: 5.0.0
- task: NuGetCommand#2
displayName: 'NuGet restore'
inputs:
restoreSolution: '$(Parameters.solution)'
- task: VSBuild#1
displayName: 'Build solution'
inputs:
solution: '$(Parameters.solution)'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\"'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
- task: VSTest#2
displayName: 'Test Assemblies'
inputs:
testAssemblyVer2: |
**\$(BuildConfiguration)\*test*.dll
!**\obj\**
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
- task: PublishSymbols#1
displayName: 'Publish symbols path'
inputs:
SearchPattern: '**\bin\**\*.pdb'
continueOnError: true
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
ArtifactName: '$(Parameters.ArtifactName)'
I believe, you do not need to install NuGetToolInstaller and vsbuild, you should firstly install DotNetCoreCLI after that you can use it. Here is manual how your yaml file should looks like.
Publishing by the IDE has no pain because it use the tools you have installed on your machine, in the pipeline you need to specify the toolin you gonna use and that is the pain.
For those who are not using the new YAML based pipeline but instead use classic editor on devops you might need to add dot net core add task and change from nuget restore to dotnet restore task
When I create a pipeline from the Azure Devops UI, my YAML looks like the below. It uses DotNetCoreCLI instead of VSBuild. Notice that it uses the Restore command instead of anything having to do with Nuget.
pool:
name: Azure Pipelines
#Your build pipeline references an undefined variable named ‘Parameters.RestoreBuildProjects’. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab. See https://go.microsoft.com/fwlink/?linkid=865972
#Your build pipeline references an undefined variable named ‘Parameters.RestoreBuildProjects’. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab. See https://go.microsoft.com/fwlink/?linkid=865972
#Your build pipeline references the ‘BuildConfiguration’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
#Your build pipeline references the ‘BuildConfiguration’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
steps:
- task: DotNetCoreCLI#2
displayName: Restore
inputs:
command: restore
projects: '$(Parameters.RestoreBuildProjects)'
- task: DotNetCoreCLI#2
displayName: Build
inputs:
projects: '$(Parameters.RestoreBuildProjects)'
arguments: '--configuration $(BuildConfiguration)'
- task: DotNetCoreCLI#2
displayName: Publish
inputs:
command: publish
publishWebProjects: True
arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)'
zipAfterPublish: True
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
condition: succeededOrFailed()
I Sometimes combine native C++ (not C++/CLI or C++/CX, just C++) and C# projects by means of P/Invoke.
I used to use such configuration:
Make C++ dll project. (ProjA)
Change target name of ProjA to $(ProjectName)_d only on Debug configuration.
Build ProjA once in Debug and Release - $(SolutionDir)Release\ProjA.dll and $(SolutionDir)Debug\ProjA_d.dll would be made.
Make C# project. (ProjB) Switch dllName of DllImport by using #if DEBUG.
Add ProjA.dll and ProjA_d.dll (and *.pdb) to ProjB as links.
Let ProjB to be built for x86 in configuration manager.
Add Build dependency.
Then everything worked well. ProjB detects changes in ProjA.
However, in Azure DevOps, it failed to build because ProjA_d.dll is not created in the Release build (step 3 is needed.)
I want to tell common way to do it if exists. or Do I have to write build event and make dummy files?
You can add three build tasks in your build pipeline and configure each build task with the right project path and configurations, one to build c++ project with debug configuration and one to build with release configuration, and the other one to build c#. Please refer to below screenshot.
Configure each build task to your need. Point the Project to the path of the specific project you want to build. Please refer to below example.
Solution
# set env and vars
- task: MSBuild#1
inputs:
solution: 'ProjA1/ProjA1.vcxproj'
platform: '$(buildPlatform)'
configuration: 'Debug'
- task: MSBuild#1
inputs:
solution: 'ProjA1/ProjA1.vcxproj'
platform: '$(buildPlatform)'
configuration: 'Release'
- task: CmdLine#2
inputs:
script: |
xcopy /I /E /Y ProjA1\Debug Debug
xcopy /I /E /Y ProjA1\Release Release
- task: MSBuild#1
inputs:
solution: 'ProjA2/ProjA2.vcxproj'
platform: '$(buildPlatform)'
configuration: 'Debug'
- task: MSBuild#1
inputs:
solution: 'ProjA2/ProjA2.vcxproj'
platform: '$(buildPlatform)'
configuration: 'Release'
- task: CmdLine#2
inputs:
script: |
xcopy /I /E /Y ProjA2\Debug Debug
xcopy /I /E /Y ProjA2\Release Release
- task: VSBuild#1
inputs:
solution: '$(solution)'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
# tests
I come from GitLab and its .gitlab-ci.yml and I am experimenting with Azure DevOps multi stage pipelines but I am quite confused about how it works and what's the best strategy even after reading several documentation articles at https://learn.microsoft.com/en-us/azure/devops/pipelines/?view=azure-devops
Please allow me to ask several related questions for the basic scenario I'm trying, which is compile, run unit tests, pack a nuget Package for the whole solution (it could contain multiple projects/nuGet packages) and publish the package to a nuGet feed (if the branch is master, a release version, otherwise a pre-release version).
This is the repository I'm grabbing the code from: https://github.com/sasw-diego/sasw-test-support
It would generate only a nuGet package but I've got other multiproject solutions which should generate many nuGet packages
This is my azure-pipelines.yml so far:
trigger:
- master
- feature/*
pool:
vmImage: ubuntu-latest
variables:
NUGET_FOLDER_NAME: nupkgs
NUGET_REPOSITORY: https://whatever
PRERELEASE_SUFFIX: $(Build.BuildId)
PIPELINE_ARTIFACT_NAME: $(Build.BuildNumber)
stages:
- stage:
displayName: 'Build'
jobs:
- job: 'Build'
steps:
- task: NuGetAuthenticate#0
displayName: 'Authenticate in NuGet feed'
- script: dotnet restore --no-cache --force
displayName: 'Restore dependencies'
- script: dotnet build --configuration Release --no-restore
displayName: 'Build for Release'
- script: ls $(System.DefaultWorkingDirectory)
displayName: 'List content'
- publish: $(System.DefaultWorkingDirectory)
artifact: $(PIPELINE_ARTIFACT_NAME)
- stage:
displayName: 'Automated Tests'
condition: succeeded()
jobs:
- job:
displayName: 'Unit Tests'
steps:
- download: current
artifact: $(PIPELINE_ARTIFACT_NAME)
- script: ls -a
displayName: 'View'
- script: ls ./test
displayName: 'View test'
- script: ls ./test/Sasw.TestSupport.UnitTests
displayName: 'View folder'
- script: dotnet vstest test/*UnitTests/bin/Release/**/*UnitTests.dll
displayName: 'Run unit tests'
- stage:
displayName: 'NuGet Package'
condition: succeeded()
jobs:
- job:
displayName: 'Pack Preview Version'
condition: ne(variables['Build.SourceBranch'], 'refs/heads/master')
steps:
- script: dotnet pack *.sln --configuration Release --output $(NUGET_FOLDER_NAME)
displayName: 'Pack'
- job:
displayName: 'Pack Stable Version'
condition: eq(variables['Build.SourceBranch'], 'refs/heads/master')
steps:
- script: dotnet pack *.sln --configuration Release --output $(NUGET_FOLDER_NAME) --version-suffix $(PRERELEASE_SUFFIX) --include-source --include-symbols -p:SymbolPackageFormat=snupkg
displayName: 'Pack'
Which is the "best" strategy for a multistage? I see Azure DevOps pipelines have the concept of Stage > Jobs > Task but they all look similar to me. So I decide to divide the process in stages such as Build - AutomatedTests - NuGet Package - Publish
As you can see, it's a sequential process where each stage needs something from the previous one. The automated tests needs the built code (dll), the nuGet package needs also access to the built code, the publish needs access to the nupkg generated, etc. I don't know whether it's ok to follow this strategy or it's better to have a single stage with multiple jobs, or even a single job with multiple tasks. As I said I don't fully understand the benefit of having so many concepts and how do they fit in with my needs.
Is Azure multistage pipelines supposed to replace the old Build and Release as separate concepts? It makes sense to me to have the CI/CD in one place with a multistage approach and scriptable to make it versioned in a source control repository. But I still see the Release concept as a separate one currently on Azure DevOps. So probably I should use the azure pipelines yml up until the package "step" and then with Release go grab this nupkg and publish it onto some feed. Not sure what the benefit would be though.
I am having problems making the output of a stage as the input of the next one, and probably it's because I don't fully get it. In the yml above the build stage succeeds but the Automated Testing stage fails on its Run Unit Tests job with an error No test source files were specified. I verified this happens because there is no generated folder bin at all. It's seems strange since I am copying everything from the previous stage (and the previous stage generated bin folders with dll), but then the next stage, despite being able to download everything, it cannot find the tests.
This is the log for the stage that fails: https://gist.github.com/sasw-diego/df66eccf71bbfc044a4d72be96268c9a
It'd be very helpful if somebody spots what am I missing to be able to understand this process. Any link to clarify all these concepts would be much appreciated. Ta
PS: This is a similar generic CI/CD I had in GitLab to upload 1 or many nuGets to a feed:
https://gist.github.com/sasw-diego/bf46258cb1ad0aa5241e8d1866b53f48
UPDATE:
Thanks for the answer. I successfully created a CI/CD yml with multi-stage pipelines that restores, builds, executes tests, runs a container (e.g: an eventStore host) to run integration tests against it, and releases the nuGet in artifacts. So mission accomplished! I've separated it into different stages and jobs to probe some points
trigger:
- master
- feature/*
pool:
vmImage: ubuntu-18.04
variables:
- group: sasw-common-variables
- name: NUGET_FOLDER_NAME
value: nupkgs
- name: PIPELINE_ARTIFACT_NAME
value: $(Build.BuildNumber)
- name: PATH_PIPELINE_ARTIFACT_NAME
value: $(Pipeline.Workspace)/$(PIPELINE_ARTIFACT_NAME)
- name: NUGET_API_KEY
value: $(nuget-api-key)
- name: NUGET_FEED
value: $(nuget-feed)
- name: PRERELEASE_SUFFIX
value: $(nuget-prerelease-suffix)
resources:
containers:
- container: eventstore
image: eventstore/eventstore:release-5.0.2
ports:
- 1113:1113
env:
EVENTSTORE_INT_TCP_PORT: 1113
EVENTSTORE_EXT_TCP_PORT: 1113
EVENTSTORE_INT_HTTP_PORT: 2113
EVENTSTORE_EXT_HTTP_PORT: 2113
EVENTSTORE_EXT_HTTP_PREFIXES: http://*:2113/
stages:
- stage:
displayName: 'Build'
jobs:
- job: 'Build'
displayName: 'Build & Create nuGet Package'
services:
eventstore: eventstore
steps:
- task: NuGetAuthenticate#0
displayName: 'Authenticate in NuGet feed'
- script: dotnet restore --no-cache --force
displayName: 'Restore dependencies'
- script: dotnet build --configuration Release --no-restore
displayName: 'Build with Release Configuration'
- script: dotnet vstest test/*UnitTests/bin/Release/**/*UnitTests.dll
displayName: 'Run unit tests'
- script: dotnet vstest test/*IntegrationTests/bin/Release/**/*IntegrationTests.dll
displayName: 'Run integration tests'
- script: dotnet pack *.sln --configuration Release --output $(NUGET_FOLDER_NAME)
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
displayName: 'Create release nuGet'
- script: dotnet pack *.sln --configuration Release --output $(NUGET_FOLDER_NAME) --version-suffix $(PRERELEASE_SUFFIX) --include-source --include-symbols -p:SymbolPackageFormat=snupkg
condition: and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/master'))
displayName: 'Create pre-release nuGet'
- publish: $(System.DefaultWorkingDirectory)/$(NUGET_FOLDER_NAME)
artifact: $(PIPELINE_ARTIFACT_NAME)
displayName: 'Publish pipeline artifact'
- stage:
displayName: 'Release'
condition: succeeded()
jobs:
- job: 'Publish'
displayName: 'Publish nuGet Package'
steps:
- download: current
artifact: $(PIPELINE_ARTIFACT_NAME)
displayName: 'Download pipeline artifact'
- script: ls $(PATH_PIPELINE_ARTIFACT_NAME)
displayName: 'Display contents of downloaded articacts path'
- task: NuGetAuthenticate#0
displayName: 'Authenticate in NuGet feed'
- task: UseDotNet#2
displayName: 'Use latest .NET Core sdk 3.x'
inputs:
packageType: sdk
version: 3.x
includePreviewVersions: true
installationPath: $(Agent.ToolsDirectory)/dotnet
- script: dotnet nuget push $(PATH_PIPELINE_ARTIFACT_NAME)/**/*.nupkg --source $(NUGET_FEED) --api-key $(NUGET_API_KEY) --skip-duplicate
displayName: 'Uploads nuGet packages'
your whole build definition should be a single "stage". Those Build - AutomatedTests - NuGet Package - Publish are not stages, those are logical parts of the build.
probably sometime in the future that will\might happen
that is because you are using stages when you are not supposed to. each stage runs on a different agent. you should have a single stage and all the tasks should run inside that stage.
I am using Visual Studio 2017 and Azure Dev Ops to run a test on being able to debug a .dll I don't have the source code locally. However, I have run into a problem.
I have a C# .net Standard library with a single class containing a single method in it. I'm using Azure DevOps to do the build for this library. I have created the build pipeline template for an ASP.NET project. The YAML for my build pipeline is as follows:
steps:
task: NuGetToolInstaller#0
displayName: 'Use NuGet 4.4.1'
inputs:
versionSpec: 4.4.1
task: NuGetCommand#2
displayName: 'NuGet restore'
inputs:
restoreSolution: '$(Parameters.solution)'
vstsFeed: 'a1deac36-75b8-4a5c-a86c-26a137db5913'
task: VSBuild#1
displayName: 'Build solution'
inputs:
solution: '$(Parameters.solution)'
msbuildArgs: '/t:restore;build;pack /p:PackageVersion=$(Build.BuildNumber) /p:PackageOutputPath=$(build.artifactstagingdirectory) /p:AssemblyFileVersion=$(Build.BuildNumber)'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
clean: true
msbuildArchitecture: x64
task: PublishSymbols#2
displayName: 'Publish symbols path'
inputs:
SearchPattern: '**\bin\**\*.pdb'
SymbolServerType: TeamServices
continueOnError: true
task: PublishBuildArtifacts#1
displayName: 'Publish Artifact'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
ArtifactName: '$(Parameters.ArtifactName)'
The build creates .dll, .pdb, and .nupkg files. The .pdb appears to be uploaded correctly to the Symbol Server I have access to. I have created a local c# console app project referencing the built .nupkg file. When I run the console app, it says it loaded symbols successfully from the Symbol Server (my Symbol Cache locally has the corresponding .pdb file). However, when I go to step into the method contained in the class in the .dll, I am prompted for the source code file. In my output window in Visual Studio there is the following error:
SRCSRV: The module 'C:\Users\<USER_NAME>\Source\Workspaces\ConsoleApp1\ConsoleApp1\bin\Debug\ClassLibrary1.dll' does not contain source server information.
I have the 'Enable source server support' checkbox checked, along with the top two child checkboxes selected. I also have 'Enable Just My Code' unchecked and 'Enable Source Link support' checked.
I have read over all of the Microsoft docs pages about .pdbs and Azure Dev-Ops and believe I have everything set correctly, but for some reason it still prompts me for the source file instead of being able to use the source server. So am I missing something in my build or somewhere else that would cause this error when trying to step into the compiled code?