Skip to main content
The staging workflow validates every commit on main by running tests, collecting coverage, and building the desktop bundle. It acts as the gate a commit must pass before it can be promoted to production.

Overview

Trigger

Runs automatically on every push to main, and can also be triggered manually via workflow_dispatch.

Environment

Uses the staging GitHub Actions environment, which supplies STAGING_* secrets to the validation job.

Running the staging check locally

Run the same validation that CI executes:
yarn validate:staging
The script (scripts/validate-staging.sh) performs the following steps in order:
1

Check for required env templates

Verifies that all three .env.example files exist:
  • packages/backend/.env.example
  • packages/mobile/.env.example
  • packages/desktop/.env.example
The script exits immediately with an error if any file is missing.
2

Run workspace tests

yarn test
Runs the test suite across all workspaces (backend, mobile, desktop).
3

Collect critical coverage

yarn coverage
Generates coverage reports for backend, mobile, and desktop workspaces.
4

Build the desktop release candidate bundle

yarn workspace desktop build
Produces packages/desktop/dist, confirming the desktop app compiles without errors.
Run yarn validate:staging before opening a pull request or tagging a release candidate to catch failures early.

GitHub Actions workflow

The validate-staging job in .github/workflows/cd.yml runs on every push to main:
name: Release Pipeline

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  validate-staging:
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: yarn
      - name: Install dependencies
        run: yarn install --frozen-lockfile || yarn install
      - name: Prepare staging env files
        run: |
          # Writes packages/backend/.env, packages/mobile/.env,
          # and packages/desktop/.env from STAGING_* secrets
          # (falls back to safe defaults when secrets are absent)
      - name: Run staging validation
        run: yarn validate:staging
      - name: Upload staging artifacts
        uses: actions/upload-artifact@v4
        with:
          name: staging-release-${{ github.sha }}
          path: |
            artifacts/staging-release.json
            packages/backend/coverage
            packages/mobile/coverage
            packages/desktop/coverage
            packages/desktop/dist
The job writes .env files for each package from STAGING_* secrets before running the validation. If a secret is absent, the workflow falls back to safe default values so CI remains reproducible without a full secrets configuration. After a successful run, the job uploads:
  • artifacts/staging-release.json — a manifest with the git SHA, ref, and run ID.
  • Coverage reports for all three packages.
  • The compiled desktop bundle at packages/desktop/dist.

Staging secrets

These secrets must be configured in the staging GitHub Actions environment:
SecretDescription
STAGING_DATABASE_URLFull Prisma-compatible connection string
STAGING_DB_HOSTDatabase host
STAGING_DB_PORTDatabase port
STAGING_DB_NAMEDatabase name
STAGING_DB_USERDatabase user
STAGING_DB_PASSWORDDatabase password
STAGING_JWT_SECRETSecret used to sign JWT tokens
STAGING_DEFAULT_LOGIN_PASSWORDInitial admin password
STAGING_SMTP_HOSTSMTP server host
STAGING_SMTP_PORTSMTP server port
STAGING_SMTP_SECUREtrue for TLS, false otherwise
STAGING_SMTP_USERSMTP authentication user
STAGING_SMTP_PASSSMTP authentication password
STAGING_EMAIL_FROMSender address for outgoing emails
All secrets have safe defaults in the workflow so validation can run without them. However, tests that exercise real database or email behavior require the actual secrets to be configured.

Release candidate acceptance criteria

A commit is considered a valid release candidate when all of the following are true:
  1. yarn validate:staging passes locally or in CI.
  2. The validate-staging job in the Release Pipeline workflow finishes green.
  3. Coverage reports and packages/desktop/dist are present in the uploaded artifacts.
  4. No open regression reopens a previously closed phase or issue.

Rollback and rejection

If validation fails, the commit is not promoted:
  1. Fix the issue in a hotfix/* or feature/* branch.
  2. Re-run yarn validate:staging locally to confirm the fix.
  3. Merge to main and wait for the workflow to go green.
  4. Do not create a rc-* tag until CI is fully green.
If a release candidate tag has already been created and is later rejected, withdraw the tag and issue a new release/YYYY-MM-DD-rcN+1.

Build docs developers (and LLMs) love