Manual Test Run — main #4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |