perf: cache video audio probe and skip library scans when opening ove… #45
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| jobs: | |
| # Run the Ren'Py testcases harness against pinned SDKs -- the code path | |
| # pytest cannot cover (real .rpy screens + the 7.x/Py2 runtime). The SDK | |
| # launcher (renpy.sh at the SDK root) is passed straight to | |
| # bin/test_harness.sh, which sniffs the bundled major version from | |
| # renpy/__init__.py and runs the matching DSL template. | |
| testcases: | |
| name: testcases (Ren'Py ${{ matrix.renpy }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - renpy: "7.4.10" | |
| os: ubuntu-22.04 | |
| - renpy: "8.5.3" | |
| os: ubuntu-latest | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| # Explicit fixture root (empty is fine -- CueDatabase.open() creates all | |
| # subdirs at init). Never let the run inherit a machine-local pointer | |
| # file, which would override the env var. | |
| RENPY_CUE_DIR: ${{ github.workspace }}/tests/fixtures/data | |
| # Headless runner: no audio device. The testcases play no audio. | |
| SDL_AUDIODRIVER: dummy | |
| # Legacy workers default to one per vCPU (capped at 8), so the 7.x leg | |
| # runs parallel here (2 workers on the standard runner). 7.4.10 drops | |
| # synthetic test-mouse clicks under multi-engine Xvfb contention, so each | |
| # worker starts its own display (bin/test_harness.sh); one per core | |
| # avoids that contention. The modern leg is single-process and ignores | |
| # workers. | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # Pinned SDKs are immutable, so a version-keyed cache never goes stale. | |
| # Restoring the extracted tree skips the 100-150MB download + tar.bz2 | |
| # decompress on every run. | |
| - name: Cache Ren'Py SDK | |
| uses: actions/cache@v4 | |
| id: cache-sdk | |
| with: | |
| path: renpy-${{ matrix.renpy }}-sdk | |
| key: renpy-sdk-${{ matrix.renpy }}-${{ runner.os }} | |
| - name: Download Ren'Py SDK | |
| if: steps.cache-sdk.outputs.cache-hit != 'true' | |
| run: | | |
| curl -fL "https://www.renpy.org/dl/${{ matrix.renpy }}/renpy-${{ matrix.renpy }}-sdk.tar.bz2" -o sdk.tar.bz2 | |
| tar xjf sdk.tar.bz2 | |
| - name: Set SDK_DIR | |
| run: echo "SDK_DIR=$PWD/renpy-${{ matrix.renpy }}-sdk" >> "$GITHUB_ENV" | |
| # The video-variant testcases encode with real ffmpeg/ffprobe; the ubuntu | |
| # runner images don't ship them, so a job launch fails with OSError errno 2 | |
| # (the "fix weird layout shift" era of CI failures). Install before run. | |
| - name: Install ffmpeg | |
| run: sudo apt-get update && sudo apt-get install -y ffmpeg | |
| # The `test` command is uses_display=True and the 7.x leg forces | |
| # SDL_VIDEODRIVER=x11 -- both need a real X server. xvfb provides it. | |
| - name: Run testcases | |
| # Explicit `bash` invocation: the repo lives on a filesystem that | |
| # doesn't persist the exec bit (core.fileMode=false), so the scripts | |
| # aren't executable in the working tree. | |
| # The 7.x leg runs parallel workers, each with its own Xvfb display, so | |
| # wrapping it in xvfb-run too would nest a second display layer (and | |
| # leak XAUTHORITY across displays). Only the modern single-process leg | |
| # needs the wrapper. | |
| run: | | |
| if [ "${{ matrix.renpy }}" = "8.5.3" ]; then | |
| xvfb-run -a bash bin/test_harness.sh "$SDK_DIR/renpy.sh" | |
| else | |
| bash bin/test_harness.sh "$SDK_DIR/renpy.sh" | |
| fi | |
| # Fast gate: pyright + 120-char lint, then the pytest suite, under the | |
| # modern toolchain. Mirrors the /lint and /test skills via bin/*.sh. | |
| check: | |
| name: lint + test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| id: python | |
| with: | |
| python-version: "3.12" | |
| # Cache the poetry venv in-project. The key includes the exact resolved | |
| # Python patch because a venv's interpreter symlink is tied to that | |
| # path -- when the hosted image bumps the patch the key changes and the | |
| # venv is rebuilt, instead of restoring a dead one. | |
| - name: Cache poetry venv | |
| uses: actions/cache@v4 | |
| id: cache-venv | |
| with: | |
| path: .venv | |
| key: poetry-venv-${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} | |
| - name: Install poetry + deps | |
| run: | | |
| python -m pip install --upgrade pip "poetry==2.4.1" | |
| poetry config virtualenvs.in-project true | |
| poetry install | |
| # bin/lint.sh calls bare `pyright` (not `poetry run pyright`), so the | |
| # project venv's bin/ must be on PATH. | |
| # | |
| # pyrightconfig.json's extraPaths point at the SDK in .local/ (a | |
| # gitignored, local-only location this runner must recreate). Download the | |
| # SDK and unpack it into .local/ so pyright can resolve renpy.* on this | |
| # clean runner. Uses its own cache key (not the harness job's) so the two | |
| # jobs can't race on the same key with different path layouts. | |
| - name: Cache Ren'Py SDK for pyright | |
| uses: actions/cache@v4 | |
| id: cache-sdk | |
| with: | |
| path: .local/renpy-8.5.3-sdk | |
| key: pyright-sdk-8.5.3-${{ runner.os }} | |
| - name: Download Ren'Py SDK for pyright | |
| if: steps.cache-sdk.outputs.cache-hit != 'true' | |
| run: | | |
| mkdir -p .local | |
| curl -fL "https://www.renpy.org/dl/8.5.3/renpy-8.5.3-sdk.tar.bz2" -o sdk.tar.bz2 | |
| tar xjf sdk.tar.bz2 -C .local | |
| - name: Lint | |
| run: | | |
| export PATH="$(poetry env info -p)/bin:$PATH" | |
| bash bin/lint.sh | |
| - name: Test | |
| run: bash bin/test.sh |