docs(conformance): finish reading the second-source documents #30
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@v7 | |
| - uses: actions/setup-python@v7 | |
| 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@v7 | |
| 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 | |
| types: | |
| name: Types | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-python@v7 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install the type checker | |
| run: pipx install mypy==1.14.1 | |
| # Strict, with every optional error class the version offers. A processor | |
| # core is masked integers, flag bits and addressing modes end to end, and a | |
| # width crossing a boundary it should not is exactly what this catches. The | |
| # settings live in pyproject.toml so a local run and this one agree. | |
| - name: Every annotation has to hold | |
| run: mypy | |
| test: | |
| name: Tests on Python ${{ matrix.python }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python: ["3.12", "3.13", "3.14"] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-python@v7 | |
| 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 mos65xx conformance -name '*.test.py' | sort) | |
| exit "${status}" | |
| shell: bash | |
| - name: Coverage must be total | |
| run: python -m coverage report | |
| conformance: | |
| name: Conformance against SingleStepTests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-python@v7 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| # One key for every suite, taken from the file that pins them all, so the | |
| # two jobs that need them share one entry rather than filling the cache | |
| # with the same gigabytes twice. | |
| - name: Cache the suites | |
| id: cache | |
| uses: actions/cache@v6 | |
| with: | |
| path: ~/.cache/conformance-suites | |
| key: suites-${{ hashFiles('conformance/suites.json') }} | |
| - name: Fetch the suite | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: python conformance/fetch.py ~/.cache/conformance-suites | |
| # A pull request runs a tenth of each suite for a quick answer. A push to | |
| # main runs every case, because the number of them is what the claim of | |
| # conformance rests on, and the claim covers every part rather than one. | |
| - name: Run every suite | |
| run: | | |
| if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then | |
| limit=1000 | |
| else | |
| limit=0 | |
| fi | |
| status=0 | |
| while read -r suite model; do | |
| echo "::group::${suite} as a ${model}" | |
| python conformance/singlestep.py \ | |
| "${HOME}/.cache/conformance-suites/${suite}" "${limit}" --model "${model}" || status=1 | |
| echo "::endgroup::" | |
| done <<'SUITES' | |
| 65816/65816/v1 65816 | |
| 6502/6502/v1 6502 | |
| nes6502/nes6502/v1 2a03 | |
| synertek65c02/synertek65c02/v1 65c02 | |
| rockwell65c02/rockwell65c02/v1 r65c02 | |
| wdc65c02/wdc65c02/v1 w65c02 | |
| SUITES | |
| exit "${status}" | |
| shell: bash | |
| cycles: | |
| name: Cycle for cycle against SingleStepTests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-python@v7 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| # One key for every suite, taken from the file that pins them all, so the | |
| # two jobs that need them share one entry rather than filling the cache | |
| # with the same gigabytes twice. | |
| - name: Cache the suites | |
| id: cache | |
| uses: actions/cache@v6 | |
| with: | |
| path: ~/.cache/conformance-suites | |
| key: suites-${{ hashFiles('conformance/suites.json') }} | |
| - name: Fetch the suite | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: python conformance/fetch.py ~/.cache/conformance-suites | |
| # Every cycle of an eight-bit part is a bus cycle, so this compares timing | |
| # and side effects at once: address, value, and read against write, in | |
| # order. On the 65816 it also compares eight output pins per cycle, and the | |
| # cycles where the part drives no valid address at all. | |
| - name: Compare the bus, cycle by cycle | |
| run: | | |
| if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then | |
| limit=1000 | |
| else | |
| limit=0 | |
| fi | |
| status=0 | |
| while read -r suite model; do | |
| echo "::group::${suite} as a ${model}" | |
| python conformance/cycles.py \ | |
| "${HOME}/.cache/conformance-suites/${suite}" "${limit}" --model "${model}" || status=1 | |
| echo "::endgroup::" | |
| done <<'SUITES' | |
| 65816/65816/v1 65816 | |
| 6502/6502/v1 6502 | |
| nes6502/nes6502/v1 2a03 | |
| synertek65c02/synertek65c02/v1 65c02 | |
| rockwell65c02/rockwell65c02/v1 r65c02 | |
| wdc65c02/wdc65c02/v1 w65c02 | |
| SUITES | |
| exit "${status}" | |
| shell: bash |