Skip to content

Release Docs & Versioning

TODO: review by @shinratttensei1

This document outlines our standardized release process using GitFlow and GitHub CI/CD for:

  • k8s Cluster with:
    • Online App
    • MongoDB
  • Robot Microservice ( DOES NOT need staging )
  • Offline app core ( DOES NOT need staging )

Example workflow from developing to release

Online App

Suppose:

  1. You have just merged a new feature to develop
  2. CI/CD is already configured for all branches

Step 1: Merge develop → staging

git checkout staging
git pull origin staging
git merge develop
git push origin staging

CI/CD triggers on staging and deploys to the staging environment. Test and verify the build on staging before continuing.

Step 2: Merge staging → release branch

Create the release branch if it does not exist yet:

git checkout -b release/1.4.2
git push origin release/1.4.2

Or, if the branch already exists:

git checkout release/1.4.2
git pull origin release/1.4.2

Then merge staging into it and update the changelog:

git merge staging

Update CHANGELOG.md with the changes for this version. See Writing changelog.md.

git add CHANGELOG.md
git commit -m "Update changelog and bump version to 1.4.2"
git push origin release/1.4.2

CI/CD triggers on release/1.4.2 and handles the production deployment. The workflow also generates the version map file and commits it back to the branch (see CI/CD Workflows).

Step 3: Merge release → main

Once the release is confirmed, merge into main to keep it up to date with the latest shipped code:

git checkout main
git pull origin main
git merge release/1.4.2
git push origin main

CI/CD on main does not redeploy — this merge is purely to preserve the latest state in the default branch.

Offline App

Suppose:

  1. You have just merged a new feature to develop
  2. CI/CD is already configured for all branches

Step 1: Merge develop → release branch

The offline app has no staging environment. Merge directly from develop into the release branch.

Create the branch if it does not exist yet:

git checkout develop
git pull origin develop
git checkout -b release/1.4.2
git push origin release/1.4.2

Or, if the branch already exists:

git checkout release/1.4.2
git pull origin release/1.4.2
git merge develop
git push origin release/1.4.2

Step 2: Trigger the workflow manually

From this point, all the work is done inside this repo april-robots-offline-deployment-kit

The CI/CD workflow uses workflow_dispatch and must be triggered manually from GitHub Actions:

  1. Go to the repository on GitHub.
  2. Open the Actions tab.
  3. Select the release workflow from the list.
  4. Click Run workflow.
  5. Choose release/1.4.2 as the source branch.
  6. Confirm and run.

The workflow builds and compiles the Offline Backend and Frontend into a distributable app and publishes a GitHub Release.

To release the same version again (e.g. after a fix), you must first delete the existing tag and GitHub Release for that version before re-running the workflow. Otherwise the workflow will fail on a duplicate tag.

Robot Microservices

Microservices have no staging environment and no manual workflow trigger. The only thing a developer needs to do is push to a release/** branch — the CI/CD workflow handles everything automatically.

git checkout develop
git pull origin develop
git checkout -b release/1.2.0
git push origin release/1.2.0

The workflow triggers on any push to a branch matching release/**. It:

  1. Extracts the version number from the branch name (e.g., release/1.2.01.2.0).
  2. Builds a Docker image.
  3. Pushes two tags to GHCR:
    • Full version tag — the exact version from the branch name, e.g., 1.2.0 or 1.2.0-beta.
    • General version tag — major.minor + suffix + -latest, e.g., 1.2-latest or 1.2-beta-latest. This tag is what the offline app uses to pull the newest compatible MS image without pinning a patch version.

Examples:

BranchFull tagGeneral tag
release/1.2.01.2.01.2-latest
release/1.2.11.2.11.2-latest
release/1.2.0-beta1.2.0-beta1.2-beta-latest

To release the same version again (e.g. after a fix), just push a new commit to the existing release/1.2.0 branch — the workflow will retrigger and overwrite the GHCR image tags automatically.

How to Ensure Releases Are Valid

All commits must go through following sequence: -> develop -> staging (excluding offline app branches) -> release -> main GitHub actions are successful after on each branch. CI pipeline (tests) must pass Staging build has been tested and approved Tag is only created after final approval

Writing changelog.md

This file should include all notable changes for each version of the application. It must follow the Keep a Changelog format.

Each version section should also contain a ### Compatible Offline Versions block that lists:

  • Specific offline app versions (0.2.0, 0.2.2)
  • Or version ranges (0.2.0 - 0.2.4), which will be expanded automatically.

Example:

## [1.0.0] - 2017-06-20

### Compatible offline versions:

- 0.2.0 - 0.2.7
- 0.3.0

### Added

- "Why keep a changelog?" section.
- "Who needs a changelog?" section.
- "How do I make a changelog?" section.

### Changed

- Start using "changelog" over "change log" since it's the common usage.
- Fix phrasing and spelling in German translation.
  ...

Version naming and tags

We follow Semantic Versioning (SemVer):

  • Format: MAJOR.MINOR.PATCH
  • Examples: 1.4.0, 1.4.1, 2.0.0
  • MAJOR version (X.0.0): Increased for breaking changes or incompatible API/database updates.
    • Example: Database schema is changed and old clients will not work with new data.
  • MINOR version (0.X.0): Increased when new features are added in a backward-compatible way.
    • Example: Added a new report export feature to the Offline App; old apps still work.
  • PATCH version (0.0.X): Increased for backward-compatible bug fixes and small improvements.
    • Example: Fixed a typo in a UI element or corrected a minor database entry.

In addition to the full version tag, each MS release also pushes a major.minor[-suffix]-latest rolling tag (e.g., 1.2-latest, 1.2-beta-latest). This is the tag the offline app uses at startup to pull the newest compatible microservice image without needing to know the exact patch version. See Robot Microservices for how this tag is published, and Offline App — Podman manager for how it is consumed.

General Guidelines

  • Bump MAJOR if any change breaks compatibility or requires all deployments to upgrade.
  • Bump MINOR for new features that do not break old functionality.
  • Bump PATCH for fixes, tweaks, or documentation updates.

Examples

Initial Stable Release

  • Scenario: Project is stable and ready for production.
  • Version: 1.0.0

Adding New Features (MINOR)

  • Scenario: Support for a new robot type added in a backward-compatible way.
  • From → To: 1.0.0 → 1.1.0
  • Scenario: User management added to Online App in a backward-compatible way.
  • From → To: 1.1.0 → 1.2.0

Bug Fixes (PATCH)

  • Scenario: File upload bug fixed.
  • From → To: 1.2.0 → 1.2.1
  • Scenario: Fix for sync failure on slow internet.
  • From → To: 1.2.1 → 1.2.2

Breaking Changes (MAJOR)

  • Scenario: Database schema changed, old Offline Apps incompatible.
  • From → To: 1.4.2 → 2.0.0
  • Scenario: Offline and Online App API fully refactored.
  • From → To: 2.0.0 → 3.0.0

Cloud Sync-Specific Examples

  • New mandatory field in children records, migration required: 1.4.0 → 2.0.0 (MAJOR)
  • New optional field in actions, old Offline Apps can ignore: 1.4.0 → 1.5.0 (MINOR)
  • Something not affecting cloud sync compatibility: 1.5.0 → 1.5.1 (PATCH)

Docker Image Tags:

TODO: Why is this provided in this documentation?

ghcr.io/org-name/image-name:1.4.0
ghcr.io/org-name/image-name:latest (for staging only)

Example on our registry:

ghcr.io/novators-kz/april-robots-online-general-api:1.4.0
ghcr.io/novators-kz/april-robots-online-general-api:latest

[!NOTE] You can access our packages in (Packages) You need a PAT configured to have packages:write rights (About permissions for GitHub Packages).

CI/CD Workflows

What is automated vs manual

Online AppOffline AppRobot MS
Build Docker / exe imageCI — on staging, release/**CI — workflow_dispatch on release/**CI — on release/**
Push to GHCRCICICI
Deploy to stagingCI — on stagingN/AN/A
Deploy to productionCI — on release/** (SSH restart)N/AN/A
Generate version mapCI — on release/**N/AN/A
Insert version map into MongoDBCI — on release/**N/AN/A
Create Git tagManualCIN/A (no release)
Publish GitHub ReleaseManualCIN/A
QA / staging approvalManualManualManual
Writing CHANGELOGManualN/AN/A

Online App — branch triggers

BranchCI action
developTests and linting
stagingTests, build Docker image, deploy to staging environment
release/**Tests, build Docker image, deploy to production (SSH restart), generate and insert version map
mainNo deployment — merge only

Version map generation (on release/**):

When a push is made to a release/{version} branch, the workflow:

  1. Parses the version from the branch name (e.g., release/1.4.01.4.0).
  2. Reads CHANGELOG.md and extracts the ### Compatible offline versions block for that version.
  3. Expands any version ranges (e.g., 0.2.0 - 0.2.4) into individual versions.
  4. Generates version_maps/{version}.json.
  5. Validates the generated file against version_map.schema.json using ajv-cli.
  6. Commits the file back to the branch with [skip ci] to avoid re-triggering the workflow.

Example version_maps/1.4.0.json:

{
  "version": "1.4.0",
  "compatible_offline_versions": ["0.2.0", "0.2.1", "0.2.2", "0.2.3", "0.2.4"],
  "release_date": "2025-07-24"
}

Offline App — workflow_dispatch

The offline app build does not trigger automatically on push. A developer manually runs the workflow in april-robots-offline-deployment-kit and selects the release/{version} branch. The workflow checks out the frontend and backend repos at matching release/{version} branches, builds everything, assembles the .env, compiles the InnoSetup installer, and publishes a GitHub Release with setup.exe and release.zip. See Offline App — CI/CD release pipeline for the full step-by-step.

Robot Microservices — push to release branch

The MS workflow triggers automatically on any push to release/**. It builds the Docker image, derives the major.minor[-suffix]-latest rolling tag from the branch name, and pushes both the full version tag and the rolling tag to GHCR. No GitHub Release is created. See Robot Microservices for details.