-
-
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/
├── Changelog-ProjectGroups.ps1
├── Generate-Project-Changelogs.ps1
├── Generate-Root-Changelog.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
- Generate-Root-Changelog.ps1
- Changelog-ProjectGroups.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 |
| Generate or preview the grouped root changelog | Generate-Root-Changelog.ps1 |
| Define the project/area groups used by the root changelog | Changelog-ProjectGroups.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 per-project changelogs
Generate-Root-Changelog.ps1
│
└── maintains the grouped repository changelog
Changelog-ProjectGroups.ps1
│
└── supplies shared root-changelog grouping rules
release.ps1
│
└── freezes current changelogs into a release and creates the tag
Changelog-ProjectGroups.ps1 is a support file rather than a script a maintainer normally runs directly.
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 and maintains 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 test-only projects are intentionally excluded from per-project changelog generation.
The repository-level CHANGELOG.md remains the canonical repository-wide history, while the project changelogs provide package- and component-specific views of the same Git history.
Generate-Project-Changelogs.ps1 treats released history in an existing changelog as authoritative and the current development section as generated state.
When a project has no CHANGELOG.md yet, or the file is empty, the script bootstraps the complete project history from Git:
no CHANGELOG.md
↓
generate complete tagged history
+
generate current untagged changes
↓
create CHANGELOG.md
Without -Tag, the current commits appear under:
# [Unreleased]If -Tag vX.Y.Z is supplied during bootstrap, those current commits are written under that version instead, while older Git tags remain as historical version sections.
For an existing changelog, the script does not regenerate released sections. It removes only a leading [Unreleased] section, regenerates the current commit range from Git, and joins that generated section back to the untouched released history:
existing CHANGELOG.md
↓
preserve released history exactly
↓
remove leading [Unreleased]
↓
regenerate commits since latest tag
↓
insert fresh [Unreleased] or -Tag section
This makes normal [Unreleased] refreshes idempotent: running the generator repeatedly against unchanged Git history should produce the same changelog rather than stacking duplicate current sections.
The safest way to inspect what the script would generate is:
.\Tooling\scripts\Generate-Project-Changelogs.ps1 -PreviewOnly-PreviewOnly prints the complete resulting changelogs and does not modify files on disk.
Unreleased generation is the script's normal behavior. There is no caller-facing -Unreleased switch.
To refresh the current project changelogs:
.\Tooling\scripts\Generate-Project-Changelogs.ps1For each existing project changelog, the leading [Unreleased] section is regenerated from commits since the latest Git tag while released history remains untouched.
A version can be supplied explicitly:
.\Tooling\scripts\Generate-Project-Changelogs.ps1 -Tag v1.2.3When -Tag is supplied, the current unreleased commit range is written under that release version rather than [Unreleased].
release.ps1 uses this behavior 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"
)| Parameter | Purpose |
|---|---|
-Tag |
Stamp the current unreleased commits with a version such as v1.2.3
|
-PreviewOnly |
Print the complete resulting changelogs without changing files |
-Projects |
Override the default project list |
-CliffConfigPath |
Use a different cliff.toml configuration |
The script writes generated content through temporary files. A failed git-cliff invocation therefore does not need to overwrite an existing project changelog first.
If any git-cliff operations fail, the script collects the failed project names and reports them when processing finishes.
The root changelog has a different job from an individual project changelog.
It answers:
What has changed across Gondwana as a repository, organized by project or repository area?
Generate-Root-Changelog.ps1 maintains the leading derived section of the canonical root:
CHANGELOG.md
while preserving all existing released history.
The root generator loads its project and repository-area definitions from:
Tooling/scripts/Changelog-ProjectGroups.ps1
It then asks git-cliff for the current commits matching each group's include paths.
The result is grouped beneath the current release heading:
# [Unreleased]
## Gondwana
### Added
- ...
## Gondwana.WinForms
### Fixed
- ...
## Build / Repository
### Maintenance
- ...A commit may intentionally appear under multiple groups when it changes multiple areas.
Normal usage is:
.\Tooling\scripts\Generate-Root-Changelog.ps1The script:
- reads the existing root
CHANGELOG.md - generates the grouped current commit range since the latest Git tag
- replaces any leading
[Unreleased]section - preserves the existing versioned release history
Conceptually:
existing root CHANGELOG.md
↓
preserve released history
↓
regenerate grouped current range
↓
replace leading [Unreleased]
Unlike the project generator, the root generator deliberately does not bootstrap a missing changelog. The canonical root CHANGELOG.md must already exist and contain a recognized [Unreleased] or versioned release heading.
To preview the complete resulting file without writing it:
.\Tooling\scripts\Generate-Root-Changelog.ps1 -PreviewOnlyFor release orchestration, release.ps1 also uses the internal:
-SectionOnly
mode to obtain only the generated current section for the pre-deployment release-notes preview.
Supplying a tag converts the current grouped range into a versioned release section:
.\Tooling\scripts\Generate-Root-Changelog.ps1 -Tag v1.2.3The heading becomes conceptually:
# [v1.2.3] - 2026-09-01and the grouped project/area structure remains the same.
When a previous tag exists, a tagged root section also includes a GitHub comparison link for the full changelog range.
| Parameter | Purpose |
|---|---|
-Tag |
Stamp the generated current section with a release version |
-PreviewOnly |
Print the complete resulting root changelog without modifying it |
-SectionOnly |
Return only the generated current section; used internally by release.ps1
|
-ChangelogPath |
Use a different root changelog path |
-CliffConfigPath |
Use a different cliff.toml configuration |
Changelog-ProjectGroups.ps1 is a shared support file for grouped root changelog generation.
It defines:
project / area name
+
one or more git-cliff include paths
for entries such as:
- Gondwana
- audio packages
- Avalonia
- Blazor
- hosting
- SDL2 input
- video
- widgets
- WinForms
- CLI, MCP, templates, Studio, and other tooling
- Build / Repository
The Build / Repository group includes repository infrastructure such as GitHub workflows, Tooling/scripts, shared build files, versioning files, solution files, and the repository README.
The file is dot-sourced by Generate-Root-Changelog.ps1; it is not intended to be run directly.
Keeping the group definitions in one place matters because both running [Unreleased] generation and tagged release generation must use the same grouping rules.
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 --> PREVIEW[Generate root release-notes preview]
PREVIEW --> CONFIRM[Type DEPLOY]
CONFIRM --> ROOT[Generate root vX.Y.Z section]
ROOT --> PROJECTS[Generate project vX.Y.Z sections]
PROJECTS --> COMMIT[Commit changelog changes]
COMMIT --> VERIFY[Re-verify NBGV version]
VERIFY --> TAG[Create vX.Y.Z tag]
TAG --> PUSH[Atomically push branch + tag]
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.
The atomic push is important: the versioned changelog commit and its Git tag are published to the remote as one transaction. If either ref is rejected, neither remote ref is updated.
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 root release section is generated by:
Generate-Root-Changelog.ps1
using the shared groups defined in:
Changelog-ProjectGroups.ps1
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.
The same root generator and group definitions are used for both the running [Unreleased] section and the eventual tagged release section. This prevents development-time and release-time changelog grouping from drifting apart.
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, release.ps1 invokes both changelog generators with the resolved version tag.
First:
Generate-Root-Changelog.ps1 -Tag vX.Y.Z
replaces the root [Unreleased] block with the grouped versioned release section.
Then:
Generate-Project-Changelogs.ps1 -Tag vX.Y.Z
replaces each project's running [Unreleased] section with its project-specific versioned release section.
The root and project changelogs therefore provide complementary views:
root CHANGELOG.md
└── canonical repository-wide grouped history
project CHANGELOG.md files
└── project/package-specific histories
The script stages the root changelog and discovered project changelogs, then creates a commit with a message of the form:
docs: update changelog for vX.Y.Z
If generation produces no changelog changes, no changelog commit is created.
The release commit is not pushed by itself. The branch update and release tag are pushed together later as one atomic Git operation.
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
Before creating it, the script refreshes local knowledge of remote tags and checks both local and remote state.
If the same version tag already exists, the script recreates the local tag at the current release commit and uses a forced tag refspec when the remote tag must be replaced.
The branch and tag are then pushed together with an atomic Git push:
release commit at HEAD
+
vX.Y.Z tag at HEAD
↓
git push --atomic
If either ref update is rejected, the remote branch and remote tag are both left unchanged. This prevents a versioned changelog commit from reaching master without its corresponding release tag, or vice versa.
Once the atomic push succeeds:
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.
Gondwana's changelog/release system now has several cooperating pieces:
Changelog-ProjectGroups.ps1
Generate-Root-Changelog.ps1
Generate-Project-Changelogs.ps1
.github/workflows/changelog-master.yml
release.ps1
.github/workflows/release.yml
Their responsibilities are deliberately separated.
Answers:
Which project and repository areas should appear in the grouped root changelog, and which paths belong to each one?
It provides shared grouping configuration and is not run directly.
Answers:
What changed across Gondwana as a whole since the latest tag?
It maintains the grouped root [Unreleased] section during development and converts that same current range into a versioned root release section when -Tag is supplied.
Answers:
What changed in each individual project?
It maintains the corresponding project changelogs, preserving released history and regenerating the current development range.
Answers:
New development changes reached
master. Do the running changelogs need to be refreshed?
After a non-changelog push to master, it runs both changelog generators.
If the generated files changed, the workflow opens or updates an automation pull request on:
automation/update-changelogs
containing only CHANGELOG.md files and enables auto-merge for that PR.
Changelog-only pushes are ignored, which prevents the automation from recursively triggering itself. The update job is also concurrency-grouped so a newer master update can supersede an older in-progress changelog refresh.
The same workflow also validates changelog behavior on relevant pull requests, including preview safety, idempotence, root grouping, missing project changelog bootstrap, and tagged generation.
Answers:
Is the repository ready to release, what version is it, and what release tag should be pushed?
It performs local validation, previews the root release notes, freezes root and project current sections under the NBGV-derived version, commits them, creates the tag, and atomically pushes the branch and tag.
Answers:
A release tag now exists. How do we build and publish it?
It performs the remote release build and publication.
During normal development:
commit reaches master
↓
changelog-master.yml
↓
Generate-Root-Changelog.ps1
+
Generate-Project-Changelogs.ps1
↓
automation changelog PR
↓
auto-merge
↓
root + project [Unreleased] sections stay current
During a release:
release.ps1
├── root vX.Y.Z section
├── project vX.Y.Z sections
├── changelog commit
└── vX.Y.Z tag
↓
atomic push
↓
release.yml
├── GitHub Release
├── NuGet
├── GitHub Packages
└── API documentation
The central distinction is:
normal development → refresh derived [Unreleased] state
release → freeze that state into vX.Y.Z and publish it
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 main layers, with GitHub Actions automating the changelog and publication boundaries.
DEVELOPMENT ENVIRONMENT
└── Setup-Gondwana-Dev.ps1
prepares the machine
LOCAL ITERATION
├── Reinstall-Gondwana-Cli.ps1
└── Reinstall-Gondwana-Templates.ps1
test unpublished local packages
CHANGELOG / RELEASE MANAGEMENT
├── Changelog-ProjectGroups.ps1
│ defines root changelog grouping
├── Generate-Root-Changelog.ps1
│ maintains repository-wide history
├── Generate-Project-Changelogs.ps1
│ maintains project-specific history
└── release.ps1
freezes current history into a version and starts deployment
Around those scripts, GitHub Actions provides two automation boundaries:
master commit
↓
changelog-master.yml
↓
refresh root + project [Unreleased]
↓
automation PR / auto-merge
release tag
↓
release.yml
↓
build and publish the release
Or, even more simply:
Setup prepares the developer.
Reinstall scripts test local tooling.
Changelog keeps current development history derived from Git.
Release freezes 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