Skip to content

fix(backups): secure pCloud setup and durable conversation exports #15608

fix(backups): secure pCloud setup and durable conversation exports

fix(backups): secure pCloud setup and durable conversation exports #15608

name: OpenAPI Contract
on:
# Nightly calls run these same jobs against one immutable main snapshot.
workflow_call:
inputs:
nightly_main_sha:
description: Main SHA pinned by the unfiltered nightly caller
type: string
required: false
default: ''
push:
branches:
- main
paths:
- 'backend/**'
- 'docs/api-reference/openapi.json'
- 'docs/api-reference/app-client-openapi.json'
- 'docs/api-reference/integration-public-openapi.json'
- 'app/lib/backend/http/api/**'
- 'app/lib/backend/schema/**'
- 'app/lib/backend/schema/gen/**'
- 'app/lib/models/announcement.dart'
- 'app/lib/models/subscription.dart'
- 'app/lib/models/user_usage.dart'
- 'desktop/windows/src/renderer/src/lib/omiApi.generated.ts'
- 'web/app/src/lib/omiApi.generated.ts'
- 'web/admin/lib/services/omi-api/omiApi.generated.ts'
- 'web/personas-open-source/src/lib/omiApi.generated.ts'
- 'docs/docs.json'
- '.github/workflows/openapi-contract.yml'
pull_request:
paths:
- 'backend/**'
- 'docs/api-reference/openapi.json'
- 'docs/api-reference/app-client-openapi.json'
- 'docs/api-reference/integration-public-openapi.json'
- 'app/lib/backend/http/api/**'
- 'app/lib/backend/schema/**'
- 'app/lib/backend/schema/gen/**'
- 'app/lib/models/announcement.dart'
- 'app/lib/models/subscription.dart'
- 'app/lib/models/user_usage.dart'
- 'desktop/windows/src/renderer/src/lib/omiApi.generated.ts'
- 'web/app/src/lib/omiApi.generated.ts'
- 'web/admin/lib/services/omi-api/omiApi.generated.ts'
- 'web/personas-open-source/src/lib/omiApi.generated.ts'
- 'docs/docs.json'
- '.github/workflows/openapi-contract.yml'
workflow_dispatch:
permissions:
contents: read
concurrency:
# Preserve every main/manual compatibility result while cancelling obsolete
# PR revisions that can no longer merge.
group: openapi-contract-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || format('run-{0}', github.run_id) }}-${{ inputs.nightly_main_sha != '' && format('nightly-{0}', github.run_id) || 'normal' }}
cancel-in-progress: true
env:
# Abort a stalled git HTTP transfer instead of hanging. Hosted-runner fetches
# from github.com intermittently stop receiving data for 7-10 minutes before
# the connection resets (Backend Hermetic E2E run 39435458398 spent 498 s in
# "Checkout code" and hit its 10-minute cap). With these set, git aborts any
# transfer that stays under 1 KB/s for 60 s, and actions/checkout retries the
# fetch (its built-in 3 attempts); a healthy depth-1 fetch takes ~20 s.
# Applies to every git network call in the workflow, including script steps.
GIT_HTTP_LOW_SPEED_LIMIT: "1000"
GIT_HTTP_LOW_SPEED_TIME: "60"
jobs:
openapi-contract:
name: Public Developer API contract
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
ref: ${{ inputs.nightly_main_sha || github.sha }}
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version-file: backend/.python-version
- name: Set up uv
uses: astral-sh/setup-uv@ecd24dd710f2fb0dca1693a67af11fc4a5c5ec84
with:
# Exact version resolves locally; an unset version means "latest",
# which fetches the astral-sh/versions manifest and has hard-failed
# CI on that network call. Matches backend/Dockerfile UV_VERSION.
version: "0.11.13"
enable-cache: true
cache-dependency-glob: backend/openapi-requirements.txt
- name: Fetch released app-client contract baseline
if: github.event_name == 'pull_request'
run: git fetch --no-tags origin "${{ github.base_ref }}"
- name: Reject released app-client breaking changes
if: github.event_name == 'pull_request'
run: python backend/scripts/check_app_client_openapi_compatibility.py --base-ref FETCH_HEAD
- name: Reject public Developer API breaking changes
if: github.event_name == 'pull_request'
run: >-
python backend/scripts/check_app_client_openapi_compatibility.py --base-ref FETCH_HEAD
--head-spec docs/api-reference/openapi.json --label 'Developer API'
- name: Check committed OpenAPI contract
working-directory: backend
run: scripts/openapi_runner.sh scripts/export_openapi.py --check ../docs/api-reference/openapi.json
- name: Check committed app-client OpenAPI contract
working-directory: backend
run: scripts/openapi_runner.sh scripts/export_openapi.py --surface app-client --check ../docs/api-reference/app-client-openapi.json
- name: Check committed integration OpenAPI contract
working-directory: backend
run: scripts/openapi_runner.sh scripts/export_openapi.py --surface integration-public --check ../docs/api-reference/integration-public-openapi.json
- name: Report backend route policy inventory
working-directory: backend
run: scripts/openapi_runner.sh scripts/route_policy_inventory.py --manifest route_policy_manifest.yaml --check --report-only
- name: Enforce backend route policy baseline
run: |
args=()
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
args+=(--base-ref FETCH_HEAD)
fi
python backend/scripts/check_route_policy_baseline.py "${args[@]}"
- name: Check generated app-client Dart schemas
run: python backend/scripts/generate_dart_models.py --all --check
- name: Check generated app-client TypeScript schemas
run: python backend/scripts/generate_ts_openapi_types.py --check
- name: Check generated desktop Swift DTOs
run: python backend/scripts/generate_swift_openapi_types.py --check