diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json
index 44e1bb4696..a9bcc2bd4b 100644
--- a/.nuke/build.schema.json
+++ b/.nuke/build.schema.json
@@ -6,9 +6,6 @@
"build": {
"type": "object",
"properties": {
- "api-baseline": {
- "type": "string"
- },
"configuration": {
"type": "string"
},
@@ -16,6 +13,9 @@
"type": "boolean",
"description": "Indicates to continue a previously failed build attempt"
},
+ "force-api-baseline": {
+ "type": "string"
+ },
"force-nuget-version": {
"type": "string"
},
@@ -83,6 +83,7 @@
"CompileNative",
"CreateIntermediateNugetPackages",
"CreateNugetPackages",
+ "DownloadApiBaselinePackages",
"GenerateCppHeaders",
"OutputApiDiff",
"OutputVersion",
@@ -121,6 +122,7 @@
"CompileNative",
"CreateIntermediateNugetPackages",
"CreateNugetPackages",
+ "DownloadApiBaselinePackages",
"GenerateCppHeaders",
"OutputApiDiff",
"OutputVersion",
diff --git a/NuGet.Config b/NuGet.Config
index 2042fea360..99d827d465 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -3,7 +3,6 @@
-
-
+
diff --git a/api/Avalonia.Android.nupkg.xml b/api/Avalonia.Android.nupkg.xml
deleted file mode 100644
index deed9db4de..0000000000
--- a/api/Avalonia.Android.nupkg.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- CP0001
- T:Avalonia.Android.AvaloniaMainActivity`1
- baseline/net8.0-android34.0/Avalonia.Android.dll
- target/net8.0-android34.0/Avalonia.Android.dll
-
-
- CP0002
- M:Avalonia.Android.AndroidViewControlHandle.get_HandleDescriptor
- baseline/net8.0-android34.0/Avalonia.Android.dll
- target/net8.0-android34.0/Avalonia.Android.dll
-
-
- CP0007
- T:Avalonia.Android.AndroidViewControlHandle
- baseline/net8.0-android34.0/Avalonia.Android.dll
- target/net8.0-android34.0/Avalonia.Android.dll
-
-
\ No newline at end of file
diff --git a/api/Avalonia.Browser.nupkg.xml b/api/Avalonia.Browser.nupkg.xml
deleted file mode 100644
index 0fb414ed14..0000000000
--- a/api/Avalonia.Browser.nupkg.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- CP0002
- M:Avalonia.Browser.JSObjectControlHandle.get_Handle
- baseline/net8.0-browser1.0/Avalonia.Browser.dll
- target/net8.0-browser1.0/Avalonia.Browser.dll
-
-
- CP0002
- M:Avalonia.Browser.JSObjectControlHandle.get_HandleDescriptor
- baseline/net8.0-browser1.0/Avalonia.Browser.dll
- target/net8.0-browser1.0/Avalonia.Browser.dll
-
-
- CP0007
- T:Avalonia.Browser.JSObjectControlHandle
- baseline/net8.0-browser1.0/Avalonia.Browser.dll
- target/net8.0-browser1.0/Avalonia.Browser.dll
-
-
\ No newline at end of file
diff --git a/api/Avalonia.FreeDesktop.nupkg.xml b/api/Avalonia.FreeDesktop.nupkg.xml
deleted file mode 100644
index f5fcb60bc8..0000000000
--- a/api/Avalonia.FreeDesktop.nupkg.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- CP0001
- T:Tmds.DBus.SourceGenerator.PropertyChanges`1
- baseline/netstandard2.0/Avalonia.FreeDesktop.dll
- target/netstandard2.0/Avalonia.FreeDesktop.dll
-
-
\ No newline at end of file
diff --git a/api/Avalonia.Skia.nupkg.xml b/api/Avalonia.Skia.nupkg.xml
deleted file mode 100644
index b275cbff58..0000000000
--- a/api/Avalonia.Skia.nupkg.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- CP0002
- M:Avalonia.Skia.SkiaSharpExtensions.ToSKFilterQuality(Avalonia.Media.Imaging.BitmapInterpolationMode)
- baseline/netstandard2.0/Avalonia.Skia.dll
- target/netstandard2.0/Avalonia.Skia.dll
-
-
- CP0006
- M:Avalonia.Skia.ISkiaGpuWithPlatformGraphicsContext.TryGetGrContext
- baseline/netstandard2.0/Avalonia.Skia.dll
- target/netstandard2.0/Avalonia.Skia.dll
-
-
\ No newline at end of file
diff --git a/api/Avalonia.Themes.Fluent.nupkg.xml b/api/Avalonia.Themes.Fluent.nupkg.xml
deleted file mode 100644
index 717b64f81e..0000000000
--- a/api/Avalonia.Themes.Fluent.nupkg.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- CP0007
- T:Avalonia.Themes.Fluent.ColorPaletteResources
- baseline/netstandard2.0/Avalonia.Themes.Fluent.dll
- target/netstandard2.0/Avalonia.Themes.Fluent.dll
-
-
- CP0008
- T:Avalonia.Themes.Fluent.ColorPaletteResources
- baseline/netstandard2.0/Avalonia.Themes.Fluent.dll
- target/netstandard2.0/Avalonia.Themes.Fluent.dll
-
-
\ No newline at end of file
diff --git a/api/Avalonia.Win32.nupkg.xml b/api/Avalonia.Win32.nupkg.xml
deleted file mode 100644
index 3ce897deda..0000000000
--- a/api/Avalonia.Win32.nupkg.xml
+++ /dev/null
@@ -1,214 +0,0 @@
-
-
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.DockPosition
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IDockProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IExpandCollapseProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IGridItemProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IGridProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IInvokeProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IMultipleViewProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IRangeValueProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IRawElementProviderAdviseEvents
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IRawElementProviderFragment
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IRawElementProviderFragmentRoot
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IRawElementProviderSimple
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IRawElementProviderSimple2
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IScrollItemProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IScrollProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.ISelectionItemProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.ISelectionProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.ISynchronizedInputProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.ITableItemProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.ITableProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.ITextProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.ITextRangeProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IToggleProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.ITransformProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IValueProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.IWindowProvider
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.NavigateDirection
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.ProviderOptions
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.RowOrColumnMajor
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.SupportedTextSelection
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.SynchronizedInputType
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.TextPatternRangeEndpoint
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.TextUnit
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.WindowInteractionState
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
- CP0001
- T:Avalonia.Win32.Interop.Automation.WindowVisualState
- baseline/netstandard2.0/Avalonia.Win32.dll
- target/netstandard2.0/Avalonia.Win32.dll
-
-
\ No newline at end of file
diff --git a/api/Avalonia.iOS.nupkg.xml b/api/Avalonia.iOS.nupkg.xml
deleted file mode 100644
index 5f6e822d81..0000000000
--- a/api/Avalonia.iOS.nupkg.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- CP0002
- M:Avalonia.iOS.UIViewControlHandle.get_HandleDescriptor
- baseline/net8.0-tvos17.0/Avalonia.iOS.dll
- target/net8.0-tvos17.0/Avalonia.iOS.dll
-
-
- CP0007
- T:Avalonia.iOS.UIViewControlHandle
- baseline/net8.0-tvos17.0/Avalonia.iOS.dll
- target/net8.0-tvos17.0/Avalonia.iOS.dll
-
-
\ No newline at end of file
diff --git a/api/Avalonia.nupkg.xml b/api/Avalonia.nupkg.xml
deleted file mode 100644
index 8d64cb2a82..0000000000
--- a/api/Avalonia.nupkg.xml
+++ /dev/null
@@ -1,268 +0,0 @@
-
-
-
-
- CP0001
- T:Avalonia.Controls.PseudolassesExtensions
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Data.Core.CastTypePropertyPathElement
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Data.Core.ChildTraversalPropertyPathElement
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Data.Core.EnsureTypePropertyPathElement
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Data.Core.IPropertyPathElement
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Data.Core.PropertyPath
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Data.Core.PropertyPathBuilder
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Data.Core.PropertyPropertyPathElement
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Utilities.CharacterReader
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Utilities.IdentifierParser
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Utilities.KeywordParser
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0001
- T:Avalonia.Utilities.StyleClassParser
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Diagnostics.AppliedStyle.get_HasActivator
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Diagnostics.AppliedStyle.get_IsActive
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Diagnostics.AppliedStyle.get_Style
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Diagnostics.StyledElementExtensions.GetStyleDiagnostics(Avalonia.StyledElement)
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Diagnostics.StyleDiagnostics.#ctor(System.Collections.Generic.IReadOnlyList{Avalonia.Diagnostics.AppliedStyle})
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Diagnostics.StyleDiagnostics.get_AppliedStyles
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Threading.DispatcherPriorityAwaitable.get_IsCompleted
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Threading.DispatcherPriorityAwaitable.GetAwaiter
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Threading.DispatcherPriorityAwaitable.GetResult
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Threading.DispatcherPriorityAwaitable.OnCompleted(System.Action)
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Threading.DispatcherPriorityAwaitable`1.GetAwaiter
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Threading.DispatcherPriorityAwaitable`1.GetResult
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0002
- M:Avalonia.Controls.Primitives.IPopupHost.ConfigurePosition(Avalonia.Visual,Avalonia.Controls.PlacementMode,Avalonia.Point,Avalonia.Controls.Primitives.PopupPositioning.PopupAnchor,Avalonia.Controls.Primitives.PopupPositioning.PopupGravity,Avalonia.Controls.Primitives.PopupPositioning.PopupPositionerConstraintAdjustment,System.Nullable{Avalonia.Rect})
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0002
- M:Avalonia.Controls.Screens.#ctor(Avalonia.Platform.IScreenImpl)
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0006
- M:Avalonia.Input.Platform.IClipboard.FlushAsync
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0006
- M:Avalonia.Input.Platform.IClipboard.TryGetInProcessDataObjectAsync
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0006
- M:Avalonia.Platform.Storage.IStorageFolder.GetFileAsync(System.String)
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0006
- M:Avalonia.Platform.Storage.IStorageFolder.GetFolderAsync(System.String)
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0006
- M:Avalonia.Controls.Notifications.IManagedNotificationManager.Close(System.Object)
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0006
- M:Avalonia.Controls.Notifications.INotificationManager.Close(Avalonia.Controls.Notifications.INotification)
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0006
- M:Avalonia.Controls.Notifications.INotificationManager.CloseAll
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0006
- M:Avalonia.Controls.Primitives.IPopupHost.ConfigurePosition(Avalonia.Controls.Primitives.PopupPositioning.PopupPositionRequest)
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0006
- M:Avalonia.Controls.Primitives.IPopupHost.TakeFocus
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0006
- P:Avalonia.Controls.Platform.IInsetsManager.DisplayEdgeToEdgePreference
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0006
- P:Avalonia.Controls.Platform.IInsetsManager.DisplaysEdgeToEdge
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0007
- T:Avalonia.Threading.DispatcherPriorityAwaitable
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0007
- T:Avalonia.Threading.DispatcherPriorityAwaitable`1
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0008
- T:Avalonia.Threading.DispatcherPriorityAwaitable
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0008
- T:Avalonia.Threading.DispatcherPriorityAwaitable`1
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0009
- T:Avalonia.Diagnostics.StyleDiagnostics
- baseline/netstandard2.0/Avalonia.Base.dll
- target/netstandard2.0/Avalonia.Base.dll
-
-
- CP0009
- T:Avalonia.Controls.Screens
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
- CP0012
- M:Avalonia.Controls.Button.OnAccessKey(Avalonia.Interactivity.RoutedEventArgs)
- baseline/netstandard2.0/Avalonia.Controls.dll
- target/netstandard2.0/Avalonia.Controls.dll
-
-
\ No newline at end of file
diff --git a/build/SharedVersion.props b/build/SharedVersion.props
index d18aa6447c..37d14a5647 100644
--- a/build/SharedVersion.props
+++ b/build/SharedVersion.props
@@ -3,7 +3,6 @@
Avalonia
12.0.999
- 11.1.0
Avalonia Team
Copyright 2013-$([System.DateTime]::Now.ToString(`yyyy`)) © The AvaloniaUI Project
https://avaloniaui.net/?utm_source=nuget&utm_medium=referral&utm_content=project_homepage_link
diff --git a/nukebuild/ApiDiffHelper.cs b/nukebuild/ApiDiffHelper.cs
index ac6be61ee3..1ef0995eff 100644
--- a/nukebuild/ApiDiffHelper.cs
+++ b/nukebuild/ApiDiffHelper.cs
@@ -1,313 +1,464 @@
+#nullable enable
+
using System;
using System.Collections.Generic;
-using System.Diagnostics;
+using System.Collections.Immutable;
using System.IO;
using System.IO.Compression;
using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text.RegularExpressions;
+using System.Security.Cryptography;
+using System.Threading;
using System.Threading.Tasks;
+using NuGet.Common;
+using NuGet.Configuration;
+using NuGet.Frameworks;
+using NuGet.Packaging;
+using NuGet.Protocol;
+using NuGet.Protocol.Core.Types;
+using NuGet.Versioning;
+using Nuke.Common.IO;
using Nuke.Common.Tooling;
-using Serilog;
using static Serilog.Log;
public static class ApiDiffHelper
{
- static readonly HttpClient s_httpClient = new();
-
- public static async Task GetDiff(
- Tool apiDiffTool, string outputFolder,
- string packagePath, string baselineVersion)
+ const string NightlyFeedUri = "https://nuget-feed-nightly.avaloniaui.net/v3/index.json";
+ const string MainPackageName = "Avalonia";
+ const string FolderLib = "lib";
+
+ public static void ValidatePackage(
+ Tool apiCompatTool,
+ PackageDiffInfo packageDiff,
+ AbsolutePath suppressionFilesFolderPath,
+ bool updateSuppressionFile)
{
- await using var baselineStream = await DownloadBaselinePackage(packagePath, baselineVersion);
- if (baselineStream == null)
- return;
+ Information("Validating API for package {Id}", packageDiff.PackageId);
- if (!Directory.Exists(outputFolder))
- {
- Directory.CreateDirectory(outputFolder!);
- }
+ Directory.CreateDirectory(suppressionFilesFolderPath);
- using (var target = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.Read), ZipArchiveMode.Read))
- using (var baseline = new ZipArchive(baselineStream, ZipArchiveMode.Read))
- using (Helpers.UseTempDir(out var tempFolder))
- {
- var targetDlls = GetDlls(target);
- var baselineDlls = GetDlls(baseline);
+ var suppressionArgs = "";
+
+ var suppressionFile = suppressionFilesFolderPath / (packageDiff.PackageId + ".nupkg.xml");
+ if (suppressionFile.FileExists())
+ suppressionArgs += $""" --suppression-file="{suppressionFile}" --permit-unnecessary-suppressions """;
- var pairs = new List<(string baseline, string target)>();
+ if (updateSuppressionFile)
+ suppressionArgs += $""" --suppression-output-file="{suppressionFile}" --generate-suppression-file --preserve-unnecessary-suppressions """;
- var packageId = GetPackageId(packagePath);
+ var allErrors = new List();
- // Don't use Path.Combine with these left and right tool parameters.
- // Microsoft.DotNet.ApiCompat.Tool is stupid and treats '/' and '\' as different assemblies in suppression files.
- // So, always use Unix '/'
- foreach (var baselineDll in baselineDlls)
+ Parallel.ForEach(
+ packageDiff.Frameworks,
+ framework =>
{
- var baselineDllPath = await ExtractDll("baseline", baselineDll, tempFolder);
+ var args = $""" -l="{framework.BaselineFolderPath}" -r="{framework.CurrentFolderPath}" {suppressionArgs}""";
- var targetTfm = baselineDll.target;
- var targetDll = targetDlls.FirstOrDefault(e =>
- e.target.StartsWith(targetTfm) && e.entry.Name == baselineDll.entry.Name);
- if (targetDll is null)
- {
- if (s_tfmRedirects.FirstOrDefault(t => baselineDll.target.StartsWith(t.oldTfm) && (t.package is null || packageId == t.package)).newTfm is {} newTfm)
- {
- targetTfm = newTfm;
- targetDll = targetDlls.FirstOrDefault(e =>
- e.target.StartsWith(targetTfm) && e.entry.Name == baselineDll.entry.Name);
- }
- }
+ var localErrors = GetErrors(apiCompatTool(args));
- if (targetDll?.entry is null)
+ if (localErrors.Length > 0)
{
- throw new InvalidOperationException($"Some assemblies are missing in the new package {packageId}: {baselineDll.entry.Name} for {baselineDll.target}");
+ lock (allErrors)
+ allErrors.AddRange(localErrors);
}
+ });
- var targetDllPath = await ExtractDll("target", targetDll, tempFolder);
+ ThrowOnErrors(allErrors, packageDiff.PackageId, "ValidateApiDiff");
+ }
- pairs.Add((baselineDllPath, targetDllPath));
- }
+ public static void GenerateMarkdownDiff(
+ Tool apiDiffTool,
+ PackageDiffInfo packageDiff,
+ AbsolutePath rootOutputFolderPath,
+ string baselineDisplay,
+ string currentDisplay)
+ {
+ Information("Creating markdown diff for package {Id}", packageDiff.PackageId);
- await Task.WhenAll(pairs.Select(p => Task.Run(() =>
- {
- var baselineApi = p.baseline + Random.Shared.Next() + ".api.cs";
- var targetApi = p.target + Random.Shared.Next() + ".api.cs";
- var resultDiff = p.target + ".api.diff.cs";
-
- GenerateApiListing(apiDiffTool, p.baseline, baselineApi, tempFolder);
- GenerateApiListing(apiDiffTool, p.target, targetApi, tempFolder);
-
- var args = $"""-c core.autocrlf=false diff --no-index --minimal """;
- args += """--ignore-matching-lines="^\[assembly: System.Reflection.AssemblyVersionAttribute" """;
- args += $""" --output {resultDiff} {baselineApi} {targetApi}""";
-
- using (var gitProcess = new Process())
+ var packageOutputFolderPath = rootOutputFolderPath / packageDiff.PackageId;
+ Directory.CreateDirectory(packageOutputFolderPath);
+
+ // Not specifying -eattrs incorrectly tries to load AttributesToExclude.txt, create an empty file instead.
+ // See https://github.com/dotnet/sdk/issues/49719
+ var excludedAttributesFilePath = (AbsolutePath)Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString());
+ File.WriteAllBytes(excludedAttributesFilePath!, []);
+
+ try
+ {
+ var allErrors = new List();
+
+ // The API diff tool is unbelievably slow, process in parallel.
+ Parallel.ForEach(
+ packageDiff.Frameworks,
+ framework =>
{
- gitProcess.StartInfo = new ProcessStartInfo
+ var frameworkOutputFolderPath = packageOutputFolderPath / framework.Framework.GetShortFolderName();
+ var args = $""" -b="{framework.BaselineFolderPath}" -bfn="{baselineDisplay}" -a="{framework.CurrentFolderPath}" -afn="{currentDisplay}" -o="{frameworkOutputFolderPath}" -eattrs="{excludedAttributesFilePath}" """;
+
+ var localErrors = GetErrors(apiDiffTool(args));
+
+ if (localErrors.Length > 0)
{
- CreateNoWindow = true,
- RedirectStandardError = false,
- RedirectStandardOutput = false,
- FileName = "git",
- Arguments = args,
- WorkingDirectory = tempFolder
- };
- gitProcess.Start();
- gitProcess.WaitForExit();
- }
+ lock (allErrors)
+ allErrors.AddRange(localErrors);
+ }
+ });
- var resultFile = new FileInfo(Path.Combine(tempFolder, resultDiff));
- if (resultFile.Length > 0)
- {
- resultFile.CopyTo(Path.Combine(outputFolder, Path.GetFileName(resultDiff)), true);
- }
- })));
+ ThrowOnErrors(allErrors, packageDiff.PackageId, "OutputApiDiff");
+
+ MergeFrameworkMarkdownDiffFiles(
+ rootOutputFolderPath,
+ packageOutputFolderPath,
+ [..packageDiff.Frameworks.Select(info => info.Framework)]);
+
+ Directory.Delete(packageOutputFolderPath, true);
+ }
+ finally
+ {
+ File.Delete(excludedAttributesFilePath);
}
}
- private static readonly (string package, string oldTfm, string newTfm)[] s_tfmRedirects = new[]
- {
- // We use StartsWith below comparing these tfm, as we ignore platform versions (like, net6.0-ios16.1).
- ("Avalonia.Android", "net6.0-android", "net8.0-android"),
- ("Avalonia.iOS", "net6.0-ios", "net8.0-ios"),
- // Browser was changed from net7.0 to net8.0-browser.
- ("Avalonia.Browser", "net7.0", "net8.0-browser"),
- ("Avalonia.Browser.Blazor", "net7.0", "net8.0-browser"),
- // Designer was moved from netcoreapp to netstandard.
- ("Avalonia", "netcoreapp2.0", "netstandard2.0"),
- ("Avalonia", "net461", "netstandard2.0")
- };
-
- public static async Task ValidatePackage(
- Tool apiCompatTool, string packagePath, string baselineVersion,
- string suppressionFilesFolder, bool updateSuppressionFile)
+ static void MergeFrameworkMarkdownDiffFiles(
+ AbsolutePath rootOutputFolderPath,
+ AbsolutePath packageOutputFolderPath,
+ ImmutableArray frameworks)
{
- if (!Directory.Exists(suppressionFilesFolder))
+ // At this point, the hierarchy looks like:
+ // markdown/
+ // ├─ net8.0/
+ // │ ├─ api_diff_Avalonia.md
+ // │ ├─ api_diff_Avalonia.Controls.md
+ // ├─ netstandard2.0/
+ // │ ├─ api_diff_Avalonia.md
+ // │ ├─ api_diff_Avalonia.Controls.md
+ //
+ // We want one file per assembly: merge all files with the same name.
+ // However, it's very likely that the diff is the same for several frameworks: in this case, keep only one file.
+
+ var assemblyGroups = frameworks
+ .SelectMany(GetFrameworkDiffFiles, (framework, filePath) => (framework, filePath))
+ .GroupBy(x => x.filePath.Name)
+ .OrderBy(x => x.Key, StringComparer.OrdinalIgnoreCase);
+
+ foreach (var assemblyGroup in assemblyGroups)
{
- Directory.CreateDirectory(suppressionFilesFolder!);
+ using var writer = File.CreateText(rootOutputFolderPath / assemblyGroup.Key.Replace("api_diff_", ""));
+ var addSeparator = false;
+
+ foreach (var similarDiffGroup in assemblyGroup.GroupBy(x => HashFile(x.filePath), ByteArrayEqualityComparer.Instance))
+ {
+ if (addSeparator)
+ writer.WriteLine();
+
+ using var reader = File.OpenText(similarDiffGroup.First().filePath);
+ var firstLine = reader.ReadLine();
+
+ writer.Write(firstLine);
+ writer.WriteLine(" (" + string.Join(", ", similarDiffGroup.Select(x => x.framework.GetShortFolderName())) + ")");
+
+ while (reader.ReadLine() is { } line)
+ writer.WriteLine(line);
+
+ addSeparator = true;
+ }
+ }
+
+ AbsolutePath[] GetFrameworkDiffFiles(NuGetFramework framework)
+ {
+ var frameworkFolderPath = packageOutputFolderPath / framework.GetShortFolderName();
+ if (!frameworkFolderPath.DirectoryExists())
+ return [];
+
+ return Directory.GetFiles(frameworkFolderPath, "*.md")
+ .Where(filePath => Path.GetFileName(filePath) != "api_diff.md")
+ .Select(filePath => (AbsolutePath)filePath)
+ .ToArray();
}
- await using var baselineStream = await DownloadBaselinePackage(packagePath, baselineVersion);
- if (baselineStream == null)
+ static byte[] HashFile(AbsolutePath filePath)
+ {
+ using var stream = File.OpenRead(filePath);
+ return SHA256.HashData(stream);
+ }
+ }
+
+ public static void MergePackageMarkdownDiffFiles(
+ AbsolutePath rootOutputFolderPath,
+ string baselineDisplay,
+ string currentDisplay)
+ {
+ const string mergedFileName = "_diff.md";
+
+ var filePaths = Directory.EnumerateFiles(rootOutputFolderPath, "*.md")
+ .Where(filePath => Path.GetFileName(filePath) != mergedFileName)
+ .Order(StringComparer.OrdinalIgnoreCase)
+ .ToArray();
+
+ using var writer = File.CreateText(rootOutputFolderPath / mergedFileName);
+
+ writer.WriteLine($"# API diff between {baselineDisplay} and {currentDisplay}");
+
+ if (filePaths.Length == 0)
+ {
+ writer.WriteLine();
+ writer.WriteLine("No changes.");
return;
+ }
- using (var target = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.Read), ZipArchiveMode.Read))
- using (var baseline = new ZipArchive(baselineStream, ZipArchiveMode.Read))
- using (Helpers.UseTempDir(out var tempFolder))
+ foreach (var filePath in filePaths)
{
- var targetDlls = GetDlls(target);
- var baselineDlls = GetDlls(baseline);
+ writer.WriteLine();
+
+ using var reader = File.OpenText(filePath);
+
+ while (reader.ReadLine() is { } line)
+ {
+ if (line.StartsWith('#'))
+ writer.Write('#');
+
+ writer.WriteLine(line);
+ }
+ }
+ }
- var left = new List();
- var right = new List();
+ static string[] GetErrors(IEnumerable
@@ -21,13 +21,14 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+