由于来自私有 Nuget 提要的包,Azure DevOps 管道无法将 Blazor Wasm 应用程序部署到静态 Web 应用程序

Azure DevOps pipeline unable to deploy Blazor Wasm app to Static Web App due to package from private Nuget feed

我尝试将 Blazor Wasm 应用程序从我的 Azure DevOps 存储库部署到 Azure 静态 Web 应用程序。我的应用程序基于标准模板,但也使用托管在 Azure Artifacts 私有源中的 Nuget 包。我尝试了几种管道任务组合,但 none 似乎可以解决问题。

尝试 1:要点

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
- checkout: self
  submodules: true
- task: AzureStaticWebApp@0
  inputs:
    app_location: 'src/[project_name]'
    output_location: 'wwwroot'
    azure_static_web_apps_api_token: '[my_token]'

任务失败并出现明显错误,表明未使用托管包的私有 nuget 提要:

Determining projects to restore...
/working_dir/src/[project_folder]/[project_name].csproj : error NU1101: Unable to find package [my_private_package_in_private_feed]. No packages exist with this id in source(s): nuget.org
  Failed to restore /working_dir/src/[project_folder]/[project_name].csproj (in 7.91 sec).

由于此任务没有 feedsToUse 和 vstsFeed 配置选项,我研究了单独恢复 Nuget 包。

尝试 2:添加 Nuget 恢复

- task: DotNetCoreCLI@2
  displayName: 'dotnet restore'
  inputs:
    command: restore
    projects: '**/*.csproj'
    feedsToUse: 'select'
    vstsFeed: '[my_private_feed]'

添加上面的 dotnet restore 任务成功注册了私有提要并从中恢复了 nuget 包,但似乎此注册不适用于接下来的部署任务。部署任务失败并出现与上述相同的错误。

尝试 3:在部署期间跳过构建

我最后的尝试是试图让部署任务使用之前任务的输出,所以我设置了一个完整的 dotnet build-publish 管道,并在部署任务中将 skip_app_build 设置为 true,以避免构建和恢复失败:

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
- checkout: self
  submodules: true
- task: DotNetCoreCLI@2
  displayName: 'dotnet restore'
  inputs:
    command: restore
    projects: '**/*.csproj'
    feedsToUse: 'select'
    vstsFeed: '[my_private_feed]'
- task: DotNetCoreCLI@2
  displayName: 'Build'
  inputs:
    command: 'build'
    configuration: $(configuration)
    projects: '**/*.csproj'
- task: DotNetCoreCLI@2
  displayName: 'Publish...'
  inputs:
    command: publish
    publishWebProjects: true
    arguments: '--configuration Release --output $(Build.ArtifactStagingDirectory)'
    zipAfterPublish: false
- task: AzureStaticWebApp@0
  inputs:
    skip_app_build: true
    app_location: 'src/[project_folder]'
    output_location: 'wwwroot'
    azure_static_web_apps_api_token: '[my_token]'

这会产生以下错误,表示(已发布?)默认文件丢失:

App Directory Location: '[app_location]' was found.
No Api directory specified. Azure Functions will not be created.
Skipping step to build /working_dir/src/[project_folder] with Oryx
Failed to find a default file in the app artifacts folder ([app_location]). Valid default files: index.html,Index.html.
If your application contains purely static content, please verify that the variable 'app_location' in your deployment configuration file points to the root of your application.
If your application requires build steps, please validate that a default file exists in the build output directory.

对于 app_location,按照说明 here,我使用了 csproj 文件的位置 (src/[project_folder]),其中确实没有 index.html 或存在其他默认文件。但是,当我使用 src/[project_folder]/wwwroot 时,我克服了上述错误。

对于 output_location,大多数教程都使用 wwwroot,但它们没有使用成熟的管道方法。我还尝试匹配构建 (../bin/Release/net5.0/wwwroot) 和发布 ($(Build.ArtifactStagingDirectory)/[project_folder]) 任务的输出文件夹。

无论我使用哪个文件夹,管道都会完成,但是当打开 Web 应用程序时,看起来有些但不是所有文件都已部署:

Network traffic when opening the application

我不知道从这里到哪里去。

所以方法 3 结果是 the right one,但有一个警告。

显然需要添加一个额外的步骤来将输出文件复制到 app_location 文件夹,如前所述 here

最初我尝试保留 $(Build.ArtifactStagingDirectory) 变量,但这没有用,所以我最终使用了固定路径。

最终结果如下所示:

trigger:
- feature-initial-version

pool:
  vmImage: ubuntu-latest

variables:
  buildConfiguration: 'Release'

steps:
- checkout: self
  submodules: true
- task: DotNetCoreCLI@2
  displayName: 'dotnet restore'
  inputs:
    command: 'restore'
    projects: '**/*.csproj'
    feedsToUse: 'select'
    vstsFeed: '[my_private_feed]'
- task: DotNetCoreCLI@2
  displayName: 'Build'
  inputs:
    command: 'build'
    arguments: '--configuration $(buildConfiguration)'
    projects: '**/*.csproj'
- task: DotNetCoreCLI@2
  displayName: 'Publish...'
  inputs:
    command: 'publish'
    publishWebProjects: true
    arguments: '--configuration $(buildConfiguration) --output ./src/website/build --verbosity n'
    zipAfterPublish: false
- task: DownloadPipelineArtifact@2
  displayName: "Download artifacts"
  inputs:
    path: './src/website/build' # same as the publish output folder
- task: AzureStaticWebApp@0
  inputs:
    skip_app_build: true # don't try building, since restore will fail
    app_location: 'src/website/build/[project_folder]/wwwroot' # subfolder of the publish output folder
    output_location: '' # should remain empty if skip_app_build: true
    azure_static_web_apps_api_token: [my_token]'

这对我有用:

- task: DotNetCoreCLI@2
  displayName: 'dotnet build'
  inputs:
    command: 'build'
    arguments: '--configuration Release'
    projects: 'Blazor.App.csproj'

- task: DotNetCoreCLI@2
  displayName: 'dotnet publish'
  inputs:
    command: 'publish'
    publishWebProjects: true
    arguments: '--configuration Release'
    zipAfterPublish: false

- task: AzureStaticWebApp@0
  inputs:
    skip_app_build: true
    app_location: '/bin/Release/net6.0/publish/wwwroot'
    output_location: ''
    azure_static_web_apps_api_token: '..................'