diff --git a/.opencode/commands/issue.md b/.opencode/commands/issue.md index ffdb70a0..a1d47deb 100644 --- a/.opencode/commands/issue.md +++ b/.opencode/commands/issue.md @@ -128,8 +128,9 @@ If that value is blank, stop and ask the user for an issue number before doing a - For library/test changes (`src/**`, `tests/**`), trigger `build-library.yml`. - For sample changes (`samples/**`), trigger `build-samples.yml`. - For template changes (`templates/**`), trigger `build-template.yml`. + - For docs changes (`docs/**`, `mkdocs.yml`, `mkdocs.shared.yml`, `mkdocs.production.yml`), trigger `build-docs.yml`. - Do **not** dispatch `build-docs.yml`. Its `deploy` job has no branch guard, so any `workflow_dispatch` — including from a feature branch — publishes straight to the live GitHub Pages site. + `build-docs.yml`'s `deploy` job only runs for a `release` event, or for `workflow_dispatch` when `github.ref` starts with `refs/tags/`. Dispatching it with `--ref issues/$1` (a branch ref, not a tag) only runs its `build`/`validate` jobs — it is safe to dispatch from a feature branch and will never publish to the live GitHub Pages site. Do not pass a tag ref to `--ref` when dispatching `build-docs.yml` for pre-PR validation. If none of the changed paths match any of the above, state that no CI workflow applies and continue with local test results only. diff --git a/samples/todoapp/TodoApp.Avalonia/Directory.Build.props b/samples/todoapp/TodoApp.Avalonia/Directory.Build.props index 5732b26f..3c58333f 100644 --- a/samples/todoapp/TodoApp.Avalonia/Directory.Build.props +++ b/samples/todoapp/TodoApp.Avalonia/Directory.Build.props @@ -2,8 +2,9 @@ enable - - 11.3.18 + + 12.1.0 diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/Application.cs b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/Application.cs new file mode 100644 index 00000000..3b70f4da --- /dev/null +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/Application.cs @@ -0,0 +1,23 @@ +using Android.App; +using Android.Runtime; +using Avalonia; +using Avalonia.Android; + +namespace TodoApp.Avalonia.Android; + +// Avalonia 12 changed Android app initialization so that CreateAppBuilder()/CustomizeAppBuilder() +// are handled by an AvaloniaAndroidApplication subclass instead of AvaloniaMainActivity. +// See https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#android. +[Application] +public class Application : AvaloniaAndroidApplication +{ + protected Application(nint javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) + { + } + + protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) + { + return base.CustomizeAppBuilder(builder) + .WithInterFont(); + } +} diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/MainActivity.cs b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/MainActivity.cs index 5ad26437..d2cb4908 100644 --- a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/MainActivity.cs +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/MainActivity.cs @@ -1,6 +1,5 @@ using Android.App; using Android.Content.PM; -using Avalonia; using Avalonia.Android; namespace TodoApp.Avalonia.Android; @@ -11,11 +10,6 @@ namespace TodoApp.Avalonia.Android; Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)] -public class MainActivity : AvaloniaMainActivity +public class MainActivity : AvaloniaMainActivity { - protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) - { - return base.CustomizeAppBuilder(builder) - .WithInterFont(); - } } \ No newline at end of file diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/Properties/AndroidManifest.xml b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/Properties/AndroidManifest.xml index 7d86d689..b7a8b08c 100644 --- a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/Properties/AndroidManifest.xml +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/Properties/AndroidManifest.xml @@ -1,5 +1,5 @@  - + diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/TodoApp.Avalonia.Android.csproj b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/TodoApp.Avalonia.Android.csproj index 10129929..41f42f7f 100644 --- a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/TodoApp.Avalonia.Android.csproj +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Android/TodoApp.Avalonia.Android.csproj @@ -15,9 +15,9 @@ `dotnet build` (not just `dotnet publish`) by SDK default. This CI pipeline only ever runs `dotnet build` (see build-samples-todoapp-avalonia.yml) - it never publishes with PublishTrimmed, so no actual IL trimming/linking happens here; the analyzer is purely - diagnostic noise on framework APIs (Avalonia's BindingPlugins.DataValidators, EF Core's - DbContext(DbContextOptions) ctor) that their own maintainers have marked - [RequiresUnreferencedCode]. Setting this also sets EnableTrimAnalyzer=false (see + diagnostic noise on framework APIs (e.g. EF Core's DbContext(DbContextOptions) ctor) + that their own maintainers have marked [RequiresUnreferencedCode]. Setting this also + sets EnableTrimAnalyzer=false (see Microsoft.NET.ILLink.targets), which disables the analyzer pass itself, not just its warning output. See https://github.com/CommunityToolkit/Datasync/issues/521. --> diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Desktop/TodoApp.Avalonia.Desktop.csproj b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Desktop/TodoApp.Avalonia.Desktop.csproj index 719c5fbd..a5ed319a 100644 --- a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Desktop/TodoApp.Avalonia.Desktop.csproj +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.Desktop/TodoApp.Avalonia.Desktop.csproj @@ -14,8 +14,6 @@ - - diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.iOS/TodoApp.Avalonia.iOS.csproj b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.iOS/TodoApp.Avalonia.iOS.csproj index 24c2d933..94f5ae7d 100644 --- a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.iOS/TodoApp.Avalonia.iOS.csproj +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia.iOS/TodoApp.Avalonia.iOS.csproj @@ -10,9 +10,9 @@ because iOS app projects are marked trimmable by the SDK by default. This CI pipeline only ever runs `dotnet build` (see build-samples-todoapp-avalonia.yml) - it never publishes with PublishTrimmed, so no actual IL trimming/linking happens here; the analyzer is purely - diagnostic noise on framework APIs (Avalonia's BindingPlugins.DataValidators, EF Core's - DbContext(DbContextOptions) ctor) that their own maintainers have marked - [RequiresUnreferencedCode]. Setting this also sets EnableTrimAnalyzer=false (see + diagnostic noise on framework APIs (e.g. EF Core's DbContext(DbContextOptions) ctor) + that their own maintainers have marked [RequiresUnreferencedCode]. Setting this also + sets EnableTrimAnalyzer=false (see Microsoft.NET.ILLink.targets), which disables the analyzer pass itself, not just its warning output. See https://github.com/CommunityToolkit/Datasync/issues/521. --> diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/App.axaml.cs b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/App.axaml.cs index b3444e8d..c9f33c42 100644 --- a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/App.axaml.cs +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/App.axaml.cs @@ -2,8 +2,6 @@ using System.IO; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Data.Core; -using Avalonia.Data.Core.Plugins; using Avalonia.Markup.Xaml; using Avalonia.Threading; using Microsoft.Data.Sqlite; @@ -52,16 +50,19 @@ public override void Initialize() /// public override void OnFrameworkInitializationCompleted() { - // Line below is needed to remove Avalonia data validation. - // Without this line you will get duplicate validations from both Avalonia and CT - BindingPlugins.DataValidators.RemoveAt(0); - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.MainWindow = new MainWindow { DataContext = GetRequiredService() }; } + else if (ApplicationLifetime is IActivityApplicationLifetime activityLifetime) + { + // Android now uses IActivityApplicationLifetime instead of ISingleViewApplicationLifetime. + // See https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#android. + activityLifetime.MainViewFactory = () => new MainView { DataContext = GetRequiredService() }; + } else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform) { + // ISingleViewApplicationLifetime is still used by iOS, browser, and embedded Linux platforms. singleViewPlatform.MainView = new MainView { DataContext = GetRequiredService() }; } diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/TodoApp.Avalonia.csproj b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/TodoApp.Avalonia.csproj index 93253b0e..3610583d 100644 --- a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/TodoApp.Avalonia.csproj +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/TodoApp.Avalonia.csproj @@ -14,8 +14,6 @@ - - diff --git a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/Views/MainView.axaml b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/Views/MainView.axaml index 86ffb4ce..65426cd3 100644 --- a/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/Views/MainView.axaml +++ b/samples/todoapp/TodoApp.Avalonia/TodoApp.Avalonia/Views/MainView.axaml @@ -62,7 +62,7 @@ + PlaceholderText="Add a new Item">