name: parity # The vanilla harnesses a pull request's changes can affect, on the Mac mini's runner or playhorizon's, which hold the # maintainer's own Minecraft files (Horizon never downloads the game). Called by ci.yml for pull requests from this repository # and by run-parity.yml when a maintainer labels a fork's pull request run-parity. See docs/release-flow.md. on: workflow_call: inputs: base: description: The pull request's base commit (the harnesses its changes since then can affect) type: string required: true head: description: The commit to check out and test type: string required: true full: description: >- The pull request carries the full-parity label (a change every harness reaches, such as a crate split): it runs on playhorizon's runner only, so the Mac mini's runners stay free for the others. While that runner is busy the job waits for it. type: boolean default: false permissions: contents: read env: # Test runs never reach the telemetry server: no live-count ping, no uploads (docs/telemetry.md). HORIZON_TELEMETRY_URL: "off" jobs: parity: runs-on: ${{ inputs.full && fromJSON('["self-hosted", "horizon-game", "playhorizon"]') || fromJSON('["self-hosted", "horizon-game"]') }} # A change to core crates reruns ~350 harnesses: ~60-90 min on the Mac mini; on playhorizon (4 of its 8 vCPUs, 4 # harnesses at a time) up to a few hours, and any pull request's job may land there. timeout-minutes: ${{ inputs.full && 360 || 180 }} steps: - uses: actions/checkout@v4 with: # The commit the event names: a fork's later pushes need another run-parity label. The next step merges # main into it. ref: ${{ inputs.head }} fetch-depth: 0 persist-credentials: false # Keeps .local/ (parity state, probe builds, oracle results) and target/ between runs. clean: false - name: The head merged into main (what merging it would land) id: merge env: BASE_SHA: ${{ inputs.base }} HEAD_SHA: ${{ inputs.head }} run: | # Harness fixes and game fixes that reached main since the branch was made then apply here too: a head # tested alone failed harnesses already fixed on main (server_knockback before #2114, mob_ai's heap before # #2270, save_roundtrip before #2212). Selection then compares with this main, so it sees only the pull # request's own changes. A head that conflicts with main is tested alone. set -euo pipefail git merge --abort 2>/dev/null || true git fetch -q --no-tags origin +refs/heads/main:refs/remotes/origin/main main=$(git rev-parse origin/main) if git -c user.name=parity -c user.email=parity@localhost merge -q --no-edit --no-ff "$main" >/dev/null 2>&1; then echo "base=$main" >> "$GITHUB_OUTPUT" echo "Tested: head ${HEAD_SHA:0:9} merged into main ${main:0:9}" | tee -a "$GITHUB_STEP_SUMMARY" else git merge --abort echo "base=$BASE_SHA" >> "$GITHUB_OUTPUT" echo "::warning::head ${HEAD_SHA:0:9} conflicts with main ${main:0:9}: tested alone, without main's fixes" echo "Tested: head ${HEAD_SHA:0:9} alone (it conflicts with main ${main:0:9})" | tee -a "$GITHUB_STEP_SUMMARY" fi - uses: dtolnay/rust-toolchain@stable - name: Tools from the runner run: bash tools/ci/runner-env.sh - name: Vanilla data, and resources prepared by this preparer run: bash tools/ci/vanilla-data.sh - name: The prepared output is the one the preparer's OUTPUT_VERSION says env: BASE_SHA: ${{ steps.merge.outputs.base }} run: | # A head made before OUTPUT_VERSION (#1947) that conflicts with main has neither the tool nor the number. if [ ! -f tools/prepare_output.py ] || ! grep -q OUTPUT_VERSION crates/horizon-prepare/src/lib.rs; then echo "This head's preparer has no OUTPUT_VERSION: nothing to check" exit 0 fi python3 tools/prepare_output.py check --cache --base "$BASE_SHA" - name: The version constants are the pinned jar's run: python3 tools/gen_version_consts.py --check - name: The harnesses this change can affect env: PARITY_HOSTS: '' BASE_SHA: ${{ steps.merge.outputs.base }} run: python3 tools/parity.py --changed "$BASE_SHA" --timeout 2400 # world_spawn takes ~1480 s on a busy runner - name: Logs of the failed harnesses if: failure() uses: actions/upload-artifact@v4 with: name: parity-logs path: .local/parity-runner/logs/ if-no-files-found: ignore retention-days: 3