00.02 — Matrice stack / responsabilité / licence

00.02 — Matrice stack / responsabilité / licence#

DépôtRôleLangageVersionStack principaleStack outillageDistributionLicence
ocarinaFramework de test e2e navigateurPython3.14+hatchling, python-docx (seule dépendance d’exécution), selenium + playwright (dev seulement)ruff (ALL), mypy strict, pytest, hypothesis, pytest-mypy-plugins, syrupy, prysk (cram), allure-pytest, pre-commit, twine, buildPyPI, v1.1.10MIT
ocarina-exampleSuite canonique e2e contre l’IgoristanPython3.14+ocarina, selenium ≥ 4.40, python-dotenv, dogpile.cache, redisruff, mypy, pre-commitSource uniquementMIT
ocarina-with-ai-exampleSuite e2e CURA Healthcare co-écrite par Claude CodePython3.14+ocarina ≥ 1.0.3, selenium ≥ 4.40ruff, mypy, mypy-extensions, typing-extensions, pre-commitSource uniquementMIT
igoristanSUT public, application web volontairement chaotiqueTypeScript6.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 (orchestrateur), eslint 9 (flat), prettier 3.5, husky, lint-staged, commitlint, commitizen, terser, rollup-plugin-visualizer, vite-plugin-compression, @qalisa/vike-plugin-sitemapGitHub Pages (/igoristan/)aucune
tests-workersBackend OTP / Corsicadex pour exercer la parallélisation et les tests avec appels APITypeScript5.9.3Vercel Edge Functions (runtime: "edge"), @upstash/redis, otplib, types next (NextRequest)pnpm 11.x, @vercel/node (types)Vercel : https://tests-workers.vercel.appISC
ocarina-holy-bookDocumentation publique + skills IA + PDFTypeScript6.0.xVitePress 2 alpha, theme @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#

Apport Python 3.12+Utilisation dans Ocarina
PEP 695 (class Foo[T]:)Signature générique partout (TestSuite[Driver], Watcher[Driver], Test[Driver], Result[T], Ok[T], Thunk[T], etc.)
PEP 695 type aliases (type X = ...)Tous les 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+)Retours fluides des POMs, des loggers, des invariants
@final (3.8+)Verrouille les classes critiques (Watcher, Test, TestCycle, ChainRunner, Ok, Fail, …)
Unpack (3.11+)Signature de HumanizedDriver côté ocarina-example
Protocol (3.8+)ScreenshotDriver, SupportsWrite[str]
Literal (3.8+)Toutes les énumérations (SeleniumCliStoreKeys, LOGGERS_CHOICES, Mode)
Never (3.11+)Signature de _SilentArgumentParser.error

Conséquence pratique : il existe un workflow CI dédié unstable_python_full_build.yml qui pousse Python 3.15-dev mensuellement (cron: "0 3 1 * *"), parce qu’Ocarina veut être prêt pour le prochain interpréteur dès qu’il sort. Voir ../10-cicd/02-ocarina-workflows.md

05.07 — CI/CD de l'Igoristan

05.07 — CI/CD de l’Igoristan#

Deux workflows : ci-pr.yml sur PR (3 jobs parallèles), deploy.yml sur 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:
      # ... idem ...
      - 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:
      # ... idem ...
      - name: Typecheck
        run: pnpm typecheck
JobCommandeCache
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
JobEffet
buildpnpm install --frozen-lockfile → pnpm build (= wireit build = lint → typecheck → vike build) → upload dist/client
deployactions/deploy-pages@v5 → publie l’artifact → URL = https://mojo-molotov.github.io/igoristan/

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

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

Empêche deux déploiements simultanés (race condition).
Le second attend (cancel-in-progress: false → on ne cancel pas le run en cours).

07.11 — CI

07.11 — CI#

Trois workflows : main_ci.yml (rapide, lint + typecheck), dev_ci.yml (idem pour branches dev/feature/fix), e2e.yml (manuel, service Redis + Firefox).

Vue d’ensemble#

WorkflowTriggerPlateformeEffet
main_ci.ymlpush/PR mainubuntu + windows × py 3.14make check-coding-style (mypy + ruff). Pas de browser.
dev_ci.ymlpush dev / feature/_ / fix/_ubuntu × py 3.14id., mais Ubuntu seul
e2e.ymlworkflow_dispatch (manuel)ubuntu + service Redis + Firefox + geckodriverRun complet de la suite e2e. 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. Matrice OS : ubuntu + windows. Vérifie la portabilité Python du code projet.
  2. Pas de browser : on lance juste make check-coding-style (= mypy + ruff). Rapide, pas besoin de Selenium / Redis / OTP.
  3. Cache .venv : reuse entre runs.

dev_ci.yml#

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

jobs:
  test:
    runs-on: ubuntu-latest
    # … identique à main_ci.yml, juste Ubuntu seul …

Identique au main_ci.yml mais Ubuntu seul (Windows ne run que sur main).

Chapitre 10 — CI/CD de tout l'écosystème

Chapitre 10 — CI/CD de tout l’écosystème#

Tableau récapitulatif de tous les workflows CI de l’écosystème.

Plan#

#FichierSujet
0101-matrix.mdTableau récapitulatif de tous les workflows.
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 : pas de CI GitHub, déploiement directement pris en charge par Vercel.

Vue d’ensemble#

DépôtWorkflowsTotal
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-workersaucun (délégué à Vercel)0

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