Skip to content

feat(desktop): Omi Beta as a separate app — run beta and stable side-by-side #3021

feat(desktop): Omi Beta as a separate app — run beta and stable side-by-side

feat(desktop): Omi Beta as a separate app — run beta and stable side-by-side #3021

Workflow file for this run

name: Repo Checks
on:
push:
branches: main
pull_request:
branches: main
types: [opened, synchronize, reopened, edited, labeled, unlabeled]
permissions:
contents: read
pull-requests: read
concurrency:
group: repo-checks-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
metadata-preflight:
name: PR Metadata Preflight
if: github.event_name == 'pull_request' && contains(fromJSON('["edited", "labeled", "unlabeled"]'), github.event.action)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version-file: backend/.python-version
# The preflight can select uv-backed checks (e.g. backend-route-policy-baseline
# runs the OpenAPI runner) whenever a PR touches backend routes, so this job
# needs uv just like the sibling Hygiene job.
- name: Set up uv
uses: astral-sh/setup-uv@ecd24dd710f2fb0dca1693a67af11fc4a5c5ec84
with:
enable-cache: true
cache-dependency-glob: backend/openapi-requirements.txt
- name: Run current PR metadata preflight
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
scripts/pr-preflight \
--base "${{ github.event.pull_request.base.sha }}" \
--repository "${{ github.repository }}" \
--pr-number "${{ github.event.pull_request.number }}"
changes:
name: Detect Changes
if: github.event_name != 'pull_request' || !contains(fromJSON('["edited", "labeled", "unlabeled"]'), github.event.action)
runs-on: ubuntu-latest
outputs:
diff_base: ${{ steps.changes.outputs.diff_base }}
has_arb: ${{ steps.changes.outputs.has_arb }}
has_dart: ${{ steps.changes.outputs.has_dart }}
has_firmware: ${{ steps.changes.outputs.has_firmware }}
has_format: ${{ steps.changes.outputs.has_format }}
has_python: ${{ steps.changes.outputs.has_python }}
has_workflows: ${{ steps.changes.outputs.has_workflows }}
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Detect changed paths
id: changes
uses: ./.github/actions/detect-changes
hygiene:
name: Hygiene
runs-on: ubuntu-latest
needs: changes
if: github.event_name != 'pull_request' || !contains(fromJSON('["edited", "labeled", "unlabeled"]'), github.event.action)
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
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:
enable-cache: true
cache-dependency-glob: backend/openapi-requirements.txt
- name: Save changed files
run: |
scripts/changed-files "${{ needs.changes.outputs.diff_base }}"...HEAD > /tmp/changed-files.txt
cat /tmp/changed-files.txt
- name: Test package architecture map guardrail
run: python3 .github/scripts/test_check_package_architecture_maps.py
- name: Test product invariant PR-body checker
run: python3 .github/scripts/test_check_product_invariants.py
- name: Test PR preflight contracts
run: python3 .github/scripts/test_pr_preflight.py
- name: Run shared PR contract preflight
if: github.event_name == 'pull_request'
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
scripts/pr-preflight \
--base "${{ needs.changes.outputs.diff_base }}" \
--repository "${{ github.repository }}" \
--pr-number "${{ github.event.pull_request.number }}" \
--event-payload-file "$GITHUB_EVENT_PATH"
- name: Run deterministic check manifest on main pushes
if: github.event_name != 'pull_request'
run: python3 .github/scripts/run_checks.py --lane ci --base "${{ needs.changes.outputs.diff_base }}" --skip-pr-body-checks
- name: Test brand UI ratchet helper
run: python3 .github/scripts/test_check_brand_ui.py
- name: Check typed error flow-control ratchet
run: python3 .github/scripts/check_isinstance_return_ratchet.py
- name: Test lifecycle header checker
run: python3 .github/scripts/test_check_lifecycle_headers.py
- name: Test version-prefixed filename lint
run: python3 .github/scripts/test_check_version_prefixed_filenames.py
- name: Check desktop prod promotion policy
run: python3 .github/scripts/check-desktop-prod-promotion-policy.py
- name: Test deployment concurrency policy
run: python3 .github/scripts/check-deployment-concurrency.py --self-test
- name: Check deployment concurrency policy
run: python3 .github/scripts/check-deployment-concurrency.py
- name: Check desktop release terminology
run: python3 .github/scripts/check-desktop-release-terminology.py
- name: Test desktop qualification metadata writer
run: python3 desktop/macos/scripts/release-keyvalue.py self-test
- name: Test desktop release promotion gate
run: python3 .github/scripts/test_check_desktop_release_promotion.py
- name: Test automatic desktop beta candidate gate
run: python3 .github/scripts/test_check_desktop_auto_beta_candidate.py
- name: Check release process guards
run: python3 .github/scripts/check-release-process-guards.py
- name: Check GitHub Actions workflows
if: needs.changes.outputs.has_workflows == 'true'
run: |
GOBIN=/tmp/actionlint-bin go install github.com/rhysd/actionlint/cmd/actionlint@v1.7.12
mapfile -t files < <(grep -E '^\.github/workflows/.*\.ya?ml$' /tmp/changed-files.txt | while IFS= read -r f; do [ -f "$f" ] && echo "$f"; done || true)
if [ "${#files[@]}" -gt 0 ]; then
/tmp/actionlint-bin/actionlint -shellcheck "" "${files[@]}"
fi
formatting:
name: Formatting
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.has_format == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Save changed files
run: |
scripts/changed-files "${{ needs.changes.outputs.diff_base }}"...HEAD > /tmp/changed-files.txt
cat /tmp/changed-files.txt
- name: Setup Flutter
if: needs.changes.outputs.has_dart == 'true'
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Resolve Flutter dependencies for formatting
if: needs.changes.outputs.has_dart == 'true'
working-directory: app
run: flutter pub get
- name: Check Dart formatting
if: needs.changes.outputs.has_dart == 'true'
run: |
FILES=$(grep '\.dart$' /tmp/changed-files.txt | grep -v -e '\.gen\.dart$' -e '\.g\.dart$' | while IFS= read -r f; do [ -f "$f" ] && echo "$f"; done || true)
if [ -n "$FILES" ]; then
echo "$FILES" | xargs dart format --line-length 120 --set-exit-if-changed --output=none
fi
- name: Check Python formatting
if: needs.changes.outputs.has_python == 'true'
run: |
pip install -q black
FILES=$(grep 'backend/.*\.py$' /tmp/changed-files.txt | while IFS= read -r f; do [ -f "$f" ] && echo "$f"; done || true)
if [ -n "$FILES" ]; then
echo "$FILES" | xargs black --check --line-length 120 --skip-string-normalization
fi
- name: Check ARB formatting
if: needs.changes.outputs.has_arb == 'true'
run: |
FILES=$(grep '\.arb$' /tmp/changed-files.txt | while IFS= read -r f; do [ -f "$f" ] && echo "$f"; done || true)
failed=0
for f in $FILES; do
if ! python3 -m json.tool "$f" > /dev/null 2>&1; then
echo "FAIL: $f is not valid JSON"
failed=1
continue
fi
if ! python3 -c "
import json, sys
f = sys.argv[1]
with open(f) as fh:
original = fh.read()
formatted = json.dumps(json.loads(original), indent=4, ensure_ascii=False) + '\n'
if original != formatted:
sys.exit(1)
" "$f" 2>/dev/null; then
echo "FAIL: $f not formatted with 4-space indent"
failed=1
fi
done
if [ "$failed" -eq 1 ]; then
echo "Fix: jq --indent 4 '.' <file> > tmp && mv tmp <file>"
exit 1
fi
- name: Check C/C++ formatting
if: needs.changes.outputs.has_firmware == 'true'
run: |
FILES=$(grep -E '^(omi|omiGlass)/.*\.(c|cpp|cc|cxx|h|hpp)$' /tmp/changed-files.txt | while IFS= read -r f; do [ -f "$f" ] && echo "$f"; done || true)
if [ -n "$FILES" ]; then
echo "$FILES" | xargs clang-format --dry-run --Werror
fi