10.04 — Workflows ocarina-with-ai-example#

Voir aussi ../08-ai-example/09-ci-matrix.md

Vue d’ensemble#

WorkflowTriggerOSEffetNote
ai_proof_ci.ymlpush main, PR, dispatchubuntu × py 3.14ruff format src/ --checkruff check src/mypy src/Gate PR, rapide
ai_proof_e2e.ymldispatchubuntu × matrice firefox+chromewarm-up Heroku + run + sed filter ChromeDriver C++ stacks + uploadManuel uniquement

Différences avec ocarina-example#

Aspectocarina-exampleocarina-with-ai-example
Matrice browserFirefox seul (e2e.yml)Firefox + Chrome (parallélisés)
SUTIgoristan (GitHub Pages)CURA (Heroku eco-dyno)
Pre-runwarm-up Redis clientwarm-up Heroku dyno
Filtre outputaucunsed filtre les stack frames C++ ChromeDriver
WAIT_TIMEOUTdefault 1015 (compense les latences Heroku)

warm-up Heroku#

curl -sf --retry 6 --retry-delay 5 --retry-all-errors \
  --max-time 30 https://katalon-demo-cura.herokuapp.com/ > /dev/null
echo "Dyno is warm"

CURA runs on a Heroku dyno that sleeps after inactivity. Tests hitting a cold dyno produce timeouts (false fails) and slow confirmations (false passes on gap tests). Wake it explicitly before any browser opens.

Le filtre sed des stacktraces C++ ChromeDriver#

.venv/bin/python -u src/main.py ... 2>&1 | sed -u \
  -e '/Stacktrace:/{N;/\n#[0-9][0-9]* 0x[0-9a-f][0-9a-f]* <unknown>/{s/Stacktrace:\n[^\n]*/HIDDEN/;b};P;D}' \
  -e '/^#[0-9][0-9]* 0x[0-9a-f][0-9a-f]* <unknown>/d'

ChromeDriver release builds ship without debug symbols. On errors it dumps raw C++ stack frames ("#N 0x") into the WebDriver response, which Selenium surfaces as the exception message — polluting both the live log and the pretty-print summary with unreadable hex noise. No Python-side fix exists. Strip the frames with sed before they land. pipefail preserves Python’s exit code through the pipe.

  • ChromeDriver, en cas d’erreur, dump des stack frames C++ illisibles (#0 0x7f3b... <unknown>).
  • Selenium les remonte dans le message d’exception.
  • Pollue les logs et la sortie pretty_print_results
  • Pas de correctif pertinent à faire directement dans le code Python.
  • sed les vire avant que ça n’atteigne l’utilisateur, directement depuis le shell.

set -o pipefail préserve l’exit code de Python.

fail-fast: false#

strategy:
  fail-fast: false
  matrix:
    include:
      - browser: firefox
        driver: geckodriver
      - browser: chrome
        driver: chromedriver

Si Firefox fail, Chrome continue.
La valeur est dans la comparaison des deux runs.

WAIT_TIMEOUT: 15#

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
  WAIT_TIMEOUT: 15

15 secondes au lieu du default 10. Compense les latences Heroku dyno qui peuvent être supérieures à la moyenne même après cold-start (même avec warm-up curl, les requêtes suivantes peuvent être lentes).

Rappel : _NOT_CONFIRMED_TIMEOUT = 10 (dans confirmation.py) n’est pas affecté (cf. ../08-ai-example/06-data-gaps.md).

Firefox#

- name: Install geckodriver
  if: matrix.browser == 'firefox'
  run: |
    GECKO_VERSION=0.36.0
    wget -q https://github.com/mozilla/geckodriver/releases/download/v$GECKO_VERSION/geckodriver-v$GECKO_VERSION-linux64.tar.gz
    tar -xzf geckodriver-v$GECKO_VERSION-linux64.tar.gz
    chmod +x geckodriver

- name: Setup Firefox
  if: matrix.browser == 'firefox'
  uses: browser-actions/setup-firefox@fcf821c621167805dd63a29662bd7cb5676c81a8

Chrome#

- name: Install chromedriver
  if: matrix.browser == 'chrome'
  run: |
    CHROME_VER=$(google-chrome-stable --version | grep -oP '\d+\.\d+\.\d+\.\d+')
    wget -q -O chromedriver.zip \
      "https://storage.googleapis.com/chrome-for-testing-public/${CHROME_VER}/linux64/chromedriver-linux64.zip"
    unzip -q chromedriver.zip
    mv chromedriver-linux64/chromedriver ./chromedriver
    chmod +x ./chromedriver

ubuntu-latest ships google-chrome-stable. On extrait sa version exacte, on télécharge le chromedriver matché depuis le CDN officiel Google chrome-for-testing-public.

→ Garantit la compatibilité Chrome ↔ ChromeDriver.

Enumerate traces#

- name: Enumerate traces
  if: always()
  run: |
    sync
    find $GITHUB_WORKSPACE/.screenshots -type f 2>/dev/null || true
    find $GITHUB_WORKSPACE/.ocarina_logs -type f 2>/dev/null || true
    find $GITHUB_WORKSPACE/.reports -type f 2>/dev/null || true

Step qui force une synchronisation du système de fichiers et liste les traces produites avant l’upload. Permet de voir directement dans les logs GitHub quels fichiers ont été générés.

Upload artifacts par navigateur#

- name: Upload screenshots
  if: always()
  uses: actions/upload-artifact@v4
  with:
    name: screenshots-${{ matrix.browser }}
    path: .screenshots/
    retention-days: 7

Noms incluant le navigateur (screenshots-firefox, screenshots-chrome). Pas de collision entre les deux runs parallèles.

Conservé 7 jours.