00.02 — Stack / responsibility / license matrix

00.02 — Stack / responsibility / license matrix#

RepositoryRoleLanguageVersionPrimary stackTooling stackDistributionLicense
ocarinaBrowser e2e test frameworkPython3.14+hatchling, python-docx (sole runtime dependency), selenium + playwright (dev only)ruff (ALL), mypy strict, pytest, hypothesis, pytest-mypy-plugins, syrupy, prysk (cram), allure-pytest, pre-commit, twine, buildPyPI, v1.1.10MIT
ocarina-exampleCanonical e2e suite against the IgoristanPython3.14+ocarina, selenium ≥ 4.40, python-dotenv, dogpile.cache, redisruff, mypy, pre-commitSource onlyMIT
ocarina-with-ai-examplee2e suite against CURA Healthcare, co-written with Claude CodePython3.14+ocarina ≥ 1.0.3, selenium ≥ 4.40ruff, mypy, mypy-extensions, typing-extensions, pre-commitSource onlyMIT
igoristanPublic SUT, deliberately chaotic web appTypeScript6.0.xReact 19.2, Vike 0.4.258 (SSG), Vite 7.3, TailwindCSS 4 (alpha), valibot, react-hook-form, react-dropzone, usehooks-ts, throttleit, lucide-react, uuidpnpm 11, Node 24, wireit (orchestrator), eslint 9 (flat), prettier 3.5, husky, lint-staged, commitlint, commitizen, terser, rollup-plugin-visualizer, vite-plugin-compression, @qalisa/vike-plugin-sitemapGitHub Pages (/igoristan/)none
tests-workersOTP / Corsicadex backend, the substrate that exercises parallelization and API testsTypeScript5.9.3Vercel Edge Functions (runtime: "edge"), @upstash/redis, otplib, next types (NextRequest)pnpm 11.x, @vercel/node (types)Vercel: https://tests-workers.vercel.appISC
ocarina-holy-bookPublic documentation + AI skills + PDFsTypeScript6.0.xVitePress 2 alpha, @sugarat/theme, vue 3.5, pagefind, vitepress-plugin-image-optimizepnpm 11, Node 24, eslint 9, prettier 3.8, husky, lint-staged, commitlint, sass-embeddedGitHub Pages (/ocarina-holy-book/)MIT

Python early adopter#

Python 3.12+ featureUse in Ocarina
PEP 695 (class Foo[T]:)Generic signatures everywhere (TestSuite[Driver], Watcher[Driver], Test[Driver], Result[T], Ok[T], Thunk[T], etc.)
PEP 695 type aliases (type X = ...)Every alias: type Result[T] = Ok[T] | Fail, type Effect = Callable[[], None], type Thunk[T] = Callable[[], T], type Mode = Literal[...]
TypeGuard (Python 3.10+)is_ok, is_fail, is_test_result_ok, is_test_result_fail, is_test_result_skipped
Self (3.11+)Fluent returns from POMs, loggers, invariants
@final (3.8+)Locks critical classes (Watcher, Test, TestCycle, ChainRunner, Ok, Fail, …)
Unpack (3.11+)HumanizedDriver signature in ocarina-example
Protocol (3.8+)ScreenshotDriver, SupportsWrite[str]
Literal (3.8+)All enums (SeleniumCliStoreKeys, LOGGERS_CHOICES, Mode)
Never (3.11+)_SilentArgumentParser.error signature

Practical consequence: there is a dedicated CI workflow unstable_python_full_build.yml that pushes Python 3.15-dev monthly (cron: "0 3 1 * *"), because Ocarina aims to be ready for the next interpreter as soon as it ships. See ../10-cicd/02-ocarina-workflows.md

05.07 — Igoristan CI/CD

05.07 — Igoristan CI/CD#

Two workflows: ci-pr.yml on PR (3 parallel jobs), deploy.yml on push main (GitHub Pages).

ci-pr.yml#

name: CI/PR

on:
  pull_request:
    branches: ["**"]
  workflow_dispatch:

defaults:
  run:
    shell: bash

jobs:
  format-check:
    runs-on: ubuntu-latest
    env:
      WIREIT_CACHE: github
    steps:
      - uses: actions/checkout@v6
      - uses: pnpm/action-setup@v5
        with: { version: 11 }
      - uses: actions/setup-node@v6
        with: { node-version: 24, cache: "pnpm" }
      - uses: google/wireit@setup-github-actions-caching/v2
      - name: Install project
        run: make install
      - name: Formatcheck
        run: make ci:format-check

  lint:
    runs-on: ubuntu-latest
    env:
      WIREIT_CACHE: github
    steps:
      # ... same ...
      - uses: actions/cache@v5
        with:
          path: .eslintcache
          key: eslint-cache-${{ hashFiles('eslint.config.ts', 'src/**/*.*', 'package.json') }}
      - name: Lint
        run: pnpm lint

  typecheck:
    runs-on: ubuntu-latest
    env:
      WIREIT_CACHE: github
    steps:
      # ... same ...
      - name: Typecheck
        run: pnpm typecheck
JobCommandCache
format-checkpnpm exec prettier . --check (via wireit)wireit + node_modules
lintpnpm exec eslint ... --max-warnings 0 --cachewireit + .eslintcache (actions/cache)
typechecktsc --build --pretty tsconfig.jsonwireit + tsbuildinfo
                          PR opened / push
                                  │
                ┌─────────────────┼─────────────────┐
                ▼                 ▼                 ▼
        ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
        │ format-check │ │     lint     │ │  typecheck   │
        │ (1-2 minutes)│ │ (1-2 minutes)│ │ (1-2 minutes)│
        └──────────────┘ └──────────────┘ └──────────────┘
                │                 │                 │
                └─────────────────┴─────────────────┘
                                  ▼
                             PR mergeable

deploy.yml#

name: Deploy to GitHub Pages

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: pnpm/action-setup@v5
        with: { version: 11 }
      - uses: actions/setup-node@v6
        with: { node-version: 24, cache: "pnpm" }
      - name: Install dependencies
        run: pnpm install --frozen-lockfile
      - name: Build
        run: pnpm build
      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v4
        with: { path: dist/client }

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - id: deployment
        uses: actions/deploy-pages@v5
JobEffect
buildpnpm install --frozen-lockfile → pnpm build (= wireit build = lint → typecheck → vike build) → upload dist/client
deployactions/deploy-pages@v5 → publishes the artifact → URL = https://mojo-molotov.github.io/igoristan/

concurrency: pages + cancel-in-progress: false#

concurrency:
  group: "pages"
  cancel-in-progress: false

Prevents two simultaneous deployments (race condition).
The second waits (cancel-in-progress: false → we don’t cancel the running one).

07.11 — CI

07.11 — CI#

Three workflows: main_ci.yml (fast, lint + typecheck), dev_ci.yml (same for dev/feature/fix branches), e2e.yml (manual, Redis service + Firefox).

Overview#

WorkflowTriggerPlatformEffect
main_ci.ymlpush/PR mainubuntu + windows × py 3.14make check-coding-style (mypy + ruff). No browser.
dev_ci.ymlpush dev / feature/_ / fix/_ubuntu × py 3.14id., but Ubuntu only
e2e.ymlworkflow_dispatch (manual)ubuntu + Redis service + Firefox + geckodriverFull run of the e2e suite. Upload .screenshots/, .ocarina_logs/, .reports/.

main_ci.yml#

name: Main branch CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:

defaults:
  run:
    shell: bash

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        python-version: ["3.14"]
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with: { python-version: "3.14" }
      - uses: actions/cache@v5
        with:
          path: .venv
          key: venv-${{ runner.os }}-py3.14-${{ hashFiles('pyproject.toml') }}
      - name: Install
        run: make install-on-ci
      - name: Check coding style
        run: |
          . .venv/bin/activate
          make check-coding-style
  1. OS matrix: ubuntu + windows — verifies Python portability.
  2. No browser: just make check-coding-style (mypy + ruff). Fast, no Selenium / Redis / OTP.
  3. .venv cache: reused between runs.

dev_ci.yml#

on:
  push:
    branches: [dev, "feature/**", "fix/**"]
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    # … identical to main_ci.yml, just Ubuntu only …

Identical to main_ci.yml but Ubuntu only (Windows only runs on main).

Chapter 10 — CI/CD across the whole ecosystem

Chapter 10 — CI/CD across the whole ecosystem#

Summary table of every CI workflow in the ecosystem.

Outline#

#FileTopic
0101-matrix.mdSummary table of every workflow.
0202-ocarina-workflows.mdocarina: main_ci.yml, dev_ci.yml, unstable_python_full_build.yml
0303-example-workflows.mdocarina-example: main_ci.yml, dev_ci.yml, e2e.yml
0404-ai-workflows.mdocarina-with-ai-example: ai_proof_ci.yml, ai_proof_e2e.yml
0505-igoristan-workflows.mdigoristan: ci-pr.yml, deploy.yml
0606-holy-book-workflow.mdocarina-holy-book: deploy.yml
0707-tests-workers-vercel.mdtests-workers: no GitHub CI, deployment handled directly by Vercel.

Overview#

RepoWorkflowsTotal
ocarinamain_ci + dev_ci + unstable_python_full_build3
ocarina-examplemain_ci + dev_ci + e2e3
ocarina-with-ai-exampleai_proof_ci + ai_proof_e2e2
igoristanci-pr + deploy2
ocarina-holy-bookdeploy1
tests-workersnone (delegated to Vercel)0

+ ocarina/.github/actions/allure-history/action.yml.