Deploying .NET Core 3.0 API to Azure Web App using Release Pipeline - azure

I'm attempting to upgrade my API from .NET Core 2.2 to 3.0, but I cannot get the Azure Web App to actually run the application using 3.0.
My build pipeline configuration:
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
steps:
- task: UseDotNet#2
displayName: 'Use .NET Core 3'
inputs:
version: 3.x
- script: dotnet tool install --global dotnet-ef
- script: dotnet build --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
- task: efcore-migration-script-generator-task#0
inputs:
projectpath: 'Models/Models.csproj'
databasecontexts: 'DataContext'
startupprojectpath: 'Api/Api.csproj'
targetfolder: '$(build.artifactstagingdirectory)/migrations'
- script: dotnet publish --output $(Build.ArtifactStagingDirectory)
displayName: 'dotnet publish $(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
I then have a multi-stage release pipeline that publishes the artifact to Azure using the Azure App Service Deploy Task. Everything runs without issue
I've installed the preview extension, as directed here, and running the powershell command Test-Path D:\home\SiteExtensions\AspNetCoreRuntime.3.0.x86\ returns true. I'm still seeing the following error though.
ANCM Failed to Find Native Dependencies
Back in Powershell, running dotnet --version and dotnet --list-runtimes shows that it only recognizes .NET Core 2 runtimes, despite the 3.0 runtime being present. As best I can tell, installing the site extension doesn't update the path to use the new dotnet version, and the Azure Devops deploy task doesn't seem to have any options to override the default. Has anyone managed to get a .NET Core 3 app deployed through Azure Devops Release Pipelines?

I don't consider it a good solution by any means, but the workaround I'm using right now that is working is to add a web.config file that passes the full path to the site extension version of dotnet
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="D:\home\SiteExtensions\AspNetCoreRuntime.3.0.x86\dotnet" arguments=".\Api.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
</system.webServer>
</location>
</configuration>
I'm still looking for a solution that isn't so error prone.

Related

Telerik Nuget package restore in Azure build pipeline fails

I'm attempting to pull Nuget packages from Telerik's Nuget repository into an Azure build pipeline, however, none of the pipeline configuration attempts I've made seem to work. I either receive an error stating my nuget.config is not formatted correctly or a 401 error when connecting to the repository.
The below configuration section is from my build definition. I've tried using NuGetCommand as well as NuGetRestore:
- task: NuGetToolInstaller#1
inputs:
versionSpec: '5.0.2'
- task: NuGetAuthenticate#1
inputs:
nuGetServiceConnections: 'Telerik_v3'
- task: NuGetCommand#2
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
feedsToUse: 'config'
nugetConfigPath: './XXXXXXX/nuget.config'
#'$(System.DefaultWorkingDirectory)/XXXXXXX/NuGet.config'
externalFeedCredentials: 'Telerik_v3'
# - task: NuGetRestore#1
# inputs:
# solution: '**/*.sln'
# selectOrConfig: 'config'
# nugetConfigPath: './XXXXXXX/nuget.config'
Here is my nuget.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="NuGet" value="https://api.nuget.org/v3/index.json" protocolVersion="3"/>
<add key="Telerik_NuGet" value="https://nuget.telerik.com/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
Here is the error I receive:
NuGet.Protocol.Core.Types.FatalProtocolException: Unable to load the service index for source https://nuget.telerik.com/v3/index.json. ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
Tweaking the configuration slightly I get this error:
##[error]The nuget command failed with exit code(1) and error(NuGet.Configuration.NuGetConfigurationException: NuGet.Config is not valid XML. Path: 'D:\a\1\Nuget\tempNuGet_966.config'. ---> System.Xml.XmlException: An error occurred while parsing EntityName. Line 10, position 46.
I based my build tasks on the NuGetCommandv2 and NuGetRestore v1 documentation as well as what I found on Telerik's site.
When we want to use private nuget packages like Telerik we need to specify credentials in Nuget.config_
Connection name
Feed URL
Username
Password
NOTE:
In order to add a reference to this NuGet package to your project, firstly need to add Telerik credentials into Visual Studio.
example:
dotnet nuget update source "Telerik" --source "https://nuget.telerik.com/v3/index.json" --configfile "nuget.config" --username '*************' --password '***********' --store-password-in-clear-text
Here I found one reference github by Lance McCarthy

Azure build pipeline unable to restore NuGet packages from private feed when using NuGet.Config file from solution

I am trying to build a C# project in DevOps build pipeline. The project is using a single Azure Artifacts private feed. The NuGet.config is as given by the Azure portal from the Nuget tab of connect feed page. The file is at the root of the solution.
NuGet.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositorypath" value=".\packages" />
<packageSources>
<clear />
<add key="<myfeedname>" value="https://pkgs.dev.azure.com/<myorg>/<myproject>/_packaging/<myfeedname>/nuget/v3/index.json" />
</packageSources>
</config>
</configuration>
I am having difficulty restoring packages when using NuGet.config from the solution. The log shows some evidence of using the azure org related URLs but not the project or feed. The restore cannot find packages. However, if I specify the feed and package folder in the NuGet restore task itself, it works fine and downloads all packages. I am expecting the task to find the private feed URL automatically from the NuGet.config file, authenticate (since inside pipeline), and download packages. The config file works fine in local builds asking for org user credentials (pop up) when using VS. The NuGet.config is checked into repo and hence there are no credentials used.
I also have NuGet Authenticate task just in case. (The working version doesn't even need this task).
- task: NuGetAuthenticate#0
What is wrong with the non-working version?
Working Version:
- task: NuGetCommand#2
displayName: "Step: Restore NuGet"
inputs:
command: 'restore'
feedsToUse: 'select'
vstsFeed: '<myproject>/<MyFeed>'
includeNuGetOrg: false
restoreSolution: '$(solution)'
restoreDirectory: "../../packages"
verbosityRestore: Detailed
continueOnError: true
Non-Working Version:
- task: NuGetCommand#2
displayName: "Step: Restore NuGet"
inputs:
command: 'restore'
restoreSolution: '$(solution)'
feedsToUse: 'config'
nugetConfigPath: "NuGet.config"
verbosityRestore: Detailed
continueOnError: true
From non-working version, the log shows that it is using the file as expected.
C:\hostedtoolcache\windows\NuGet\5.8.1\x64\nuget.exe restore D:\a\1\s\<solution-file-path> -Verbosity Detailed -NonInteractive -ConfigFile D:\a\1\s\NuGet.config
NuGet Version: 5.8.1.7021
Some errors:
WARNING: Unable to find version '6.0.0' of package 'Microsoft.CodeAnalysis.NetAnalyzers'.
NU1100: Unable to resolve 'AsyncFixer (>= 1.5.1)' for '.NETFramework,Version=v4.8'.
I also find some logs related to devops org for auth but no mention of project or feed name,
##[debug]Discovered URL prefixes: https://dev.azure.com/<my-org>/,.....others....
:
##[debug]Got auth token
..
:
##[error]Packages failed to restore
No mention of NuGet sources used in log. (System.Debug set to true in variables)
The working version shows the private feed as source used at the end.
NuGet Config files used:
D:\a\1\Nuget\tempNuGet_2852.config
Feeds used:
https://pkgs.dev.azure.com/<org>/<proj>/_packaging/<feed>/nuget/v3/index.json
However, I want to use the config version since it seems to be the right approach.

How to resolve target-issues in Azure Devops Pipeline when creating Self-contained deployments

Because Azure AppServices doesn't (anymore) support .NET Core 2.1 on x64 with framework-dependent deployments, we are currently publishing self-contained win-x64 versions of our .NET Core 2.1 Web API.
I'm trying to setup an Azure Pipeline in Yaml for CI/CD purposes and deploy it to Azure App Service deployment slot.
The issue I'm trying to resolve is this error-message: project.assets.json' doesn't have a target for 'netcoreapp2.1/win10-x64'
/usr/bin/dotnet publish /home/vsts/work/1/s/MyApp.WebApi/MyApp.WebApi.csproj --configuration Release -f netcoreapp2.1 -r win10-x64 --self-contained true --no-restore --output /home/vsts/work/1/a/MyApp.WebApi
Microsoft (R) Build Engine version 16.8.3+39993bd9d for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
/usr/share/dotnet/sdk/5.0.102/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(241,5): error NETSDK1047: Assets file '/home/vsts/work/1/s/MyApp.WebApi/obj/project.assets.json' doesn't have a target for 'netcoreapp2.1/win10-x64'. Ensure that restore has run and that you have included 'netcoreapp2.1' in the TargetFrameworks for your project. You may also need to include 'win10-x64' in your project's RuntimeIdentifiers. [/home/vsts/work/1/s/MyApp.WebApi/MyApp.WebApi.csproj]
##[error]Error: The process '/usr/bin/dotnet' failed with exit code 1
This is my 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:
- develop
pool:
vmImage: 'ubuntu-20.04'
variables:
buildConfiguration: 'Release'
buildPlatform: x64
steps:
- task: DotNetCoreCLI#2
displayName: dotnet restore
inputs:
command: 'restore'
projects: '**/*.csproj'
feedsToUse: 'config'
nugetConfigPath: './NuGet.config'
externalFeedCredentials: 'Hangfire Pro'
- task: DotNetCoreCLI#2
displayName: dotnet publish
inputs:
command: 'publish'
publishWebProjects: true
feedsToUse: 'config'
nugetConfigPath: './NuGet.config'
externalFeedCredentials: 'Hangfire Pro'
arguments: '--configuration $(BuildConfiguration) -f netcoreapp2.1 -r win10-x64 --self-contained true --no-restore --output $(build.artifactstagingdirectory)'
# this code takes all the files in $(Build.ArtifactStagingDirectory) and uploads them as an artifact of your build.
- task: PublishBuildArtifacts#1
inputs:
pathtoPublish: '$(Build.ArtifactStagingDirectory)'
artifactName: 'MyAppWebApi'
I tried modifying the CSPROJ file by adding these:
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
**<RuntimeIdentifiers>win10-x64;win-x64</RuntimeIdentifiers>**
and
<PlatformTarget>x64</PlatformTarget>
Please delete the obj and bin folders from your project. Also the <TargetFramework> in your .csproj file was singular. Please try to add an "s" and it become "TargetFrameworks" to see if it works.
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
You could refer to this thread for more possible solutions.
BTW, there are different build environment between Microsoft-hosted Windows-2019 agents(which install Visual Studio Enterprise 2019) and your local machine, you could try to use self-hosted Windows agents to build your project without additional environment preparation steps.
A few things went wrong during my work. The most important one is that all the changes I've tried to make were pushed to the Develop-branch while the Pipeline was running on a different branch. My inexperience with Pipelines (and also Git) mainly caused this. I was under the impression that the trigger line in YAML pointed to the repository to restore and publish.
I finally got it working with the following steps. Like Edward Han mentioned, I tried to restore and publish by command line on my local machine. These also gave me some errors I needed to fix. Like adding this line to all (30+) referenced csproj files:
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
Then add this configuration to the webproject csproj:
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
Then my final YAML file is this:
trigger:
- develop
pool:
vmImage: 'windows-2019'
variables:
buildConfiguration: 'Release'
buildPlatform: x64
steps:
- task: UseDotNet#2
displayName: 'Use .Net Core sdk 2.1.x'
inputs:
version: 2.1.x
- task: DotNetCoreCLI#2
displayName: dotnet restore
inputs:
command: 'restore'
projects: '**/*.csproj'
arguments: '-r win-x64'
feedsToUse: 'config'
nugetConfigPath: './NuGet.config'
externalFeedCredentials: 'Hangfire Pro'
- task: DotNetCoreCLI#2
displayName: dotnet test
inputs:
command: 'test'
projects: '**/*[Tt]ests/*.csproj'
arguments: '--configuration $(BuildConfiguration)'
testRunTitle: 'dotnet test 2'
- task: DotNetCoreCLI#2
displayName: dotnet publish
inputs:
command: 'publish'
publishWebProjects: true
arguments: '--configuration $(BuildConfiguration) -r win-x64 --self-contained true --no-restore --output $(build.artifactstagingdirectory)'
# this code takes all the files in $(Build.ArtifactStagingDirectory) and uploads them as an artifact of your build.
- task: PublishBuildArtifacts#1
inputs:
pathtoPublish: '$(Build.ArtifactStagingDirectory)'
artifactName: 'MyAppWebApi'
Few important things I changed/added:
Explicitly tell to use .NET Core 2.1.*
Add -runtime parameter to the RESTORE command
Conslusion
Although I studied some Pluralsight courses, YouTube video's and blogs, I still ended up reading the Microsoft Docs/MSDN. Being used to use publishing by the Visual Studio User Interface, switching to command-line really was a big difference. A lot more depencenies are needed to be looked at. Tip: really read the urls these error messages provide, they do contain enough information to resolve your issue. At least, that's what I learned.

Why is my Azure Dev Ops Pipeline failing to restore a package?

I'm using Azure Dev Ops to work with my ASP.NET Core web application. I'm setting up a pipeline but I'm getting errors. The errors are coming from a package restore issue since my application uses the KendoUI library I have to create a service connection for the private NuGet packages that are required. Having done that, the build still fails and I was wondering what is going wrong?
Error Message
[error]The nuget command failed with exit code(1) and error(NU1102: Unable to find package Telerik.UI.for.AspNet.Core with version (>=
2019.2.619)
- Found 1 version(s) in NuGetOrg [ Nearest version: 2016.3.914 ] Errors in d:\a\1\s\MyCompany\MyProject.UI.csproj
NU1102: Unable to find package Telerik.UI.for.AspNet.Core with version (>= 2019.2.619)
- Found 1 version(s) in NuGetOrg [ Nearest version: 2016.3.914 ])
[error]Packages failed to restore
I spoke with Telerik support who said the above code is because there is a failure in authentication and that causes the system to look for an older version which is causing this compatibility issue. I was asked to check my authentication which I have, yet this error persists.
I followed the documentation from Telerik on how to achieve this which you can find here: https://www.telerik.com/blogs/azure-devops-and-telerik-nuget-packages
Ok, to start off, my project has a nuget.config file located in its root directory. The contents of the file are:
nuget.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageRestore>
<add key="enabled" value="True" />
<add key="automatic" value="True" />
</packageRestore>
<activePackageSource>
<add key="All" value="(Aggregate source)" />
</activePackageSource>
<packageSources>
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
<add key="Telerik" value="https://nuget.telerik.com/nuget" />
</packageSources>
<packageSourceCredentials>
<Telerik>
<add key="Username" value="me#mybusiness.com" />
<add key="ClearTextPassword" value="MyFunkYPassword19!" />
</Telerik>
</packageSourceCredentials>
</configuration>
Within Azure Dev Ops, I have created a service connection in the manner described in their documentation which has the name username and password as the above code
In my pipeline, I have added the Nuget package which is set to restore using my service connection above.
# 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:
- master
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#1
- task: NuGetCommand#2
inputs:
restoreSolution: '$(solution)'
- task: NuGetCommand#2
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
feedsToUse: 'config'
nugetConfigPath: 'MyProject/nuget.config'
externalFeedCredentials: 'Telerik NuGet'
- task: VSBuild#1
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"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: VSTest#2
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
The settings for the above pipeline step are as follows:
Does anyone have any ideas what's going on, is my setup incorrect?
I managed to get this working by accident. It was the order of the steps that was causing the problem. The output of the build showed that no matter what I did the pipeline was looking at a tempNuget.config file and not the one I had specified. Since there are two NuGet steps in the job I moved the Telerik up by one level and this ensured the system used the correct nuget.config file instead of looking at a temp one it was creating.
Here are the altered steps that caused it to start working, please note the Telerik step has been moved up by one step.
# 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:
- master
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#1
- task: NuGetCommand#2
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
feedsToUse: 'config'
nugetConfigPath: 'MyProject/nuget.config'
externalFeedCredentials: 'Telerik NuGet'
- 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:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: VSTest#2
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'

Deploying a WebAPI project with several webjobs in Azure Devops

I am trying to use Azure Devops to do CI/CD. I have created the appropriate Git triggers to build when I push and I create a new release whenever I have produced a new build.
In the release tab I am trying to deploy a WebAPI project with several webjobs using the "Deploy Azure App Service" template. All the logs seem to indicate everything goes fine, but in the end I have nothing when I check the app service in Azure!
I have tried many different configurations and even a few more templates. They all seem fine according to the logs, but nothing is actually ever deployed!
If I try to build/deploy from VS2017 it works beautifully!
QUESTION
what do I need to do in order to successfully deploy my code via Azure Devops
.
My build YAML file is fairly close to the default, only added the CopyFiles#2 due to another SO post suggesting it:
trigger:
tags:
include:
- slot*
branches:
include:
- dev
pool:
vmImage: 'VS2017-Win2016'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
name: $(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
steps:
- task: NuGetToolInstaller#0
- 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: CopyFiles#2
inputs:
targetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts#1
condition: succeeded() #and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
- task: VSTest#2
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
Second step I create a release from the artifacts produced via the YAML file.
Please add the following line in your package or folder option
$(System.DefaultWorkingDirectory)\*.*
It will make sure to pick all the files while deploying.
Also please refer to these ways to deploy webjob to azure:
Modify Visual Studio Build task to deploy webjob with FileSystem (MSBuild Arguments: /p:DeployOnBuild=true /p:WebPublishMethod=FileSystem /p:publishUrl="$(build.artifactstagingdirectory)\\WebJob" /p:DeployDefaultTarget=WebPublish)
Add Delete Files task to release definition to delete bin folder (Source Folder:
$(System.DefaultWorkingDirectory)/WebJobVnext/drop/WebJob); Contents:bin)
Modify Azure App Service Deploy task (
Uncheck Publish using Web Deploy option.
Package or folder: $(System.DefaultWorkingDirectory)/[artifact name]
/drop/WebJob)
Hope it helps.
There are two main problems with your deploy task.
As Mohit said, you need to specify the zip file of the web project you want to deploy, not just the directory it is in.
You need to uncheck "Exclude files from the App_Data folder". This will prevent webjobs from deploying with the website
2.1 If you haven't, in Visual Studio, you need to right click your web project Add > Existing Project as Azure Webjob. Do this for every webjob project so it will package the webjobs with the website

Resources