Fix the Azure Function Node.js GitHub Actions Windows workflow

post

When deploying Node.js-based Azure Functions using GitHub Actions, you might face an issue with the Windows workflow. In the latest template, there is an issue in the build step where the actions/upload-artifact action fails to upload the artifact due to too many files. The problem is caused by the node_modules folder, which contains many files (even for a starter Azure Function project).

Another issue I spotted is that if the build step is successful, the deployment job will deploy all the dependencies (including the development dependencies) to the Azure Function App. Deploying the development dependencies is not recommended as it increases the deployment size and should not be required to run your functions.

Fix the build artifact issue

To fix the issue, you must exclude the node_modules folder from the artifact upload and install an npm during the deployment. You can do this using the ignore pattern in the actions/upload-artifact action.

Updates to the actions/upload-artifact action
1
2
3
4
5
6
7
8
- name: Upload artifact for deployment job
  uses: actions/upload-artifact@v4
  with:
    name: node-app
    path: |
      .
      !./src # Exclude the source code (optional)
      !./node_modules # Exclude the node_modules folder      
tip

I excluded the source files (!./src) from being published to the Azure Function as they are not required for running the functions. You are free to include/exclude those.

Fix the deployment dependencies issue

To fix the deployment dependencies issue, you must install only the production dependencies during the deployment. You can use the --omit=dev flag in the npm install command. Add the following step to the deployment job after the actions/download-artifact action to install the production dependencies.

Install the production dependencies during deployment
1
2
3
4
5
6
- name: "Install production dependencies"
  shell: pwsh
  run: |
    pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
    npm i --omit=dev
    popd    

The complete updated workflow

Here is the complete updated workflow with the above fixes.

Updated azure-functions.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
name: Build and deploy Node.js project to Azure Function App

on:
  push:
    branches:
      - main
  workflow_dispatch:

env:
  AZURE_FUNCTIONAPP_PACKAGE_PATH: "."
  NODE_VERSION: "20.x"

jobs:
  build:
    runs-on: windows-latest
    steps:
      - name: "Checkout GitHub Action"
        uses: actions/checkout@v4

      - name: Setup Node ${{ env.NODE_VERSION }} Environment
        uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: "Resolve Project Dependencies Using Npm"
        shell: pwsh
        run: |
          pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
          npm install
          npm run build --if-present
          npm run test --if-present
          popd          

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v4
        with:
          name: node-app
          path: |
            .
            !./src # Exclude the source code (optional)
            !./node_modules # Exclude the node_modules folder            

  deploy:
    runs-on: windows-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@v4
        with:
          name: node-app

      - name: "Resolve Project Dependencies Using Npm"
        shell: pwsh
        run: |
          pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
          npm i --omit=dev
          popd          

      - name: Login to Azure
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.<client-id> }}
          tenant-id: ${{ secrets.<tenant-id> }}
          subscription-id: ${{ secrets.<subscription-id> }}

      - name: "Run Azure Functions Action"
        uses: Azure/functions-action@v1
        id: fa
        with:
          app-name: "to-delete-function"
          slot-name: "Production"
          package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}

Comments

Back to top