是 Azure 应用服务的一项功能,可用于在与 Web 应用、API 应用或移动应用相同的实例中运行程序或脚本。 Azure 应用服务是一种基于 HTTP 的服务,用于托管 Web 应用程序、REST API 和移动后端。

    .NET Framework 中的 Web 控制台应用可轻松使用 Azure 服务生成和部署 WebJobs。此外,可以使用 Azure DevOps Pipelines 轻松为 CI/CD 配置 WebJobs 控制台应用,以便在每次成功生成时自动将 Web 应用部署到 Azure 应用服务。因此,Azure 管道支持使用 Azure DevOps 服务以持续集成 (CI) /持续交付 (CD) 方式进行生成、测试和部署。

    如果在 .NET Framework 中生成 WebJob 控制台应用,则通过将父 API 或 Web 应用链接到 Web/API 应用,可以非常轻松地生成和部署 WebJob,如下所示:



使用 Azure DevOps Pipelines 生成 .NET Core WebJob 控制台应用 CI/CD_.netcore



使用 Azure DevOps Pipelines 生成 .NET Core WebJob 控制台应用 CI/CD_microsoft_02

    .NET Core 中的设计不支持上述 WebJob 控制台应用程序与父 Web/API 应用的链接。那么我们该怎么做呢?

    在本文中,我们将了解如何独立于父 Web/API 应用生成 .NET Core WebJob 控制台应用,并使用 Azure DevOps 生成和发布管道将其部署在现有的父 Web/API 应用下。

生成管道:生成 .NET Core 控制台应用

若要生成 .NET Core 控制台应用,我们需要在 Azure DevOps 生成管道中执行四个基本生成任务。

  • dotnet restore
  • dotnet build
  • dotnet publish
  • 将生成项目发布到放置位置

Azure Web 作业仅支持以下文件类型:

  • .cmd、.bat、.exe
  • .ps1(使用 PowerShell.ps1 (using PowerShell)
  • .sh(使用 Bash)
  • .php(使用 PHP)
  • .py(使用 Python)
  • .js(使用Node.js)
  • .jar(使用 Java)

由于我们位于 .NET Core 中,因此我们期望有一个 .exe 文件作为控制台应用的输出。如果仅通过运行来生成 .NET Core 应用,它将生成一个 .DLL 文件,但不会生成.EXE文件。若要生成.EXE文件作为生成输出,请在步骤中使用以下参数:dotnet buildpublish

--configuration $(BuildConfiguration) --self-contained -r win10-x64 --output $(build.artifactstagingdirectory)

    这个参数在这里会有所不同,因为这将在构建中生成一个.EXE文件。--self-contained -r win10-x64

    接下来,选择该选项。这将从生成输出中创建一个 ZIP 文件。Enable Zip Published Projects

使用 Azure DevOps Pipelines 生成 .NET Core WebJob 控制台应用 CI/CD_ci/cd_03

一旦它被发布到ZIP文件夹并完成,我们需要将此ZIP文件拖放到放置位置。用作要发布的路径。使用您选择的任何项目名称。在此示例中,项目名称为:$(Build.ArtifactStagingDirectory)webjobs_drop

使用 Azure DevOps Pipelines 生成 .NET Core WebJob 控制台应用 CI/CD_devops_04

发布管道:将生成项目部署到 Azure 应用服务

运行生成管道后,你将在位置获取生成输出。webjobs_drop/.zip

若要将其部署到 Azure 应用服务中运行的任何现有 Web/API 应用的 WebJob,我们必须运行 Azure PowerShell 脚本任务来实现此目的。

我们将用于将生成输出部署到应用服务。这会将压缩的生成输出解压缩到文件夹中。KUDU Zip Deploy APIwwwroot\App_Data\Jobs\\ 

若要设置发布管道,我们需要使用以下管道变量创建一个空管道:

  • resourceGroupName- 应用程序的资源组名称
  • scheduleName- 有争议/触发(在本例中,它是连续的)
  • scmApiUrl- SCM API 网址;示例:https://.scm.azurewebsites.net/api
  • webJobName- 您的 WebJob 名称;您的代码将部署在 wwwroot\App_Data\Jobs\scheduleName\webJobName 文件夹下
  • zippedArtifactPath- 构建输出文件的压缩工件路径

使用 Azure DevOps Pipelines 生成 .NET Core WebJob 控制台应用 CI/CD_azure_05



使用 Azure DevOps Pipelines 生成 .NET Core WebJob 控制台应用 CI/CD_microsoft_06

设置变量后,我们需要执行以下操作:

  • 添加一个Azure PowerShell script task
  • 选择“Azure 连接”类型
  • 选择 WebApp 所在的 Azure 订阅
  • 选择“脚本类型”作为内联脚本

使用 Azure DevOps Pipelines 生成 .NET Core WebJob 控制台应用 CI/CD_microsoft_07

在内联脚本编辑器中,添加以下 PowerShell 脚本:

#Zipped artifact path - get the path from Azure DevOps Pipeline variables
$path = "$(System.DefaultWorkingDirectory)\$($env:zippedArtifactPath)"

#Test the path if exists
if (-not (Test-Path $path)) 
{
    throw [System.IO.FileNotFoundException] "$($path) not found."
}

#Resource type and details
$resourceType = "Microsoft.Web/sites/config"
$resourceName = "$($env:webAppName)/publishingcredentials"

#Get the Publishing Profile details
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $($env:resourceGroupName) -ResourceType $resourceType -ResourceName $resourceName -Action list -Force

#Creating the Auth Token using user name and password from Publish profile credentials
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName,$publishingCredentials.Properties.PublishingPassword)))

#Get the file from the Build Artifacts path 
$files = Get-ChildItem -Path $path -Recurse
Test-Path -Path $files[0]   

#Authentication Header
$authHeader = " Basic " + $base64AuthInfo

#Kudu Zip Deploy API URL
$deployUrl = "$($env:scmApiUrl)/zip/site/wwwroot/App_Data/jobs/$($env:scheduleName)/$($env:webJobName)/"

#Invoke Kudu Zip Deploy API to deploy the WebJob
$contentType = "multipart/form-data"
$userAgent = "powershell/1.0"
$ZipHeaders = @{
Authorization = $authHeader
}

$response = Invoke-RestMethod -Uri  ([System.Uri]::new($deployUrl)) -Headers $ZipHeaders  -UserAgent $userAgent -Method PUT -InFile $files[0] -ContentType $contentType

Write-Host "Deployment Successful"

此 PowerShell 脚本将获取 Web 应用的发布配置文件详细信息,并使用此信息登录到 KUDU ZipDeploy API,以将 Zipped 生成输出上传到所需位置。

部署位置定义如下:

  • SCM API URL 和虚拟目录路径 https://<>.scm.azurewebsites.net/api/zip site/wwwroot/App_Data/jobs/<continuous/triggered>/

访问特定于环境的配置

上述生成和发布管道将为 .NET Core 控制台应用程序生成并生成.EXE文件,并将生成输出部署到 Azure 应用服务虚拟目录。在某些情况下,Web 作业可能需要读取某些特定于环境的配置。在这种情况下,您必须将特定于环境的文件添加为 .appsettings.jsonappsettings.json

要从特定于环境的 JSON 文件中读取值,我们可以依赖该变量。可以从 Azure 门户手动设置此变量,也可以在应用设置部分使用 Azure 发布管道部署父 WebApp/API 应用时设置此变量。ASPNETCORE_ENVIRONMENT

builder.ConfigureAppConfiguration((hostingContext, config) =>
 {
     var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
     Console.WriteLine("Environment Variable: " + environmentName);
     var env = hostingContext.HostingEnvironment;
     Console.WriteLine("hostingContext.HostingEnvironment: " + env.EnvironmentName);

     config.SetBasePath(Directory.GetCurrentDirectory())
     .AddJsonFile($"appsettings.json", optional: true, reloadOnChange: true)
     .AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true)
     .AddEnvironmentVariables().Build();
 });

将上述代码添加到文件中,以便从文件中读取特定于环境的值。Program.csappsettings.json

总而言之,我们执行了以下操作:

  • dotnet publishwith 参数,用于生成 WebJob 支持的 EXE 文件--self-contained -r win10-x64 
  • 压缩生成项目目录
  • 使用 API 将 WebJob 控制台应用程序发布到现有的 web/API 应用程序虚拟目录。KUDU ZipDeployAzure PowerShell Script