z3660: honour the minterm on a rect copy #3
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: Windows | |
| # Two parallel builder jobs produce the portable Windows zip and the prebuilt | |
| # test executables (both are full release compiles and roughly equally | |
| # expensive, so splitting them halves the critical path), then the checks fan | |
| # out in parallel against those artifacts, mirroring ci.yml: the packaged zip | |
| # is booted from a clean directory, and the unit suites plus the probe golden | |
| # renders (pixel-exact deterministic boots on the bundled AROS ROM) run | |
| # against the same release binaries. This is also the only Windows coverage | |
| # (the main CI runs on macOS and Linux), so the code-path triggers below run | |
| # the full release build on pull requests too. On a v* tag push (or a manual | |
| # run with release_tag) the zip is attached to the GitHub Release by the | |
| # release job, which runs only after every check passes. | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ["v*"] | |
| paths: | |
| - "src/**" | |
| - "vendor/**" | |
| - "assets/**" | |
| - "Cargo.lock" | |
| - "Cargo.toml" | |
| - ".cargo/**" | |
| - "packaging/windows/**" | |
| - ".github/workflows/windows.yml" | |
| pull_request: | |
| paths: | |
| - "src/**" | |
| - "vendor/**" | |
| - "assets/**" | |
| - "Cargo.lock" | |
| - "Cargo.toml" | |
| - ".cargo/**" | |
| - "packaging/windows/**" | |
| - ".github/workflows/windows.yml" | |
| # Manual rebuild. Use this to attach a zip to a release whose tag predates | |
| # this workflow (the v* tag tree has no windows.yml, so a tag push cannot | |
| # trigger it): run it against a branch that has the source parity you want | |
| # (for v0.2.0, main is identical to the tag bar the Homebrew bump) and set | |
| # release_tag to push the built zip onto that existing release. | |
| workflow_dispatch: | |
| inputs: | |
| release_tag: | |
| description: "Existing release tag to attach the zip to (e.g. v0.2.0). Leave blank to only upload a workflow artifact." | |
| required: false | |
| default: "" | |
| concurrency: | |
| group: windows-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| name: Build Windows zip | |
| # Compiles the release binary and packages the portable zip; the sibling | |
| # test-bins job compiles the test executables in parallel on its own | |
| # runner. | |
| runs-on: windows-latest | |
| steps: | |
| - name: Force LF checkout | |
| # The runner's git converts detected-text files to CRLF on checkout | |
| # by default. The repo carries no .gitattributes, and tests that | |
| # embed or read committed fixtures expect the bytes as committed, so | |
| # keep the working tree identical to the macOS/Linux jobs. | |
| run: git config --global core.autocrlf false | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: x86_64-pc-windows-msvc | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Build release zip | |
| shell: pwsh | |
| run: packaging/windows/build-zip.ps1 | |
| - name: Locate artifact | |
| id: artifact | |
| shell: pwsh | |
| run: | | |
| $zip = Get-ChildItem Copperline-*-win-x64.zip | Select-Object -First 1 | |
| "path=$($zip.Name)" >> $env:GITHUB_OUTPUT | |
| - name: Upload zip | |
| # Consumed by the zip-smoke and release jobs, and kept as the | |
| # workflow artifact. Uploading here (before the checks run) also | |
| # means a failing check still leaves the zip downloadable for | |
| # debugging. | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: copperline-windows | |
| path: ${{ steps.artifact.outputs.path }} | |
| if-no-files-found: error | |
| test-bins: | |
| name: Build test binaries | |
| # Compiles the #[test] targets once and hands the finished executables | |
| # to the test jobs below (needs: test-bins) as a workflow artifact. | |
| # Binaries, not a shared cargo cache: the test executables are plain | |
| # libtest binaries and run fine without cargo. cargo builds the emulator | |
| # binary here too (the integration tests spawn it through the | |
| # compile-time CARGO_BIN_EXE_copperline path), so the staged | |
| # copperline.exe pairs with the probe_golden harness compiled alongside | |
| # it and this job needs nothing from the zip build. Swatinem/rust-cache | |
| # keys per job, so each builder keeps its own warm cache. | |
| runs-on: windows-latest | |
| steps: | |
| - name: Force LF checkout | |
| # Keep committed fixture bytes identical to the build job (see the | |
| # comment there). | |
| run: git config --global core.autocrlf false | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: x86_64-pc-windows-msvc | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Compile test binaries | |
| shell: pwsh | |
| # The JSON build plan maps each test target to its hash-suffixed | |
| # executable so the binaries can be staged under stable names for | |
| # the fan-out jobs. The asset-gated integration tests under tests/ | |
| # keep compiling here too (they are #[ignore]d at run time, not | |
| # excluded from the build). | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| cargo test --release --locked --target x86_64-pc-windows-msvc --no-run --message-format=json > cargo-test-build.json | |
| if ($LASTEXITCODE -ne 0) { throw "cargo test --no-run exited with $LASTEXITCODE" } | |
| New-Item -ItemType Directory -Force -Path ci-bins | Out-Null | |
| Copy-Item target\x86_64-pc-windows-msvc\release\copperline.exe ci-bins\ | |
| Get-Content cargo-test-build.json | ForEach-Object { | |
| $msg = $_ | ConvertFrom-Json | |
| if ($msg.reason -eq "compiler-artifact" -and $msg.profile.test -and $msg.executable) { | |
| switch ("$($msg.target.kind[0]):$($msg.target.name)") { | |
| "lib:copperline" { Copy-Item $msg.executable ci-bins\unit-lib.exe } | |
| "bin:copperline" { Copy-Item $msg.executable ci-bins\unit-bin-copperline.exe } | |
| "bin:copperline-ctl" { Copy-Item $msg.executable ci-bins\unit-bin-copperline-ctl.exe } | |
| "test:probe_golden" { Copy-Item $msg.executable ci-bins\probe_golden.exe } | |
| } | |
| } | |
| } | |
| Get-ChildItem ci-bins | |
| - name: Upload binaries for the test jobs | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: windows-test-bins | |
| path: ci-bins/ | |
| zip-smoke: | |
| name: Packaged zip boot smoke | |
| needs: build | |
| runs-on: windows-latest | |
| # No checkout: the zip must stand on its own, which is the point of the | |
| # test. | |
| steps: | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: copperline-windows | |
| - name: Smoke test the packaged zip | |
| shell: pwsh | |
| # Expand the freshly built zip outside the workspace and boot it from | |
| # there: the run must find the bundled AROS ROM through the sibling | |
| # aros\ lookup next to the exe (romsearch.rs), not the source tree's | |
| # assets/aros fallback that a repo-root cwd would satisfy. A capture | |
| # run opens no window or audio device (src/main.rs windowless | |
| # capture), so a clean exit plus a non-empty PNG proves the shipped | |
| # bundle boots on a bare Windows host. | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| Set-StrictMode -Version Latest | |
| $zip = Get-ChildItem Copperline-*-win-x64.zip | Select-Object -First 1 | |
| $stage = Join-Path $env:RUNNER_TEMP "zip-smoke" | |
| Expand-Archive -Path $zip.FullName -DestinationPath $stage | |
| $exe = Get-ChildItem -Path $stage -Recurse -Filter copperline.exe | Select-Object -First 1 | |
| Set-Location $exe.DirectoryName | |
| & $exe.FullName --noaudio --screenshot-after 10 smoke.png | |
| if ($LASTEXITCODE -ne 0) { throw "packaged emulator exited with $LASTEXITCODE" } | |
| if ((Get-Item smoke.png).Length -eq 0) { throw "screenshot is empty" } | |
| unit-tests: | |
| name: Unit tests | |
| needs: test-bins | |
| runs-on: windows-latest | |
| steps: | |
| - name: Force LF checkout | |
| # Keep committed fixture bytes identical to the build job (see the | |
| # comment there); some unit tests read fixtures at run time. | |
| run: git config --global core.autocrlf false | |
| - uses: actions/checkout@v7 | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: windows-test-bins | |
| path: ci-bins | |
| - name: Unit tests | |
| shell: pwsh | |
| # The inline #[cfg(test)] suites in the lib and binaries, prebuilt | |
| # by the test-bins job (this is everything a root `cargo test` runs | |
| # besides tests/probe_golden.rs, which has its own job below; the | |
| # crate has no doctests). | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| ./ci-bins/unit-lib.exe | |
| if ($LASTEXITCODE -ne 0) { throw "unit-lib exited with $LASTEXITCODE" } | |
| ./ci-bins/unit-bin-copperline.exe | |
| if ($LASTEXITCODE -ne 0) { throw "unit-bin-copperline exited with $LASTEXITCODE" } | |
| ./ci-bins/unit-bin-copperline-ctl.exe | |
| if ($LASTEXITCODE -ne 0) { throw "unit-bin-copperline-ctl exited with $LASTEXITCODE" } | |
| probe-golden: | |
| name: Probe golden renders | |
| needs: test-bins | |
| runs-on: windows-latest | |
| steps: | |
| - name: Force LF checkout | |
| # Keep committed fixture bytes identical to the build job (see the | |
| # comment there); the golden comparison reads committed renders. | |
| run: git config --global core.autocrlf false | |
| - uses: actions/checkout@v7 | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: windows-test-bins | |
| path: ci-bins | |
| - name: Probe golden renders | |
| shell: pwsh | |
| # tests/probe_golden.rs is fully self-contained (committed probe | |
| # binaries booted on the bundled AROS ROM) and compares each probe's | |
| # deterministic render pixel-for-pixel against the references in | |
| # timing-test/golden/ -- proving the emulation core behaves | |
| # identically on Windows, not merely that it compiles. Each probe is | |
| # its own #[test], so the boots run in parallel on the runner's | |
| # cores. See timing-test/README.md "CI golden renders" for the | |
| # re-bless workflow. | |
| # | |
| # The test harness spawns the emulator through the compile-time | |
| # CARGO_BIN_EXE_copperline path, which on hosted runners is the same | |
| # absolute path in every job of this repo -- hence the copy into the | |
| # --target build directory before running. | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| New-Item -ItemType Directory -Force -Path target\x86_64-pc-windows-msvc\release | Out-Null | |
| Copy-Item ci-bins\copperline.exe target\x86_64-pc-windows-msvc\release\copperline.exe | |
| ./ci-bins/probe_golden.exe | |
| if ($LASTEXITCODE -ne 0) { throw "probe_golden exited with $LASTEXITCODE" } | |
| - name: Upload probe render diffs | |
| # On a golden mismatch the test writes the actual renders and diff | |
| # masks; surface them so the regression is reviewable from the run. | |
| if: failure() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: probe-golden-diffs-windows | |
| path: target/probe-golden/ | |
| if-no-files-found: ignore | |
| release: | |
| name: Attach zip to release | |
| # Runs only once every Windows check has passed, preserving the old | |
| # single-job ordering where the tests gated the release attach. Plain | |
| # ubuntu: this job only moves the already-built artifact. | |
| needs: [zip-smoke, unit-tests, probe-golden] | |
| if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.release_tag != '') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: copperline-windows | |
| - name: Locate artifact | |
| id: artifact | |
| # Fail fast if the downloaded zip is not where this job expects it; | |
| # an unmatched glob would otherwise pass the literal pattern to the | |
| # upload steps below. | |
| run: | | |
| zip=(Copperline-*-win-x64.zip) | |
| if [ ! -f "${zip[0]}" ]; then | |
| echo "no Copperline-*-win-x64.zip in $PWD" >&2 | |
| exit 1 | |
| fi | |
| echo "path=${zip[0]}" >> "$GITHUB_OUTPUT" | |
| - name: Attach to release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: ${{ steps.artifact.outputs.path }} | |
| - name: Attach to existing release (manual run) | |
| if: github.event_name == 'workflow_dispatch' && inputs.release_tag != '' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| # --clobber so a re-run replaces the asset instead of failing on a | |
| # name clash; --repo because this job runs without a checkout. | |
| run: gh release upload "${{ inputs.release_tag }}" "${{ steps.artifact.outputs.path }}" --clobber --repo "${{ github.repository }}" |