From 6722683e29008d21aae45866a1e5013f62e38908 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Fri, 10 Jul 2026 08:30:21 -0600 Subject: [PATCH 1/4] ci: fix release/stable/9.0 build against current SDK & runner images The first full CI run on the 9.0 branch in a while (triggered by the #3407 navigation backport push) failed due to toolchain drift, not the backported code itself: - Maui & Uno fail with NETSDK1202: the net8.0 platform workloads (net8.0-android/ios/maccatalyst/macos) are now end-of-life, and the CI SDK (10.0.301) fails the build over it. Opt out of the EOL checks via CheckEolWorkloads/CheckEolTargetFramework - the 9.0 maintenance branch intentionally targets .NET 8 for its lifecycle. - Forms fails because the Xamarin.Android (MonoAndroid) language targets ship only with Visual Studio's Xamarin component, which was dropped from windows-latest (VS 18) and windows-2025. Pin the Forms job to windows-2022, the last hosted image that still includes it. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/ci.yml | 4 ++++ Directory.Build.props | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 908cd80ab..0aac118ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,6 +55,10 @@ jobs: build-prism-forms: uses: avantipoint/workflow-templates/.github/workflows/msbuild-build.yml@v1 with: + # Prism.Forms builds the Xamarin.Android (MonoAndroid) target, whose language targets + # ship only with Visual Studio's Xamarin component. That component was dropped from + # windows-latest (VS 18) and windows-2025, so pin to windows-2022 which still includes it. + runs-on: windows-2022 name: Build Prism.Forms solution-path: PrismLibrary_Forms.slnf code-sign: true diff --git a/Directory.Build.props b/Directory.Build.props index 1b57ba9bd..157510486 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -25,6 +25,15 @@ $(WarningsAsErrors);IDE0003 enable + + false + false From faa27845f5601451debdc92609549c81f011532a Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Fri, 10 Jul 2026 08:46:31 -0600 Subject: [PATCH 2/4] ci: roll test host forward so net6.0 tests run on current runners build-prism-core and build-prism-wpf built cleanly but failed at "Run Tests": the test projects target net6.0, whose runtime is EOL and no longer present on the runner images, so the test host aborted with "You must install or update .NET to run this application" before any test executed. Set RollForward=Major for test projects so the host rolls net6.0 forward to the newest installed major runtime. Runtime selection only - the test assemblies are still built against net6.0. Verified locally: Prism.Core.Tests passes 277/277 and the property lands in the test runtimeconfig the host reads. Co-Authored-By: Claude Opus 4.8 --- Directory.Build.props | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Directory.Build.props b/Directory.Build.props index 157510486..e40dc21ce 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -138,6 +138,17 @@ + + + Major + + From 3b0a156bb4e7ac2366529bd5f97e83d655b14d07 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Fri, 10 Jul 2026 09:12:35 -0600 Subject: [PATCH 3/4] build: pin SDK to 8.0.x so the net8.0 workload targets build Without an SDK pin, CI resolves the newest preinstalled SDK (10.0.x). Under it the net8.0 platform workloads no longer build: net8.0-ios infers TargetPlatformVersion 1.0 (NETSDK1135) and net8.0-android is missing the MAUI Android APIs (MauiAppCompatActivity, ILifecycleBuilder.AddAndroid -> CS0246/CS1061). Pin to the 8.0 SDK this branch was built with so the matching net8.0-era workloads are used. rollForward=latestMinor keeps it on whichever 8.0.x the runner has installed (8.0.201 / 8.0.300). Co-Authored-By: Claude Opus 4.8 --- global.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/global.json b/global.json index b5b460407..b2984d4b6 100644 --- a/global.json +++ b/global.json @@ -1,4 +1,8 @@ { + "sdk": { + "version": "8.0.100", + "rollForward": "latestMinor" + }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.56", "MSBuild.Sdk.Extras": "3.0.44", From 9f28bcf755a6999b679b3e72584eb953d26b25b0 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Fri, 10 Jul 2026 09:12:36 -0600 Subject: [PATCH 4/4] test: make AsyncDelegateCommand cancellation test deterministic ICommandExecute_UsesDefaultTokenSourceFactory cancelled the token then waited a fixed 10ms before asserting IsExecuting is false. Cancellation propagates asynchronously, so on slower CI agents 10ms was not always enough and the test flaked (it aborted the whole Prism.Core.Tests run). Poll for the state transition with a generous timeout instead. Co-Authored-By: Claude Opus 4.8 --- .../Commands/AsyncDelegateCommandFixture.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/Prism.Core.Tests/Commands/AsyncDelegateCommandFixture.cs b/tests/Prism.Core.Tests/Commands/AsyncDelegateCommandFixture.cs index 3db702283..c1a6a0897 100644 --- a/tests/Prism.Core.Tests/Commands/AsyncDelegateCommandFixture.cs +++ b/tests/Prism.Core.Tests/Commands/AsyncDelegateCommandFixture.cs @@ -135,7 +135,12 @@ public async Task ICommandExecute_UsesDefaultTokenSourceFactory() Assert.True(command.IsExecuting); cts.Cancel(); - await Task.Delay(10); + + // Cancellation propagates asynchronously; a fixed delay races on slower CI agents. + // Poll until the command stops executing, bounded by a generous timeout. + var timeout = Task.Delay(2000); + while (command.IsExecuting && !timeout.IsCompleted) + await Task.Delay(10); Assert.False(command.IsExecuting); }