feat: drive every part with its own cartridge's exchanges #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: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| PYTHON_VERSION: "3.12" | |
| jobs: | |
| lint: | |
| name: Format and lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install ruff | |
| run: pipx install ruff==0.16.3 | |
| - name: Check formatting | |
| run: ruff format --check . | |
| - name: Lint | |
| run: ruff check --output-format=github . | |
| - uses: pnpm/action-setup@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - name: Install the formatter | |
| run: pnpm install --frozen-lockfile --ignore-scripts | |
| - name: Check that every JSON file is formatted | |
| run: pnpm run format:check | |
| test: | |
| name: Tests on Python ${{ matrix.python }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python: ["3.12", "3.13", "3.14"] | |
| steps: | |
| # The package reaches the processor through this submodule, and without it | |
| # the microcode backend cannot be built at all. Checking it out here does | |
| # not supply any firmware, so the runner still exercises the path a user | |
| # without an image takes. | |
| - uses: actions/checkout@v5 | |
| with: | |
| submodules: recursive | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python }} | |
| - name: Install coverage | |
| run: python -m pip install --disable-pip-version-check coverage==7.6.10 | |
| - name: Run every test file, under coverage | |
| run: | | |
| python -m coverage erase | |
| status=0 | |
| while IFS= read -r file; do | |
| echo "::group::${file}" | |
| python -m coverage run -a "${file}" || status=1 | |
| echo "::endgroup::" | |
| done < <(find snesdsp conformance -name '*.test.py' | sort) | |
| exit "${status}" | |
| shell: bash | |
| - name: Coverage must be total | |
| run: python -m coverage report | |
| firmware: | |
| name: Against the parts, when any microcode is present | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| submodules: recursive | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| # This runs the program a cartridge carries, which belongs to whoever | |
| # wrote it, so on a machine without one it says so and stops rather than | |
| # reporting a pass. Everything a machine without one can check runs in the | |
| # test job above: this package has no behaviour of its own to get wrong. | |
| # Exit 2 is the runner saying it had nothing to run, which is the honest | |
| # answer to a person who asked it to drive a part and holds no image. It is | |
| # not a failure of this build, so it is caught here rather than by making | |
| # the tool lie about it. | |
| - name: Drive the parts with the exchanges real cartridges make | |
| run: | | |
| set +e | |
| status=0 | |
| for part in dsp1 dsp2 dsp3 dsp4; do | |
| echo "::group::${part}" | |
| python conformance/against_cartridges.py "${part}" | tee -a report.txt | |
| here=${PIPESTATUS[0]} | |
| echo "::endgroup::" | |
| [ "${here}" -eq 0 ] || status="${here}" | |
| done | |
| set -e | |
| if [ "${status}" -eq 2 ]; then | |
| echo "::notice title=No microcode present::The checks that run a part's own program did not run. They are not failures; they had nothing to run." | |
| exit 0 | |
| fi | |
| exit "${status}" | |
| shell: bash |