The test host gets the same per-API assembly layout as Game Studio and picks the
API from STRIDE_GRAPHICS_API at startup. The workflow runs the fixtures once per
API (Direct3D11, Direct3D12, Vulkan); the Vulkan job uses Lavapipe with the
validation layers, without synchronization validation: on the 4-core runner it
starves the asset build and the fixtures time out. The games the fixtures build
stay on Direct3D11. A manual run can pick one API.
The Windows Vulkan setup (SDK, validation layer, Lavapipe ICD) becomes a
composite action shared with the game and enduser workflows.
A depth buffer bound read-only ended its render pass with storeOp Store.
Synchronization validation counts that as a write, so the samples reported
WRITE_AFTER_WRITE in PostProcessingEffects and Compositing.Transparent.
Synchronization validation reports a missing barrier as a validation error, which
GameTestBase turns into a test failure. Core validation does not report those.
Every suite in the GPU solution filter passes under the switch with no hazard.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VHYKv129fEUp6sxMbybZWf
release-deploy.yml already refuses a stable engine naming prerelease content, and the check in release-samples.yml wrongly refused a samples beta between engine releases (committed suffix empty).
Prevent scheduled cron triggers from running on forks by default while
allowing fork maintainers to opt in via repository variable. Aligns
build-windows-full-msbuild and test-android-game with the fork-friendly
pattern already used in check-parallel-build, test-enduser, test-ios-game,
and test-windows-editor.
The called workflows fell back to github.ref, shared by every master push, so each push cancelled the previous commit's jobs and Gate reported them as failures. PRs still group by PR number.
Labels picked at creation already fire labeled events, so opened started every suite twice. A label event still runs its suite on a draft; pushes, reopened and ready_for_review skip drafts unless ci-run-on-draft.
Adding several ci-* labels in a row fired one run per labeled event, all
in the same concurrency group. They cancelled each other, and the gate's
always() still ran inside the cancelled run and reported a false failure.
A labeled event now runs only the suite of the label just added, in its
own concurrency group. Push events keep a shared group and run every
armed suite. The aggregate gate is gone: it was not a required check,
and with per-label runs it could only see its own run's suites.
Stride.Dependencies.SpirvCross ships win-x64 only, so on win-arm64 the
shader translator has no native library to load and every shader-bearing
asset fails to compile:
TypeInitializationException: The type initializer for
'Stride.Shaders.Compilers.SpirvTranslator' threw an exception.
---> DllNotFoundException: Could not locate or load native library spirv-cross
Silk.NET.SPIRV.Cross.Native does carry a win-arm64 build, but this
package's targets strip Silk's native assets wholesale to keep native
file conflict resolution deterministic. That strip is RID-agnostic, so on
win-arm64 it removes the only available DLL and puts nothing back.
Add an ARM64 build job (MSVC cross-compile on the same runner, mirroring
dep-spirv-tools.yml) and ship the result as runtimes/win-arm64/native/.
Windows-on-ARM native dependencies landed in #2644; spirv-cross arrived a
year later with the SDSL rewrite and was never given the same treatment.
Verified locally: built stride3d/SPIRV-Cross at the packaged commit for
both RIDs, packed with this nuspec, and rebuilt a win-arm64 game from a
wiped output directory. spirv-cross.dll is deployed from the package on
its own, shader compilation succeeds, and the game runs natively on ARM64.
Linux and macOS built and tested the GPU and the API-neutral solutions in
separate steps, the latter always in full and without the test filter. Both
now go through build/Stride.Tests.Game.Desktop.slnf, which lists every suite,
narrowed by the resolver like everything else.
The Windows Direct3D11 job takes that solution too when narrowed, or when a
gold run asks for it with `api-neutral-suites`, so the API-neutral golds can
be regenerated there. Direct3D12 and Vulkan stay on the GPU solution and skip
their build when none of the needed suites is in it: the resolver now answers
that with an empty target instead of the whole solution.
Every test lane resolves its suites with build/tools/Stride.TestSuites: the
`projects` list when given, else the ones `test-filter` can hit, else all.
Windows, Linux and macOS build a solution filter narrowed to them; iOS and
Android bundle only them into the Combined app. A one-test gold run on iOS
went from 18 min of build to 5-10.
`project` becomes `projects` (a list), and the gold hint in test failures
drops it.
Also: the iOS simulator boots after the resolve step (its restore and build
took 3 min next to a cold boot), the gold run can upload binlogs, and manual
runs no longer cancel each other.
Base-repo `vars` aren't readable from a fork PR's context, so gating only on
STRIDE_ENABLE_PUSH_CI skipped every fork PR. Add the repository-name clause
already used by main.yml.
actions/checkout refuses a fork ref from a workflow_run job unless the step allows it.
This checkout is data only (sparse image folders, nothing executed, no token persisted),
so the opt-in is safe. The comment is also shortened.
The vision gate read its baselines from the base branch, so a PR updating a gold could
not pass the gate until merged. The gate now checks out the PR head's two gold folders
as a sparse, data-only checkout and judges against those, falling back to the base golds
when that checkout fails. The comparator, prompts and API key stay on the base checkout.