Pipelines, versions and releases
How every SpaceWorks-Labs repository checks, versions and ships its work, with the rules that all of them follow, the way each kind of stack does it, and an honest table of where each repository stands today.
Researched 13 November 2026 from the live GitHub organisation (workflows, branch protection, releases) and,
for the main SpaceWorks repository, from the current integration branch, which is one release ahead of
main (it has the version-bump check, the signed installer assets and docs/release-0.12.0.md; main
on GitHub is still at 0.9.3). Where something could not be verified it says not checked.
Current rule (v2.0.1, 2026-11-13): Observed at 2026-11-13: organisation tables below retain the original research snapshot, not live promises. The design-system VERSION/tag/release correction is recorded beside §§6–8; no new remote organisation audit was run by batch 1A. (1A-N30) — supersedes the line above; see docs/current-rules.md#cr-delivery-01.
Plain words used below: a workflow is a script GitHub runs for us (GitHub Actions); a job is one
step-group inside it; a required check is a job that must be green before GitHub allows a merge;
ghcr.io is GitHub’s container registry, where our Docker images live; a tag is a permanent label on one
commit; semver is the three-number version MAJOR.MINOR.PATCH.
1. Rules every product follows
Section titled “1. Rules every product follows”| Rule | What it means |
|---|---|
| Branch model | Work happens on a branch from dev. A pull request (PR) goes into dev. The maintainer promotes dev to main with a second PR. Nobody pushes to main. |
| Checks run on every PR | A PR into dev or main runs the repository’s checks. Nothing merges red. |
| Required checks are named and stable | Branch protection matches job names, so a job that is required is never renamed casually. |
| Zero reds | A failing test is a new regression, never “background noise”. Tests are kept; a test for an unshipped feature is skipped with a written reason, never deleted. |
Semver in a VERSION file |
The root VERSION file holds MAJOR.MINOR.PATCH. It is raised (strictly higher than main) on every PR into main. |
| A release note per version | docs/release-<version>.md (SpaceWorks) or the changelog entry says what changed, in plain English. |
Tags are vX.Y.Z-main.<run>.<sha> |
The build tag combines the series, the CI run number and the commit. Servers pin that exact tag, so an update always means one known build. The person-facing title is <Product> X.Y.Z. |
| Releases are built by CI only | The first time a new VERSION reaches main, CI builds the images and creates the GitHub Release. Nobody builds or uploads a release by hand. |
| Artifacts per kind | Server products: two Docker images (backend, frontend) for linux/amd64 and linux/arm64, plus installer files. Android: APK and app bundle. iOS: an app build. Static sites: a Pages deployment. |
| Security audits | Dependencies are audited in CI (pip-audit for Python, npm audit for Node), on PRs and weekly where the dependency files rarely change. |
| Caching | Every workflow caches its package manager or build layers so a PR check stays fast. The cache is never the source of truth. |
| Secrets only in GitHub | Tokens and keys live in GitHub secrets and environments, never in a file. Test keys are generated fresh in each run. Releases are signed without a stored key where possible (keyless signing). |
| Least permission | Workflows start with contents: read and ask for more (packages: write, pages: write) only in the one job that needs it. |
| Concurrency | A newer run on the same branch cancels the older check run. A release run never cancels itself halfway. |
| Maintainer merges | CODEOWNERS asks the maintainer to review every path, and branch protection (applied to admins too) lets only the maintainer merge or push to main. Agents prepare the merge and stop. |
| Pages deploys | Static sites build on every PR (to catch broken pages) and publish to GitHub Pages only from main. |
The flow, end to end
Section titled “The flow, end to end”flowchart LR feat["Feature or fix branch from dev"] -- "pull request" --> dev["dev"] dev --> pr_checks["PR checks: build, lint, types, tests, audit"] pr_checks -- "all green" --> promote["Maintainer opens PR dev to main"] promote --> bump["version-bump check: VERSION strictly higher, release note exists"] bump -- "green" --> merge["Maintainer merges to main"] pr_checks -. "red: fix and push again" .-> feat merge --> release["Release workflow on main"] release --> new{"New VERSION?"} new -- "yes" --> images["Build and push images to ghcr.io"] images --> assets["Installer files, signed checksums"] assets --> gh["GitHub Release created"] gh --> latest["Marked latest, rolling tags promoted"] latest --> deploy["Optional: deploy to our own server"] new -- "no" --> imgonly["Images only, no GitHub Release"]On this topic
Section titled “On this topic”- Pipelines per stack Django and React, Next.js and Prisma, Android, iOS and static sites.
- Where each repository stands The status table, the bring-up list, the new-repository checklist and branch protection.