Introduction
When publishing a Blazor WASM app, and providing that there is no server element, all the files are static and (providing you avoid Github's prohibited uses), free.
The post is intended to save you all the pain I've just been through working it all out. It does use some best practices around versioning and tagging, which you can choose to use or not.
If you choose not to use them, you can skip the next section.
Versions and Tags
The way I choose to version my projects is with NerdBank Gitversioning:
If you're not already using it, you DO want this. It versions your code based on two things:
- Your declared base version from a version.json file in your solution root
- The "Git height" (the number of commits since the version.json files changed)
My version file looks like this:
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
"version": "0.1",
"publicReleaseRefSpec": [
"^refs/heads/main",
"^refs/heads/release/v\\d+(?:\\.\\d+)?$"
]
}
For this example, I'm versioning at v0.1. Just replace the 0.1 in red above with the minor version that you're currently on.
Next, let's look at tagging. You don't want to publish every time you do a commit. Some people like to commit to a release branch and use that for their Continuous Integration / Continuous Deployment (CI/CD). Me, I like to release when I tag.
So here's the Powershell that I use for automatic tagging based on the Git versioning. Save the following as Tag.Ps1:
#Tag.ps1
$ErrorActionPreference = "Stop"
# This script will tag the current commit and push it to the origin
# Note: If nbgv (the Nerdbank Gitversioning executable) does not work then install it using either of the following
#dotnet tool install -g nbgv
#dotnet tool update -g nbgv
# Ensure to get latest changes on the branch to ensure we're at the correct git height
git pull
if (git status --porcelain) {
Write-Error "Git repo is not clean. Ensure any changes have been committed."
exit 1;
}
$nbgvVersion = nbgv get-version -v Version
$versionParts = $nbgvVersion.Split(".")
$versionString = $versionParts[0] + "." + $versionParts[1] + "." + $versionParts[2];
Write-Host("Tagging as " + $versionString);
git tag -a "$versionString" -m "Tagged version ${versionString}"
Write-Host("Pushing tag...");
git push origin $versionString
---
When this file doesn't run due to it not being signed, research how to do this yourself. I'm not going to include that here, as this is a security issue and you need to
Again, use this or not - entirely up to you.
Github action
Github is able to detect certain events and run workflows based on them. These workflows are stored in your solution's ".github/workflows" folder as .yml files. You can simply create that folder, create a file and Github will automatically detect and use it.
The following workflow detects a tag push for 0.1.* and runs. It does everything needed to build your solution and publish it to Github pages:
name: Deploy Blazor WASM to GitHub Pages
on:
push:
tags: [0.1.*]
jobs:
deploy-to-github-pages:
runs-on: ubuntu-latest
steps:
# Uses GitHub's checkout action to checkout code form the main branch
- uses: actions/checkout@v2
with:
fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
# Sets up .NET Core SDK 7.x
- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: 7.x
include-prerelease: false
# Publishes Blazor project to the release-folder
- name: Publish .NET Core Project
run: dotnet publish PanoramicData.JsonMagic.Web/PanoramicData.JsonMagic.Web.csproj -c Release -o release --nologo
# Copy index.html to 404.html to serve the same file when a file is not found
- name: copy index.html to 404.html
run: cp release/wwwroot/index.html release/wwwroot/404.html
# Add .nojekyll file to tell GitHub pages to not treat this as a Jekyll project. (Allow files and folders starting with an underscore)
- name: Add .nojekyll file
run: touch release/wwwroot/.nojekyll
# Deploy to GitHub pages
- name: Deploy wwwroot to GitHub Pages
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BASE_BRANCH: main # The branch the action should deploy from.
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: release/wwwroot
SINGLE_COMMIT: true
Note that James Ives' script takes the output from the main branch and publishes it onto the gh-pages branch. In other words, one of your branches (which you will have to create) doesn't have your code on it, it has your output on it.
If you want to execute on every push, you can replace:
on:
push:
tags: [0.1.*]
...with (for example):
on:
push:
branches:
- production
Github config
Great, so this will work, yes? Well nearly. The next thing you have to do is to attach the Github Page to your gh-pages branch. Just set it up to look like this on Github (under Settings / Pages). Note that the custom URL is optional. If you don't have access to DNS, you can simply use the URL provided by Github, which will be in the form:
- https://panoramicdata.github.io/PanoramicData.JsonMagic
To do this, go to
Settings -> Action -> General -> Workflow permissions
and choose read and write permissions
Now, when you run Tag.ps1, the tag will trigger the GitHub Action, which will publish to your site! You can track progress on the GitHub Actions page.