Skip to content

Manual Test Run — main #4

Manual Test Run — main

Manual Test Run — main #4

name: Manual Test Run (Resumable)
run-name: Manual Test Run — ${{ github.ref_name }}
on:
workflow_dispatch:
permissions:
contents: read # Required to checkout repository contents
jobs:
run-tests:
name: Full Test Suite
runs-on: ubuntu-latest
steps:
# ==========================================
# 1. BASE SETUP (Checkout & Environments)
# ==========================================
- name: Checkout repository
uses: actions/checkout@v5
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install Pipenv
run: pip install pipenv
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: '24'
# ==========================================
# 2. CACHES
# ==========================================
- name: Cache Pipenv
uses: actions/cache@v5
with:
path: ~/.local/share/virtualenvs
key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }}
restore-keys: |
${{ runner.os }}-pipenv-
- name: Cache NPM
uses: actions/cache@v5
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
# For Playwright we use a fixed cache per version
- name: Get Playwright version (from package.json)
id: playwright-version
working-directory: ./frontend
run: echo "PLAYWRIGHT_VERSION=$(node -p "require('./package.json').devDependencies['@playwright/test'].replace(/[\^~]/g, '')" || echo 'fallback')" >> $GITHUB_ENV
- name: Cache Playwright Browsers
uses: actions/cache@v5
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
# ==========================================
# 3. INSTALLATION & TESTS
# ==========================================
- name: Install Python Dependencies
run: pipenv install --dev
- name: Install Frontend & Playwright Dependencies (via dev.py)
timeout-minutes: 15
run: pipenv run ./dev.py install
- name: Run Complete Test Suite
id: run_tests
timeout-minutes: 180
run: pipenv run ./dev.py test --fresh-run --quiet --log-file /tmp/test-run-cache/full-run.log all
# Copy the cache to a plain (non-dotfile) name in a dedicated folder before
# upload. This sidesteps any glob/dotfile-matching quirk in the upload-artifact
# action and gives a clear, visible log line confirming whether the runner
# actually produced scripts/test_runner/.run_cache.json.
# The full run log (--log-file above) already lands in /tmp/test-run-cache/.
- name: Prepare test run cache for upload
if: always()
run: |
mkdir -p /tmp/test-run-cache
if [ -f scripts/test_runner/.run_cache.json ]; then
cp scripts/test_runner/.run_cache.json /tmp/test-run-cache/run_cache.json
echo "✅ Found scripts/test_runner/.run_cache.json, staged for upload:"
cat /tmp/test-run-cache/run_cache.json
else
echo "⚠️ scripts/test_runner/.run_cache.json does not exist — nothing to upload."
ls -la scripts/test_runner/ || true
fi
if [ -f /tmp/test-run-cache/full-run.log ]; then
echo "✅ Full run log present ($(wc -l < /tmp/test-run-cache/full-run.log) lines):"
tail -n 40 /tmp/test-run-cache/full-run.log || true
else
echo "⚠️ /tmp/test-run-cache/full-run.log missing — the run may have crashed before producing it."
fi
# Upload resume cache + full log on both pass/fail so dev can download them,
# place .run_cache.json at scripts/test_runner/.run_cache.json locally, then run:
# ./dev.py test --resume all
# and read full-run.log to see exactly how/where the run stopped.
# if: always() matters because normal step failures would otherwise skip upload.
- name: Upload test run cache
if: always()
uses: actions/upload-artifact@v6
with:
name: test-run-cache-${{ github.run_id }}
path: /tmp/test-run-cache/
if-no-files-found: warn
retention-days: 14