Search submit icon
Copied RSS Feed

Blazor

Blazor CI/CD with GitHub Actions: Automate Deployment to Azure Static Web Apps

Summarize this blog post with:

ChatGPT logoChatGPTPerplexity logoPerplexityClaude logoClaudeGrok logoGrok

TL;DR: Automate your Blazor app deployment using GitHub Actions. This guide walks you through building a secure CI/CD pipeline for Blazor WebAssembly, running unit and Playwright tests, deploying to Azure Static Web Apps, monitoring with Application Insights, and hardening workflows with CodeQL, secret scanning, and Dependabot.

High-performing DevOps teams don’t just ship code faster; they deliver with confidence. According to the 2024 DevOps report, elite teams deploy 182× more often, restore service 2293× faster, and reduce lead time for changes by 127× compared to low performers. The secret? Eliminating manual steps from the delivery pipeline.

Blazor WebAssembly apps are ideal for this kind of acceleration. The framework compiles to static files, and Azure Static Web Apps can serve each new build globally within seconds. By integrating GitHub Actions into your workflow, you can:

  • Test every commit automatically so regressions never reach production.
  • Deploy successful builds instantly to Azure, with no zip uploads and no portal clicks.
  • Validate the live site with Playwright smoke tests and capture runtime errors in Application Insights.

This guide provides the exact YAML configuration, scripts, and Azure setup to automate your Blazor CI/CD pipeline end-to-end, helping you ship updates faster, with less risk, and zero extra overhead.

Prerequisites

Before you create the workflow, make sure you have the following in place:

  • GitHub account and repository: You’ll need a GitHub account with a repository. For this guide, we assume main as the default branch.
  • Azure subscription: Ensure you have an Azure subscription with permission to create a Static Web App. The Starter tier works perfectly for this setup.
  • .NET SDK: Install the .NET 8 SDK or later on your local machine to build and deploy the Blazor application.
  • Blazor WASM project: Have a Blazor WebAssembly project ready for deployment.
  • Runner choice: Decide on your runner.
    • GitHub-hosted runners (e.g., ubuntu-latest) work out of the box.
    • Self-hosted runners are also fine, but make sure the .NET SDK is installed.
  • Deployment token: Finally, set up your deployment token:
    • In the Azure Portal, open your Static Web AppManage deployment tokencopy the token.
    • Then, in GitHub, go to Settings → Secrets → Actions → New secret, and paste the token as AZURE_STATIC_WEB_APPS_API_TOKEN.

You can find the full example and YAML configuration in the GitHub repo.

Step 1: Create the build & test workflow

Begin by creating a folder named .github/workflows at the root of your repository. Inside it, add a file called blazor-ci.yml.

What happens under the hood

  • Triggers: The workflow runs on every push to main and on every pull request targeting main. That keeps both feature branches and trunk clean.
  • SDK installation: actions/setup-dotnet downloads the latest .NET 8 runtime, caches it, and adds it to $PATH.
  • Build vs. publish: dotnet build compiles the code, and dotnet publish generates the static wwwroot folder that Azure needs.
  • Code coverage: The --collect switch stores coverage data so you can upload it to a badge service or track change‑failure rate trends later.
  • Artifacts: Uploading publish/wwwroot saves about 30 seconds in the deploy job because you avoid rebuilding.

Step 2: Deploy to Azure Static Web Apps

Next, add a second job within the same YAML file, immediately after the build job.

Why use needs: build?

The needs keyword ensures that the deploy job runs only if the build job succeeds. If tests fail, the pipeline stops.

What this action does?

  • It compresses wwwroot, uploads it to the production slot, and waits for Azure to finish the swap.
  • It emits outputs like static_web_app_url (production) and preview_url (for PRs). Save these for Playwright tests.

Pull request previews

Static Web Apps automatically spin up a temporary environment for every PR. The same deployment step handles this seamlessly, and reviewers receive a private URL like: https://pr-42-sitename.azurestaticapps.net.

Step 3: Run post-deploy smoke tests with playwright

Run end‑to‑end (E2E) tests to catch problems that unit tests miss, such as broken routing and missing static files. Playwright is a fast choice because GitHub ships ready‑to‑use browser bundles.

Create tests/e2e with two files:

playwright.config.ts:

example.spec.ts:

Now append a third job to the workflow:

If a test fails, the job stops and marks the build as failed. The site will remain offline until the issue is resolved.

Add --reporter=html and upload the playwright-report folder as an artifact to get a rich dashboard of screenshots.

Step 4: Monitor production with application insights

Static Web Apps integrates with Application Insights out of the box. Here’s what you do:

  1. Turn on Application Insights in the Azure Portal under Static Web App → Settings → Application Insights.
  2. Copy the connection string.
  3. Add it to staticwebapp.config.json at the root of your project:
    {
      "navigationFallback": {
        "rewrite": "/index.html"
      },
      "logging": {
        "connectionString": "InstrumentationKey=..."
      }
    }
  4. Save the string as a GitHub secret APPINSIGHTS_CONNECTIONSTRING, if you prefer to inject it at build time.

Automated health gate

Insert a final step inside the e2e job (after Playwright) that asks App Insights for exceptions  in the last five minutes:

- name: Fail if Exceptions > 0
  uses: azure/cli@v1
  with:
    inlineScript: |
      count=$(az monitor app-insights query \
        --app MySite \
        --analytics-query "exceptions | where timestamp > ago(5m) | count" \
        --query "tables[0].rows[0][0]")

      if [ $count -gt 0 ]; then
        echo "::error::Application errors detected: $count"
        exit 1
      fi

If your deployment introduces runtime crashes, the pipeline fails, so you can roll back before customers notices.

Step 5: Secure and harden the pipeline

Treat CI/CD as part of your supply chain and harden it early.

1. Run dependency scanning (CodeQL)

Initialize and run CodeQL analysis to surface known CVEs in third-party packages.

- name: Initialize CodeQL
  uses: github/codeql-action/init@v3
  with:
    languages: csharp

- name: Run CodeQL analysis
  uses: github/codeql-action/analyze@v3

2. Enable secret scanning + push protection

Turn it on under Repo → Code Security → Secret Scanning so GitHub blocks commits that leak API keys.

3. Configure dependabot for automatic version updates

Add .github/dependabot.yml so NuGet and npm updates land as PRs, each going through the same pipeline.

4. Pin action versions

Lock actions to full commit SHAs (e.g., Azure/static-web-apps-deploy@42a7b9…) instead of @v2 to eliminate supply-chain drift.

5. Secure self‑hosted runners

Run them in a dedicated subnet without long‑lived credentials and use OIDC federation with Azure instead of PATs.

Step 6: Troubleshooting quick reference

Here are common issues and quick fixes:

  1. deployment_token was not provided
    • Double‑check the secret name.
    • It must be exactly AZURE_STATIC_WEB_APPS_API_TOKEN.
  2. 404 Static Web App not found
    • The token points to a different resource group.
    • Regenerate it from the correct Static Web App.
  3. No projects found during dotnet build
    • Your solution is in a subfolder.
    • Add working-directory: src or pass the .sln.
  4. Slow restore every run
    • Cache the NuGet folder:
      - name: Use NuGet cache
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.0.x'
          cache: true
      
  5. Playwright can’t connect
    • Ensure the SITE_URL environment variable is empty in push builds to main.
    • Read static_web_app_url, not preview_url, after a merge.

Putting it all together

Your finished .github/workflows/blazor-ci.yml now contains three jobs:

  1. Build: compiles, runs unit‑tests, publishes, and uploads artifacts.
  2. Deploy: pulls artifacts and deploys to Static Web Apps (production or PR slot).
  3. e2e: runs Playwright smoke tests and checks Application Insights for runtime errors.

A single green tick signals:

  • The code compiles on a clean machine.
  • Unit tests pass.
  • The site is live at its final URL.
  • Core pages respond correctly.
  • No new exceptions appeared.

You’ve automated all four DORA metrics: deployment frequency, lead‑time for changes (minutes), mean‑time‑to‑restore (App Insights alerts), and change‑failure rate (Playwright + unit tests).

Syncfusion Blazor components can be transformed into stunning and efficient web apps.

Conclusion

Thank you for reading! By investing just a few hours, you can replace manual ZIP uploads with a repeatable, observable, and secure CI/CD pipeline. With GitHub Actions, each commit is automatically built and tested, the compiled site is deployed to Azure Static Web Apps, Playwright smoke tests are executed, and Application Insights is checked for errors.

This streamlined setup reduces lead time, increases deployment frequency, and lowers the risk of change failure, meeting all four DORA metrics without any manual steps.

For questions or assistance, feel free to reach out via our support forumsupport portal, or feedback portal. We’re always happy to help!.

Nipuni Arunodi profile icon

Meet the Author

Nipuni Arunodi

I'm an experienced web developer And familiar with JavaScript, TypeScript, Angular, React, NodeJS, MySQL, MongoDB. I started to share my knowledge through blogs in early 2020 and the ever-changing technology trends have motivated me ever since.