Skip to content

chore(env): sync .env.example non-secret config with current settings #658

chore(env): sync .env.example non-secret config with current settings

chore(env): sync .env.example non-secret config with current settings #658

Workflow file for this run

name: CI
on:
# ready_for_review is not in the default type set, and without it a draft PR
# turned ready would never start a run.
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
# Cancel superseded runs on the same PR/branch to save CI minutes.
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
env:
PYTHON_VERSION: "3.11.15"
UV_VERSION: "0.11.28"
NODE_VERSION: "20.20.2"
jobs:
backend:
name: Backend (lint, types, tests)
# Skip while the PR is a draft; the ready_for_review event starts the real run.
# Repeated per job because there is no workflow-level `if`. The event_name guard
# comes first so push and workflow_dispatch runs are unaffected.
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
runs-on: [qiniu, ubuntu-24.04]
timeout-minutes: 15
permissions:
contents: read
# Lets codecov-action mint a short-lived OIDC token instead of a CODECOV_TOKEN
# secret -- works for public repos without needing repo/org secret access.
id-token: write
defaults:
run:
working-directory: backend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- uses: astral-sh/setup-uv@v6
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
cache-dependency-glob: backend/uv.lock
# Single source of truth: mirrors the local scripts/check.sh gate
# (uv lock --check, ruff check, ruff format --check, mypy, pytest+coverage, alembic heads).
- name: Quality gate
run: bash scripts/check.sh
- name: Upload coverage report
if: always()
uses: actions/upload-artifact@v4
with:
name: backend-coverage
path: backend/coverage.xml
if-no-files-found: ignore
- name: Upload coverage to Codecov
if: always()
uses: codecov/codecov-action@v5
with:
files: backend/coverage.xml
flags: backend
use_oidc: true
# Public repo: don't fail the build if the Codecov upload itself has
# trouble (rate limit, transient outage) -- coverage reporting is
# informational, not a merge gate.
fail_ci_if_error: false
migrations:
name: Backend (migrations)
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
runs-on: [qiniu, ubuntu-24.04]
timeout-minutes: 10
defaults:
run:
working-directory: backend
services:
postgres:
image: postgres:16.4-alpine
env:
POSTGRES_DB: timeapp
POSTGRES_USER: timeapp
POSTGRES_PASSWORD: timeapp
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U timeapp -d timeapp"
--health-interval 5s
--health-timeout 5s
--health-retries 10
env:
TIMEFLOW_DATABASE_URL: postgresql+psycopg://timeapp:timeapp@127.0.0.1:5432/timeapp
TIMEFLOW_TEST_DATABASE_URL: postgresql+psycopg://timeapp:timeapp@127.0.0.1:5432/timeapp
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- uses: astral-sh/setup-uv@v6
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
cache-dependency-glob: backend/uv.lock
- name: Install dependencies
run: uv sync --locked --all-groups
# Validate the migration chain against a real Postgres, both directions.
- name: Apply migrations (upgrade head)
run: uv run alembic upgrade head
- name: PostgreSQL schema and repository integration tests
run: >-
uv run pytest
tests/test_postgres_schema.py
tests/test_postgres_schedule_repository.py
tests/test_auth_integration.py::test_postgres_jwt_returns_only_its_committed_schedule_snapshot
tests/test_auth_integration.py::test_postgres_empty_account_returns_an_empty_schedule_snapshot
--no-cov
- name: Verify downgrade path (downgrade base)
run: uv run alembic downgrade base
frontend:
name: Frontend (lint, types, build)
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
runs-on: [qiniu, ubuntu-24.04]
timeout-minutes: 15
permissions:
contents: read
# Lets codecov-action mint a short-lived OIDC token instead of a CODECOV_TOKEN
# secret -- works for public repos without needing repo/org secret access.
id-token: write
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Install dependencies
run: npm ci
- name: Checks (lint, format, typecheck)
run: npm run check
# Re-runs both suites with coverage instrumentation on -- npm run check's
# test step above doesn't collect coverage, so this is a second pass just
# for the Codecov report, not a second correctness gate.
- name: Test coverage
run: npm run test:coverage
- name: Upload coverage to Codecov
if: always()
uses: codecov/codecov-action@v5
with:
directory: frontend/coverage
flags: frontend
use_oidc: true
fail_ci_if_error: false
- name: Export build
run: npx expo export --platform android --output-dir dist
docker:
name: Build and push backend image
needs:
- backend
- migrations
- frontend
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: [qiniu, ubuntu-24.04]
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push backend image
uses: docker/build-push-action@v6
with:
context: ./backend
push: true
tags: |
ghcr.io/1024xengineer/timeflow-backend:latest
ghcr.io/1024xengineer/timeflow-backend:${{ github.sha }}
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}