Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Automated Versioning and Releases

traunts edited this page Sep 10, 2023 · 10 revisions

Intro

Source Codebase Data Codebase Composite changes game version

Motivation

The main motivations for these changes are:

  • Merging the Source and Data repositories so that changes that affect both of them are unified in single Pull Requests.

    Currently, if Source changes are made that require follow-up Data changes then a PR must be opened, reviewed and merged separately in each repo (and vice versa)

    The current approach to this is careful manual synchronisation of two pull requests across two repositories, but this promotes certain issues.

    The lack of coupling is undesirable as it:

    • reduces the human visibility of a set of changes that affect both codebases, as they require two pull requests with two separate reviews
    • adds overhead to the contribution, for the same reasons as above
    • can lead to a desynchronised repository state, where Source changes have been approved and merged but the Data changes have not, leaving the game effectively "broken" on the development branch
    • severely limits the viability of the unified versioning scheme discussed in this document, as outlined below

    If merged, the two codebases will still reside in directories independent of each other. As such, this unification will not increase the number of merge conflicts that a contributor experiences, even with high commit frequency to both codebases.

    Specifically, Data/Source changes will only conflict with commits against their respective codebase, so the inclusion of the Data codebase will not affect Source commit history.
    If composite work experiences merge conflicts, those conflicts would occur in any case with the current setup.

  • Achieving the unified codebase required to version the game as a whole

    When trying to version the packaged game, we run into an issue caused by two of its current features:

    • As discussed above, there is no strict synchronisation between the Source and Data codebases.

    • The property used to compare mod compatibility (the GameVersion) is set before build-time, and "baked" into the executable code when it is compiled.

    These two features cause issues when trying to provide a definitive game version for mods to depend on.
    The Source codebase, which is responsible for the GameVersion, needs to be aware of any changes in the Data codebase, and those changes must retrigger a full build of the game and increment the version correctly.

    The issue is compounded when dealing with composite changes, which must somehow be recognised as a single batch to avoid double-incrementing the game version.

  • Automate versioning and releases so we can easily distribute releases and test builds while preserving mod compatibility where possible

    This is the main aim of the changes: to use the existing build workflows and automated change detection to regularly produce releases without manual input.

    These changes aim to:

    • Increase how often we make patch/content updates available. This gives quicker gameplay/playtest feedback, and improves the visibility of work done on the game

    • Make development and testing builds available easily without external hosting links or the need to manually package them. This includes the possibility of alpha/beta release channels.

    • Accurately update the game version whenever these releases are published, and track breaking changes to mods.

Updated Versioning Scheme

See here for details

As described in the announcement and the above post, this work relies on the new semantic versioning scheme to automate releases.

The automation changes also require that git tags act as the new source of truth as to which version the game is currently in (see next section). As such, these changes require that we push a new git tag matching the above specification to represent the changeover point in the project's git history.

This first tag can either restart the versioning scheme at v1.0.0 or can be manually set to continue from Pre5 as v5.0.0 (both are valid choices)

It is recommended that we announce this switch to reduce confusion about the change in versioning.

Automated Versioning

To automate incrementing the game version, we need to record which type of version update a batch of changes should trigger, be it a major bump, minor bump or patch.

To achieve this, I propose we adopt the Conventional Commits standard on at least some of the commits made to release branches (master, development).

More information is available here: https://www.conventionalcommits.org/en/v1.0.0-beta.4/

Ideally, this would apply to every commit so changes are captured on an atomic level, but that imposes unrealistic expectations on contributors to a community project.

The minimum requirement for this automated versioning scheme to work is that at least one commit from a batch being pushed to a release branch must meet this standard if a release is to be triggered with those changes, or if they would bump versions.

I propose that, given most contributors aren't inclined to adjust their commit format (or work with a project that enforces it strictly), it should be the responsibility of the Core Game Managers when merging.

The merge commit is sufficient to trigger an automated release if well-formatted and can be edited through the GitHub web interface. Only Core Game Managers can merge a PR to a release branch => save people changing the way they work.

There is a potential to use this standard to scope commits, labelling which area of the project they change: source code, game data or both.

Example:

fix(source): stop asserts crashing the game

Recording this isn't in the scope of the changes, but would allow us to group them more effectively for future release notes.

Moving to a Monorepo

Version number updates may be triggered by changes to both the source code and game data. Automating this requires that we merge the source and data codebases to enable us to track changes to both in a single repository.

See here for details

This wiki page and linked sandbox repositories describe and demonstrate the process of merging the two repositories while maintaining Git commit history and issues.

Automated Releases

These changes collectively enable us to automate new releases of the game, along with the associated version updates.

By scanning the formatted commits to a release branch, we can determine which version to release, generate release notes and publish release artefacts under this new release tag to GitHub.

Semantic Release is an automated version management and package publishing tool that allows us to achieve these steps, via a convenient npm package and a .releaserc.json file.

Release Branches:

Releases are scoped to a branch

Release Steps

Semantic Release has been configured to perform several steps to version and publish a release, each of which has its own customisation:

  • Analyse Commits

    Semantic Release reads the commit history and tags of the current branch

  • Generate Release Notes

  • Git

  • GitHub

The source of truth for which version the game is in changes to the git tags of each release commit (which includes the changes to the c_VersionString value). These

At no point should we be required to manually increment the version. It'll be overwritten on push anyway.

Requirements

Monorepo, as otherwise versioning the source / data is too hard.

Devs must have at least one Conventional Commits spec commit in a push to correctly increment the version number and trigger a build

No more manual changes to version number

Dev builds will still suffer from needing to update the mod SupportedGameVersion each release, as they must match exactly.