Deploy & Releases

How each component is built and shipped, from the .github/workflows/ of each repo. The webhook URLs/tokens and Play service accounts referenced here are held privately (vault + the private operations docs).

The shared pattern

Every repo uses the same three-workflow shape:

Workflow Trigger Action
ci.yaml Pull request (+ manual) Build & test; posts a results comment on the PR
deploy-staging.yaml Push tag staging-v* (+ manual) Test, then deploy to staging
deploy-prod.yaml Push tag v* (+ manual) Test, then deploy to production

Releases are cut by pushing a git tag. There is no auto-deploy on merge to a branch.

Server apps — API, admin, web-platform

CI builds/tests; on a release tag, a job POSTs to the Coolify deploy webhook:

curl -X POST "$DEPLOY_WEBHOOK_URL_PROD" \
     -H "Authorization:Bearer $DEPLOY_WEBHOOK_AUTH_HEADER"

Coolify then pulls the repo, rebuilds (nixpacks for the API, Dockerfile for admin), and swaps the running container.

  • API (bme-konza-api): CI runs go mod tidy + go test ./... (Go 1.25). Prod uses DEPLOY_WEBHOOK_URL_PROD, staging uses DEPLOY_WEBHOOK_URL_STAGING.
  • Admin (Oa-admin-panel): CI runs npm ci, npm run lint, and a test Docker build (Node 24).
  • Web-platform (BME-KONZA-web-platform): Nuxt build/lint.

Cut a server release

# from the repo, on the commit you want to ship
git tag staging-v1.2.3 && git push origin staging-v1.2.3   # → staging
# verify on staging, then:
git tag v1.2.3 && git push origin v1.2.3                    # → production

Mobile app — oxygen-alliance-app

Different flow: GitHub Actions builds and signs the Android App Bundle and uploads it to Google Play. No Coolify involvement.

  • Tag staging-v* → build --flavor staging --dart-define=API_URL=https://<STAGING_API_HOST>, sign with the upload keystore, upload to Play (internal/staging track) via STAGING_SERVICE_ACCOUNT.
  • Tag v* → build --flavor production --dart-define=API_URL=https://api.bme-konza.org, sign, upload AAB and the ProGuard mapping.txt to the production track via PROD_SERVICE_ACCOUNT (r0adkll/upload-google-play, track: production, inAppUpdatePriority: 2).

Java 21 (temurin), Flutter 3.38.9. Signing secrets are listed in 01-secrets-credentials (private handover docs); full release detail in 10-mobile-app.md.

Cut an app release

  1. Bump version: in pubspec.yaml (e.g. 1.4.3+69 — the +N build number must increase for every Play upload).
  2. git tag staging-v1.4.3 && git push origin staging-v1.4.3, test from Play internal track.
  3. git tag v1.4.3 && git push origin v1.4.3 to ship to production.

Versioning & branching — [TODO]

[TODO: branching model — trunk-based? a develop branch? — and who reviews/approves PRs.] The CI gate (tests/lint on PR) is the only automated check before merge.

Rollback

  • Server: re-tag the previous good commit, or redeploy the prior image from the Coolify dashboard. [TODO: confirm Coolify keeps previous images / has a one-click rollback]
  • App: Play Console → halt the rollout, or promote the previous release. A new build number is required to publish a fix.