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:
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.
Before you create the workflow, make sure you have the following in place:
main as the default branch.ubuntu-latest) work out of the box.AZURE_STATIC_WEB_APPS_API_TOKEN.You can find the full example and YAML configuration in the GitHub repo.
Begin by creating a folder named .github/workflows at the root of your repository. Inside it, add a file called blazor-ci.yml.
dotnet build compiles the code, and dotnet publish generates the static wwwroot folder that Azure needs. --collect switch stores coverage data so you can upload it to a badge service or track change‑failure rate trends later.publish/wwwroot saves about 30 seconds in the deploy job because you avoid rebuilding.Next, add a second job within the same YAML file, immediately after the build job.
The needs keyword ensures that the deploy job runs only if the build job succeeds. If tests fail, the pipeline stops.
wwwroot, uploads it to the production slot, and waits for Azure to finish the swap.static_web_app_url (production) and preview_url (for PRs). Save these for Playwright tests.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.
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.
Static Web Apps integrates with Application Insights out of the box. Here’s what you do:
staticwebapp.config.json at the root of your project: {
"navigationFallback": {
"rewrite": "/index.html"
},
"logging": {
"connectionString": "InstrumentationKey=..."
}
} APPINSIGHTS_CONNECTIONSTRING, if you prefer to inject it at build time.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.
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.
Here are common issues and quick fixes:
- name: Use NuGet cache
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
cache: true
Your finished .github/workflows/blazor-ci.yml now contains three jobs:
A single green tick signals:
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).
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 forum, support portal, or feedback portal. We’re always happy to help!.