Search code examples
angularazureazure-web-app-servicegithub-actions

Why is the ClientApp/dist folder unexpectedly empty after Azure web app deploys via github actions?


I am deploying a Single Page (angular) App integrated with a .Net Core 8.0 WebSite. I deploy to an Azure Web App.

After the deployment the ClientApp/dist folder is empty. It should contain the distribution components from my angular app.

It appears that the final deployment stage is removing, or refusing, the Client/dist folder contents. It only affects the ClientApp/dist folder. Other folders and files seem to be as I'd expect.

Am I missing some setting/switch/or option that controls population of the Client/dist folder?

The git actions yaml file is pasted lower down[1]

The rest of this post records why I think this...

Stage 1

Evidence The .Net Core app throws an exception stating it cannot find the index.html file. I used kudu to look at the wwwroot/ClientApp/dist folder. It's empty. I expected to see index.html and other files in there.

I traced index.html through the process. I'm assuming the other files that belong in ClientApp/dist will follow the same path.

Stage 2

Evidence I enabled detail logging of the build and deploy process. In the output of the dotnet publish I see it report creating the runtime, main, polyfils and styles. I infer that it's created index.html as well.

Stage 3

In the "Upload artifact for deployment job" output I see index.html mentioned

Evidence In the log I see ##[debug]File:/home/runner/.dotnet/myapp/ClientApp/dist/index.html was found using the provided searchPath

...and later... ##[debug]/home/runner/.dotnet/myapp/ClientApp/dist/index.html is less than 64k in size. Creating a gzip file in-memory to potentially reduce the upload size ##[debug]A gzip file created for /home/runner/.dotnet/myapp/ClientApp/dist/index.html helped with reducing the size of the original file. The file will be uploaded using gzip.

..and... ##[debug]File: 28/245. /home/runner/.dotnet/myapp/ClientApp/dist/index.html took 68.236 milliseconds to finish upload

Stage 4

In the deploy phase, sub phase "Download artifact from build job" I see index.html mentioned again

Evidence In the log output I see... ##[debug]File: 92/245. /home/runner/work/[Redacted]/[Redacted]/ClientApp/dist/index.html took 263.048 milliseconds to finish downloading.

That last log line leads me to expect the index.html file to show up in wwwroot/ClientApp/dist when I use kudo to inspect the deployed files.

Conclusion

It looks as though the 'Download artifact from build job' stage has 'lost' the entire contents of the ClientApp/dist directory.

AFAICT files are ONLY missing from the specific directory ClientApp/dist. There are other .html, .js, and .css files that have faithfully arrived in their expected places.

This is my first experience with Azure I'll probably need hand holding.

[1] git actions yaml file

name: Build and deploy ASP.Net Core app to Azure Web App - develop-redacted

on:
  push:
    branches:
      - develop
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '8.x'
          include-prerelease: true

      - name: Set up node 16.20.2
        uses: actions/setup-node@v4
        with:
            node-version: '16.20.2'

      - name: Build with dotnet
        run: dotnet build --configuration Release

      - name: dotnet publish
        run: dotnet publish ./NetCoreWebsite/NetCoreWebsite.csproj -c Release -o ${{env.DOTNET_ROOT}}/myapp

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v3
        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 #This is required for requesting the JWT

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v3
        with:
          name: .net-app
      
      - name: Login to Azure
        uses: azure/login@v1
        with:
          client-id: ${{ secrets.redacted }}
          tenant-id: ${{ secrets.redacted }}
          subscription-id: ${{ secrets.redacted }}

      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'develop-redacted'
          slot-name: 'Production'
          package: .

Solution

  • Am I missing some setting/switch/or option that controls population of the Client/dist folder?

    • You were not building the dist folder in the using command npm run build
    • You need to upload after building.
    • In you .yml file you were only selecting the node version, no operations were being done after node selection.

    This Worked for me.

    #my directory :

    Webapp/
    │
    ├── .github/
    │   └── workflows/
    │       └── main_dotnetwithangualr.yml
    │
    ├── WebApplication2/
    |   ├── angular-app/
    |   │   ├── src/
    |   │   │   └── ...                             
    |   │   ├── angular.json
    |   │   ├── package.json
    |   │   └── ...
    │   ├── Controllers/
    │   │   └── ...               
    │   ├── Models/
    │   │   └── ... 
    │   ├── Properties/
    │   │   └── ...                 
    │   ├── Views/
    │   │   └── ...                 
    │   ├── wwwroot/
    │   │   └── ...                
    │   ├── appsettings.json
    │   ├── Program.cs
    │   └── WebApplication2.csproj
    │
    └── WebApplication2.sln
    

    main_dotnetwithangualr.yml:

    # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
    # More GitHub Actions for Azure: https://github.com/Azure/actions
    
    name: Build and deploy ASP.Net Core app to Azure Web App - dotnetwithangualr
    
    on:
      push:
        branches:
          - main
      workflow_dispatch:
    
    jobs:
      build:
        runs-on: windows-latest
    
        steps:
          - uses: actions/checkout@v4
    
          - name: Set up .NET Core
            uses: actions/setup-dotnet@v1
            with:
              dotnet-version: '8.x'
              include-prerelease: true
    
          - name: Set up Node.js version  
            uses: actions/setup-node@v3  
            with:  
              node-version: '18.x'
    
          - name: npm install, build, and test  
            run: |
              npm install
              npm run build
            working-directory: WebApplication2/angular-app/  # building `dist`, using `package.json` as it is available in "WebApplication2/angular-app/" path I added working directory.
    
          - name: Upload artifact for deployment job
            uses: actions/upload-artifact@v3
            with:
              name: angular
              path: ./WebApplication2/angular-app/dist/  # uploading files and folders created inside `dist`
    
          - 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@v3
            with:
              name: .net-app
              path: ${{env.DOTNET_ROOT}}/myapp
    
      deploy:
        runs-on: windows-latest
        needs: build
        environment:
          name: 'Production'
          url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
        
        steps:
          - name: Download artifact from build job
            uses: actions/download-artifact@v3
            with:
              name: .net-app
              
          - name: Download artifact from angular build job
            uses: actions/download-artifact@v3
            with:
              name: angular
          
          - name: Deploy to Azure Web App
            id: deploy-to-webapp
            uses: azure/webapps-deploy@v2
            with:
              app-name: 'dotnetwithangualr'
              slot-name: 'Production'
              package: .
              publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_E48F4EC67FB14F22A7CD2D3AA9C7BDF5 }}
    

    OUTPUT:

    dist in local :

    uploaded files on azure :