Skip to content

Build and Publish Runtime NuGet Packages #77

Build and Publish Runtime NuGet Packages

Build and Publish Runtime NuGet Packages #77

Workflow file for this run

name: Build and Publish Runtime NuGet Packages
on:
workflow_dispatch:
inputs:
publish_to_nuget:
description: 'Publish to NuGet.org'
required: false
default: false
type: boolean
publish_to_github:
description: 'Publish to GitHub Packages'
required: false
default: false
type: boolean
version:
description: |
Package version to publish.
Stable release: 2026.4.23.1
Pre-release: 2026.4.23.1-preview.1
Leave empty to use the version currently in each .csproj file.
required: false
default: ''
type: string
# --- Package selection ---
pkg_GumCommon:
description: 'FlatRedBall.GumCommon'
type: boolean
default: true
pkg_GumDataTypes:
description: 'FlatRedBall.GumDataTypes'
type: boolean
default: true
pkg_ToolsUtilities:
description: 'FlatRedBall.ToolsUtilities.NetStandard'
type: boolean
default: true
pkg_MonoGame:
description: 'Gum.MonoGame'
type: boolean
default: true
pkg_KNI:
description: 'Gum.KNI'
type: boolean
default: true
pkg_FNA:
description: 'Gum.FNA'
type: boolean
default: true
pkg_SkiaSharp:
description: 'Gum.SkiaSharp'
type: boolean
default: true
pkg_SkiaSharpMaui:
description: 'Gum.SkiaSharp.Maui'
type: boolean
default: true
pkg_Raylib:
description: 'Gum.raylib'
type: boolean
default: true
pkg_ShapesMonoGame:
description: 'Gum.Shapes.MonoGame'
type: boolean
default: true
pkg_ShapesKNI:
description: 'Gum.Shapes.KNI'
type: boolean
default: true
pkg_Expressions:
description: 'Gum.Expressions'
type: boolean
default: true
pkg_ThemesMonoGame:
description: 'Gum.Themes.Editor.MonoGame'
type: boolean
default: true
pkg_ThemesKni:
description: 'Gum.Themes.Editor.Kni'
type: boolean
default: true
pkg_Sokol:
description: 'Gum.sokol'
type: boolean
default: true
pkg_GumCli:
description: 'GumCli'
type: boolean
default: true
env:
DOTNET_VERSIONS: '6.0.x;8.0.x;9.0.x' # Multiple .NET versions
CONFIGURATION: Release
SOLUTION_FILE: 'AllLibraries.sln' # Specify which solution to build
jobs:
build-and-publish:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history for version calculation
submodules: recursive # Fetch all submodules recursively
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
- name: Install required workloads
run: |
dotnet workload install wasm-tools
dotnet workload install maui
# IncludeAndroid=true forces KniGum's net9.0-android TFM to be restored, built, and
# packed. KniGum uses opt-in for Android (see KniGum.csproj); without this flag the
# published Gum.KNI nupkg would silently drop its Android TFM.
- name: Restore dependencies
run: dotnet restore ${{ env.SOLUTION_FILE }} -p:IncludeAndroid=true
- name: Compute version override
id: ver
shell: pwsh
run: |
$v = '${{ github.event.inputs.version }}'.Trim()
if ($v -ne '') {
echo "flag=-p:Version=$v" >> $env:GITHUB_OUTPUT
} else {
echo "flag=" >> $env:GITHUB_OUTPUT
}
- name: Build solution
run: dotnet build ${{ env.SOLUTION_FILE }} --configuration ${{ env.CONFIGURATION }} --no-restore -p:IncludeAnalyzers=true -p:IncludeAndroid=true ${{ steps.ver.outputs.flag }}
# Vic says - why run tests? This seems redundant since we already run tests before merging into main
# - name: Run tests
# run: dotnet test ${{ env.SOLUTION_FILE }} --configuration ${{ env.CONFIGURATION }} --no-build --verbosity normal
# Pack NuGet packages (Debug build) - includes both .nupkg and .snupkg
- name: Pack NuGet packages
run: dotnet pack ${{ env.SOLUTION_FILE }} --configuration ${{ env.CONFIGURATION }} --no-build --output ./nupkgs --include-symbols --include-source -p:IncludeAnalyzers=true -p:IncludeAndroid=true ${{ steps.ver.outputs.flag }}
# Build and pack GumCli as a dotnet tool (not in AllLibraries.sln)
- name: Build GumCli
run: dotnet build Tools/Gum.Cli/Gum.Cli.csproj --configuration ${{ env.CONFIGURATION }}
- name: Pack GumCli
run: dotnet pack Tools/Gum.Cli/Gum.Cli.csproj --configuration ${{ env.CONFIGURATION }} --no-build --output ./nupkgs ${{ steps.ver.outputs.flag }}
# Upload artifacts for inspection (both .nupkg and .snupkg)
- name: Upload NuGet packages as artifacts
uses: actions/upload-artifact@v4
with:
name: nuget-packages
path: |
./nupkgs/*.nupkg
./nupkgs/*.snupkg
# Publish to NuGet.org (when explicitly requested, filtered by package selection)
- name: Publish to NuGet.org
if: github.event.inputs.publish_to_nuget == 'true'
shell: pwsh
run: |
$selected = @()
if ('${{ github.event.inputs.pkg_GumCommon }}' -eq 'true') { $selected += 'FlatRedBall.GumCommon' }
if ('${{ github.event.inputs.pkg_GumDataTypes }}' -eq 'true') { $selected += 'FlatRedBall.GumDataTypes' }
if ('${{ github.event.inputs.pkg_ToolsUtilities }}' -eq 'true') { $selected += 'FlatRedBall.ToolsUtilities.NetStandard' }
if ('${{ github.event.inputs.pkg_MonoGame }}' -eq 'true') { $selected += 'Gum.MonoGame' }
if ('${{ github.event.inputs.pkg_KNI }}' -eq 'true') { $selected += 'Gum.KNI' }
if ('${{ github.event.inputs.pkg_FNA }}' -eq 'true') { $selected += 'Gum.FNA' }
if ('${{ github.event.inputs.pkg_SkiaSharp }}' -eq 'true') { $selected += 'Gum.SkiaSharp' }
if ('${{ github.event.inputs.pkg_SkiaSharpMaui }}' -eq 'true') { $selected += 'Gum.SkiaSharp.Maui' }
if ('${{ github.event.inputs.pkg_Raylib }}' -eq 'true') { $selected += 'Gum.raylib' }
if ('${{ github.event.inputs.pkg_ShapesMonoGame }}' -eq 'true') { $selected += 'Gum.Shapes.MonoGame' }
if ('${{ github.event.inputs.pkg_ShapesKNI }}' -eq 'true') { $selected += 'Gum.Shapes.KNI' }
if ('${{ github.event.inputs.pkg_Expressions }}' -eq 'true') { $selected += 'Gum.Expressions' }
if ('${{ github.event.inputs.pkg_ThemesMonoGame }}' -eq 'true') { $selected += 'Gum.Themes.Editor.MonoGame' }
if ('${{ github.event.inputs.pkg_ThemesKni }}' -eq 'true') { $selected += 'Gum.Themes.Editor.Kni' }
if ('${{ github.event.inputs.pkg_Sokol }}' -eq 'true') { $selected += 'Gum.sokol' }
if ('${{ github.event.inputs.pkg_GumCli }}' -eq 'true') { $selected += 'GumCli' }
Write-Host "Selected packages: $($selected -join ', ')"
Get-ChildItem "./nupkgs/*.nupkg" | ForEach-Object {
$name = $_.BaseName -replace '\.\d+\.\d+\.\d+.*$', ''
if ($selected -contains $name) {
Write-Host "Publishing $($_.Name)..."
dotnet nuget push $_.FullName --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
} else {
Write-Host "Skipping $($_.Name) (not selected)"
}
}
# Publish to GitHub Packages (when explicitly requested, filtered by package selection)
- name: Publish to GitHub Packages
if: github.event.inputs.publish_to_github == 'true'
shell: pwsh
run: |
$selected = @()
if ('${{ github.event.inputs.pkg_GumCommon }}' -eq 'true') { $selected += 'FlatRedBall.GumCommon' }
if ('${{ github.event.inputs.pkg_GumDataTypes }}' -eq 'true') { $selected += 'FlatRedBall.GumDataTypes' }
if ('${{ github.event.inputs.pkg_ToolsUtilities }}' -eq 'true') { $selected += 'FlatRedBall.ToolsUtilities.NetStandard' }
if ('${{ github.event.inputs.pkg_MonoGame }}' -eq 'true') { $selected += 'Gum.MonoGame' }
if ('${{ github.event.inputs.pkg_KNI }}' -eq 'true') { $selected += 'Gum.KNI' }
if ('${{ github.event.inputs.pkg_FNA }}' -eq 'true') { $selected += 'Gum.FNA' }
if ('${{ github.event.inputs.pkg_SkiaSharp }}' -eq 'true') { $selected += 'Gum.SkiaSharp' }
if ('${{ github.event.inputs.pkg_SkiaSharpMaui }}' -eq 'true') { $selected += 'Gum.SkiaSharp.Maui' }
if ('${{ github.event.inputs.pkg_Raylib }}' -eq 'true') { $selected += 'Gum.raylib' }
if ('${{ github.event.inputs.pkg_ShapesMonoGame }}' -eq 'true') { $selected += 'Gum.Shapes.MonoGame' }
if ('${{ github.event.inputs.pkg_ShapesKNI }}' -eq 'true') { $selected += 'Gum.Shapes.KNI' }
if ('${{ github.event.inputs.pkg_Expressions }}' -eq 'true') { $selected += 'Gum.Expressions' }
if ('${{ github.event.inputs.pkg_ThemesMonoGame }}' -eq 'true') { $selected += 'Gum.Themes.Editor.MonoGame' }
if ('${{ github.event.inputs.pkg_ThemesKni }}' -eq 'true') { $selected += 'Gum.Themes.Editor.Kni' }
if ('${{ github.event.inputs.pkg_Sokol }}' -eq 'true') { $selected += 'Gum.sokol' }
if ('${{ github.event.inputs.pkg_GumCli }}' -eq 'true') { $selected += 'GumCli' }
Write-Host "Selected packages: $($selected -join ', ')"
Get-ChildItem "./nupkgs/*.nupkg" | ForEach-Object {
$name = $_.BaseName -replace '\.\d+\.\d+\.\d+.*$', ''
if ($selected -contains $name) {
Write-Host "Publishing $($_.Name)..."
dotnet nuget push $_.FullName --api-key ${{ secrets.GITHUB_TOKEN }} --source https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json --skip-duplicate
} else {
Write-Host "Skipping $($_.Name) (not selected)"
}
}