26. Build, publish, and deploy

Goal

Why this matters

Prerequisites

1. Build vs publish

2. Avalonia build tooling & project file essentials

Avalonia ships MSBuild targets that compile XAML and pack resources alongside your assemblies. Understanding them keeps design-time and publish-time behavior in sync.

<ItemGroup>
  <AvaloniaResource Include="Assets/**" />
  <AvaloniaResource Include="Themes/**/*.axaml" />
</ItemGroup>

3. Runtime identifiers (RIDs)

Common RIDs:

4. Publish configurations

Framework-dependent (requires installed .NET runtime)

dotnet publish -c Release -r win-x64 --self-contained false

Smaller download; target machine must have matching .NET runtime. Good for enterprise scenarios.

Self-contained (bundled runtime)

dotnet publish -c Release -r osx-arm64 --self-contained true

Larger download; runs on machines without .NET. Standard for consumer apps.

Single-file

dotnet publish -c Release -r linux-x64 /p:SelfContained=true /p:PublishSingleFile=true

Creates one executable (plus a few native libraries depending on platform). Avalonia may extract resources native libs to temp; test startup.

ReadyToRun

dotnet publish -c Release -r win-x64 /p:SelfContained=true /p:PublishReadyToRun=true

Precompiles IL to native code; faster cold start at cost of larger size. Measure before deciding.

Trimming (advanced)

dotnet publish -c Release -r osx-arm64 /p:SelfContained=true /p:PublishTrimmed=true

Aggressive size reduction; risky because Avalonia/XAML relies on reflection. Requires careful annotation/preservation with DynamicDependency or ILLinkTrim files. Start without trimming; enable later with thorough testing.

Publish options matrix (example)

Option Pros Cons
Framework-dependent Small Requires runtime install
Self-contained Runs anywhere Larger downloads
Single-file Simple distribution Extracts natives; more memory
ReadyToRun Faster cold start Larger size
Trimmed Smaller Risk of missing types

5. Output directories and manifest validation

Publish outputs to bin/Release/<TFramework>/<RID>/publish.

Examples:

Verify resources (images, fonts) present; confirm AvaloniaResource includes them. Use dotnet publish /bl:publish.binlog and inspect the binlog with MSBuild Structured Log to confirm each resource path is copied.

6. Asset packing and resources

7. Platform packaging

Windows

macOS

Linux

Android

iOS

Browser (WASM)

8. Automation (CI/CD)

jobs:
  publish:
    runs-on: $
    strategy:
      matrix:
        include:
          - os: windows-latest
            rid: win-x64
          - os: macos-latest
            rid: osx-arm64
          - os: ubuntu-latest
            rid: linux-x64
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.0.x'
      - name: Restore workloads
        run: dotnet workload restore
      - name: Publish
        run: |
          dotnet publish src/MyApp/MyApp.csproj \
            -c Release \
            -r $ \
            --self-contained true \
            /p:PublishSingleFile=true \
            /p:InformationalVersion=$
      - name: Collect binlog on failure
        if: failure()
        run: dotnet publish src/MyApp/MyApp.csproj -c Release -r $ /bl:publish-$.binlog
      - uses: actions/upload-artifact@v4
        with:
          name: myapp-$
          path: src/MyApp/bin/Release/net8.0/$/publish
      - name: Upload binlog
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: publish-logs-$
          path: publish-$.binlog

9. Verification checklist

10. Troubleshooting

Problem Fix
Missing native libs on Linux Install required packages (libicu, fontconfig, libx11, etc.). Document dependencies.
Startup crash only in Release Enable logging to file; check for missing assets; ensure AvaloniaResource includes.
High CPU at startup Investigate ReadyToRun vs normal build; pre-load data asynchronously vs synchronously.
Code signing errors (macOS/Windows) Confirm certificates, entitlements, notarization steps.
Publisher mismatch (store upload) Align package IDs, manifest metadata with store requirements.
CompileAvaloniaXamlTask failure Clean obj/, fix XAML build errors, and examine the /bl binlog to inspect generated task arguments.
Native dependency failure (Skia/WASM) Use ldd/otool/wasm-ld reports to list missing libraries; bundle them or switch to self-contained publishes.

11. Practice exercises

  1. Publish self-contained builds for win-x64, osx-arm64, linux-x64. Run each and note size/performance differences.
  2. Enable PublishSingleFile and PublishReadyToRun for one target; compare startup time and size.
  3. Experiment with trimming on a small sample; protect reflective types with DynamicDependency or ILLinkTrim descriptors and verify at runtime.
  4. Set up a GitHub Actions workflow to publish RID-specific artifacts, collect binlogs on failure, and attach a checksum file.
  5. Optional: create MSIX (Windows) or DMG (macOS) packages, sign them, and run locally to test installation/updates.
  6. Bonus: add a custom MSBuild target that zips the publish folder and uploads a checksum to your CI artifacts.

Look under the hood (source & docs)

Check yourself

What's next