-
-
Notifications
You must be signed in to change notification settings - Fork 2
Tooling Scripts
Gondwana includes a small set of PowerShell scripts for repository maintenance, local development, changelog generation, and releases.
They live under:
Tooling/scripts/
├── Generate-Project-Changelogs.ps1
├── Reinstall-Gondwana-Cli.ps1
├── Reinstall-Gondwana-Templates.ps1
├── Setup-Gondwana-Dev.ps1
└── release.ps1
These are maintainer and contributor tools. They are not part of the Gondwana runtime and are not required by games that consume Gondwana through NuGet.
Their purpose is to make common repository operations repeatable instead of relying on somebody remembering the right sequence of dotnet, Git, NuGet, git-cliff, and other commands.
- Which script should I use?
- Running the scripts
- Setup-Gondwana-Dev.ps1
- Reinstall-Gondwana-Cli.ps1
- Reinstall-Gondwana-Templates.ps1
- Generate-Project-Changelogs.ps1
- release.ps1
- How the release scripts fit together
- Local packages and caching
- Safety and failure behavior
- Mental model
| Goal | Script |
|---|---|
| Set up a new Gondwana development machine | Setup-Gondwana-Dev.ps1 |
Test changes to the gondwana CLI locally |
Reinstall-Gondwana-Cli.ps1 |
Test changes to Gondwana dotnet new templates locally |
Reinstall-Gondwana-Templates.ps1 |
| Generate or preview project-specific changelogs | Generate-Project-Changelogs.ps1 |
| Prepare and start an official Gondwana release | release.ps1 |
A useful distinction is:
Setup-Gondwana-Dev.ps1
│
└── prepares a machine
Reinstall-*.ps1
│
└── supports local development
Generate-Project-Changelogs.ps1
│
└── maintains release history
release.ps1
│
└── initiates an official release
From the repository root, a script can be invoked with its repository-relative path:
.\Tooling\scripts\Setup-Gondwana-Dev.ps1or:
.\Tooling\scripts\release.ps1 -PreviewOnlyThe scripts resolve the Gondwana repository root from their own location, so they do not depend heavily on the shell's current working directory.
That is intentional.
A maintenance script should know where the repository is because of where the script lives, rather than assuming the user happened to open PowerShell in exactly the right directory.
Most of the scripts explicitly require PowerShell 5.1 or later.
This is the bootstrap script for a Gondwana development environment.
Its intended use is:
Clone Gondwana, run one script, and get the machine as close as possible to ready for development.
It is designed to be idempotent: running it again should update, restore, or verify existing tools rather than assuming the machine is empty.
Basic usage:
.\Tooling\scripts\Setup-Gondwana-Dev.ps1The script performs thirteen numbered checks or setup operations.
It first verifies that:
git
is available on PATH.
Git is a hard prerequisite. If it cannot be found, setup stops.
The script verifies that a .NET 8 SDK is installed.
On Windows, if it is missing and winget is available, the script attempts to install:
Microsoft.DotNet.SDK.8
automatically.
On other platforms, it reports that .NET 8 must be installed through the platform's normal package-management mechanism or the .NET installer.
Gondwana contains a .NET tool manifest.
The setup script restores those tools using:
dotnet tool restoreThis includes tooling such as Nerdbank.GitVersioning (nbgv).
The complete Gondwana solution is restored in Release configuration with:
EnableWindowsTargeting=true
This is important because the solution contains Windows-targeted projects even when some development or CI work occurs outside Windows.
The restore also forces dependency reevaluation rather than simply trusting a potentially stale local cache.
Unless disabled, the script builds:
Gondwana.sln
in:
Release
configuration.
This turns setup into more than a dependency installer.
It also provides an immediate sanity check:
Can this machine actually build Gondwana?
To skip this step:
.\Tooling\scripts\Setup-Gondwana-Dev.ps1 -SkipBuildThe script checks for the global:
Gondwana.Cli
.NET tool.
If it is missing, it installs it.
If it already exists, the script attempts to update it.
It also handles the case where the configured package source contains an older version than the version already installed. In that situation, setup keeps the newer installed version rather than treating the attempted downgrade as fatal.
The global command provided by the package is:
gondwana
The script similarly checks for:
Gondwana.Templates
and installs or updates the template package.
These are the templates used by commands such as Gondwana's dotnet new project templates.
If a newer local template package is already installed than the configured source provides, setup is intended to preserve the current installation rather than blindly downgrade it.
Steps 8 through 12 can be skipped with:
.\Tooling\scripts\Setup-Gondwana-Dev.ps1 -SkipOptionalThis is useful when only the core repository dependencies are needed.
The script checks for the .NET:
wasm-tools
workload.
If missing, it installs it.
If already present, installed workloads are updated.
This supports Gondwana's Blazor/WebAssembly development path.
The script checks for SDL2 native binaries used by:
Gondwana.Input.SDL2
If SDL2 is not detected, setup prints guidance rather than treating it as a fatal error.
That is because SDL2 is only required when using the SDL2 input package.
The script checks for LibVLC, used by:
Gondwana.Video
On Windows, when LibVLC is missing and winget is available, setup attempts to install VLC:
VideoLAN.VLC
If automatic installation is unavailable or fails, the script reports manual installation guidance.
Again, this is an optional subsystem dependency rather than a requirement for the Gondwana core engine.
Gondwana uses:
git-cliff
for changelog generation.
Setup verifies that it exists.
On Windows, it can install or update it through:
winget
using the orhun.git-cliff package.
git-cliff is especially important to the release scripts described later on this page.
butler is itch.io's command-line publishing tool.
If it is missing, the script attempts to download the appropriate current binary from itch.io's Broth CDN.
The script supports platform-specific packages for:
- Windows
- Linux
- macOS
and installs Butler under a user-local itch directory.
Typical locations are:
%LOCALAPPDATA%\itch\butler
on Windows and:
~/.itch/butler
on Unix-like systems.
The installation directory is added to PATH for the current PowerShell session.
The script also reminds the developer that it should be added permanently if Butler is expected to be available in future shells.
Authentication is then performed separately with:
butler loginFinally, setup runs:
gondwana doctorwhen the command is available.
This provides an end-of-setup health check rather than simply assuming that every preceding installation produced a usable environment.
Conceptually:
install / restore / verify
↓
build Gondwana
↓
check optional tools
↓
gondwana doctor
| Parameter | Purpose |
|---|---|
-SkipBuild |
Skip the Release build |
-SkipOptional |
Skip WASM, SDL2, LibVLC, git-cliff, and Butler setup |
For a minimal bootstrap:
.\Tooling\scripts\Setup-Gondwana-Dev.ps1 -SkipBuild -SkipOptionalFor a complete development environment:
.\Tooling\scripts\Setup-Gondwana-Dev.ps1This script exists for local CLI development.
Normally, installing the Gondwana CLI looks something like:
dotnet tool install --global Gondwana.CliThat obtains a package from a configured package source.
That is not what you want while actively editing:
Tooling/Gondwana.Cli
because your newest changes have not necessarily been published anywhere.
Reinstall-Gondwana-Cli.ps1 solves that problem.
The script:
- packs the local
Gondwana.Cliproject - places the resulting package in a local package directory
- detects whether
Gondwana.Cliis currently installed globally - uninstalls the existing global tool if necessary
- clears the cached
gondwana.clipackage - installs the newly packed local package globally
- attempts to display the installed
gondwana --version
Conceptually:
flowchart LR
SRC[Gondwana.Cli source] --> PACK[dotnet pack]
PACK --> FEED[Local NuGet directory]
OLD[Installed CLI] --> REMOVE[Uninstall]
FEED --> INSTALL[Install global tool]
REMOVE --> INSTALL
INSTALL --> CMD[gondwana]
NuGet caching is normally a good thing.
During local package development, however, repeatedly producing packages with the same version number can cause an older cached package to be reused.
The CLI reinstall script explicitly removes the local cached:
gondwana.cli
package before installing.
That helps ensure:
"Install my local CLI" actually means the CLI that was just packed.
.\Tooling\scripts\Reinstall-Gondwana-Cli.ps1The default configuration is:
Release
and the default local package directory is:
.local-nuget
at the repository root.
Select the build configuration used by dotnet pack.
For example:
.\Tooling\scripts\Reinstall-Gondwana-Cli.ps1 -Configuration DebugSelect another local package directory:
.\Tooling\scripts\Reinstall-Gondwana-Cli.ps1 `
-PackageOutput artifacts\local-toolsRelative paths are resolved from the Gondwana repository root.
Use this script when changing things such as:
- Gondwana CLI commands
gondwana doctor- CLI argument handling
- CLI output
- CLI project creation or utility behavior
It is a development loop:
edit CLI
↓
run Reinstall-Gondwana-Cli.ps1
↓
run gondwana ...
↓
inspect result
↓
edit again
No public NuGet release is required.
This is the template equivalent of the CLI reinstall script.
It exists for development of:
Tooling/Gondwana.Templates
without publishing a new template package first.
The script:
- packs
Gondwana.Templates - identifies the exact
.nupkgit just produced - determines that package's version
- detects and uninstalls any currently installed
Gondwana.Templates - creates an isolated temporary NuGet package cache
- installs the freshly packed package directly
- verifies the installed template package
- lists available Gondwana templates
- restores the caller's original
NUGET_PACKAGESenvironment - removes its temporary cache
The temporary cache is particularly important.
It isolates the reinstall operation from whatever versions NuGet may already have stored globally.
.\Tooling\scripts\Reinstall-Gondwana-Templates.ps1After installation, the script runs the equivalent of:
dotnet new list gondwanaso the developer can immediately see the Gondwana templates currently registered with the .NET template system.
The same two main development parameters are available as the CLI script.
.\Tooling\scripts\Reinstall-Gondwana-Templates.ps1 `
-Configuration Debug.\Tooling\scripts\Reinstall-Gondwana-Templates.ps1 `
-PackageOutput artifacts\local-templatesThe default package directory is again:
.local-nuget
They solve similar problems but target two different .NET mechanisms.
| Script | Installation mechanism |
|---|---|
Reinstall-Gondwana-Cli.ps1 |
dotnet tool |
Reinstall-Gondwana-Templates.ps1 |
dotnet new |
The CLI becomes a command:
gondwana
The templates become entries available to:
dotnet new
Gondwana is a repository containing many separately meaningful projects.
A root changelog answers:
What changed in Gondwana as a whole?
But somebody consuming only:
Gondwana.WinForms
may instead want to know:
What changed in Gondwana.WinForms?
Generate-Project-Changelogs.ps1 creates those project-specific histories.
The script uses:
git-cliff
with Gondwana's repository-level:
cliff.toml
configuration.
Each project is processed with an --include-path filter.
Conceptually:
all repository commits
│
├── touched Gondwana/** ?
│ └── Gondwana/CHANGELOG.md
│
├── touched Gondwana.Widgets/** ?
│ └── Gondwana.Widgets/CHANGELOG.md
│
└── touched Gondwana.WinForms/** ?
└── Gondwana.WinForms/CHANGELOG.md
This is intentional.
Suppose a commit changes both:
Gondwana/**
and:
Gondwana.WinForms/**
That commit may legitimately appear in both project changelogs.
This is not duplication in the bookkeeping sense.
Each changelog answers a different question:
Did this change affect this project?
For both projects, the answer is yes.
The script contains a default project list covering Gondwana library and tooling projects.
Demos and the unit-test project are intentionally excluded from this per-project changelog generation.
The root CHANGELOG.md remains the canonical repository-wide release history.
When a project has no changelog yet, the script uses git-cliff in normal output mode so the initial changelog header is generated.
Conceptually:
no CHANGELOG.md
↓
create complete changelog
For an existing changelog, it uses prepend behavior:
existing CHANGELOG.md
↓
prepend newest release
↓
retain previous history
This keeps newest releases at the top.
The safest way to inspect what the script would generate is:
.\Tooling\scripts\Generate-Project-Changelogs.ps1 `
-Unreleased `
-PreviewOnly-PreviewOnly writes the generated result to the console and does not modify the changelog files.
To actually write the current unreleased changes:
.\Tooling\scripts\Generate-Project-Changelogs.ps1 -UnreleasedA version can be supplied explicitly:
.\Tooling\scripts\Generate-Project-Changelogs.ps1 `
-Tag v1.2.3 `
-UnreleasedThe release script uses this form when preparing an official Gondwana release.
For development or testing, a subset can be requested:
.\Tooling\scripts\Generate-Project-Changelogs.ps1 `
-Projects @(
"Gondwana",
"Gondwana.WinForms"
) `
-Unreleased| Parameter | Purpose |
|---|---|
-Tag |
Version tag passed to git-cliff
|
-Unreleased |
Restrict output to changes since the previous release |
-PreviewOnly |
Print output without changing files |
-Projects |
Override the default project list |
-CliffConfigPath |
Use a different cliff.toml configuration |
If any git-cliff operations fail, the script collects the failed project names and reports them when processing finishes.
release.ps1 is the local release orchestrator.
It is deliberately more conservative than the development scripts because running it can lead to packages being published publicly.
The critical distinction is:
release.ps1prepares and pushes the release tag.
It does not directly publish Gondwana to NuGet.
Pushing the version tag triggers Gondwana's GitHub Actions release.yml workflow, which performs the actual remote release build and publication.
flowchart TD
DEV[release.ps1] --> CHECKS[Pre-flight checks]
CHECKS --> TESTS[Gondwana.Tests]
TESTS --> VERSION[NBGV version]
VERSION --> NOTES[Generate changelogs]
NOTES --> CONFIRM[Type DEPLOY]
CONFIRM --> COMMIT[Commit changelog changes]
COMMIT --> TAG[Create vX.Y.Z tag]
TAG --> PUSH[Push tag to GitHub]
PUSH --> ACTIONS[GitHub Actions release.yml]
ACTIONS --> GH[GitHub Release]
ACTIONS --> NUGET[NuGet.org]
ACTIONS --> PACKAGES[GitHub Packages]
ACTIONS --> DOCS[Published API docs]
The local script and the GitHub workflow therefore form two halves of one release system.
Before allowing a normal release, the script verifies several conditions.
These include:
- Git is installed
- .NET is installed
-
nbgvis installed -
git-cliffis installed -
cliff.tomlexists - the current directory belongs to a Git repository
- the required release branch is checked out
- local repository state has been refreshed from the remote
- local
mastermatches remotemaster - there are no unstaged changes
- there are no staged-but-uncommitted changes
By default, the required branch is:
master
and the remote is:
origin
Before creating the release, the script runs:
Testing/Gondwana.Tests/Gondwana.Tests.csproj
in Release configuration.
If the tests fail:
release stops
There is no "publish it anyway" path built into the normal script.
That is exactly where a release script should be stubborn.
The script asks Nerdbank.GitVersioning for:
NuGetPackageVersion
and constructs the Git tag from that version.
For example:
NuGetPackageVersion = 1.4.2
↓
v1.4.2
The release version is therefore derived from the repository's versioning configuration rather than being manually typed into the release command.
The release script creates a grouped root release section.
It organizes changes by project or repository area, including sections such as:
- Gondwana
- audio projects
- Avalonia
- Blazor
- hosting
- SDL2 input
- video
- widgets
- WinForms
- tooling projects
- build/repository changes
Each group asks git-cliff for changes touching the paths assigned to that group.
Groups are deliberately allowed to overlap.
A commit affecting two components can belong under both component headings.
git-cliff generates category headings of its own.
Because release.ps1 places those beneath project headings, it demotes the generated Markdown headings by one level.
Conceptually:
## Gondwana.WinForms
### Added
### Fixedrather than having the project's heading and the changelog category compete at the same Markdown level.
When a previous release tag exists, the generated root section ends with a comparison link conceptually equivalent to:
previous tag ... new tag
on GitHub.
That provides a direct path from the human-readable changelog to the complete Git diff.
Before doing a real release, use:
.\Tooling\scripts\release.ps1 -PreviewOnlyPreview mode still performs meaningful validation and changelog generation so the proposed release can be inspected.
But it does not:
- write the changelogs
- create a changelog commit
- create a Git tag
- push anything
- trigger deployment
This should normally be the first release command run.
A real release requires an explicit confirmation.
The script asks the maintainer to type:
DEPLOY
exactly.
Anything else cancels the operation.
That is intentionally harder to trigger than a simple Y.
The command sits immediately before operations that can ultimately result in an immutable public NuGet release.
After confirmation, the script updates the root:
CHANGELOG.md
and then invokes:
Generate-Project-Changelogs.ps1
to update individual project changelogs.
It stages all generated changelog changes and creates a commit with a message of the form:
docs: update changelog for vX.Y.Z
That commit is pushed to the required branch before the tag is created.
After committing the changelog, the script asks NBGV for the version again.
The value is expected to remain unchanged.
If the changelog commit unexpectedly changes the calculated version, the script aborts before tagging.
This protects against releasing:
version calculated before commit
while the actual tag points at a commit whose calculated version is something different.
The final local release operation is the version tag.
The tag follows:
v<version>
For example:
v1.4.2
The script checks both local and remote tag state.
If the same version tag already exists, the current script deliberately removes and replaces it before pushing the new tag.
That is powerful behavior and is one reason release.ps1 should be treated as release infrastructure rather than a casual utility script.
Once the tag is pushed:
GitHub receives vX.Y.Z
↓
.github/workflows/release.yml runs
At that point, publication is handed off to GitHub Actions.
| Parameter | Default | Purpose |
|---|---|---|
-Remote |
origin |
Git remote used for synchronization and push |
-RequiredBranch |
master |
Branch required for a normal release |
-ChangelogPath |
CHANGELOG.md |
Root changelog location |
-CliffConfigPath |
cliff.toml |
git-cliff configuration |
-PreviewOnly |
off | Validate and preview without deployment |
For almost all normal Gondwana releases, the intended sequence is simply:
.\Tooling\scripts\release.ps1 -PreviewOnlyinspect the result, then:
.\Tooling\scripts\release.ps1and type:
DEPLOY
when satisfied.
There are three different pieces involved in Gondwana's changelog/release system:
Generate-Project-Changelogs.ps1
release.ps1
.github/workflows/release.yml
Their responsibilities are different.
Answers:
What changed in each individual project?
and writes the corresponding project changelogs.
Answers:
Is the repository ready to release, what version is it, and what release tag should be pushed?
It performs local validation, writes changelogs, commits them, and creates the tag.
Answers:
A release tag now exists. How do we build and publish it?
It performs the remote release build and publication.
Together:
git history
↓
git-cliff
↓
release.ps1
├── root changelog
├── project changelogs
├── changelog commit
└── vX.Y.Z tag
↓
GitHub Actions
├── GitHub Release
├── NuGet
├── GitHub Packages
└── API documentation
The two Reinstall-* scripts exist partly because package caches are designed for released packages, not rapid iteration.
Normally:
package ID + package version
should uniquely identify package contents.
During development, however, it is convenient to repeatedly build:
Gondwana.Cli 1.2.3
without incrementing the version after every edit.
That creates a problem:
same package ID
+ same version
+ different local contents
NuGet may reasonably assume it already has that package.
The development scripts therefore take explicit measures to avoid stale package reuse.
The CLI script clears the cached CLI package before reinstalling.
The template script goes further and temporarily points:
NUGET_PACKAGES
at an isolated temporary directory.
After installation, it restores the previous environment and deletes the temporary cache.
This behavior is development-specific.
Published package versions should remain immutable.
These scripts generally use:
$ErrorActionPreference = 'Stop'and command wrappers that inspect:
$LASTEXITCODE
for external programs.
That means failures are intended to stop the operation rather than quietly allowing later steps to continue from an invalid state.
This is particularly important for:
- builds
- tests
- Git operations
- package installation
- changelog generation
- releases
The reinstall scripts modify local developer state:
global .NET tool installation
template installation
local package caches
If something goes wrong, the operation can normally be repeated.
A release can ultimately create:
- Git commits
- remote Git tags
- GitHub Releases
- NuGet packages
A published NuGet package version cannot simply be overwritten with different contents later.
For that reason:
release.ps1
contains substantially more validation and confirmation than the local development scripts.
Use:
-PreviewOnlybefore a real deployment.
The scripts fall into three layers.
DEVELOPMENT ENVIRONMENT
└── Setup-Gondwana-Dev.ps1
prepares the machine
LOCAL ITERATION
├── Reinstall-Gondwana-Cli.ps1
└── Reinstall-Gondwana-Templates.ps1
test unpublished local packages
RELEASE MANAGEMENT
├── Generate-Project-Changelogs.ps1
└── release.ps1
prepare repository history and start deployment
Or, even more simply:
Setup prepares the developer.
Reinstall scripts test local tooling.
Changelog records what changed.
Release turns that history into a versioned deployment.
None of these scripts are required to run a Gondwana game.
They exist to make development and release engineering around the engine predictable, repeatable, and considerably less dependent on somebody remembering seventeen shell commands in exactly the right order.
- Home
- Make Your First Game in 30 Minutes
- Engine Architecture Overview
- Gondwana Engine Lifecycle
- Gondwana CLI Cheatsheet
- Assets Files
- Tilesheets
- Scenes and SceneLayers
- Sprites
- Views, Cameras, and Viewports
- DirectDrawing
- Game State Files
- Logging
- Movement and Controllers
- Input Handling
- Collision Detection
- Timers and Engine Timing
- Using the Effects System
- Engine Configuration