Azure Devops Release pipeline(s) for multiple Azure Functions - .net-core

I have a solution containing 3 projects: 2 Azure Functions and a shared library.
I have created 2 Function Apps in Azure.
My Build Pipeline is triggered every time something changes in the solution.
Now, trying to set my release pipeline
I can see I can choose the target App Service, but I can't seem to find a way to tell which function to deploy there.
It seems by default, it deploys both of them, and the first one deployed is just overwritten by the second one.
So I don't mind doing 2 release pipelines, but how do I specify : "deploy this proj from the solution".
EDIT1:
I didnt put the yaml files directly in the solution, I just added the steps in the build :
But in the release pipeline I dont see the zip file

Azure Function is built into a zip, which can be saved into an artifact during function building. You should have an azure-pipelines.yaml in each fuction project. There you can specify the artifact details, normally after restore and build steps, and zipping the build output:
// restore step ...
// build step ...
// now .net publishing step with zipping. You can also set this to false and use ArchiveFiles#2 step instead
- task: DotNetCoreCLI#2
displayName: 'MyFunction: Publish'
inputs:
command: publish
arguments: '--configuration Release --output publish_output'
projects: '$(System.DefaultWorkingDirectory)/MyFunction/MyFunction.sln'
publishWebProjects: false
zipAfterPublish: True
// Now publish your zip as artifact
- task: PublishBuildArtifacts#1
displayName: 'MyFunction: Publish Artifact MyFunction.zip'
inputs:
PathtoPublish: '$(System.DefaultWorkingDirectory)/.......'
ArtifactName: 'MyFuction-Deploy'
Or in editor:
Than in your release pipeline click on the 3 dots near the "Package or folder" option. You should see a folder for linked artifacts, inside your build subfolder and than the artifact with your function app zip inside.
You can produce several artifacts for different function apps in your unified build pipeline, and than choose appropriate artifact to deploy in your different release pipelines.

Related

Where is the .dSYM file when building a Xamarin Forms 5 iOS with a Azure Devops Mac Build Agent

I'm using an Azure Devops Pipeline to build our Xamarin Forms 5.x app.
We have a self hosted DevOps agent installed on a mac which is used to build the iOS project, then we push the .ipa file up to App Center.
What I'd like to do is also push up the .dSYM file so we can get symbolicated crash reports.
I cannot find a .dSYM file in any of the agents folders, Microsoft's help file doesn't help iOS Symbolication, any suggestions where I can find this file?
The build tasks for my pipeline look like:
- task: XamariniOS#2
displayName: 'Build Xamarin.iOS solution'
inputs:
solutionFile: '**/*.sln'
configuration: '$(buildConfiguration)'
buildForSimulator: false
packageApp: true
- task: CopyFiles#2
displayName: 'Copy Files to Artifact Staging Directory'
inputs:
SourceFolder: '$(System.DefaultWorkingDirectory)'
Contents: '**/*.ipa'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
flattenFolders: true
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact iOS'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'iOS'
publishLocation: Container
Solution for Visual Studio:
If you have enabled device-specific builds, the .dSYM can be found in the following directory:
<project directory>/bin/<platform>/<configuration>/device-builds/<device>-<os-version>/
For example:
TestApp/bin/iPhone/Release/device-builds/iphone8.4-11.3.1/
If you have not enabled device-specific builds, the .dSYM can be found in the following directory:
<project directory>/bin/<platform>/<configuration>/
For example:
TestApp/bin/iPhone/Release/
Solution for Xcode:
In general, if there is no human modification, the DSYM file will be stored in
`~/Library/Developer/Xcode`
You can use the find command to find all .dSYM files under the current pat
allFiles=`find ~/Library/Developer/Xcode/Archives -iname '*.dSYM'`
Of course, if you want to be more precise, you can add the upper -type parameter :
filesPath=`find ~/Library/Developer/Xcode/Archives -iname '*.dSYM' -type f`
So I have found the dSYM folder, and it was in the Azure DevOps Mac Build Agent's _work folder (as per the Visual Studio Folders mentioned in #guangyu-bai-msft in the above post).
The reason I could not see the folder on the Azure DevOps Mac Build Agents _work folder after the build is something to do with the agent which seems to be moving some of the output files from:
<project directory>/bin/<platform>/<configurtion>
To the Agents binary folder:
_work\1\b
Then the Agent deletes the bin and obj folders under the project.
This is not a step I've added to my Pipeline, and I cannot see it logged by any of the steps, so I can only assume it's the Agent doing this. As long as I zip/copy the dSYM folder before the Pipeline stage finishes it works fine.
I've added a step as follows to the pipeline after CopyFiles#2 on the original post:
- task: ArchiveFiles#2
# https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/archive-files-v2?view=azure-pipelines&viewFallbackFrom=azure-devops
displayName: 'Compress dSYM Folder to Artifact Staging Directory'
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)/<path to project>/bin/iPhone/Release/<project name>.app.dSYM'
includeRootFolder: false
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/<project name>.app.dSYM.zip'
replaceExistingArchive: true

Core ASP.NET Project Azure Build Pipeline

I have a simple solution that have two projects in it and I want it go through the azure build pipeline. One project is pure class files that will get build a DLL but that code is not the GIT repo in the same folder. And the other project is ASP.NET project and I have configured that in the pipeline. When I am trying to build the project it is giving me an error as below:
MSBUILD : error MSB1011: Specify which project or solution file to use
because this folder contains more than one project or solution file.
[error]Cmd.exe exited with code '1'.
Yaml File
# ASP.NET Core
# Build and test ASP.NET Core projects targeting .NET Core.
# Add steps that run tests, create a NuGet package, deploy, and more:
# https://learn.microsoft.com/azure/devops/pipelines/languages/dotnet-core
trigger:
- master
pool:
name: 'buildserver'
variables:
buildConfiguration: 'Release'
steps:
- script: dotnet build --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
The error is asking you to identify the .sln or .csproj (or other proj type) file b/c dotnet doesn't know what you want it to do.
I tend to use variables for this kind of thing because I'm often using the solution name in other tasks.
example:
trigger:
- master
pool:
name: 'buildserver'
variables:
buildConfiguration: 'Release'
slnName: 'mySol'
solution: 'some/dir/$(slnName).sln'
steps:
- script: dotnet build $(solution) --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
.csproj example:
With a repository (and solution) structure as follows:
(this is the part of your question that remains unclear)
myRepo
|--.git
|--src
|--proj1
| |--proj1.csproj
|
|--proj2
| |--proj2.csproj
|
|--mySol.sln
You would simply call out the .csproj file you want the pipeline to build.
trigger:
- master
pool:
name: 'buildserver'
variables:
buildConfiguration: 'Release'
projName: 'proj1'
project: 'src/$(projName)/$(projName).csproj'
steps:
- script: dotnet build $(project) --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
With the above examples you shouldn't need to specify the .sln or .csproj as each potential build target lives in its own directory, and the dotnet cli searches from $pwd if you don't give it a value. Therefore, if your pipeline is working in the root of the repo (default behavior), dotnet should find the .sln file first and build it.
However
If your directory structure looks like the following, then you would need to specify:
myRepo
|--.git
|--src
|--proj1.csproj
|--class1.cs
|--class2.cs
|--proj2
| |--proj2.csproj
| |--class1.cs
|
|--mySol.sln
In the above dotnet doesn't know whether you want to build mySol.sln or proj1.csproj, so indicating the file to build should solve your problem, but I might suggest that you restructure your repository.
If proj2 doesn't make its home in myRepo
And is a dependency of proj1 then you will need to do some other acrobatics (ie: manual git repo clone) in the pipeline to get that project and it's files where they need to be. If this is the case, I would strongly suggest you treat proj2 as a completely independent product and deliver it to those projects (proj1) that depend upon it via NuGet or other package delivery method.

How to publish self-contained dotnet core package via pipeline UI to azure artifacts?

I have created an application using dotnet core. I am building it as a self-contained package. I am attempting to publish it to an Azure artifact server using the pipeline UI. I have been able to successfully build the self-contained package, and have been able to successfully publish it to the drop. I have not been able to figure out how to get the NuGet pack command (and subsequent Nuget push) to pick up the self-contained package to place as a downloadable package on the artifact server.
Here is the YAML for my publish task:
steps:
- task: DotNetCoreCLI#2
displayName: 'dotnet publish'
inputs:
command: publish
publishWebProjects: false
projects: '**/TelemetryReceiver.csproj'
arguments: '-c release -r win-x64 --self-contained true'
Here is the YAML for the task that copies to build staging:
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: CopyFiles#2
displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
inputs:
SourceFolder: '$(build.sourcesdirectory)'
Contents: '**\bin\$(BuildConfiguration)\**'
TargetFolder: '$(build.artifactstagingdirectory)'
Here is the YAML for publish:
steps:
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: drop'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)\src\TelemetryReceiver\bin\Release\netcoreapp2.2\win-x64'
And here is the YAML for the NuGet pack:
steps:
- task: NuGetCommand#2
displayName: 'NuGet pack'
inputs:
command: pack
packagesToPack: src/telemetryreceiver/telemetryreceiver.csproj
versioningScheme: byPrereleaseNumber
On the copy step, the logs indicate the full self-contained package is indeed being copied to "\src\TelemetryReceiver\bin\Release\netcoreapp2.2\win-x64". But one the final package is downloaded from the artifact server, it is only picking up the contents of the "netcoreapp2.2" directory.
I am confused, of course, about how the "dotnet publish" and "NuGet pack" tasks are supposed to relate. It seems as if both independently evaluate the .csproj file and that is it.
How to publish self-contained dotnet core package via pipeline UI to azure artifacts?
You may misunderstand the task dotnet publish, which is not used to publish the nuget package. It used to create a .zip file archive that's ready for publishing to a web app:
Check the document Deploy a web app for some more details.
As test, you can view the content of that .zip:
To publish self-contained dotnet core package via pipeline UI to azure artifacts, you just need use the Copy task and PublishBuildArtifacts task.
The reason why it only pick up the contents of the "netcoreapp2.2" directory, that because you are not the correct syntax in the Contents in the copy task, it should be specify to the .nupkg:
Contents: '**\bin\$(BuildConfiguration)\**\*.nupkg'
Then, in the artifacts:
Alternatively, we could specify the package folder to $(Build.ArtifactStagingDirectory) in the nuget pack task:
In this case, we do not need the copy task to copy package to the ArtifactStagingDirectory, just use task PublishBuildArtifacts.
Hope this helps.

Web.config release transform not being applied as part of web application build in Azure DevOps server

I have an ASP.Net framework (v4.7) web application which I have a build pipeline for in Azure Devops Server (2019).
There is a Visual Studio Build task which builds the solution fine and publishes out the site to the _PublishedWebsites folder. The trouble is, the web.config transform for the release has not been applied and it still has debug="true" set which is not what I want for automated deployment.
The msbuild arguments for the task are: /p:outdir="$(build.artifactstagingdirectory)" and the BuildConfiguration variable for the build is set to release.
When I have published the project using visual studio the web.release.config transform is applied and the debug attribute has been removed from the web.config file in the published content.
Is there something I am missing here?
Edit: Build pipeline YAML:
queue:
name: Default
demands:
- msbuild
- visualstudio
#Your build pipeline references an undefined variable named ‘Parameters.solution’. 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.solution’. 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 ‘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 ‘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 an undefined variable named ‘Parameters.ArtifactName’. 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
steps:
- task: NuGetCommand#2
displayName: 'NuGet restore'
inputs:
restoreSolution: '$(Parameters.solution)'
- task: VSBuild#1
displayName: 'Build solution'
inputs:
solution: '$(Parameters.solution)'
vsVersion: 16.0
msbuildArgs: '/p:outdir="$(build.artifactstagingdirectory)"'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
- task: VisualStudioTestPlatformInstaller#1
displayName: 'Visual Studio Test Platform Installer'
inputs:
versionSelector: latestStable
- task: VSTest#2
displayName: 'Test Assemblies'
inputs:
testAssemblyVer2: |
$(build.artifactstagingdirectory)\*test*.dll
!**\obj\**
vsTestVersion: toolsInstaller
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
- task: PublishSymbols#2
displayName: 'Publish symbols path'
inputs:
SearchPattern: '**\bin\**\*.pdb'
PublishSymbols: false
continueOnError: true
- script: |
cd ProjectName.Web.CMS
copy cmsimport.lic bin /y
displayName: 'Copy CMSImport licence to bin folder'
- script: |
ECHO Copying over the umbraco, umbraco_client and CMSImport content for deployment.
xcopy ProjectName.Web.CMS\packages\UmbracoCms.7.5.14\UmbracoFiles\umbraco $(build.artifactstagingdirectory)\_PublishedWebsites\ProjectName.Web.CMS\umbraco\ /s /e /r /y
xcopy "ProjectName.Web.CMS\packages\UmbracoCms.7.5.14\UmbracoFiles\umbraco_client" $(build.artifactstagingdirectory)\_PublishedWebsites\ProjectName.Web.CMS\umbraco_client\ /s /e /r /y
xcopy ProjectName.Web.CMS\packages\CMSImport.3.5\content\umbraco $(build.artifactstagingdirectory)\_PublishedWebsites\ProjectName.Web.CMS\umbraco\ /s /e /r /y
displayName: 'Copy umbraco related content to staging'
enabled: false
- script: |
cd ProjectName.Web.CMS
move robots_UAT.txt $(build.artifactstagingdirectory)\_PublishedWebsites\ProjectName.Web.CMS\robots.txt
displayName: 'Add robots.txt file to artifacts staging directory'
- task: ArchiveFiles#2
displayName: 'Archive $(build.artifactstagingdirectory)\_PublishedWebsites\ProjectName.Web.CMS\'
inputs:
rootFolderOrFile: ' $(build.artifactstagingdirectory)\_PublishedWebsites\ProjectName.Web.CMS\'
includeRootFolder: false
archiveFile: '$(Build.ArtifactStagingDirectory)/ProjectName.Web.CMS.zip'
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)\ProjectName.Web.CMS.zip'
ArtifactName: '$(Parameters.ArtifactName)'
I managed to get the transform to apply after adding in the XDT Transform build task to my Azure DevOps build server.
I did some reading which indicated that the transforms as part of a CI/CD pipeline are applied as part of the Azure App Service deploy or IIS deploy release tasks and not carried out by msbuild.
This is also an interesting article. Unfortunately the File Transform build task is pre-release and you have to build the task from source yourself if you are using Azure DevOps Server on-prem. I had a go but after installation of the package the task was not showing as being available to add. The XDT Transform task was a good replacement and does the job nicely.
msbuild will perform the transform only if below task in written in your project (csproj) file
<Target Name="AfterBuild"> </Target>
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="Web_config_AfterBuild" AfterTargets="AfterBuild" Condition="Exists('Web.$(Configuration).config')">
<TransformXml Source="Web.config" Destination="$(OutputPath)Web.config" Transform="Web.$(Configuration).config" />
</Target>

How to specify Solution file in Azure DevOps Pipeline

I am having trouble configuring an Azure DevOps Dotnet core build process.
I have a simple dotnet core project which I am attempting to build in an Azure DevOps environment.
The project is in a subfolder within my repo, but I cannot figure out how to specify how the Pipeline should find my csproj file. The MSDN documentation suggests that you can specify it but there are no examples and all of my attempts are met with errors.
When building a pipeline with the standard dotnet CLI template, the YAML created is:
# ASP.NET Core
# Build and test ASP.NET Core web applications targeting .NET Core.
# Add steps that run tests, create a NuGet package, deploy, and more:
# https://learn.microsoft.com/vsts/pipelines/languages/dotnet-core
pool:
vmImage: 'Ubuntu 16.04'
variables:
buildConfiguration: 'Release'
steps:
- script: dotnet build --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
However this is met with the error:
MSBUILD : error MSB1003: Specify a project or solution file.
The current working directory does not contain a project or solution file.
The documentation linked above suggests using a "task" based syntax rather than a script, and I assume that in the documentation the inputs are listed in the same order as the examples listed underneath.
If you use the script you specify the csproj file after the build word:
- script: dotnet build myrepo/test/test.csproj --configuration $(buildConfiguration)
The best way to use Azure DevOps Pipeline is to use tasks for the build pipeline, in the Dotnet Core yaml build task you specify the file in the inputs section:
- task: DotNetCoreCLI#2
inputs:
command: 'build'
projects: 'myrepo/test/test.csproj'

Resources