Kristof
Kristof

Reputation: 11

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

I try to deploy a Blazor Wasm application from my Azure DevOps repo to an Azure static web app. My app is based on the standard template, but is also using a Nuget package hosted in private feed in Azure Artifacts. I have tried several combinations of pipeline tasks but none seem to do the trick.

Attempt 1: The essentials

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]'

The task fails with a clear error, indicating that the private nuget feed hosting the package is not used:

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).

Since there is no feedsToUse and vstsFeed configuration options for this task, I looked into restoring the Nuget packages separately.

Attempt 2: Adding Nuget restore

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

Adding the above dotnet restore task successfully registers the private feed and restores the nuget package from it, but it seems this registration is not available to the deployment task coming next. The deploy task fails with the same error as above.

Attempt 3: Skip the build during deploy

My last attempt was trying to let the deploy task use the output from the previous tasks, so I set up a full dotnet build-publish pipeline, and set skip_app_build to true in the deploy task, to avoid a build & failing restore:

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]'

This produces the following error, saying the (published?) default files are missing:

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.

For app_location, as per instructions here, I used the location of the csproj file (src/[project_folder]), where indeed no index.html or other default file exists. However when I use src/[project_folder]/wwwroot, I get past the above error.

For output_location, wwwroot is what most tutorials use, but they don't use the full-blown pipeline approach. I have also tried to match the output folders from the build (../bin/Release/net5.0/wwwroot) and the publish ($(Build.ArtifactStagingDirectory)/[project_folder]) tasks.

Regardless of which folder I use, the pipeline completes, but when opening the web app, it looks like some but not all files got deployed:

Network traffic when opening the application

I don't know where to go from here.

Upvotes: 1

Views: 2389

Answers (2)

unsane
unsane

Reputation: 119

This worked for me:

- 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: '..................'

Upvotes: 0

Kristof
Kristof

Reputation: 11

So approach 3 turned out to be the right one, but with a caveat.

Apparently it is necessary to add an extra step to copy the output files to the app_location folder, as mentioned here.

Initially I tried keeping $(Build.ArtifactStagingDirectory) variable, but that didn't work, so I ended up using a fixed path.

The final result looks like this:

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]'

Upvotes: 0

Related Questions