Deploying .NET Azure Functions with GitHub Actions: The Hidden Trick You Need to Know

I recently found myself deep in the weeds trying to get .NET Azure Functions to deploy using GitHub Actions. What seemed like a straightforward process quickly turned into a time-consuming troubleshooting effort. If you’ve struggled with a similar issue, this post may save you some time and headaches.

The Problem

Deploying .NET Azure Functions from a GitHub Actions pipeline should be simple, right? In my setup, I had configured everything to build, archive, and publish the necessary build artifacts for deployment. Yet, no matter what I tried, the deployment would appear to succeed, but no functions would be listed in the Azure Portal or via the command line tool. This was particularly baffling because if I deployed the same .NET artifacts from my laptop using the CLI tools, everything would work perfectly.

This issue specifically arises if you are building and then uploading an artifact, and then downloading and deploying it later, such as when you have a separate build and deploy workflow.

After hours of trial and error and combing through documentation, I finally found the answer buried in an issue discussion on GitHub: Azure Functions .NET Worker Issue #1240.

The Solution

The key change that resolved my problem was adding the include-hidden-files: true option in the GitHub Actions workflow. This ensures that hidden files, like those in the .azurefunctions directory, are included in the artifact packaging.

Here’s the relevant part of the GitHub Actions workflow file:

- name: Archive production artifacts
  uses: actions/upload-artifact@v4
  with:
    name: build-artifact
    if-no-files-found: error
    include-hidden-files: true
    path: |
      global.json
      MyApp.Web/bin/Release/net8.0/publish
      MyApp.Database/bin/Release/net8.0
      MyApp.Functions/bin/Release/net8.0      

Why This Matters

The include-hidden-files: true setting is crucial because without it, hidden directories such as .azurefunctions are excluded from the artifact. This exclusion causes the deployment to appear successful, but with no functions showing up in the Azure Portal or through the command line tool. This can be especially frustrating when deploying directly from a local machine with CLI tools works perfectly, highlighting a discrepancy in the deployment process.

To check the functions in your .NET deployment, you can use a command like:

func azure functionapp list-functions myapp-functions-test

This will list the functions and their triggers in the specified .NET deployment.

Conclusion

If you’re deploying .NET Azure Functions using GitHub Actions and encounter issues with missing files in your deployment artifacts or functions not appearing as expected, make sure to include include-hidden-files: true in your upload-artifact step. It’s a simple change, but one that can save you hours of frustration.