Search code examples
c#angularazuregithub-actionsasp.net-core-webapi

Deploying Angular / ASP.NET Core Web API to Azure with GitHub Actions


I have a VS 2022 solution that I created from the "Angular and ASP.NET Core" template. The basic folder layout is like this:

-MySln
    -angular.client
    -webapi.server

It runs fine locally.

I have a GitHub .yml workflow to build/deploy them, and it has this line:

run npm run build -- --configuration production --output-path "../webapi.server/wwwroot"

When I look at the final folder structure on the Ubuntu web app (or just download the zip artifact), it looks like this:

~/site
    wwwroot  <- the DLLs are here
        wwwroot   <- nested wwwroot folder
            browser    <- has the index.html etc.

I can get to my swagger page just fine in a browser. But entering just the root gives 404.

If I take out the 'wwwroot' from the yml file, to avoid the nested wwwroots, like this:

run: npm run build -- --configuration production --output-path "../webapi.server"

The .NET Core build will fail that comes right after (maybe because the angular build clears out all the source files in the ASP.NET Core Web API project before output files?)

What am I doing wrong?


Solution

  • I have created sample Angular and Asp.NET core App using Visual Studio template and deployed to Single Azure Web App.

    According to this MS Doc when we deploy a combined Angular and ASP.NET Core template to Azure, we only need to publish the ASP.NET application, as it will serve the frontend.

    Make sure your .csproj file of the API is like the one below:

    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <SpaRoot>..\angularapp1.client</SpaRoot>
        <SpaProxyLaunchCommand>npm start</SpaProxyLaunchCommand>
        <SpaProxyServerUrl>https://localhost:60843</SpaProxyServerUrl>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.12" />
        <PackageReference Include="Microsoft.AspNetCore.SpaProxy">
          <Version>8.*-*</Version>
        </PackageReference>
        <PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
      </ItemGroup>
      <ItemGroup>
        <ProjectReference Include="..\angularapp1.client\angularapp1.client.esproj">
          <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
        </ProjectReference>
      </ItemGroup>
    </Project>
    

    Add below lines to Program.cs file:

    app.UseDefaultFiles();
    app.UseStaticFiles();
    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    

    Workflow File:

    name: Build and deploy ASP.Net Core app to Azure Web App - kaaspangularapp
    on:
      push:
        branches:
          - master
      workflow_dispatch:
    jobs:
      build:
        runs-on: ubuntu-latest
        permissions:
          contents: read 
        steps:
          - uses: actions/checkout@v4
          - name: Set up .NET Core
            uses: actions/setup-dotnet@v4
            with:
              dotnet-version: '8.x'
          - name: Build with dotnet
            run: dotnet build --configuration Release
          - name: dotnet publish
            run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp
          - name: Upload artifact for deployment job
            uses: actions/upload-artifact@v4
            with:
              name: .net-app
              path: ${{env.DOTNET_ROOT}}/myapp
      deploy:
        runs-on: ubuntu-latest
        needs: build
        environment:
          name: 'Production'
          url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
        permissions:
          id-token: write 
          contents: read 
        steps:
          - name: Download artifact from build job
            uses: actions/download-artifact@v4
            with:
              name: .net-app
          - name: Login to Azure
            uses: azure/login@v2
            with:
              client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_CD22FD0395784F639518925E1EFC70E2 }}
              tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_66FF58BA62F64705AC9886468C33CB78 }}
              subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_09510F2585DB4F73936186765AAE5652 }}
          - name: Deploy to Azure Web App
            id: deploy-to-webapp
            uses: azure/webapps-deploy@v3
            with:
              app-name: 'kaaspangularapp'
              slot-name: 'Production'
              package: .       
    

    Azure Output:

    enter image description here