From 4384866c1b6cdca69b7a6f19362a1c75649adbbc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:44:31 +0200 Subject: [PATCH 01/23] [main] Update dependencies from dotnet/installer (#21251) This pull request updates the following dependencies ## From https://github.com/dotnet/installer - **Subscription**: 80cb9ffd-f92f-4fc8-9f8b-08dbca46abfb - **Build**: 20240916.16 - **Date Produced**: September 17, 2024 1:00:49 AM UTC - **Commit**: d47192a544ebc4e405d6f8b9e6c1bdbf692717d5 - **Branch**: refs/heads/release/8.0.1xx - **Updates**: - **Microsoft.Dotnet.Sdk.Internal**: [from 8.0.109-servicing.24419.10 to 8.0.110-servicing.24466.16][1] [1]: https://github.com/dotnet/installer/compare/6e9002c2ef...d47192a544 --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- global.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5e30fbb655d4..58304fe951ff 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/installer - 6e9002c2efcfc09687feca31864ebc987c3c9ec8 + d47192a544ebc4e405d6f8b9e6c1bdbf692717d5 https://github.com/dotnet/runtime diff --git a/eng/Versions.props b/eng/Versions.props index 6750fdeea73b..e76292d91857 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -3,7 +3,7 @@ 0.11.4-alpha.23509.2 - 8.0.109-servicing.24419.10 + 8.0.110-servicing.24466.16 8.0.8 8.0.0-rtm.23524.7 9.0.0-beta.24408.2 diff --git a/global.json b/global.json index cafd9183b631..eeba0556d378 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "8.0.109-servicing.24419.10" + "version": "8.0.110-servicing.24466.16" } } From f7f04c51b61df6379bac77229c9eb82c94c3f695 Mon Sep 17 00:00:00 2001 From: VS MobileTools Engineering Service 2 Date: Fri, 20 Sep 2024 02:30:13 -0700 Subject: [PATCH 02/23] [main] Bump to the correct .NET 8/Xcode 15.0 version (#21279) Backport of #21278 Co-authored-by: Alex Soto --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 58304fe951ff..a2ab74bbc735 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -48,21 +48,21 @@ 5edc544b7dacf82a9d5a68d1d39609789b30d07d - + https://github.com/xamarin/xamarin-macios - 492e53f5b423c6e9cbdb48f3d57c92a1f97b5005 + 06fea905cf900ab5296b08d7b67dadddc733dd65 - + https://github.com/xamarin/xamarin-macios - 492e53f5b423c6e9cbdb48f3d57c92a1f97b5005 + 06fea905cf900ab5296b08d7b67dadddc733dd65 - + https://github.com/xamarin/xamarin-macios - 492e53f5b423c6e9cbdb48f3d57c92a1f97b5005 + 06fea905cf900ab5296b08d7b67dadddc733dd65 - + https://github.com/xamarin/xamarin-macios - 492e53f5b423c6e9cbdb48f3d57c92a1f97b5005 + 06fea905cf900ab5296b08d7b67dadddc733dd65 https://github.com/dotnet/runtime diff --git a/eng/Versions.props b/eng/Versions.props index e76292d91857..0c9a6baf0b30 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -22,9 +22,9 @@ 16.4.7142 16.4.7142 - 17.0.8519 - 14.0.8519 - 17.0.8519 - 17.0.8519 + 17.0.8523 + 14.0.8523 + 17.0.8523 + 17.0.8523 From ba954b9c245e4c4015404966711d6c984e533450 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 20 Sep 2024 17:44:15 +0200 Subject: [PATCH 03/23] [builds] Delete most of the legacy logic. (#21239) --- Make.config | 8 - builds/Makefile | 1007 +---------------- release/Makefile | 151 --- tests/Makefile | 2 - tests/xharness/Harness.cs | 2 - tests/xharness/IHarness.cs | 1 - .../automation/templates/build/build.yml | 12 - 7 files changed, 1 insertion(+), 1182 deletions(-) diff --git a/Make.config b/Make.config index 37b1b6bfdcd5..fb8642a8b92c 100644 --- a/Make.config +++ b/Make.config @@ -650,21 +650,13 @@ XCODE_IOS_ARCHIVE_VERSION=xcode-12D4e XCODE_MACOS_ARCHIVE_VERSION=xcode-12D4e MONO_IOS_FILENAME:=ios-release-Darwin-$(MONO_HASH).7z MONO_IOS_URL:=https://download.mono-project.com/mono-sdks/$(XCODE_IOS_ARCHIVE_VERSION)/$(MONO_IOS_FILENAME) -MONO_MAC_FILENAME:=mac-release-Darwin-$(MONO_HASH).7z -MONO_MAC_URL:=https://download.mono-project.com/mono-sdks/$(XCODE_MACOS_ARCHIVE_VERSION)/$(MONO_MAC_FILENAME) -MONO_MACCATALYST_FILENAME:=maccat-release-Darwin-$(MONO_HASH).7z -MONO_MACCATALYST_URL:=https://download.mono-project.com/mono-sdks/$(XCODE_MACOS_ARCHIVE_VERSION)/$(MONO_MACCATALYST_FILENAME) # Setup various variables depending on whether mono is downloaded or built from source ifeq ($(MONO_BUILD_FROM_SOURCE),) MONO_IOS_SDK_DESTDIR:=$(abspath $(TOP)/builds/downloads/$(basename $(MONO_IOS_FILENAME))) -MONO_MAC_SDK_DESTDIR:=$(abspath $(TOP)/builds/downloads/$(basename $(MONO_MAC_FILENAME))) -MONO_MACCATALYST_SDK_DESTDIR:=$(abspath $(TOP)/builds/downloads/$(basename $(MONO_MACCATALYST_FILENAME))) MONO_BUILD_MODE=download-mono else MONO_IOS_SDK_DESTDIR:=$(abspath $(MONO_PATH)/sdks/out) -MONO_MAC_SDK_DESTDIR:=$(abspath $(MONO_PATH)/sdks/out) -MONO_MACCATALYST_SDK_DESTDIR:=$(abspath $(MONO_PATH)/sdks/out) MONO_BUILD_MODE=compile-mono endif diff --git a/builds/Makefile b/builds/Makefile index 2b050d2ed04e..3a33d9754283 100644 --- a/builds/Makefile +++ b/builds/Makefile @@ -1,8 +1,6 @@ TOP=.. include $(TOP)/Make.config -PREFIX=$(abspath $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/) - # Keep all intermediate files always. .SECONDARY: @@ -19,19 +17,13 @@ endif download: download-mono download-mono: \ downloads/$(basename $(MONO_IOS_FILENAME)) \ - downloads/$(basename $(MONO_MAC_FILENAME)) \ - downloads/$(basename $(MONO_MACCATALYST_FILENAME)) \ downloads/$(basename $(MONO_IOS_FILENAME)): MONO_URL=$(MONO_IOS_URL) -downloads/$(basename $(MONO_MAC_FILENAME)): MONO_URL=$(MONO_MAC_URL) -downloads/$(basename $(MONO_MACCATALYST_FILENAME)): MONO_URL=$(MONO_MACCATALYST_URL) include $(TOP)/mk/colors.mk DOWNLOADS = \ downloads/$(MONO_IOS_FILENAME) \ - downloads/$(MONO_MAC_FILENAME) \ - downloads/$(MONO_MACCATALYST_FILENAME) \ # This target downloads the mono archives, there's one for Xamarin.iOS and one for Xamarin.Mac. # If doing many clean builds, it's possible to copy the downloaded zip file to ~/Library/Caches/xamarin-macios @@ -178,959 +170,16 @@ all-local:: $(DOTNET_DOWNLOADS) clean-local:: $(Q) rm -Rf downloads .stamp-download-mono -ifeq ($(MONO_BUILD_FROM_SOURCE),) - -all-local:: .stamp-download-mono .stamp-mono-ios-sdk-destdir - -else - -# this is a list of all the files from mono we care about, so that we -# can use that list as dependencies for our makefile targets --include .deps.mono.mk -.deps.mono.mk: $(TOP)/Make.config $(TOP)/mk/mono.mk - $(Q) printf 'MONO_DEPENDENCIES += Makefile \\\n' > $@.tmp - $(Q) cd $(MONO_PATH) && git ls-files --recurse-submodules 'mcs/class/*.cs' 'mcs/build/*.cs' 'external/*.cs' '*.h' '*.c' '*.cpp' | sed 's/ /\\ /g' | sed 's@^\(.*\)$$@ $(MONO_PATH)/\1 \\@' >> $(abspath $@).tmp - $(Q) mv $@.tmp $@ - -# -# Configuration for the mono sdk makefiles -# -SDK_ARGS= \ - XCODE_DIR=$(XCODE_DEVELOPER_ROOT) \ - IOS_VERSION=$(IOS_SDK_VERSION) IOS_VERSION_MIN=$(MIN_IOS_SDK_VERSION) \ - TVOS_VERSION=$(TVOS_SDK_VERSION) TVOS_VERSION_MIN=$(MIN_TVOS_SDK_VERSION) \ - WATCHOS_VERSION=$(WATCH_SDK_VERSION) WATCHOS_VERSION_MIN=$(MIN_WATCHOS_SDK_VERSION) \ - WATCHOS64_32_VERSION=$(WATCH_SDK_VERSION) WATCHOS64_32_VERSION_MIN=$(MIN_WATCHOS64_32_SDK_VERSION) \ - MACOS_VERSION=$(MACOS_SDK_VERSION) MACOS_VERSION_MIN=$(MIN_MACOS_SDK_VERSION) - -SDK_CONFIG = $(MONO_PATH)/sdks/Make.config -SDK_BUILDDIR = $(MONO_PATH)/sdks/builds - -$(SDK_CONFIG): - echo "ENABLE_IOS=1" >> $@ - echo "ENABLE_MAC=1" >> $@ - echo "ENABLE_MACCAT=1" >> $@ - - -ifdef DISABLE_BUILDS_MAKEFILE_DEP -BUILDS_MAKEFILE_DEP = -else -BUILDS_MAKEFILE_DEP = Makefile -endif - -.stamp-configure-mono: $(SDK_CONFIG) - ulimit -n 4096 && $(MAKE) -C $(SDK_BUILDDIR) configure-ios configure-mac $(SDK_ARGS) - $(Q) touch $@ - -.stamp-compile-mono: .stamp-configure-mono $(MONO_DEPENDENCIES) $(BUILDS_MAKEFILE_DEP) $(TOP)/Make.config $(TOP)/mk/mono.mk - $(MAKE) -C $(SDK_BUILDDIR) package-ios package-ios-bcl $(SDK_ARGS) - $(MAKE) -C $(SDK_BUILDDIR) package-mac package-mac-bcl $(SDK_ARGS) - $(MAKE) -C $(SDK_BUILDDIR) package-maccat package-maccat-bcl $(SDK_ARGS) - $(Q) touch $@ - -clean-local:: - $(MAKE) -C $(SDK_BUILDDIR) clean $(SDK_ARGS) - $(Q) rm -f .stamp-compile-mono - -all-local:: .stamp-compile-mono .stamp-mono-ios-sdk-destdir - -endif +all-local:: .stamp-mono-ios-sdk-destdir .stamp-mono-ios-sdk-destdir: .stamp-$(MONO_BUILD_MODE) ln -sf $(MONO_IOS_SDK_DESTDIR) mono-ios-sdk-destdir $(Q) touch $@ -ifndef DISABLE_STRIP -INSTALL_STRIP_FLAG=-s -endif - -# -# Xamarin.iOS/WatchOS/TVOS/Mac/MacCatalyst BCL assemblies -# -install-local:: install-bcl -all-local:: install-bcl - -$(MONO_IOS_SDK_DESTDIR)/ios-bcl/%: .stamp-$(MONO_BUILD_MODE) -$(MONO_MAC_SDK_DESTDIR)/mac-bcl/%: .stamp-$(MONO_BUILD_MODE) - -IOS_ASSEMBLIES = \ - I18N \ - I18N.CJK \ - I18N.MidEast \ - I18N.Other \ - I18N.Rare \ - I18N.West \ - Microsoft.CSharp \ - Mono.CSharp \ - Mono.Data.Sqlite \ - Mono.Data.Tds \ - Mono.Security \ - mscorlib \ - System \ - System.ComponentModel.Composition \ - System.ComponentModel.DataAnnotations \ - System.Core \ - System.Data \ - System.Data.Services.Client \ - System.Data.DataSetExtensions \ - System.IdentityModel \ - System.IO.Compression \ - System.IO.Compression.FileSystem \ - System.Json \ - System.Net \ - System.Net.Http \ - System.Net.Http.WinHttpHandler \ - System.Numerics \ - System.Numerics.Vectors \ - System.Reflection.Context \ - System.Runtime.Serialization \ - System.Security \ - System.ServiceModel \ - System.ServiceModel.Internals \ - System.ServiceModel.Web \ - System.Transactions \ - System.Web.Services \ - System.Windows \ - System.Xml \ - System.Xml.Linq \ - System.Xml.Serialization - -MAC_ASSEMBLIES = \ - I18N \ - I18N.CJK \ - I18N.MidEast \ - I18N.Other \ - I18N.Rare \ - I18N.West \ - mscorlib \ - Microsoft.CSharp \ - Mono.CSharp \ - Mono.CompilerServices.SymbolWriter \ - Mono.Data.Sqlite \ - Mono.Data.Tds \ - Mono.Security \ - System.ComponentModel.Composition \ - System.ComponentModel.DataAnnotations \ - System.Core \ - System.Data.Services.Client \ - System.Data.DataSetExtensions \ - System.Data \ - System.IdentityModel \ - System.IO.Compression.FileSystem \ - System.IO.Compression \ - System.Json \ - System.Net.Http \ - System.Net \ - System.Numerics \ - System.Runtime.Serialization \ - System.ServiceModel.Web \ - System.ServiceModel \ - System.ServiceModel.Internals \ - System.Transactions \ - System.Web.Services \ - System.Windows \ - System.Xml.Linq \ - System.Xml.Serialization \ - System.Xml \ - System \ - System.Security \ - System.Reflection.Context \ - System.Net.Http.WinHttpHandler \ - System.Numerics.Vectors - -MAC_4_5_ASSEMBLIES = \ - $(MAC_ASSEMBLIES) \ - Mono.Messaging \ - Mono.Posix \ - System.Configuration \ - System.Configuration.Install \ - System.Data.Linq \ - System.EnterpriseServices \ - System.IdentityModel.Selectors \ - System.Messaging \ - System.Runtime.Serialization.Formatters.Soap - -COMMON_FACADE_ASSEMBLIES = \ - Microsoft.Win32.Primitives \ - Microsoft.Win32.Registry \ - Microsoft.Win32.Registry.AccessControl \ - System.AppContext \ - System.Collections \ - System.Collections.Concurrent \ - System.Collections.NonGeneric \ - System.Collections.Specialized \ - System.ComponentModel \ - System.ComponentModel.Annotations \ - System.ComponentModel.EventBasedAsync \ - System.ComponentModel.Primitives \ - System.ComponentModel.TypeConverter \ - System.Console \ - System.Data.Common \ - System.Data.SqlClient \ - System.Diagnostics.Contracts \ - System.Diagnostics.Debug \ - System.Diagnostics.FileVersionInfo \ - System.Diagnostics.Process \ - System.Diagnostics.StackTrace \ - System.Diagnostics.TextWriterTraceListener \ - System.Diagnostics.Tools \ - System.Diagnostics.TraceEvent \ - System.Diagnostics.TraceSource \ - System.Diagnostics.Tracing \ - System.Drawing.Common \ - System.Drawing.Primitives \ - System.Dynamic.Runtime \ - System.Globalization \ - System.Globalization.Calendars \ - System.Globalization.Extensions \ - System.IO \ - System.IO.Compression.ZipFile \ - System.IO.FileSystem \ - System.IO.FileSystem.AccessControl \ - System.IO.FileSystem.DriveInfo \ - System.IO.FileSystem.Primitives \ - System.IO.FileSystem.Watcher \ - System.IO.IsolatedStorage \ - System.IO.MemoryMappedFiles \ - System.IO.Pipes \ - System.IO.UnmanagedMemoryStream \ - System.Linq \ - System.Linq.Expressions \ - System.Linq.Parallel \ - System.Linq.Queryable \ - System.Net.AuthenticationManager \ - System.Net.Cache \ - System.Net.HttpListener \ - System.Net.Mail \ - System.Net.NameResolution \ - System.Net.NetworkInformation \ - System.Net.Ping \ - System.Net.Primitives \ - System.Net.Requests \ - System.Net.Security \ - System.Net.ServicePoint \ - System.Net.Sockets \ - System.Net.Utilities \ - System.Net.WebHeaderCollection \ - System.Net.WebSockets \ - System.Net.WebSockets.Client \ - System.ObjectModel \ - System.Reflection \ - System.Reflection.Emit \ - System.Reflection.Emit.ILGeneration \ - System.Reflection.Emit.Lightweight \ - System.Reflection.Extensions \ - System.Reflection.Primitives \ - System.Reflection.TypeExtensions \ - System.Resources.Reader \ - System.Resources.ReaderWriter \ - System.Resources.ResourceManager \ - System.Resources.Writer \ - System.Runtime \ - System.Runtime.CompilerServices.VisualC \ - System.Runtime.Extensions \ - System.Runtime.Handles \ - System.Runtime.InteropServices \ - System.Runtime.InteropServices.RuntimeInformation \ - System.Runtime.InteropServices.WindowsRuntime \ - System.Runtime.Numerics \ - System.Runtime.Serialization.Formatters \ - System.Runtime.Serialization.Json \ - System.Runtime.Serialization.Primitives \ - System.Runtime.Serialization.Xml \ - System.Security.AccessControl \ - System.Security.Claims \ - System.Security.Cryptography.Algorithms \ - System.Security.Cryptography.Csp \ - System.Security.Cryptography.DeriveBytes \ - System.Security.Cryptography.Encoding \ - System.Security.Cryptography.Encryption \ - System.Security.Cryptography.Encryption.Aes \ - System.Security.Cryptography.Encryption.ECDiffieHellman \ - System.Security.Cryptography.Encryption.ECDsa \ - System.Security.Cryptography.Hashing \ - System.Security.Cryptography.Hashing.Algorithms \ - System.Security.Cryptography.Primitives \ - System.Security.Cryptography.ProtectedData \ - System.Security.Cryptography.RandomNumberGenerator \ - System.Security.Cryptography.RSA \ - System.Security.Cryptography.X509Certificates \ - System.Security.Principal \ - System.Security.Principal.Windows \ - System.Security.SecureString \ - System.ServiceModel.Duplex \ - System.ServiceModel.Http \ - System.ServiceModel.NetTcp \ - System.ServiceModel.Primitives \ - System.ServiceModel.Security \ - System.ServiceProcess.ServiceController \ - System.Text.Encoding \ - System.Text.Encoding.CodePages \ - System.Text.Encoding.Extensions \ - System.Text.RegularExpressions \ - System.Threading \ - System.Threading.AccessControl \ - System.Threading.Overlapped \ - System.Threading.Tasks \ - System.Threading.Tasks.Parallel \ - System.Threading.Thread \ - System.Threading.ThreadPool \ - System.Threading.Timer \ - System.ValueTuple \ - System.Xml.ReaderWriter \ - System.Xml.XDocument \ - System.Xml.XmlDocument \ - System.Xml.XmlSerializer \ - System.Xml.XPath \ - System.Xml.XPath.XDocument \ - System.Xml.Xsl.Primitives \ - netstandard - -MOBILE_ADDITIONAL_FACADE_ASSEMBLIES = \ - System.Buffers \ - System.Memory \ - System.Reflection.DispatchProxy \ - System.Runtime.Loader \ - System.Security.Cryptography.Cng \ - System.Security.Cryptography.OpenSsl \ - System.Security.Cryptography.Pkcs \ - System.Threading.Tasks.Extensions \ - System.Xml.XPath.XmlDocument - -TVOS_ASSEMBLIES = $(IOS_ASSEMBLIES) -WATCHOS_ASSEMBLIES = $(filter-out Mono.Security Mono.Data.Tds,$(IOS_ASSEMBLIES)) -MACCATALYST_ASSEMBLIES = $(IOS_ASSEMBLIES) - -IOS_REPL_ASSEMBLIES = mscorlib System System.Core System.Xml Mono.CSharp -TVOS_REPL_ASSEMBLIES = $(IOS_REPL_ASSEMBLIES) -WATCHOS_REPL_ASSEMBLIES = $(IOS_REPL_ASSEMBLIES) -MACCATALYST_REPL_ASSEMBLIES = $(IOS_REPL_ASSEMBLIES) - -IOS_FACADE_ASSEMBLIES = $(COMMON_FACADE_ASSEMBLIES) $(MOBILE_ADDITIONAL_FACADE_ASSEMBLIES) -TVOS_FACADE_ASSEMBLIES = $(COMMON_FACADE_ASSEMBLIES) $(MOBILE_ADDITIONAL_FACADE_ASSEMBLIES) -WATCHOS_FACADE_ASSEMBLIES = $(COMMON_FACADE_ASSEMBLIES) $(MOBILE_ADDITIONAL_FACADE_ASSEMBLIES) -MAC_FACADE_ASSEMBLIES = $(COMMON_FACADE_ASSEMBLIES) $(MOBILE_ADDITIONAL_FACADE_ASSEMBLIES) -MAC_4_5_FACADE_ASSEMBLIES = $(COMMON_FACADE_ASSEMBLIES) System.Net.Http.Rtc -MACCATALYST_FACADE_ASSEMBLIES = $(COMMON_FACADE_ASSEMBLIES) $(MOBILE_ADDITIONAL_FACADE_ASSEMBLIES) - -IOS_BCL_DIRECTORIES = \ - $(PREFIX)/lib/mono/2.1 \ - $(PREFIX)/lib/mono/2.1/Facades \ - $(PREFIX)/lib/mono/2.1/repl \ - $(PREFIX)/lib/mono/Xamarin.iOS \ - $(PREFIX)/lib/mono/Xamarin.iOS/Facades \ - $(PREFIX)/lib/mono/Xamarin.iOS/repl - -WATCHOS_BCL_DIRECTORIES = \ - $(PREFIX)/lib/mono/Xamarin.WatchOS \ - $(PREFIX)/lib/mono/Xamarin.WatchOS/Facades \ - $(PREFIX)/lib/mono/Xamarin.WatchOS/repl - -TVOS_BCL_DIRECTORIES = \ - $(PREFIX)/lib/mono/Xamarin.TVOS \ - $(PREFIX)/lib/mono/Xamarin.TVOS/Facades \ - $(PREFIX)/lib/mono/Xamarin.TVOS/repl - -MACCATALYST_BCL_DIRECTORIES = \ - $(PREFIX)/lib/mono/Xamarin.MacCatalyst \ - $(PREFIX)/lib/mono/Xamarin.MacCatalyst/Facades \ - $(PREFIX)/lib/mono/Xamarin.MacCatalyst/repl - -MAC_BCL_DIRECTORIES = \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac/Facades \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5 \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5/Facades - -NO_PDB_ASSEMBLIES = System.Windows System.Xml.Serialization -MAC_NO_PDB_ASSEMBLIES = System.Windows System.Xml.Serialization - -IOS_BCL_TARGETS = \ - $(foreach file,$(IOS_ASSEMBLIES),$(PREFIX)/lib/mono/2.1/$(file).dll) \ - $(foreach file,$(filter-out $(NO_PDB_ASSEMBLIES),$(IOS_ASSEMBLIES)),$(PREFIX)/lib/mono/2.1/$(file).pdb) \ - $(foreach file,$(IOS_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.iOS/$(file).dll) \ - $(foreach file,$(filter-out $(NO_PDB_ASSEMBLIES),$(IOS_ASSEMBLIES)),$(PREFIX)/lib/mono/Xamarin.iOS/$(file).pdb) \ - $(foreach file,$(IOS_FACADE_ASSEMBLIES),$(PREFIX)/lib/mono/2.1/Facades/$(file).dll) \ - $(foreach file,$(IOS_FACADE_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.iOS/Facades/$(file).dll) \ - $(foreach file,$(IOS_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/2.1/repl/$(file).dll) \ - $(foreach file,$(IOS_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/2.1/repl/$(file).pdb) \ - $(foreach file,$(IOS_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.iOS/repl/$(file).dll) \ - $(foreach file,$(IOS_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.iOS/repl/$(file).pdb) \ - -WATCHOS_BCL_TARGETS = \ - $(foreach file,$(WATCHOS_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.WatchOS/$(file).dll) \ - $(foreach file,$(filter-out $(NO_PDB_ASSEMBLIES),$(WATCHOS_ASSEMBLIES)),$(PREFIX)/lib/mono/Xamarin.WatchOS/$(file).pdb) \ - $(foreach file,$(WATCHOS_FACADE_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.WatchOS/Facades/$(file).dll) \ - $(foreach file,$(WATCHOS_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.WatchOS/repl/$(file).dll) \ - $(foreach file,$(WATCHOS_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.WatchOS/repl/$(file).pdb) \ - -TVOS_BCL_TARGETS = \ - $(foreach file,$(TVOS_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.TVOS/$(file).dll) \ - $(foreach file,$(filter-out $(NO_PDB_ASSEMBLIES),$(TVOS_ASSEMBLIES)),$(PREFIX)/lib/mono/Xamarin.TVOS/$(file).pdb) \ - $(foreach file,$(TVOS_FACADE_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.TVOS/Facades/$(file).dll) \ - $(foreach file,$(TVOS_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.TVOS/repl/$(file).dll) \ - $(foreach file,$(TVOS_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.TVOS/repl/$(file).pdb) \ - -MACCATALYST_BCL_TARGETS = \ - $(foreach file,$(MACCATALYST_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.MacCatalyst/$(file).dll) \ - $(foreach file,$(filter-out $(NO_PDB_ASSEMBLIES),$(MACCATALYST_ASSEMBLIES)),$(PREFIX)/lib/mono/Xamarin.MacCatalyst/$(file).pdb) \ - $(foreach file,$(MACCATALYST_FACADE_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.MacCatalyst/Facades/$(file).dll) \ - -# the mono archive doesn't have the repl assemblies yet -MACCATALYST_BCL_TARGETS_DISABLED = \ - $(foreach file,$(MACCATALYST_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.MacCatalyst/repl/$(file).dll) \ - $(foreach file,$(MACCATALYST_REPL_ASSEMBLIES),$(PREFIX)/lib/mono/Xamarin.MacCatalyst/repl/$(file).pdb) \ - -MAC_BCL_TARGETS = \ - $(foreach file,$(MAC_ASSEMBLIES),$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac/$(file).dll) \ - $(foreach file,$(filter-out $(MAC_NO_PDB_ASSEMBLIES),$(MAC_ASSEMBLIES)),$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac/$(file).pdb) \ - $(foreach file,$(MAC_FACADE_ASSEMBLIES),$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac/Facades/$(file).dll) \ - $(foreach file,$(MAC_4_5_ASSEMBLIES),$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5/$(file).dll) \ - $(foreach file,$(filter-out $(MAC_NO_PDB_ASSEMBLIES),$(MAC_4_5_ASSEMBLIES)),$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5/$(file).pdb) \ - $(foreach file,$(MAC_4_5_FACADE_ASSEMBLIES),$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5/Facades/$(file).dll) \ - -$(PREFIX)/lib/mono/Xamarin.iOS/Facades/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.iOS/Facades - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch/Facades/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.iOS/repl/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.iOS/repl - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_runtime/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.iOS/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.iOS - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch/$(notdir $@) $@ - -$(PREFIX)/lib/mono/2.1/Facades/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/2.1/Facades - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch/Facades/$(notdir $@) $@ - -$(PREFIX)/lib/mono/2.1/repl/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/2.1/repl - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_runtime/$(notdir $@) $@ - -$(PREFIX)/lib/mono/2.1/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/2.1 - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.WatchOS/Facades/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.WatchOS/Facades - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_watch/Facades/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.WatchOS/repl/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.WatchOS/repl - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_watch_runtime/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.WatchOS/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.WatchOS - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_watch/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.TVOS/Facades/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.TVOS/Facades - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_tv/Facades/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.TVOS/repl/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.TVOS/repl - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_tv_runtime/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.TVOS/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.TVOS - $(Q) install -m 0755 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_tv/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.MacCatalyst/Facades/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.MacCatalyst/Facades - $(Q) install -m 0755 $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-bcl/monotouch/Facades/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.MacCatalyst/repl/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.MacCatalyst/repl - $(Q) install -m 0755 $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-bcl/monotouch_runtime/$(notdir $@) $@ - -$(PREFIX)/lib/mono/Xamarin.MacCatalyst/%: .stamp-$(MONO_BUILD_MODE) | $(PREFIX)/lib/mono/Xamarin.MacCatalyst - $(Q) install -m 0755 $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-bcl/monotouch/$(notdir $@) $@ - -$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac/Facades/%: .stamp-$(MONO_BUILD_MODE) | $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac/Facades - $(Q) install -m 0755 $(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac/Facades/$(notdir $@) $@ - -$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac/%: .stamp-$(MONO_BUILD_MODE) | $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac - $(Q) install -m 0755 $(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac/$(notdir $@) $@ - -$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5/Facades/%: .stamp-$(MONO_BUILD_MODE) | $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5/Facades - $(Q) install -m 0755 $(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac_net_4_5/Facades/$(notdir $@) $@ - -$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5/%: .stamp-$(MONO_BUILD_MODE) | $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5 - $(Q) install -m 0755 $(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac_net_4_5/$(notdir $@) $@ - -$(IOS_BCL_DIRECTORIES) $(WATCHOS_BCL_DIRECTORIES) $(TVOS_BCL_DIRECTORIES) $(MAC_BCL_DIRECTORIES) $(MACCATALYST_BCL_DIRECTORIES): - $(Q) mkdir -p $@ - -MONO_ARCHIVE_IOS_IGNORED_ASSEMBLIES = Mono.Simd System.Runtime.CompilerServices.Unsafe nunitlite # TODO check if we should add them -MONO_ARCHIVE_MAC_IGNORED_ASSEMBLIES = System.Runtime.CompilerServices.Unsafe nunitlite # TODO check if we should add them -MONO_ARCHIVE_MAC_4_5_IGNORED_ASSEMBLIES = SMDiagnostics System.Net.Http.WebRequest System.Runtime.CompilerServices.Unsafe nunitlite # TODO check if we should add them - -ios-assemblies-check: $(IOS_BCL_TARGETS) - $(Q) rm -f .$@* - $(Q) echo $(IOS_ASSEMBLIES) $(IOS_FACADE_ASSEMBLIES) $(MONO_ARCHIVE_IOS_IGNORED_ASSEMBLIES) | tr ' ' '\n' | sort > .$@1 - $(Q) ls -1 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch/Facades | grep dll$$ | sed 's/[.]dll//' | sort > .$@2 - $(Q) if ! diff -u .$@1 .$@2; then echo "\n*** There are assemblies in "$(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch" not defined in IOS_ASSEMBLIES or IOS_FACADE_ASSEMBLIES ***\n"; exit 1; fi - $(Q) rm -f .$@* - -watchos-assemblies-check: $(WATCHOS_BCL_TARGETS) - $(Q) rm -f .$@* - $(Q) echo $(WATCHOS_ASSEMBLIES) $(WATCHOS_FACADE_ASSEMBLIES) $(MONO_ARCHIVE_IOS_IGNORED_ASSEMBLIES) | tr ' ' '\n' | sort > .$@1 - $(Q) ls -1 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_watch $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_watch/Facades | grep dll$$ | sed 's/[.]dll//' | sort > .$@2 - $(Q) if ! diff -u .$@1 .$@2; then echo "\n*** There are assemblies in "$(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_watch" not defined in WATCHOS_ASSEMBLIES or WATCHOS_FACADE_ASSEMBLIES ***\n"; exit 1; fi - $(Q) rm -f .$@* - -tvos-assemblies-check: $(TVOS_BCL_TARGETS) - $(Q) rm -f .$@* - $(Q) echo $(TVOS_ASSEMBLIES) $(TVOS_FACADE_ASSEMBLIES) $(MONO_ARCHIVE_IOS_IGNORED_ASSEMBLIES) | tr ' ' '\n' | sort > .$@1 - $(Q) ls -1 $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_tv $(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_tv/Facades | grep dll$$ | sed 's/[.]dll//' | sort > .$@2 - $(Q) if ! diff -u .$@1 .$@2; then echo "\n*** There are assemblies in "$(MONO_IOS_SDK_DESTDIR)/ios-bcl/monotouch_tv" not defined in TVOS_ASSEMBLIES or TVOS_FACADE_ASSEMBLIES ***\n"; exit 1; fi - $(Q) rm -f .$@* - -mac-assemblies-check: $(MAC_BCL_TARGETS) - $(Q) rm -f .$@* - $(Q) echo $(MAC_ASSEMBLIES) $(MAC_FACADE_ASSEMBLIES) $(MONO_ARCHIVE_MAC_IGNORED_ASSEMBLIES) | tr ' ' '\n' | sort > .$@1 - $(Q) ls -1 $(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac $(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac/Facades | grep dll$$ | sed 's/[.]dll//' | sort > .$@2 - $(Q) if ! diff -u .$@1 .$@2; then echo "\n*** There are assemblies in "$(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac " not defined in MAC_ASSEMBLIES or MAC_FACADE_ASSEMBLIES ***\n"; exit 1; fi - $(Q) rm -f .$@* - -mac-45-assemblies-check: $(MAC_BCL_TARGETS) - $(Q) rm -f .$@* - $(Q) echo $(MAC_4_5_ASSEMBLIES) $(MAC_4_5_FACADE_ASSEMBLIES) $(MONO_ARCHIVE_MAC_4_5_IGNORED_ASSEMBLIES) | tr ' ' '\n' | sort > .$@1 - $(Q) ls -1 $(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac_net_4_5 $(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac_net_4_5/Facades | grep dll$$ | sed 's/[.]dll//' | sort > .$@2 - $(Q) if ! diff -u .$@1 .$@2; then echo "\n*** There are assemblies in "$(MONO_MAC_SDK_DESTDIR)/mac-bcl/xammac_net_4_5 " not defined in MAC_4_5_ASSEMBLIES or MAC_4_5_FACADE_ASSEMBLIES ***\n"; exit 1; fi - $(Q) rm -f .$@* - -maccatalyst-assemblies-check: $(MACCATALYST_BCL_TARGETS) - $(Q) rm -f .$@* - $(Q) echo $(MACCATALYST_ASSEMBLIES) $(MACCATALYST_FACADE_ASSEMBLIES) $(MONO_ARCHIVE_IOS_IGNORED_ASSEMBLIES) | tr ' ' '\n' | sort > .$@1 - $(Q) ls -1 $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-bcl/monotouch $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-bcl/monotouch/Facades | grep dll$$ | sed 's/[.]dll//' | sort > .$@2 - $(Q) if ! diff -u .$@1 .$@2; then echo "\n*** There are assemblies in "$(MONO_MACCATALYST_SDK_DESTDIR)/maccat-bcl/monotouch" not defined in MACCATALYST_ASSEMBLIES or MACCATALYST_FACADE_ASSEMBLIES ***\n"; exit 1; fi - $(Q) rm -f .$@* - -install-bcl-ios: $(IOS_BCL_TARGETS) ios-assemblies-check -install-bcl-tvos: $(TVOS_BCL_TARGETS) tvos-assemblies-check -install-bcl-watchos: $(WATCHOS_BCL_TARGETS) watchos-assemblies-check -install-bcl-mac: $(MAC_BCL_TARGETS) mac-assemblies-check mac-45-assemblies-check -install-bcl-maccatalyst: $(MACCATALYST_BCL_TARGETS) maccatalyst-assemblies-check - -install-bcl:: install-bcl-ios -install-bcl:: install-bcl-watchos -install-bcl:: install-bcl-tvos -install-bcl:: install-bcl-mac -install-bcl:: install-bcl-maccatalyst -### TODO END - -verify-signature: - for file in $(PREFIX)/lib/mono/2.1/*.dll; do \ - MONO_CFG_DIR=$(TOP) $(SYSTEM_SN) -q -v $$file; \ - done - @MONO_CFG_DIR=$(TOP) $(SYSTEM_SN) -q -v $(PREFIX)/lib/mono/2.1/monotouch.dll \ - @MONO_CFG_DIR=$(TOP) $(SYSTEM_SN) -q -v $(PREFIX)/lib/mono/2.1/MonoTouch.Dialog.dll \ - @MONO_CFG_DIR=$(TOP) $(SYSTEM_SN) -q -v $(PREFIX)/lib/mono/2.1/MonoTouch.NUnitLite.dll \ - @MONO_CFG_DIR=$(TOP) $(SYSTEM_SN) -q -v $(PREFIX)/lib/mono/2.1/OpenTK.dll \ - @MONO_CFG_DIR=$(TOP) $(SYSTEM_SN) -q -v $(PREFIX)/lib/mono/2.1/OpenTK-10.dll - for file in $$(find $(PREFIX)/lib/mono/2.1/Facades -name "*.dll"); do \ - MONO_CFG_DIR=$(TOP) $(SYSTEM_SN) -q -v $$file; \ - done - -# -# smcs -# FIXME: Needed because of broken MonoDevelop assumptions -# -install-local:: install-smcs -all-local:: install-smcs - -$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/bin/smcs: - @mkdir -p $(dir $@) - @echo Installing smcs script - @echo "#!/bin/bash" > $@ - @echo >> $@ - @echo "echo 'This script ($$0) is obsolete. Use csc to compile instead.'" >> $@ - @echo "exit 1" >> $@ - @chmod +x $@ - -install-smcs: $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/bin/smcs - -# -# Xamarin.Mac common pieces -# -install-local:: install-mac-common -all-local:: install-mac-common - -MAC_COMMON_DIRECTORIES = \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_DIR)/Versions \ - $(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR) \ - -MAC_COMMON_TARGETS = \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_DIR)/Versions/Current \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_DIR)/Commands \ - $(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR)/buildinfo \ - $(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR)/Version \ - $(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR)/updateinfo \ - $(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR)/Versions.plist \ - -$(MAC_DESTDIR)$(MAC_FRAMEWORK_DIR)/Versions/Current: | $(MAC_DESTDIR)$(MAC_FRAMEWORK_DIR)/Versions - $(Q_LN) ln -hfs $(MAC_INSTALL_VERSION) $@ - -$(MAC_DESTDIR)$(MAC_FRAMEWORK_DIR)/Commands: - $(Q_LN) ln -hfs $(MAC_TARGETDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/bin $@ - -$(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR)/buildinfo: $(TOP)/Make.config.inc $(GIT_DIRECTORY)/index | $(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR) - $(Q_GEN) echo "Version: $(MAC_PACKAGE_VERSION)" > $@ - $(Q) echo "Hash: $(shell git log --oneline -1 --pretty=%h)" >> $@ - $(Q) echo "Branch: $(CURRENT_BRANCH)" >> $@ - $(Q) echo "Build date: $(shell date '+%Y-%m-%d %H:%M:%S%z')" >> $@ - -$(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR)/updateinfo: $(TOP)/Make.config.inc - $(Q) echo "0ab364ff-c0e9-43a8-8747-3afb02dc7731 $(MAC_PACKAGE_UPDATE_ID)" > $@ - -$(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR)/Version: $(TOP)/Make.config.inc - $(Q) echo $(MAC_PACKAGE_VERSION) > $@ - -$(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR)/Versions.plist: $(TOP)/Versions-mac.plist.in Makefile $(TOP)/Make.config $(TOP)/mk/mono.mk $(TOP)/versions-check.csharp .stamp-$(MONO_BUILD_MODE) - $(Q) $(TOP)/versions-check.csharp $< "$(MIN_IOS_SDK_VERSION)" "$(MAX_IOS_DEPLOYMENT_TARGET)" "$(MIN_TVOS_SDK_VERSION)" "$(MAX_TVOS_DEPLOYMENT_TARGET)" "$(MIN_WATCH_OS_VERSION)" "$(MAX_WATCH_DEPLOYMENT_TARGET)" "$(MIN_MACOS_SDK_VERSION)" "$(MACOS_SDK_VERSION)" "$(MIN_MACCATALYST_SDK_VERSION)" "$(MACCATALYST_SDK_VERSION)" - $(Q_GEN) sed -e 's/@XCODE_VERSION@/$(XCODE_VERSION)/g' -e "s/@MONO_VERSION@/$(shell cat $(MONO_MAC_SDK_DESTDIR)/mac-mono-version.txt)/g" -e "s/@MIN_XM_MONO_VERSION@/$(MIN_XM_MONO_VERSION)/g" $< > $@ - -$(MAC_COMMON_DIRECTORIES): - $(Q) mkdir -p $@ - -install-mac-common: $(MAC_COMMON_TARGETS) - -# -# Xamarin.Mac Mono runtime pieces -# -install-local:: install-mac -all-local:: install-mac - -MAC_DIRECTORIES = \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/bin \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/etc/mono/assemblies/System \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/Frameworks \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/pkgconfig \ - -MAC_TARGETS = \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmonosgen-2.0.a \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmono-profiler-log.a \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmono-native-compat.a \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmono-native-unified.a \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmonosgen-2.0.dylib \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libMonoPosixHelper.dylib \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmono-native-compat.dylib \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmono-native-unified.dylib \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmono-2.0.dylib \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmono-2.0.a \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/pkgconfig/mono-2.pc \ - $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/etc/mono/assemblies/System/System.config \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/bin/mono-sgen \ - $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/bin/aarch64-darwin-mono-sgen \ - -$(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/%: .stamp-$(MONO_BUILD_MODE) | $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib - $(Q) $(CP) $(MONO_MAC_SDK_DESTDIR)/mac-libs/$(notdir $@) $@ - -$(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmono-2.0.dylib $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/libmono-2.0.a: | $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib - $(Q) ln -sf libmonosgen-2.0$(suffix $@) $@ - -$(MONO_MAC_SDK_DESTDIR)/mac-pkgconfig/mono-2.pc: .stamp-$(MONO_BUILD_MODE) - -$(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/pkgconfig/mono-2.pc: $(MONO_MAC_SDK_DESTDIR)/mac-pkgconfig/mono-2.pc | $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/lib/pkgconfig - $(Q) $(CP) $< $@ - -$(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/etc/mono/assemblies/System/System.config: mac-System.config | $(MAC_DESTDIR)$(XAMARIN_MACOS_SDK)/etc/mono/assemblies/System - $(Q) $(CP) $< $@ - -$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/bin/mono-sgen: .stamp-$(MONO_BUILD_MODE) | $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/bin - $(Q) install -m 0755 $(MONO_MAC_SDK_DESTDIR)/mac-bin/mono-sgen $@ - -$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/bin/aarch64-darwin-mono-sgen: .stamp-$(MONO_BUILD_MODE) | $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/bin - $(Q) install -m 0755 $(MONO_MAC_SDK_DESTDIR)/mac-bin/aarch64-darwin-mono-sgen $@ - -$(MAC_DIRECTORIES): - $(Q) mkdir -p $@ - -install-mac: $(MAC_TARGETS) - -# -# Xamarin.iOS/WatchOS/TVOS common pieces -# -install-local:: install-ios-common -all-local:: install-ios-common - -IOS_COMMON_DIRECTORIES = \ - $(IOS_DESTDIR)/Library/Frameworks/Xamarin.iOS.framework/Versions \ - $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX) \ - -IOS_COMMON_TARGETS = \ - $(IOS_DESTDIR)/Library/Frameworks/Xamarin.iOS.framework/Versions/Current \ - $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/buildinfo \ - $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/Version \ - $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/updateinfo \ - $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/Versions.plist \ - -$(IOS_DESTDIR)/Library/Frameworks/Xamarin.iOS.framework/Versions/Current: | $(IOS_DESTDIR)/Library/Frameworks/Xamarin.iOS.framework/Versions - $(Q_LN) ln -hfs $(IOS_INSTALL_VERSION) $@ - -$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/buildinfo: $(TOP)/Make.config.inc $(GIT_DIRECTORY)/index | $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX) - $(Q_GEN) echo "Version: $(IOS_PACKAGE_VERSION)" > $@ - $(Q) echo "Hash: $(shell git log --oneline -1 --pretty=%h)" >> $@ - $(Q) echo "Branch: $(CURRENT_BRANCH)" >> $@ - $(Q) echo "Build date: $(shell date '+%Y-%m-%d %H:%M:%S%z')" >> $@ - -$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/Version: $(TOP)/Make.config.inc | $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX) - $(Q) echo $(IOS_PACKAGE_VERSION) > $@ - -$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/updateinfo: $(TOP)/Make.config.inc - $(Q) echo "4569c276-1397-4adb-9485-82a7696df22e $(IOS_PACKAGE_UPDATE_ID)" > $@ - -$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/Versions.plist: $(TOP)/Versions-ios.plist.in Makefile $(TOP)/Make.config $(TOP)/mk/mono.mk $(TOP)/versions-check.csharp .stamp-$(MONO_BUILD_MODE) - $(Q) $(TOP)/versions-check.csharp $< "$(MIN_IOS_SDK_VERSION)" "$(MAX_IOS_DEPLOYMENT_TARGET)" "$(MIN_TVOS_SDK_VERSION)" "$(MAX_TVOS_DEPLOYMENT_TARGET)" "$(MIN_WATCH_OS_VERSION)" "$(MAX_WATCH_DEPLOYMENT_TARGET)" "$(MIN_MACOS_SDK_VERSION)" "$(MACOS_SDK_VERSION)" "$(MIN_MACCATALYST_SDK_VERSION)" "$(MACCATALYST_SDK_VERSION)" - $(Q_GEN) sed -e 's/@XCODE_VERSION@/$(XCODE_VERSION)/g' -e "s/@MONO_VERSION@/$(shell cat $(MONO_IOS_SDK_DESTDIR)/ios-mono-version.txt)/g" $< > $@ - -$(IOS_COMMON_DIRECTORIES): - $(Q) mkdir -p $@ - -install-ios-common: $(IOS_COMMON_TARGETS) - -# -# iPhone simulator Mono runtime pieces -# -install-local:: install-iphonesimulator -all-local:: install-iphonesimulator - -IPHONESIMULATOR_DIRECTORIES = \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/Frameworks \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib - -IPHONESIMULATOR_TARGETS = \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib/libmonosgen-2.0.a \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib/libmono-profiler-log.a \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib/libmono-native-compat.a \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib/libmono-native-unified.a \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib/libmonosgen-2.0.dylib \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib/libmono-native-compat.dylib \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib/libmono-native-unified.dylib \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib/libmono-profiler-log.dylib \ - $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/Frameworks/Mono.framework/Mono \ - -$(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/lib - $(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios-sim/$(notdir $@) $@ - $(Q) if test -d $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios-sim/$(notdir $@).dSYM; then $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios-sim/$(notdir $@).dSYM $(dir $@); fi - -$(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/ios-sim/Mono.framework $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/ios-sim/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_IOSSIMULATOR_SDK)/Frameworks - -$(IPHONESIMULATOR_DIRECTORIES): - $(Q) mkdir -p $@ - -install-iphonesimulator:: $(IPHONESIMULATOR_TARGETS) - -# -# Watch simulator Mono runtime pieces -# -install-local:: install-watchsimulator -all-local:: install-watchsimulator - -WATCHSIMULATOR_DIRECTORIES = \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/Frameworks \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib - -WATCHSIMULATOR_TARGETS = \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib/libmonosgen-2.0.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib/libmono-profiler-log.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib/libmono-native-compat.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib/libmono-native-unified.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib/libmonosgen-2.0.dylib \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib/libmono-native-compat.dylib \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib/libmono-native-unified.dylib \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib/libmono-profiler-log.dylib \ - $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/Frameworks/Mono.framework/Mono \ - -$(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/lib - $(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos-sim/$(notdir $@) $@ - $(Q) if test -d $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos-sim/$(notdir $@).dSYM; then $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos-sim/$(notdir $@).dSYM $(dir $@); fi - -$(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/watchos-sim/Mono.framework $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/watchos-sim/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_WATCHSIMULATOR_SDK)/Frameworks - -$(WATCHSIMULATOR_DIRECTORIES): - $(Q) mkdir -p $@ - -install-watchsimulator: $(WATCHSIMULATOR_TARGETS) - -# -# TV simulator Mono runtime pieces -# -install-local:: install-tvsimulator -all-local:: install-tvsimulator - -TVSIMULATOR_DIRECTORIES = \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/Frameworks \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib - -TVSIMULATOR_TARGETS = \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib/libmonosgen-2.0.a \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib/libmono-profiler-log.a \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib/libmono-native-compat.a \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib/libmono-native-unified.a \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib/libmonosgen-2.0.dylib \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib/libmono-native-compat.dylib \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib/libmono-native-unified.dylib \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib/libmono-profiler-log.dylib \ - $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/Frameworks/Mono.framework/Mono \ - -$(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/lib - $(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos-sim/$(notdir $@) $@ - $(Q) if test -d $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos-sim/$(notdir $@).dSYM; then $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos-sim/$(notdir $@).dSYM $(dir $@); fi - -$(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/tvos-sim/Mono.framework $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/tvos-sim/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_TVSIMULATOR_SDK)/Frameworks - -$(TVSIMULATOR_DIRECTORIES): - $(Q) mkdir -p $@ - -install-tvsimulator: $(TVSIMULATOR_TARGETS) - -# -# Mac Catalyst Mono runtime pieces -# -install-local:: install-maccatalyst -all-local:: install-maccatalyst - -MACCATALYST_DIRECTORIES = \ - $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/Frameworks \ - $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/lib \ - -MACCATALYST_TARGETS = \ - $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/lib/libmonosgen-2.0.a \ - $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/lib/libmono-profiler-log.a \ - $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/lib/libmono-native.a \ - $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/lib/libmonosgen-2.0.dylib \ - $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/lib/libmono-native.dylib \ - -$(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/lib - $(Q) $(CP) $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-libs/$(notdir $@) $@ - $(Q) if test -d $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-libs/$(notdir $@).dSYM; then $(CP) -R $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-libs/$(notdir $@).dSYM $(dir $@); fi - -$(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-frameworks/ios-sim/Mono.framework $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_MACCATALYST_SDK_DESTDIR)/maccat-frameworks/ios-sim/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_MACCATALYST_SDK)/Frameworks - -$(XAMARIN_MACCATALYST_SDK_DIRECTORIES): - $(Q) mkdir -p $@ - -$(MACCATALYST_DIRECTORIES): - $(Q) mkdir -p $@ - -install-maccatalyst:: $(MACCATALYST_TARGETS) - -# -# iPhone device Mono runtime pieces -# -install-local:: install-iphoneos -all-local:: install-iphoneos - -IPHONEOS_DIRECTORIES = \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib - -IPHONEOS_TARGETS = \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmonosgen-2.0.a \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmono-profiler-log.a \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmono-ee-interp.a \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmono-icall-table.a \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmono-ilgen.a \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmono-native-compat.a \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmono-native-unified.a \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmonosgen-2.0.dylib \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmono-native-compat.dylib \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmono-native-unified.dylib \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/libmono-profiler-log.dylib \ - $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks/Mono.framework/Mono \ - -$(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/lib - $(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios/$(notdir $@) $@ - $(Q) if test -d $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios/$(notdir $@).dSYM; then $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-libs/ios/$(notdir $@).dSYM $(dir $@); fi - -$(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/ios/Mono.framework $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/ios/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_IPHONEOS_SDK)/Frameworks - -$(IPHONEOS_DIRECTORIES): - $(Q) mkdir -p $@ - -install-iphoneos: $(IPHONEOS_TARGETS) - -# -# Watch device Mono runtime pieces -# -install-local:: install-watchos -all-local:: install-watchos - -WATCHOS_DIRECTORIES = \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib - -WATCHOS_TARGETS = \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmonosgen-2.0.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmono-profiler-log.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmono-ee-interp.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmono-icall-table.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmono-ilgen.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmono-native-compat.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmono-native-unified.a \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmonosgen-2.0.dylib \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmono-native-compat.dylib \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmono-native-unified.dylib \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/libmono-profiler-log.dylib \ - $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks/Mono.framework/Mono \ - -$(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/lib - $(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos/$(notdir $@) $@ - $(Q) if test -d $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos/$(notdir $@).dSYM; then $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-libs/watchos/$(notdir $@).dSYM $(dir $@); fi - -$(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/watchos/Mono.framework $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/watchos/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_WATCHOS_SDK)/Frameworks - -$(WATCHOS_DIRECTORIES): - $(Q) mkdir -p $@ - -install-watchos: $(WATCHOS_TARGETS) - -# -# TV device Mono runtime pieces -# -install-local:: install-tvos -all-local:: install-tvos - -TVOS_DIRECTORIES = \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib - -TVOS_TARGETS = \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmonosgen-2.0.a \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmono-profiler-log.a \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmono-ee-interp.a \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmono-icall-table.a \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmono-ilgen.a \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmono-native-compat.a \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmono-native-unified.a \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmonosgen-2.0.dylib \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmono-native-compat.dylib \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmono-native-unified.dylib \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/libmono-profiler-log.dylib \ - $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks/Mono.framework/Mono \ - -$(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib/%: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/lib - $(Q) $(CP) $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos/$(notdir $@) $@ - $(Q) if test -d $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos/$(notdir $@).dSYM; then $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-libs/tvos/$(notdir $@).dSYM $(dir $@); fi - -$(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks/Mono.framework/Mono: .stamp-$(MONO_BUILD_MODE) | $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/tvos/Mono.framework $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks - $(Q) $(CP) -R $(MONO_IOS_SDK_DESTDIR)/ios-frameworks/tvos/Mono.framework.dSYM $(IOS_DESTDIR)$(XAMARIN_TVOS_SDK)/Frameworks - -$(TVOS_DIRECTORIES): - $(Q) mkdir -p $@ - -install-tvos: $(TVOS_TARGETS) - # # .NET # - DOTNET_COMMON_DIRECTORIES += \ $(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(DOTNET_DESTDIR)/$($(platform)_NUGET_SDK_NAME)) \ $(foreach platform,$(DOTNET_PLATFORMS_UPPERCASE),$(DOTNET_DESTDIR)/$($(platform)_NUGET_SDK_NAME)/tools) \ @@ -1164,57 +213,3 @@ install-dotnet: $(DOTNET_COMMON_TARGETS) install-local:: install-dotnet all-local:: install-dotnet -# -# Cross compilers -# -# This is the cross aot version of mono. runs on x86 but the jit/aot spits out arm. -# -# There are two versions of the cross compiler, a 32 bit version targeting arm, and a 64 -# bit version targeting arm64. -# These are compiled using the mono sdk makefiles -# -install-local:: install-cross - -$(MONO_IOS_SDK_DESTDIR)/ios-cross32-release/bin/arm-darwin-mono-sgen: .stamp-$(MONO_BUILD_MODE) -$(MONO_IOS_SDK_DESTDIR)/ios-cross64-release/bin/aarch64-darwin-mono-sgen: .stamp-$(MONO_BUILD_MODE) -$(MONO_IOS_SDK_DESTDIR)/ios-crosswatch-release/bin/armv7k-unknown-darwin-mono-sgen: .stamp-$(MONO_BUILD_MODE) -$(MONO_IOS_SDK_DESTDIR)/ios-crosswatch-release/bin/aarch64-apple-darwin10_ilp32-mono-sgen: .stamp-$(MONO_BUILD_MODE) - -$(PREFIX)/bin/arm-darwin-mono-sgen: $(MONO_IOS_SDK_DESTDIR)/ios-cross32-release/bin/arm-darwin-mono-sgen | $(PREFIX)/bin - $(call Q_2,INSTALL ,[CROSS]) install -c -m 0755 $(INSTALL_STRIP_FLAG) $^ $@ - -$(PREFIX)/bin/arm64-darwin-mono-sgen: $(MONO_IOS_SDK_DESTDIR)/ios-cross64-release/bin/aarch64-darwin-mono-sgen | $(PREFIX)/bin - $(call Q_2,INSTALL ,[CROSS]) install -c -m 0755 $(INSTALL_STRIP_FLAG) $^ $@ - -$(PREFIX)/bin/armv7k-unknown-darwin-mono-sgen: $(MONO_IOS_SDK_DESTDIR)/ios-crosswatch-release/bin/armv7k-unknown-darwin-mono-sgen | $(PREFIX)/bin - $(call Q_2,INSTALL ,[CROSS]) install -c -m 0755 $(INSTALL_STRIP_FLAG) $^ $@ - -$(PREFIX)/bin/arm64_32-darwin-mono-sgen: $(MONO_IOS_SDK_DESTDIR)/ios-crosswatch64_32-release/bin/aarch64-apple-darwin10_ilp32-mono-sgen | $(PREFIX)/bin - $(call Q_2,INSTALL ,[CROSS]) install -c -m 0755 $(INSTALL_STRIP_FLAG) $^ $@ - -$(PREFIX)/bin: - $(Q) mkdir -p $@ - -.PHONY: install-cross -install-cross: $(PREFIX)/bin/arm-darwin-mono-sgen $(PREFIX)/bin/arm64-darwin-mono-sgen $(PREFIX)/bin/armv7k-unknown-darwin-mono-sgen $(PREFIX)/bin/arm64_32-darwin-mono-sgen - -# -# LLVM -# -install-local:: install-llvm - -LLVM64_TARGETS = \ - $(PREFIX)/LLVM/bin/opt \ - $(PREFIX)/LLVM/bin/llc \ - -$(MONO_IOS_SDK_DESTDIR)/llvm-llvm64/bin/%: .stamp-$(MONO_BUILD_MODE) - -$(PREFIX)/LLVM/bin/%: $(MONO_IOS_SDK_DESTDIR)/llvm-llvm64/bin/% | $(PREFIX)/LLVM/bin - $(call Q_2,INSTALL ,[LLVM64]) install -c -m 0755 $(INSTALL_STRIP_FLAG) $^ $@ - -$(PREFIX)/LLVM/bin: - $(Q) mkdir -p $@ - -.PHONY: install-llvm64 install-llvm -install-llvm: install-llvm64 -install-llvm64: $(LLVM64_TARGETS) diff --git a/release/Makefile b/release/Makefile index b883fee8cd94..493e73a7c045 100644 --- a/release/Makefile +++ b/release/Makefile @@ -1,150 +1,9 @@ TOP=../../xamarin-macios include $(TOP)/Make.config -IOS_PACKAGE_DESTDIR=$(abspath .)/_ios-install -MAC_PACKAGE_DESTDIR=$(abspath .)/_mac-install - -IOS_PAYLOAD=$(abspath $(IOS_PACKAGE_DESTDIR)) -MAC_PAYLOAD=$(abspath $(MAC_PACKAGE_DESTDIR)) - -MAC_INSTALL_PKG=xamarin.mac-$(MAC_PACKAGE_VERSION).pkg -MAC_UNINSTALL_PKG=xamarin.mac-uninstall-$(MAC_PACKAGE_VERSION).pkg - -MAC_SED_PROCESS_IN = sed \ - -e "s/@INSTALLKBYTES@/`du -sk $(MAC_PAYLOAD) | awk '{print $$1}'`/g" \ - -e "s/@NUMFILES@/`lsbom mac-tmp-package/$(MAC_INSTALL_PKG)/Bom 2>/dev/null | wc -l | awk '{print $$1}'`/g" \ - -e "s/@INSTALL_PKG@/$(MAC_INSTALL_PKG)/g" \ - -e "s/@UNINSTALL_PKG@/$(MAC_UNINSTALL_PKG)/g" \ - -e "s,@PACKAGE_INSTALL_LOCATION@,$(MAC_PACKAGE_INSTALL_LOCATION),g" \ - -e "s/@PACKAGE_VERSION@/$(MAC_PACKAGE_VERSION)/g" \ - -e "s/@PRODUCT@/$(MAC_PRODUCT)/g" \ - -e "s,@XAMMAC_PREFIX@,$(MAC_FRAMEWORK_CURRENT_DIR),g" - -ifdef INCLUDE_MAC -ALL_PACKAGES+=$(MAC_PACKAGE_FILENAME) -endif -ifdef INCLUDE_IOS -ALL_PACKAGES+=$(IOS_PACKAGE_FILENAME) -endif - -build-for-package: - @# make sure we start with a clean slate - $(Q) git clean -xfd - $(Q) $(MAKE) -C $(TOP) install USE_SOURCE_LINKS=0 DEVMODE=0 \ - IOS_DESTDIR=$(IOS_PACKAGE_DESTDIR) IOS_TARGETDIR=/ IOS_INSTALL_VERSION=$(IOS_PACKAGE_VERSION) \ - MAC_DESTDIR=$(MAC_PACKAGE_DESTDIR) MAC_TARGETDIR=/ MAC_INSTALL_VERSION=$(MAC_PACKAGE_VERSION) - release package: - $(Q) $(MAKE) build-for-package - $(Q) $(MAKE) $(ALL_PACKAGES) - @# updateinfo, uploaded to wrench -ifdef INCLUDE_MAC - $(Q) cp $(MAC_PACKAGE_DESTDIR)/$(MAC_FRAMEWORK_DIR)/Versions/Current/updateinfo mac-updateinfo -endif -ifdef INCLUDE_IOS - $(Q) cp $(IOS_PACKAGE_DESTDIR)/$(IOS_FRAMEWORK_DIR)/Versions/Current/updateinfo ios-updateinfo -endif $(MAKE) bundle.zip msbuild.zip -# this are just a useful targets to run locally if you're not interested in the XI/XM package -# it should be almost identical to the normal 'package' target (only difference should be that the XM/XI -# bits aren't built/packaged) -ifdef INCLUDE_MAC -mac-package: - $(Q) $(MAKE) build-for-package - $(Q) $(MAKE) $(MAC_PACKAGE_FILENAME) -endif -ifdef INCLUDE_IOS -ios-package: - $(Q) $(MAKE) build-for-package - $(Q) $(MAKE) $(IOS_PACKAGE_FILENAME) -endif - -prechecks: -ifdef CROSS_BUILD_CFLAGS - echo "CROSS_BUILD_CFLAGS can't be set when building a package. Please fix Make.local.config" && exit 1 -endif -ifdef DEVICE_BUILD_CFLAGS - echo "DEVICE_BUILD_CFLAGS can't be set when building a package. Please fix Make.local.config" && exit 1 -endif - @echo Package prechecks completed successfully. - -monotouch.pkg: Makefile - @echo Building $@ - $(Q) $(MAKE) prechecks - $(Q) mkdir -p ios-work/commercial - $(Q) cp postflight-ios ios-work/commercial/postinstall - $(Q) chmod a+x ios-work/commercial/postinstall - $(Q) mkdir -p ios-tmp-package/Resources/en.lproj - $(Q) mkdir -p ios-tmp-package/monotouch.pkg - $(Q) cp $(TOP)/tools/scripts/License.txt ios-tmp-package/Resources/en.lproj/License.txt - $(Q) mkbom $(IOS_PAYLOAD) ios-tmp-package/monotouch.pkg/Bom - $(Q) (cd $(IOS_PAYLOAD); lsbom -p f $(abspath ./ios-tmp-package/monotouch.pkg/Bom) | cpio -o | gzip -9 -n > $(abspath ios-tmp-package/monotouch.pkg/Payload)) 2>/dev/null - $(Q) (cd ios-work/commercial; ls -d . ./postinstall | cpio -o | gzip -9 -n > ../../ios-tmp-package/monotouch.pkg/Scripts) 2>/dev/null - $(Q) INSTALLKBYTES=`du -sk $(IOS_PAYLOAD) | awk '{print $$1}'`; NUMFILES=`lsbom ios-tmp-package/monotouch.pkg/Bom | wc -l | awk '{print $$1}'`; sed -e "s/@INSTALLKBYTES@/$$INSTALLKBYTES/g" -e "s/@NUMFILES@/$$NUMFILES/g" -e "s/@FULL_PACKAGE_UTI@/$(IOS_PACKAGE_UTI)/g" -e "s,@MONOTOUCH_PREFIX@,$(MONOTOUCH_PREFIX),g" PackageInfo.ios.in > ios-tmp-package/monotouch.pkg/PackageInfo - @echo Built $@ - -$(IOS_PACKAGE_FILENAME): delete-xma-build-host.pkg monotouch.pkg - @echo Building $@ - @rm -Rf ios-meta-package - @cp -R ios-tmp-package ios-meta-package - @cp -R xma-tmp-package/delete-xma-build-host.pkg ios-meta-package - @$(Q) INSTALLBYTES_MTVS=`grep installKBytes ios-meta-package/delete-xma-build-host.pkg/PackageInfo | sed 's/.*installKBytes="\([0-9]*\)".*/\1/'` INSTALLKBYTES=`du -sk $(IOS_PAYLOAD) | awk '{print $$1}'`; sed -e s/@INSTALLKBYTES@/$$INSTALLKBYTES/ -e s/@INSTALLBYTES_MTVS@/$$INSTALLBYTES_MTVS/ Distribution.ios.in > ios-meta-package/Distribution - @$(Q_GEN) (cd ios-meta-package; xar --no-compress monotouch.pkg/Payload --no-compress monotouch.pkg/Scripts --no-compress delete-xma-build-host.pkg/Payload --no-compress delete-xma-build-host.pkg/Scripts -c -f ../$@ *) - @echo Built $@ - -# delete-xma-build-host is a package with the same id as the old MTVS installer, but with 0 files to install. -# This makes OSX remove all files installed by the old MTVS installer. -delete-xma-build-host.pkg: - @echo Building $@ - $(Q) rm -rf xma-work xma-tmp-package - $(Q) mkdir -p xma-work/commercial/payload - $(Q) cp preinstall.xma.in xma-work/commercial/preinstall - $(Q) chmod a+x xma-work/commercial/preinstall - $(Q) mkdir -p xma-tmp-package/$@ - $(Q) mkbom xma-work/commercial/payload xma-tmp-package/$@/Bom - $(Q) (cd xma-work/commercial/payload; lsbom -p f $(abspath ./xma-tmp-package/$@/Bom) | cpio -o | gzip -9 -n > $(abspath xma-tmp-package/$@/Payload)) 2>/dev/null - $(Q) (cd xma-work/commercial; ls -d . ./preinstall | cpio -o | gzip -9 -n > ../../xma-tmp-package/$@/Scripts) 2>/dev/null - $(Q) cp PackageInfo.xma.in xma-tmp-package/$@/PackageInfo - $(Q) cp Distribution.xma.in xma-tmp-package/Distribution - $(Q) (cd xma-tmp-package; xar --no-compress $@/Payload --no-compress $@/Scripts -c -f ../$@ *) - @echo Built $@ - -$(MAC_PACKAGE_FILENAME): - @echo Building $@ - $(Q) $(MAKE) prechecks -# xamarin.mac-v.v.v.pkg meta package - $(Q) mkdir -p mac-work/commercial - $(Q) cp postflight-mac mac-work/commercial/postflight-mac - $(Q) chmod a+x mac-work/commercial/postflight-mac - $(Q) mkdir -p mac-tmp-package/$(MAC_INSTALL_PKG) - $(Q) mkdir -p mac-tmp-package/Resources/en.lproj - $(Q) cp $(TOP)/tools/scripts/License.txt mac-tmp-package/Resources/en.lproj/License.txt - $(Q) mkbom $(MAC_PAYLOAD) mac-tmp-package/$(MAC_INSTALL_PKG)/Bom - $(Q) (cd $(MAC_PAYLOAD); lsbom -p f $(abspath ./mac-tmp-package/$(MAC_INSTALL_PKG)/Bom) | cpio -o | gzip -9 -n > $(abspath ./mac-tmp-package/$(MAC_INSTALL_PKG)/Payload)) 2>/dev/null - $(Q) (cd mac-work/commercial; ls -d . ./postflight-mac | cpio -o | gzip -9 -n > ../../mac-tmp-package/$(MAC_INSTALL_PKG)/Scripts) 2>/dev/null - $(Q) ls -d ./mono-check.sh | cpio -o | gzip -9 -n > mac-tmp-package/Scripts 2>/dev/null - $(Q) $(MAC_SED_PROCESS_IN) PackageInfo.mac.in > mac-tmp-package/$(MAC_INSTALL_PKG)/PackageInfo -# xamarin.mac-uninstall-v.v.v.pkg meta package - $(Q) mkdir -p mac-work-uninstall/commercial - $(Q) $(MAC_SED_PROCESS_IN) uninstall.in > mac-work-uninstall/commercial/uninstall - $(Q) chmod a+x mac-work-uninstall/commercial/uninstall - $(Q) mkdir -p mac-work-uninstall/payload - $(Q) mkdir -p mac-tmp-package/$(MAC_UNINSTALL_PKG) - $(Q) mkbom mac-work-uninstall/payload mac-tmp-package/$(MAC_UNINSTALL_PKG)/Bom - $(Q) (cd mac-work-uninstall/payload; lsbom -p f ../../mac-tmp-package/$(MAC_UNINSTALL_PKG)/Bom | cpio -o | gzip -9 -n > ../../mac-tmp-package/$(MAC_UNINSTALL_PKG)/Payload) 2>/dev/null - $(Q) (cd mac-work-uninstall/commercial; ls -d . ./uninstall | cpio -o | gzip -9 -n > ../../mac-tmp-package/$(MAC_UNINSTALL_PKG)/Scripts) 2>/dev/null - $(Q) $(MAC_SED_PROCESS_IN) UninstallPackageInfo.mac.in > mac-tmp-package/$(MAC_UNINSTALL_PKG)/PackageInfo -# final package - $(Q) $(MAC_SED_PROCESS_IN) Distribution.mac.in > mac-tmp-package/Distribution - $(Q_GEN) (cd mac-tmp-package; xar --no-compress Scripts --no-compress $(MAC_INSTALL_PKG)/Payload --no-compress $(MAC_INSTALL_PKG)/Scripts --no-compress $(MAC_UNINSTALL_PKG)/Payload --no-compress $(MAC_UNINSTALL_PKG)/Scripts -c -f ../$(MAC_PACKAGE_FILENAME) *) - @echo Built $@ - -clean-local:: - rm -rf ios-tmp-package ios-work ios-meta-package - rm -rf mac-tmp-package mac-work mac-work-uninstall - rm -rf *.pkg - # msbuild.zip and bundle.zip are uploaded to wrench and packaged into the VS plugin msbuild.zip: rm -Rf msbuild $@ @@ -165,21 +24,12 @@ endif cp -R $(TOP)/msbuild/Xamarin.iOS.Tasks.Windows/bin/Release/netstandard2.0/win/ msbuild/iOS $(SYSTEM_MSBUILD) $(TOP)/msbuild/Xamarin.Mac.Tasks/Xamarin.Mac.Tasks.csproj -r /p:Configuration=Release cp -R $(TOP)/msbuild/Xamarin.Mac.Tasks/bin/Release/netstandard2.0/ msbuild/Mac -ifdef INCLUDE_WATCH - mv -f msbuild/iOS/*WatchOS*.* msbuild/WatchOS - mv -f msbuild/iOS/NoCode.cs msbuild/WatchOS -endif mv -f msbuild/iOS/*TVOS*.* msbuild/TVOS cd msbuild && zip -9 -r $(abspath $@) . rm -rf msbuild bundle.zip: Version Version.rev rm -f $@ -ifdef INCLUDE_XAMARIN_LEGACY - if test -d $(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/mono; then cd $(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/mono && zip -9 -r $(CURDIR)/bundle.zip .; fi - if test -d $(IOS_DESTDIR)/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono; then cd $(IOS_DESTDIR)/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono && zip -9 -r $(CURDIR)/bundle.zip .; fi -endif -ifdef ENABLE_DOTNET $(foreach platform,$(DOTNET_PLATFORMS),export $(platform)_NUGET_REF_NAME=$($(platform)_NUGET_REF_NAME);) \ for platform in $(DOTNET_PLATFORMS); do \ cd $(CURDIR); \ @@ -191,7 +41,6 @@ ifdef ENABLE_DOTNET zip -9 -r $(CURDIR)/bundle.zip ./Microsoft.$$platform.Ref/ref/; \ rm -rf tmpdir; \ done -endif zip -9 $@ Version Version.rev Version: diff --git a/tests/Makefile b/tests/Makefile index 09d0d0efb559..b242791bc3ff 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -63,7 +63,6 @@ test.config: Makefile $(TOP)/Make.config $(TOP)/mk/mono.mk $(TOP)/eng/Version.De @echo "INCLUDE_DEVICE=$(INCLUDE_DEVICE)" >> $@ @echo "XCODE_DEVELOPER_ROOT=$(XCODE_DEVELOPER_ROOT)" >> $@ @echo "MONO_IOS_SDK_DESTDIR=$(MONO_IOS_SDK_DESTDIR)" >> $@ - @echo "MONO_MAC_SDK_DESTDIR=$(MONO_MAC_SDK_DESTDIR)" >> $@ @echo "DOTNET=$(DOTNET)" >> $@ @echo "IOS_SDK_VERSION=$(IOS_SDK_VERSION)" >> $@ @echo "TVOS_SDK_VERSION=$(TVOS_SDK_VERSION)" >> $@ @@ -98,7 +97,6 @@ test-system.config: Makefile $(TOP)/Make.config $(TOP)/mk/mono.mk $(TOP)/eng/Ver @echo "JENKINS_RESULTS_DIRECTORY=$(abspath $(JENKINS_RESULTS_DIRECTORY))" >> $@ @echo "INCLUDE_DEVICE=$(INCLUDE_DEVICE)" >> $@ @echo "MONO_IOS_SDK_DESTDIR=$(MONO_IOS_SDK_DESTDIR)" >> $@ - @echo "MONO_MAC_SDK_DESTDIR=$(MONO_MAC_SDK_DESTDIR)" >> $@ @echo "DOTNET=$(DOTNET)" >> $@ @echo "IOS_SDK_VERSION=$(IOS_SDK_VERSION)" >> $@ @echo "TVOS_SDK_VERSION=$(TVOS_SDK_VERSION)" >> $@ diff --git a/tests/xharness/Harness.cs b/tests/xharness/Harness.cs index f3a472a520e1..2d6f5b1bc2d0 100644 --- a/tests/xharness/Harness.cs +++ b/tests/xharness/Harness.cs @@ -230,7 +230,6 @@ string GetVariable (string variable, string @default = null) public string MAC_DESTDIR { get; } public string IOS_DESTDIR { get; } public string MONO_IOS_SDK_DESTDIR { get; } - public string MONO_MAC_SDK_DESTDIR { get; } public bool ENABLE_DOTNET { get; } public bool INCLUDE_XAMARIN_LEGACY { get; } public string SYSTEM_MONO { get; set; } @@ -307,7 +306,6 @@ public Harness (IResultParser resultParser, HarnessAction action, HarnessConfigu MAC_DESTDIR = GetVariable (nameof (MAC_DESTDIR)); IOS_DESTDIR = GetVariable (nameof (IOS_DESTDIR)); MONO_IOS_SDK_DESTDIR = GetVariable (nameof (MONO_IOS_SDK_DESTDIR)); - MONO_MAC_SDK_DESTDIR = GetVariable (nameof (MONO_MAC_SDK_DESTDIR)); ENABLE_DOTNET = IsVariableSet (nameof (ENABLE_DOTNET)); SYSTEM_MONO = GetVariable (nameof (SYSTEM_MONO)); DOTNET_DIR = GetVariable (nameof (DOTNET_DIR)); diff --git a/tests/xharness/IHarness.cs b/tests/xharness/IHarness.cs index 6a30ba5cbbd3..4c2ba87a8faf 100644 --- a/tests/xharness/IHarness.cs +++ b/tests/xharness/IHarness.cs @@ -41,7 +41,6 @@ public interface IHarness { string MAC_DESTDIR { get; } string IOS_DESTDIR { get; } string MONO_IOS_SDK_DESTDIR { get; } - string MONO_MAC_SDK_DESTDIR { get; } bool ENABLE_DOTNET { get; } bool INCLUDE_XAMARIN_LEGACY { get; } string SYSTEM_MONO { get; set; } diff --git a/tools/devops/automation/templates/build/build.yml b/tools/devops/automation/templates/build/build.yml index a3d0648dae20..7838afd4894c 100644 --- a/tools/devops/automation/templates/build/build.yml +++ b/tools/devops/automation/templates/build/build.yml @@ -181,18 +181,6 @@ steps: key: "$(MONO_IOS_FILENAME)" path: "$(Build.SourcesDirectory)/xamarin-macios/builds/downloads/$(MONO_IOS_FILENAME)" - - task: Cache@2 - displayName: 'Cache macOS Mono download' - inputs: - key: "$(MONO_MAC_FILENAME)" - path: "$(Build.SourcesDirectory)/xamarin-macios/builds/downloads/$(MONO_MAC_FILENAME)" - - - task: Cache@2 - displayName: 'Cache MacCatalsyt Mono download' - inputs: - key: "$(MONO_MACCATALYST_FILENAME)" - path: "$(Build.SourcesDirectory)/xamarin-macios/builds/downloads/$(MONO_MACCATALYST_FILENAME)" - # Actual build of the project - bash: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/bash/build-macios.sh name: build From 16a6284e589d748b051188283a40bd38d5c24886 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 20 Sep 2024 17:44:57 +0200 Subject: [PATCH 04/23] [devops] Append to the agent log, instead of creating the file. (#21281) Append to the agent log, instead of creating the file, when an exception occcurs. The problem is that creating the file fails if it already exists: Exception occurred: Exception calling "Parse" with "1" argument(s): "String '' was not recognized as a valid DateTime." New-Item: /Users/builder/azdo/_work/4/s/xamarin-macios/tools/devops/automation/scripts/generate_agent_logs.ps1:52 Line | 52 | New-Item -Path $Output -Value "$_" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | The file '/Users/builder/azdo/_work/4/s/agent-logs.log' already exists. --- tools/devops/automation/scripts/generate_agent_logs.ps1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/devops/automation/scripts/generate_agent_logs.ps1 b/tools/devops/automation/scripts/generate_agent_logs.ps1 index 089a65511e1a..3294e9138cc5 100644 --- a/tools/devops/automation/scripts/generate_agent_logs.ps1 +++ b/tools/devops/automation/scripts/generate_agent_logs.ps1 @@ -46,8 +46,7 @@ try { log show --predicate $Predicate --style $Style --start "$start" --end "$end" > $Output } } catch { - Write-Host "Exception occurred: $_" # Create the output file, because we later try to upload it as an artifact, and *not* uploading # if there's *no* file is much harder than just creating the file. - New-Item -Path $Output -Value "$_" + Write-Host "Exception occurred: $_" | Tee-Object -FilePath $Output -Append } From f57d91580efdf9954b2cd16aa230f0750da43941 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 23 Sep 2024 11:47:32 +0200 Subject: [PATCH 05/23] [msbuild] Fix: `Assembly.GetManifestResourceNames()` may return an empty string (#21280) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids the `UnpackLibraryResources` to fail. ``` /usr/local/share/dotnet/packs/Microsoft.iOS.Sdk.net8.0_17.5/17.5.8020/tools/msbuild/iOS/Xamarin.Shared.targets(1985,3): error MSB4018: System.ArgumentException: Value does not fall within the expected range. (Parameter 'resourceName') /usr/local/share/dotnet/packs/Microsoft.iOS.Sdk.net8.0_17.5/17.5.8020/tools/msbuild/iOS/Xamarin.Shared.targets(1985,3): error MSB4018: at System.Reflection.TypeLoading.Ecma.EcmaAssembly.GetManifestResourceInfo(String resourceName) /usr/local/share/dotnet/packs/Microsoft.iOS.Sdk.net8.0_17.5/17.5.8020/tools/msbuild/iOS/Xamarin.Shared.targets(1985,3): error MSB4018: at Xamarin.MacDev.Tasks.UnpackLibraryResources.GetAssemblyManifestResources(String fileName)+MoveNext() in /Users/builder/azdo/_work/1/s/xamarin-macios/msbuild/Xamarin.MacDev.Tasks/Tasks/UnpackLibraryResources.cs:line 254 ``` This was initially submitted by @jeromelaban in #21277. --------- Co-authored-by: Jérôme Laban --- msbuild/Xamarin.MacDev.Tasks/Tasks/UnpackLibraryResources.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/UnpackLibraryResources.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/UnpackLibraryResources.cs index a82dff8a8e43..52c9b5357cd7 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/UnpackLibraryResources.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/UnpackLibraryResources.cs @@ -251,6 +251,8 @@ IEnumerable GetAssemblyManifestResources (string fileName) } foreach (var resourceName in assembly.GetManifestResourceNames ()) { + if (string.IsNullOrEmpty (resourceName)) + continue; var info = assembly.GetManifestResourceInfo (resourceName); if (!info.ResourceLocation.HasFlag (ResourceLocation.Embedded)) continue; From ed6c16e3cd57c709b7ae921e9424b98eb5a4bdb8 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 23 Sep 2024 18:41:13 +0200 Subject: [PATCH 06/23] [UIKit] UIFontPickerViewControllerConfiguration.FilteredTraits isn't deprecated. (#21270) So remove the corresponding deprecation attributes. --- src/uikit.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/uikit.cs b/src/uikit.cs index 3999bb0d6b01..c3559a3f2381 100644 --- a/src/uikit.cs +++ b/src/uikit.cs @@ -24502,8 +24502,6 @@ interface UIFontPickerViewControllerConfiguration : NSCopying { [Export ("displayUsingSystemFont")] bool DisplayUsingSystemFont { get; set; } - [Deprecated (PlatformName.iOS, 18, 0, message: "Use the 'LanguageFilter' property instead.")] - [Deprecated (PlatformName.MacCatalyst, 18, 0, message: "Use the 'LanguageFilter' property instead.")] [Export ("filteredTraits", ArgumentSemantic.Assign)] UIFontDescriptorSymbolicTraits FilteredTraits { get; set; } From 9d9cfd2016d10b5ff1c5a2ca4a0efe6ff330f738 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 08:02:26 +0200 Subject: [PATCH 07/23] [main] Update dependencies from dotnet/xharness (#21286) This pull request updates the following dependencies ## From https://github.com/dotnet/xharness - **Subscription**: 601bc5e1-1cae-44b5-cf5f-08db9342aa2f - **Build**: 20240917.4 - **Date Produced**: September 17, 2024 9:28:26 AM UTC - **Commit**: 3cfb1a3d86da666fb80ba0adb970525e88339d57 - **Branch**: refs/heads/main - **Updates**: - **Microsoft.DotNet.XHarness.iOS.Shared**: [from 10.0.0-prerelease.24466.1 to 10.0.0-prerelease.24467.4][1] [1]: https://github.com/dotnet/xharness/compare/f20e52f773...3cfb1a3d86 --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a2ab74bbc735..55990589f698 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -82,9 +82,9 @@ https://github.com/dotnet/templating - + https://github.com/dotnet/xharness - f20e52f7731da99588dd6b4f4bd60119f03220a3 + 3cfb1a3d86da666fb80ba0adb970525e88339d57 diff --git a/eng/Versions.props b/eng/Versions.props index 0c9a6baf0b30..2424d9aaf1a5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -12,7 +12,7 @@ 8.0.0-rtm.23511.3 8.0.0 7.0.100-alpha.1.21601.1 - 10.0.0-prerelease.24466.1 + 10.0.0-prerelease.24467.4 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) From de1f7e91dd29c0325facd20d85315cb78804913f Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 24 Sep 2024 17:26:55 +0200 Subject: [PATCH 08/23] [tests] Add missing platform ignore in bgen tests. (#21282) --- tests/generator/BGenTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index 8d4a2987fb98..70f3feefdc37 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -408,6 +408,7 @@ public void Bug35176 () [TestCase (Profile.iOS)] public void INativeObjectsInBlocks (Profile profile) { + Configuration.IgnoreIfIgnoredPlatform (profile.AsPlatform ()); var bgen = new BGenTool (); bgen.Profile = profile; bgen.Defines = BGenTool.GetDefaultDefines (bgen.Profile); From 6af5fdf4d93c1a20e5009d3e565db090430afe34 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 24 Sep 2024 17:28:38 +0200 Subject: [PATCH 09/23] [devops] Improve environment dumping. (#21271) * Dump once, but correctly sorted, taking values with newlines into account. * Dump the bot's IP address as well. --- tools/devops/automation/templates/tests/stage.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/devops/automation/templates/tests/stage.yml b/tools/devops/automation/templates/tests/stage.yml index 7b5649db6792..89f4d67de919 100644 --- a/tools/devops/automation/templates/tests/stage.yml +++ b/tools/devops/automation/templates/tests/stage.yml @@ -119,8 +119,9 @@ stages: steps: - bash: | - env | sort - env + set +x + env -0 | sort -z | tr '\0' '\n' + ifconfig | grep 'inet ' displayName: 'Dump env' name: DumpEnv - template: build.yml From eabf3ab3717cad6c37861d532747dd82052da3c6 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 24 Sep 2024 23:44:02 +0200 Subject: [PATCH 10/23] [Foundation] NSUrlSessionHandler: Adds support for X509 client certificates (#21284) Addresses #13856 This was originally created by @dotMorten in #20434. Also make SecIdentity.Import use an in-memory keychain on macOS 15+, so that SecIdentity.Import works like all othe other platforms (i.e. not requiring access to the default keychain, which, among other things, is not ideal on bots). --------- Co-authored-by: Morten Nielsen Co-authored-by: dotMorten Co-authored-by: Manuel de la Pena --- src/Foundation/NSUrlSessionHandler.cs | 104 ++++++++++++++++-- src/Security/Certificate.cs | 83 +++++++++++++- .../Documentation.KnownFailures.txt | 1 - .../System.Net.Http/MessageHandlers.cs | 35 ++++++ .../System.Net.Http/NetworkResources.cs | 1 + 5 files changed, 213 insertions(+), 11 deletions(-) diff --git a/src/Foundation/NSUrlSessionHandler.cs b/src/Foundation/NSUrlSessionHandler.cs index a2029e14a34d..fb76ba63ef4e 100644 --- a/src/Foundation/NSUrlSessionHandler.cs +++ b/src/Foundation/NSUrlSessionHandler.cs @@ -567,15 +567,20 @@ public DecompressionMethods AutomaticDecompression { [EditorBrowsable (EditorBrowsableState.Never)] public bool CheckCertificateRevocationList { get; set; } = false; - // We're ignoring this property, just like Xamarin.Android does: - // https://github.com/xamarin/xamarin-android/blob/09e8cb5c07ea6c39383185a3f90e53186749b802/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs#L150 - // Note: we can't return null (like Xamarin.Android does), because the return type isn't nullable. - [UnsupportedOSPlatform ("ios")] - [UnsupportedOSPlatform ("maccatalyst")] - [UnsupportedOSPlatform ("tvos")] - [UnsupportedOSPlatform ("macos")] - [EditorBrowsable (EditorBrowsableState.Never)] - public X509CertificateCollection ClientCertificates { get { return new X509CertificateCollection (); } } + + X509CertificateCollection? _clientCertificates; + + /// Gets the collection of security certificates that are associated with requests to the server. + /// Client certificates are only supported when ClientCertificateOptions is set to ClientCertificateOptions.Manual. + public X509CertificateCollection ClientCertificates { + get { + if (ClientCertificateOptions != ClientCertificateOption.Manual) { + throw new InvalidOperationException ($"Enable manual options first on {nameof (ClientCertificateOptions)}"); + } + + return _clientCertificates ?? (_clientCertificates = new X509CertificateCollection ()); + } + } // We're ignoring this property, just like Xamarin.Android does: // https://github.com/xamarin/xamarin-android/blob/09e8cb5c07ea6c39383185a3f90e53186749b802/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs#L148 @@ -1088,6 +1093,19 @@ void DidReceiveChallengeImpl (NSUrlSession session, NSUrlSessionTask task, NSUrl } return; } +#if NET + if (sessionHandler.ClientCertificateOptions == ClientCertificateOption.Manual && challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodClientCertificate) { + var certificate = CertificateHelper.GetEligibleClientCertificate (sessionHandler.ClientCertificates); + if (certificate is not null) { + var cert = new SecCertificate (certificate); + var identity = SecIdentity.Import (certificate); + var credential = new NSUrlCredential (identity, new SecCertificate [] { cert }, NSUrlCredentialPersistence.ForSession); + completionHandler (NSUrlSessionAuthChallengeDisposition.UseCredential, credential); + return; + } + } +#endif + // case for the basic auth failing up front. As per apple documentation: // The URL Loading System is designed to handle various aspects of the HTTP protocol for you. As a result, you should not modify the following headers using // the addValue(_:forHTTPHeaderField:) or setValue(_:forHTTPHeaderField:) methods: @@ -1592,5 +1610,73 @@ protected override void Dispose (bool disposing) stream?.Dispose (); } } + +#if NET + static class CertificateHelper { + // Based on https://github.com/dotnet/runtime/blob/c2848c582f5d6ae42c89f5bfe0818687ab3345f0/src/libraries/Common/src/System/Net/Security/CertificateHelper.cs + // with the NetEventSource code removed and namespace changed. + const string ClientAuthenticationOID = "1.3.6.1.5.5.7.3.2"; + + internal static X509Certificate2? GetEligibleClientCertificate (X509CertificateCollection? candidateCerts) + { + if (candidateCerts is null || candidateCerts.Count == 0) { + return null; + } + + var certs = new X509Certificate2Collection (); + certs.AddRange (candidateCerts); + + return GetEligibleClientCertificate (certs); + } + + internal static X509Certificate2? GetEligibleClientCertificate (X509Certificate2Collection? candidateCerts) + { + if (candidateCerts is null || candidateCerts.Count == 0) { + return null; + } + + foreach (X509Certificate2 cert in candidateCerts) { + if (!cert.HasPrivateKey) { + continue; + } + + if (IsValidClientCertificate (cert)) { + return cert; + } + } + return null; + } + + static bool IsValidClientCertificate (X509Certificate2 cert) + { + foreach (X509Extension extension in cert.Extensions) { + if ((extension is X509EnhancedKeyUsageExtension eku) && !IsValidForClientAuthenticationEKU (eku)) { + return false; + } else if ((extension is X509KeyUsageExtension ku) && !IsValidForDigitalSignatureUsage (ku)) { + return false; + } + } + + return true; + } + + static bool IsValidForClientAuthenticationEKU (X509EnhancedKeyUsageExtension eku) + { + foreach (System.Security.Cryptography.Oid oid in eku.EnhancedKeyUsages) { + if (oid.Value == ClientAuthenticationOID) { + return true; + } + } + + return false; + } + + static bool IsValidForDigitalSignatureUsage (X509KeyUsageExtension ku) + { + const X509KeyUsageFlags RequiredUsages = X509KeyUsageFlags.DigitalSignature; + return (ku.KeyUsages & RequiredUsages) == RequiredUsages; + } + } +#endif } } diff --git a/src/Security/Certificate.cs b/src/Security/Certificate.cs index deb4053f1c89..796f67ce5709 100644 --- a/src/Security/Certificate.cs +++ b/src/Security/Certificate.cs @@ -583,6 +583,13 @@ public SecCertificate Certificate { } } + /// Create a from PKCS #12 data. + /// The PKCS #12 blob data as a byte array. + /// The password for the private key in the PKCS #12 data. An empty password is not supported. + /// + /// On macOS 14 or earlier this method requires access to the default keychain,where the private key + certificate will be stored. + /// On macOS 15 or later, as well as all other platforms (iOS, tvOS, Mac Catalyst), calling this method will not affect any keychains (a temporary, in-memory keychain is created for the duration of the import). + /// public static SecIdentity Import (byte [] data, string password) { if (data is null) @@ -590,8 +597,82 @@ public static SecIdentity Import (byte [] data, string password) if (string.IsNullOrEmpty (password)) // SecPKCS12Import() doesn't allow empty passwords. throw new ArgumentException (nameof (password)); using (var pwstring = new NSString (password)) - using (var options = NSDictionary.FromObjectAndKey (pwstring, SecImportExport.Passphrase)) { + using (var options = NSMutableDictionary.FromObjectAndKey (pwstring, SecImportExport.Passphrase)) { NSDictionary [] array; +#if __MACOS__ + /* There are unfortunate platform differences for SecPKCS12Import: + * + * `SecPKCS12Import` will, _on macOS only, not other platforms_, add the imported certificate + private key into the default keychain. + * + * Apple's documentation for [`SecPKCS12Import`](https://developer.apple.com/documentation/security/1396915-secpkcs12import?language=objc) + * implies importing into the keychain is optional ("[...] You can then use the Keychain Services API + * (see [Keychain services](https://developer.apple.com/documentation/security/keychain_services?language=objc)) + * to put the identities and associated certificates in the keychain."), but that doesn't match the behavior we're seeing, + * either on the bots nor locally (if I lock the keychain before running the unit test on macOS, I get a dialog asking for + * my password to unlock the keychain when this method is called). Other people on StackOverflow has run into the same issue + * (https://stackoverflow.com/q/33181127), where one of the answers points to the source code (https://stackoverflow.com/a/66846609), + * confirming this behavior. + * + * StackOverflow also suggests using [`SecItemImport`](https://developer.apple.com/documentation/security/1395728-secitemimport) + * instead, which works, with a few caveats: + * + * 1. Importing a PKCS#12 blob only returns the certificate, not the private key. This is a bug, as [confirmed](https://forums.developer.apple.com/forums/thread/31711) by Quinn "The Eskimo!": + * + * > `SecItemImport` really does support importing private keys without putting them in the keychain, + * > and that code all runs and works in the PKCS#12 case; internally I see both the certificate and + * > the private key extracted from the PKCS#12. The problem arises when the code tries to match up + * > the certificate and private key to form an identity. That code is failing in the no-keychain case, + * > so you end up getting back just the certificate. Notably, in the PEM case no matching occurs and + * > thus you get back both the certificate and the private key. + * > + * > This is clearly a bug and I’ve filed it as such (r. 25,140,029). + * + * That was 8 years ago, and 6 years later it still hasn't been fixed (as confirmed by Quinn in the same thread), so it's unlikely it'll ever be fixed. + * + * 2. So I tried exporting the X509Certificate into a PEM string instead, and that works, I successfully + * get back a `SecKey` instance and a `SecCertificate` instance! Success? + * + * 3. Nope, because there's no way to create a `SecIdentity` from `SecKey`+`SecCertificate`. You have to put + * the `SecKey` into a keychain, and then pass the `SecCertificate` to [`SecIdentityCreateWithCertificate`](https://developer.apple.com/documentation/security/1401160-secidentitycreatewithcertificate?language=objc), + * and we're back to where we started. + * + * 4. OK, what about creating a temporary `SecKeychain`, add the `SecKey` there, create the `SecIdentity`, then delete the `SecKeychain`? + * + * * [`SecKeyChain`](https://developer.apple.com/documentation/security/1401214-seckeychaincreate) was deprecated in macOS 10.10 :/ + * * curl had the same problem: + * * https://github.com/curl/curl/issues/10038 + * * https://github.com/curl/curl/issues/5403) + * + * There was PR to use a temporary keychain (https://github.com/curl/curl/pull/10059), with a number of good reasons why it was a bad idea, so it was eventually rejected: + * + * * The temporary keychain is stored on disk, which isn't particularly fast. + * * The ownership/rights of the file must be considered to ensure there are no security issues. + * * Concurrency would have to be considered with regards to cleanup - what if there are multiple threads trying to use the same location on disk. + * + * + * In [this Apple forum thread](https://forums.developer.apple.com/forums/thread/31711) a user gripes about this exact problem: + * + * > I've resorted to using a private API to created a SecIdentity from a SecCertificate and a SecKey that I already have in memory. + * + * Quinn answers: + * + * > On the macOS front, there’s nothing stopping a command-line tool running on a CI machine using the keychain. + * There are some pain points but no showstoppers. + * + * FWIW Quinn “The Eskimo!” wrote a document explaining how to find and fix problems with regards to the keychain on CI machines + * (https://developer.apple.com/forums/thread/712005). The last sentence is a gem: "Resetting trust settings is more of a challenge. + * It’s probably possible to do this with the security tool but, honestly, if you think that your CI system has messed up trust settings + * it’s easiest to throw it away and start again from scratch." - in other words if something goes wrong, the easiest is to wipe the + * machine and start over again. + * + * "some pain points" is somewhat of an understatement... + * + * The good news is that on macOS 15+, Apple added an option to use a temporary, in-memory only keychain, avoiding the whole problem, + * so let's use that! + */ + if (OperatingSystem.IsMacOSVersionAtLeast (15, 0)) + options.Add (SecImportExport.ToMemoryOnly, NSNumber.FromBoolean (true)); +#endif SecStatusCode result = SecImportExport.ImportPkcs12 (data, options, out array); if (result != SecStatusCode.Success) throw new InvalidOperationException (result.ToString ()); diff --git a/tests/cecil-tests/Documentation.KnownFailures.txt b/tests/cecil-tests/Documentation.KnownFailures.txt index 9ad4d29db89a..56aca8bf163d 100644 --- a/tests/cecil-tests/Documentation.KnownFailures.txt +++ b/tests/cecil-tests/Documentation.KnownFailures.txt @@ -47220,7 +47220,6 @@ M:Security.SecCertificate.ToX509Certificate M:Security.SecCertificate.ToX509Certificate2 M:Security.SecCertificate2.#ctor(Security.SecCertificate) M:Security.SecIdentity.GetTypeID -M:Security.SecIdentity.Import(System.Byte[],System.String) M:Security.SecIdentity.Import(System.Security.Cryptography.X509Certificates.X509Certificate2) M:Security.SecIdentity2.#ctor(Security.SecIdentity,Security.SecCertificate[]) M:Security.SecIdentity2.#ctor(Security.SecIdentity) diff --git a/tests/monotouch-test/System.Net.Http/MessageHandlers.cs b/tests/monotouch-test/System.Net.Http/MessageHandlers.cs index d08d7185c80e..4e23e7e149fe 100644 --- a/tests/monotouch-test/System.Net.Http/MessageHandlers.cs +++ b/tests/monotouch-test/System.Net.Http/MessageHandlers.cs @@ -664,6 +664,41 @@ public void RejectSslCertificatesWithCustomValidationCallbackNSUrlSessionHandler Assert.IsNull (ex2, "Callback asserts"); } } + + [Test] + public void TestNSUrlSessionHandlerSendClientCertificate () + { + string certificate_base64 = "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"; + // make the cert exportable so that the tests pass: ref: https://github.com/dotnet/runtime/issues/21581 + +#if __MACOS__ + // The test requires access to the default system keychain on macOS 14 or earlier, which is really + // annoying on bots (a password dialog will pop up, blocking the tests). So just not run this test + // on anything earlier than macOS 15.0, + TestRuntime.AssertXcodeVersion (16, 0); + var storageFlags = X509KeyStorageFlags.Exportable; +#else + var storageFlags = X509KeyStorageFlags.DefaultKeySet; +#endif + + X509Certificate2 certificate = new X509Certificate2 (global::System.Convert.FromBase64String (certificate_base64), "test", storageFlags); + string content = ""; + var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => { + using var handler = new NSUrlSessionHandler (); + handler.ClientCertificates.Add (certificate); + using var client = new HttpClient (handler); + var response = await client.GetAsync (NetworkResources.EchoClientCertificateUrl); + content = await response.EnsureSuccessStatusCode ().Content.ReadAsStringAsync (); + }, out var ex); + if (!done) { // timeouts happen in the bots due to dns issues, connection issues etc.. we do not want to fail + Assert.Inconclusive ("Request timedout."); + } else { + Assert.IsNull (ex, "Exception wasn't expected."); + X509Certificate2 certificate2 = new X509Certificate2 (global::System.Convert.FromBase64String (content)); + Assert.AreEqual (certificate.Thumbprint, certificate2.Thumbprint); + } + } + #endif [Test] diff --git a/tests/monotouch-test/System.Net.Http/NetworkResources.cs b/tests/monotouch-test/System.Net.Http/NetworkResources.cs index b4a53e376182..e0483022c32f 100644 --- a/tests/monotouch-test/System.Net.Http/NetworkResources.cs +++ b/tests/monotouch-test/System.Net.Http/NetworkResources.cs @@ -19,6 +19,7 @@ public static class NetworkResources { public static string XamarinHttpUrl => AssertNetworkConnection ("http://dotnet.microsoft.com/apps/xamarin"); public static Uri XamarinUri => new Uri (XamarinUrl); public static string StatsUrl => AssertNetworkConnection ("https://api.imgur.com/2/stats"); + public static string EchoClientCertificateUrl = "https://corefx-net-tls.azurewebsites.net/EchoClientCertificate.ashx"; public static string [] HttpsUrls => new [] { MicrosoftUrl, From 458ca8bc01802ac839f6886e573bfbd427e321d5 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 25 Sep 2024 13:34:07 +0200 Subject: [PATCH 11/23] [monotouch-test] Update usage of X509 API obsoleted in .NET 9. --- tests/monotouch-test/System.Net.Http/MessageHandlers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/monotouch-test/System.Net.Http/MessageHandlers.cs b/tests/monotouch-test/System.Net.Http/MessageHandlers.cs index 0d78093f02c8..db4134ece428 100644 --- a/tests/monotouch-test/System.Net.Http/MessageHandlers.cs +++ b/tests/monotouch-test/System.Net.Http/MessageHandlers.cs @@ -690,7 +690,7 @@ public void TestNSUrlSessionHandlerSendClientCertificate () var storageFlags = X509KeyStorageFlags.DefaultKeySet; #endif - X509Certificate2 certificate = new X509Certificate2 (global::System.Convert.FromBase64String (certificate_base64), "test", storageFlags); + X509Certificate2 certificate = X509CertificateLoader.LoadPkcs12 (global::System.Convert.FromBase64String (certificate_base64), "test", storageFlags); string content = ""; var done = TestRuntime.TryRunAsync (TimeSpan.FromSeconds (30), async () => { using var handler = new NSUrlSessionHandler (); @@ -703,7 +703,7 @@ public void TestNSUrlSessionHandlerSendClientCertificate () Assert.Inconclusive ("Request timedout."); } else { Assert.IsNull (ex, "Exception wasn't expected."); - X509Certificate2 certificate2 = new X509Certificate2 (global::System.Convert.FromBase64String (content)); + X509Certificate2 certificate2 = X509CertificateLoader.LoadPkcs12 (global::System.Convert.FromBase64String (content), null); Assert.AreEqual (certificate.Thumbprint, certificate2.Thumbprint); } } From c925668f68d3dac2213a06f1a31e29f052331587 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Wed, 25 Sep 2024 11:40:20 -0400 Subject: [PATCH 12/23] Revert "Revert "[CI] Split the sim tests and the macOS tests. (#21215)"" (#21301) Reverts xamarin/xamarin-macios#21247 This is a revert of a revert that was not needed. --- .../run-post-ci-build-macos-tests.yml | 20 +++ .../automation/run-post-ci-build-tests.yml | 1 - .../run-post-pr-build-macos-tests.yml | 19 +++ .../automation/run-post-pr-build-tests.yml | 1 - .../pipelines/run-macos-tests-pipeline.yml | 130 ++++++++++++++++++ .../pipelines/run-tests-pipeline.yml | 64 --------- .../automation/templates/tests-stage.yml | 23 ---- 7 files changed, 169 insertions(+), 89 deletions(-) create mode 100644 tools/devops/automation/run-post-ci-build-macos-tests.yml create mode 100644 tools/devops/automation/run-post-pr-build-macos-tests.yml create mode 100644 tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml diff --git a/tools/devops/automation/run-post-ci-build-macos-tests.yml b/tools/devops/automation/run-post-ci-build-macos-tests.yml new file mode 100644 index 000000000000..bbdb367de5d7 --- /dev/null +++ b/tools/devops/automation/run-post-ci-build-macos-tests.yml @@ -0,0 +1,20 @@ +# YAML pipeline for post build operations. +# This pipeline will execute the tests for the CI as soon as the workloads have been complited. + +trigger: none +pr: none + + +# we cannot use a template in a pipeline context +resources: + pipelines: + - pipeline: macios + source: xamarin-macios-ci + trigger: + stages: + - build_macos_tests + +extends: + template: templates/pipelines/run-macos-tests-pipeline.yml + parameters: + isPR: false diff --git a/tools/devops/automation/run-post-ci-build-tests.yml b/tools/devops/automation/run-post-ci-build-tests.yml index a8a20442aa95..5ffbfa0917f6 100644 --- a/tools/devops/automation/run-post-ci-build-tests.yml +++ b/tools/devops/automation/run-post-ci-build-tests.yml @@ -13,7 +13,6 @@ resources: trigger: stages: - build_packages - - build_macos_tests extends: template: templates/pipelines/run-tests-pipeline.yml diff --git a/tools/devops/automation/run-post-pr-build-macos-tests.yml b/tools/devops/automation/run-post-pr-build-macos-tests.yml new file mode 100644 index 000000000000..e324fe5d8b3e --- /dev/null +++ b/tools/devops/automation/run-post-pr-build-macos-tests.yml @@ -0,0 +1,19 @@ +# YAML pipeline for post build operations. +# This pipeline will execute the tests for the CI on PR as soon as the workloads have been complited. + +trigger: none +pr: none + +# we cannot use a template in a pipeline context +resources: + pipelines: + - pipeline: macios + source: xamarin-macios-pr + trigger: + stages: + - build_macos_tests + +extends: + template: templates/pipelines/run-macos-tests-pipeline.yml + parameters: + isPR: true diff --git a/tools/devops/automation/run-post-pr-build-tests.yml b/tools/devops/automation/run-post-pr-build-tests.yml index 84d8d1e58e72..45a676699994 100644 --- a/tools/devops/automation/run-post-pr-build-tests.yml +++ b/tools/devops/automation/run-post-pr-build-tests.yml @@ -12,7 +12,6 @@ resources: trigger: stages: - build_packages - - build_macos_tests extends: template: templates/pipelines/run-tests-pipeline.yml diff --git a/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml b/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml new file mode 100644 index 000000000000..e4f4672fb821 --- /dev/null +++ b/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml @@ -0,0 +1,130 @@ +# template to be extended by those pipelines that will run tests after a build. +parameters: + + - name: isPR + displayName: State if the tests are ran for a PR build + type: boolean + default: false + + - name: repositoryAlias + type: string + default: self + + - name: commit + type: string + default: HEAD + + - name: stageDisplayNamePrefix + type: string + default: '' + + - name: macTestsConfigurations + displayName: macOS test configurations to run + type: object + default: [ + { + stageName: 'mac_11_m1', + displayName: 'M1 - Mac Big Sur (11)', + macPool: 'VSEng-VSMac-Xamarin-Shared', + useImage: false, + statusContext: 'M1 - Mac Big Sur (11)', + demands: [ + "Agent.OS -equals Darwin", + "macOS.Name -equals BigSur", + "macOS.Architecture -equals arm64", + "Agent.HasDevices -equals False", + "Agent.IsPaired -equals False" + ] + }, + { + stageName: 'mac_12_m1', + displayName: 'M1 - Mac Ventura (12)', + macPool: 'VSEng-VSMac-Xamarin-Shared', + useImage: false, + statusContext: 'M1 - Mac Monterey (12)', + demands: [ + "Agent.OS -equals Darwin", + "macOS.Name -equals Monterey", + "macOS.Architecture -equals arm64", + "Agent.HasDevices -equals False", + "Agent.IsPaired -equals False" + ] + }, + { + stageName: 'mac_13_m1', + displayName: 'M1 - Mac Ventura (13)', + macPool: 'VSEng-VSMac-Xamarin-Shared', + useImage: false, + statusContext: 'M1 - Mac Ventura (13)', + demands: [ + "Agent.OS -equals Darwin", + "macOS.Name -equals Ventura", + "macOS.Architecture -equals arm64", + "Agent.HasDevices -equals False", + "Agent.IsPaired -equals False" + ] + }, + { + stageName: 'mac_14_x64', + displayName: 'X64 - Mac Sonoma (14)', + macPool: 'VSEng-Xamarin-RedmondMacBuildPool-iOS-Untrusted', + useImage: false, + statusContext: 'X64 - Mac Sonoma (14)', + demands: [ + "Agent.OS -equals Darwin", + "macOS.Name -equals Sonoma", + "macOS.Architecture -equals x64", + "Agent.HasDevices -equals False", + "Agent.IsPaired -equals False" + ] + }] + + +resources: + repositories: + - repository: self + checkoutOptions: + submodules: true + + - repository: yaml-templates + type: github + name: xamarin/yaml-templates + ref: refs/heads/main + endpoint: xamarin + + - repository: maccore + type: github + name: xamarin/maccore + ref: refs/heads/main + endpoint: xamarin + + - repository: release-scripts + type: github + name: xamarin/release-scripts + ref: refs/heads/only_codesign + endpoint: xamarin + +variables: + - ${{ if contains(variables['Build.DefinitionName'], 'private') }}: + - template: ../vsts-variables.yml + - template: ../variables.yml + - name: MaciosUploadPrefix + value: '' + - name: DisablePipelineConfigDetector + value: true + +stages: + - ${{ each config in parameters.macTestsConfigurations }}: + - template: ../mac/stage.yml + parameters: + isPR: ${{ parameters.isPR }} + repositoryAlias: ${{ parameters.repositoryAlias }} + commit: ${{ parameters.commit }} + stageName: ${{ config.stageName }} + displayName: ' ${{ parameters.stageDisplayNamePrefix }}${{ config.displayName }}' + macPool: ${{ config.macPool }} + useImage: ${{ config.useImage }} + statusContext: ${{ config.statusContext }} + keyringPass: $(pass--lab--mac--builder--keychain) + demands: ${{ config.demands }} + postPipeline: true diff --git a/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml b/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml index a1b127a464f5..bfa780b0c41e 100644 --- a/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml +++ b/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml @@ -84,68 +84,6 @@ parameters: ] }] - - name: macTestsConfigurations - displayName: macOS test configurations to run - type: object - default: [ - { - stageName: 'mac_11_m1', - displayName: 'M1 - Mac Big Sur (11)', - macPool: 'VSEng-VSMac-Xamarin-Shared', - useImage: false, - statusContext: 'M1 - Mac Big Sur (11)', - demands: [ - "Agent.OS -equals Darwin", - "macOS.Name -equals BigSur", - "macOS.Architecture -equals arm64", - "Agent.HasDevices -equals False", - "Agent.IsPaired -equals False" - ] - }, - { - stageName: 'mac_12_m1', - displayName: 'M1 - Mac Ventura (12)', - macPool: 'VSEng-VSMac-Xamarin-Shared', - useImage: false, - statusContext: 'M1 - Mac Monterey (12)', - demands: [ - "Agent.OS -equals Darwin", - "macOS.Name -equals Monterey", - "macOS.Architecture -equals arm64", - "Agent.HasDevices -equals False", - "Agent.IsPaired -equals False" - ] - }, - { - stageName: 'mac_13_m1', - displayName: 'M1 - Mac Ventura (13)', - macPool: 'VSEng-VSMac-Xamarin-Shared', - useImage: false, - statusContext: 'M1 - Mac Ventura (13)', - demands: [ - "Agent.OS -equals Darwin", - "macOS.Name -equals Ventura", - "macOS.Architecture -equals arm64", - "Agent.HasDevices -equals False", - "Agent.IsPaired -equals False" - ] - }, - { - stageName: 'mac_14_x64', - displayName: 'X64 - Mac Sonoma (14)', - macPool: 'VSEng-Xamarin-RedmondMacBuildPool-iOS-Untrusted', - useImage: false, - statusContext: 'X64 - Mac Sonoma (14)', - demands: [ - "Agent.OS -equals Darwin", - "macOS.Name -equals Sonoma", - "macOS.Architecture -equals x64", - "Agent.HasDevices -equals False", - "Agent.IsPaired -equals False" - ] - }] - - resources: repositories: - repository: self @@ -189,11 +127,9 @@ stages: pool: ${{ parameters.pool }} runTests: ${{ parameters.runTests }} runDeviceTests: ${{ parameters.runDeviceTests }} - runOldMacOSTests: ${{ parameters.runOldMacOSTests }} runWindowsIntegration: ${{ parameters.runWindowsIntegration }} runSamples: ${{ parameters.runSamples }} ${{ if ne(length(parameters.testConfigurations), 0)}}: testConfigurations: ${{ parameters.testConfigurations }} deviceTestsConfigurations: ${{ parameters.deviceTestsConfigurations }} - macTestsConfigurations: ${{ parameters.macTestsConfigurations }} diff --git a/tools/devops/automation/templates/tests-stage.yml b/tools/devops/automation/templates/tests-stage.yml index 7d69332b8591..94d8f1c2dfc3 100644 --- a/tools/devops/automation/templates/tests-stage.yml +++ b/tools/devops/automation/templates/tests-stage.yml @@ -20,10 +20,6 @@ parameters: type: boolean default: false -- name: runOldMacOSTests - type: boolean - default: true - - name: runWindowsIntegration type: boolean default: true @@ -157,9 +153,6 @@ parameters: - name: deviceTestsConfigurations type: object -- name: macTestsConfigurations - type: object - - name: stageDisplayNamePrefix type: string default: '' @@ -265,22 +258,6 @@ stages: commit: ${{ parameters.commit }} postPipeline: true -- ${{ if eq(parameters.runOldMacOSTests, true) }}: - - ${{ each config in parameters.macTestsConfigurations }}: - - template: ./mac/stage.yml - parameters: - isPR: ${{ parameters.isPR }} - repositoryAlias: ${{ parameters.repositoryAlias }} - commit: ${{ parameters.commit }} - stageName: ${{ config.stageName }} - displayName: ' ${{ parameters.stageDisplayNamePrefix }}${{ config.displayName }}' - macPool: ${{ config.macPool }} - useImage: ${{ config.useImage }} - statusContext: ${{ config.statusContext }} - keyringPass: $(pass--lab--mac--builder--keychain) - demands: ${{ config.demands }} - postPipeline: true - - ${{ if eq(parameters.runWindowsIntegration, true) }}: - template: ./windows/stage.yml parameters: From d588d3d2cd99c464efe99aaf292836cfa26d0168 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 25 Sep 2024 17:50:59 +0200 Subject: [PATCH 13/23] [devops] Remove some dead code. (#21269) --- tools/devops/add-summaries.sh | 15 ----- tools/devops/fetch-maccore.sh | 17 ----- tools/devops/push-performance-data.sh | 39 ------------ tools/devops/system-info.sh | 16 ----- tools/devops/utils.csx | 90 --------------------------- 5 files changed, 177 deletions(-) delete mode 100755 tools/devops/add-summaries.sh delete mode 100755 tools/devops/fetch-maccore.sh delete mode 100755 tools/devops/push-performance-data.sh delete mode 100755 tools/devops/system-info.sh delete mode 100644 tools/devops/utils.csx diff --git a/tools/devops/add-summaries.sh b/tools/devops/add-summaries.sh deleted file mode 100755 index e97cee10f1a8..000000000000 --- a/tools/devops/add-summaries.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -e - -set +x - -X="#vso" - -FILE=$PWD/xamarin-macios/tests/TestSummary.md -if ! test -f "$FILE"; then -echo ":fire: Tests failed catastrophically (no summary found)" > "$FILE" -fi - -echo "#${X}[task.addattachment type=Distributedtask.Core.Summary;name=Test results;]$FILE" - -echo "[Jenkins build]($WRENCH_URL)" > Wrench.md -echo "#${X}[task.addattachment type=Distributedtask.Core.Summary;name=Jenkins;]$PWD/Wrench.md" diff --git a/tools/devops/fetch-maccore.sh b/tools/devops/fetch-maccore.sh deleted file mode 100755 index cecdb7c19eec..000000000000 --- a/tools/devops/fetch-maccore.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -eux - -# maccore is already checked out, but our script does a different remote -# ('xamarin' vs 'origin'), so add the different remote, and at the same time -# use https for the repository (instead of git@), since GitHub auth on Azure -# Devops only works with https. - -cd "$(dirname "${BASH_SOURCE[0]}")" -cd "$(git rev-parse --show-toplevel)/../maccore" -git remote add -f xamarin https://github.com/xamarin/maccore -cd ../xamarin-macios - -# Make sure we've enabled our xamarin bits -./configure --enable-xamarin - -# fetch the hash we want -make reset-maccore V=1 diff --git a/tools/devops/push-performance-data.sh b/tools/devops/push-performance-data.sh deleted file mode 100755 index 1144154d10ab..000000000000 --- a/tools/devops/push-performance-data.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -ex - -cd xamarin-macios-data -git checkout main -cp -cr ../logs/ ./ - -mv ./*/*.zip . -for zip in ./*.zip; do - unzip "$zip" -done - -# Merge each individual xml file into one big xml file -DIR=perf-data/samples/$BUILD_SOURCEBRANCHNAME/$BUILD_SOURCEVERSION -cd "$DIR" -# Merge the xml files from each bot into a big per-bot xml file. Don't merge -# the xml from all the bots together into a single enormous xml file, because -# it'll be close to GitHub's size limit per file (limit is 100mb, the enormous -# xml file would be ~80mb now), and might very well pass that one day. -for job in ????????-????-????-????-????????????; do -{ - echo '' - echo '' - find "$job" -name '*perfdata*.xml' -print0 | xargs -0 -n 1 tail -n +2 | grep -F -v -e '' -e '' - echo '' -} > "data-$job.xml" -done - -# Add the big xml files to git -git add data-*.xml -git commit -m "Add performance data for $BUILD_SOURCEBRANCHNAME/$BUILD_SOURCEVERSION." - -# Push! -# Try to push 5 times, just in case someone else pushed first. -COUNTER=5 -while [[ $COUNTER -gt 0 ]]; do - if git push; then break; fi - git pull - (( COUNTER-- )) -done diff --git a/tools/devops/system-info.sh b/tools/devops/system-info.sh deleted file mode 100755 index 455544f3f0dd..000000000000 --- a/tools/devops/system-info.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -x - -# we do not want errors to fail the script, we want to print as much info as possible, so we don't pass -e to bash - -uname -a -ls -la /Library/Frameworks/Xamarin.iOS.framework/Versions -ls -la /Library/Frameworks/Xamarin.Mac.framework/Versions -ls -la /Library/Frameworks/ObjectiveSharpie.framework/Versions/ -ls -lad /Applications/Xcode* -xcode-select -p -mono --version -env | sort -uptime -ps aux - -exit 0 diff --git a/tools/devops/utils.csx b/tools/devops/utils.csx deleted file mode 100644 index 6589f76ca9e9..000000000000 --- a/tools/devops/utils.csx +++ /dev/null @@ -1,90 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading.Tasks; - -using Newtonsoft.Json.Linq; - -string DownloadWithGithubAuth (string uri) -{ - var downloader = new Downloader (); - var path = Path.GetTempFileName (); - var headers = new List<(string, string)> (); - var authToken = AuthToken ("github.com"); - if (!string.IsNullOrEmpty (authToken)) - headers.Add (("Authorization", $"token {authToken}")); - path = downloader - .DownloadItemAsync ( - uri, - headers.ToArray (), - Path.GetDirectoryName (path), - Path.GetFileName (path), - options: Downloader.Options.Default.WithUseCache (false)) - .GetAwaiter () - .GetResult (); - try { - return File.ReadAllText (path); - } finally { - File.Delete (path); - } -} - -string manifest_url = null; -string GetManifestUrl (string hash) -{ - var page = 1; - var hasContent = true; - while (manifest_url == null && hasContent) { - var url = $"https://api.github.com/repos/xamarin/xamarin-macios/statuses/{hash}?page={page}"; - var json = (JArray) JToken.Parse (DownloadWithGithubAuth (url)); - hasContent &= json.HasValues; - if (hasContent) { - manifest_url = (string) ((JValue) json.Where ((v) => v ["context"].ToString () == "vsts-devdiv artifacts").Select ((v) => v ["target_url"]).FirstOrDefault ())?.Value; - } - page++; - } - - if (manifest_url == null) - throw new Exception ($"Could not find the manifest for {hash}. Is the commit already built by CI?"); - return manifest_url; -} - -string[] manifest = null; -string[] GetManifest (string hash) -{ - // The manifest is gone but we can fake it until we make it using the "vsts-devdiv artifacts" - if (manifest == null) { - var artifactsUrl = GetManifestUrl (hash); - var artifactsjson = (JArray) JToken.Parse (DownloadWithGithubAuth (artifactsUrl)); - manifest = artifactsjson.Select ((v) => (string) v ["url"])?.ToArray (); - } - return manifest; -} - -// Looks for a variable either in the environment, or in current repo's Make.config. -// Returns null if the variable couldn't be found. -IEnumerable make_config = null; -string FindConfigurationVariable (string variable, string hash = "HEAD") -{ - var value = Environment.GetEnvironmentVariable (variable); - if (!string.IsNullOrEmpty (value)) - return value; - - if (make_config == null) - make_config = Exec ("git", "show", $"{hash}:Make.config"); - foreach (var line in make_config) { - if (line.StartsWith (variable + "=", StringComparison.Ordinal)) - return line.Substring (variable.Length + 1); - } - - return null; -} - -void InstallPackage (string name, string url) -{ - Console.WriteLine ($"Installing {name} from {url}"); - var version = Regex.Match (url, "[0-9]+[.][0-9]+[.][0-9]+([.][0-9]+)?").Value; - Item (name, version).Source (url); -} From cabb3e5e5e82747275a3d18377a8672d573f5000 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 25 Sep 2024 17:51:24 +0200 Subject: [PATCH 14/23] [tests/devops] Remove logic to build samples. (#21267) It's old, hasn't been executed in years and quite bitrotten by now (it only builds legacy Xamarin samples for instance). We could port it to .NET, but first we'd need sample apps, and there aren't many of those yet. --- tests/sampletester/.gitignore | 3 - tests/sampletester/BaseTester.cs | 68 ---- .../sampletester/BaselineTest/AppDelegate.cs | 27 -- .../BaselineTest/BaselineTest.csproj | 73 ---- .../BaselineTest/BaselineTest.sln | 23 -- tests/sampletester/BaselineTest/Info.plist | 48 --- .../BaselineTest/LaunchScreen.storyboard | 27 -- tests/sampletester/Configuration.cs | 115 ------- tests/sampletester/GitHub.cs | 64 ---- tests/sampletester/HtmlReport.xslt | 284 ---------------- tests/sampletester/Makefile | 27 -- tests/sampletester/ProcessHelper.cs | 308 ----------------- tests/sampletester/Properties/AssemblyInfo.cs | 4 - tests/sampletester/README.md | 34 -- tests/sampletester/SampleTester.cs | 319 ------------------ tests/sampletester/Samples.cs | 254 -------------- tests/sampletester/TestPlatform.cs | 7 - .../images/provision_from_commit.png | Bin 99793 -> 0 bytes tests/sampletester/sampletester.csproj | 79 ----- tests/sampletester/sampletester.sln | 25 -- .../automation/scripts/TestResults.Tests.ps1 | 1 - tools/devops/automation/scripts/VSTS.psm1 | 1 - .../automation/scripts/parse_pr_labels.ps1 | 5 - .../templates/build/build-stage.yml | 2 - .../pipelines/run-tests-pipeline.yml | 6 - .../automation/templates/tests-stage.yml | 21 -- .../devops/build-samples-report-to-github.sh | 39 --- tools/devops/build-samples.csx | 57 ---- tools/devops/build-samples.sh | 6 - tools/devops/build-samples.yml | 231 ------------- tools/devops/prepare-performance-data.sh | 14 - 31 files changed, 2172 deletions(-) delete mode 100644 tests/sampletester/.gitignore delete mode 100644 tests/sampletester/BaseTester.cs delete mode 100644 tests/sampletester/BaselineTest/AppDelegate.cs delete mode 100644 tests/sampletester/BaselineTest/BaselineTest.csproj delete mode 100644 tests/sampletester/BaselineTest/BaselineTest.sln delete mode 100644 tests/sampletester/BaselineTest/Info.plist delete mode 100644 tests/sampletester/BaselineTest/LaunchScreen.storyboard delete mode 100644 tests/sampletester/Configuration.cs delete mode 100644 tests/sampletester/GitHub.cs delete mode 100644 tests/sampletester/HtmlReport.xslt delete mode 100644 tests/sampletester/Makefile delete mode 100644 tests/sampletester/ProcessHelper.cs delete mode 100644 tests/sampletester/Properties/AssemblyInfo.cs delete mode 100644 tests/sampletester/README.md delete mode 100644 tests/sampletester/SampleTester.cs delete mode 100644 tests/sampletester/Samples.cs delete mode 100644 tests/sampletester/TestPlatform.cs delete mode 100644 tests/sampletester/images/provision_from_commit.png delete mode 100644 tests/sampletester/sampletester.csproj delete mode 100644 tests/sampletester/sampletester.sln delete mode 100755 tools/devops/build-samples-report-to-github.sh delete mode 100644 tools/devops/build-samples.csx delete mode 100755 tools/devops/build-samples.sh delete mode 100644 tools/devops/build-samples.yml delete mode 100755 tools/devops/prepare-performance-data.sh diff --git a/tests/sampletester/.gitignore b/tests/sampletester/.gitignore deleted file mode 100644 index 8e972cb58de2..000000000000 --- a/tests/sampletester/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -TestResult*.html -TestResult*.xml -.failed-stamp diff --git a/tests/sampletester/BaseTester.cs b/tests/sampletester/BaseTester.cs deleted file mode 100644 index 6a5d579f8b3a..000000000000 --- a/tests/sampletester/BaseTester.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Reflection; - -using NUnit.Framework; - -namespace Xamarin.Tests { - [TestFixture] - [Parallelizable (ParallelScope.Self)] - public abstract class BaseTester { - string repository; - public virtual string Repository { - get { - if (repository is null) - repository = (string) GetType ().GetField ("REPO", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).GetValue (null); - return repository; - } - protected set { - repository = value; - } - } - - string hash; - public virtual string Hash { - get { - if (hash is null) - hash = (string) GetType ().GetField ("HASH", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).GetValue (null); - return hash; - } - protected set { - hash = value; - } - } - - string org; - public virtual string Org { - get { - if (org is null) - org = (string) GetType ().GetField ("ORG", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)?.GetValue (null) ?? "xamarin"; - return org; - } - protected set { - org = value; - } - } - - string default_branch; - public virtual string DefaultBranch { - get { - if (default_branch is null) - default_branch = (string) GetType ().GetField ("DEFAULT_BRANCH", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)?.GetValue (null); - return default_branch; - - } - set { - default_branch = value; - } - } - - protected BaseTester () - { - } - - protected BaseTester (string repository, string hash) - { - this.repository = repository; - this.hash = hash; - } - } -} diff --git a/tests/sampletester/BaselineTest/AppDelegate.cs b/tests/sampletester/BaselineTest/AppDelegate.cs deleted file mode 100644 index 3acc74202cd8..000000000000 --- a/tests/sampletester/BaselineTest/AppDelegate.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Foundation; -using UIKit; - -namespace BaselineTest { - [Register ("AppDelegate")] - public class AppDelegate : UIResponder, IUIApplicationDelegate { - UIWindow window; - UIViewController vc; - - [Export ("application:didFinishLaunchingWithOptions:")] - public bool FinishedLaunching (UIApplication application, NSDictionary launchOptions) - { - window = new UIWindow (UIScreen.MainScreen.Bounds); - vc = new UIViewController (); - vc.View.BackgroundColor = UIColor.Green; - window.RootViewController = vc; - window.MakeKeyAndVisible (); - - return true; - } - - static void Main (string [] args) - { - UIApplication.Main (args, null, typeof (AppDelegate)); - } - } -} diff --git a/tests/sampletester/BaselineTest/BaselineTest.csproj b/tests/sampletester/BaselineTest/BaselineTest.csproj deleted file mode 100644 index 2625d2f87735..000000000000 --- a/tests/sampletester/BaselineTest/BaselineTest.csproj +++ /dev/null @@ -1,73 +0,0 @@ - - - - Debug - iPhoneSimulator - {E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F} - {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {edc1b0fa-90cd-4038-8fad-98fe74adb368} - Exe - BaselineTest - BaselineTest - Resources - true - NSUrlSessionHandler - PackageReference - latest - - - true - full - false - bin\iPhoneSimulator\Debug - DEBUG - prompt - 4 - x86_64 - None - true - - - none - true - bin\iPhoneSimulator\Release - prompt - 4 - None - x86_64 - - - true - full - false - bin\iPhone\Debug - DEBUG - prompt - 4 - ARM64 - iPhone Developer - true - - - none - true - bin\iPhone\Release - prompt - 4 - ARM64 - iPhone Developer - - - - - - - - - - - - - - - diff --git a/tests/sampletester/BaselineTest/BaselineTest.sln b/tests/sampletester/BaselineTest/BaselineTest.sln deleted file mode 100644 index b2b66729db02..000000000000 --- a/tests/sampletester/BaselineTest/BaselineTest.sln +++ /dev/null @@ -1,23 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BaselineTest", "BaselineTest.csproj", "{E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|iPhoneSimulator = Debug|iPhoneSimulator - Release|iPhoneSimulator = Release|iPhoneSimulator - Debug|iPhone = Debug|iPhone - Release|iPhone = Release|iPhone - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F}.Debug|iPhone.ActiveCfg = Debug|iPhone - {E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F}.Debug|iPhone.Build.0 = Debug|iPhone - {E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F}.Release|iPhone.ActiveCfg = Release|iPhone - {E7E76A89-6DB7-4CF6-953C-6D9ADC656C6F}.Release|iPhone.Build.0 = Release|iPhone - EndGlobalSection -EndGlobal diff --git a/tests/sampletester/BaselineTest/Info.plist b/tests/sampletester/BaselineTest/Info.plist deleted file mode 100644 index 39c7ebc9116d..000000000000 --- a/tests/sampletester/BaselineTest/Info.plist +++ /dev/null @@ -1,48 +0,0 @@ - - - - - CFBundleDisplayName - BaselineTest - CFBundleIdentifier - com.xamarin.BaselineTest - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1.0 - LSRequiresIPhoneOS - - MinimumOSVersion - 11.0 - UIDeviceFamily - - 1 - 2 - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile~ipad - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - XSAppIconAssets - Assets.xcassets/AppIcon.appiconset - CFBundleName - BaselineTest - - diff --git a/tests/sampletester/BaselineTest/LaunchScreen.storyboard b/tests/sampletester/BaselineTest/LaunchScreen.storyboard deleted file mode 100644 index f18534b49b24..000000000000 --- a/tests/sampletester/BaselineTest/LaunchScreen.storyboard +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/sampletester/Configuration.cs b/tests/sampletester/Configuration.cs deleted file mode 100644 index 696a337a87e5..000000000000 --- a/tests/sampletester/Configuration.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.IO; -using System.Reflection; - -namespace Xamarin.Tests { - public partial class Configuration { - static object lock_obj = new object (); - static string sample_root_directory; - public static string SampleRootDirectory { - get { - lock (lock_obj) { - if (sample_root_directory is null) { - sample_root_directory = Path.Combine (Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location), "repositories"); - Directory.CreateDirectory (sample_root_directory); - CreateNugetConfig (sample_root_directory); - CreateGlobalConfig (sample_root_directory); - } - } - return sample_root_directory; - } - } - - static void CreateNugetConfig (string root) - { - var nuget_conf = Path.Combine (root, "NuGet.config"); - // We're cloning into a subdirectory of xamarin-macios, which already has a NuGet.config - // So create a Nuget.config that clears out any previous configuration and adds nuget.org as - // single nuget source so that none of the sample tests pick up xamarin-macios' NuGet.config. - File.WriteAllText (nuget_conf, -@" - - - - - - - - - - - - -"); - } - - static void CreateGlobalConfig (string root) - { - var global_json = Path.Combine (root, "global.json"); - // Workaround for https://github.com/NuGet/Home/issues/7956 - // See also: - // * https://github.com/mono/mono/issues/13537 - // * https://github.com/xamarin/maccore/issues/1811 - // The version number here must match the version in tools/devops/build-samples.csx - File.WriteAllText (global_json, - @"{ -""sdk"": { - ""version"": ""2.2.204"" -} - } -"); - } - - static string tested_hash; - public static string TestedHash { - get { - lock (lock_obj) { - if (tested_hash is not null) - return tested_hash; - - tested_hash = GetCurrentHash (Environment.CurrentDirectory); - return tested_hash; - } - } - } - - public static string GetCurrentHash (string directory) - { - return ProcessHelper.RunProcess ("git", "log -1 --pretty=%H", directory).Trim (); - } - - public static string GetCurrentRemoteUrl (string directory) - { - return ProcessHelper.RunProcess ("git", "remote get-url origin", directory).Trim (); - } - - static string mono_version; - public static string MonoVersion { - get { - lock (lock_obj) { - if (mono_version is not null) - return mono_version; - - // We only care about the first line - mono_version = ProcessHelper.RunProcess ("mono", "--version").Split (new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries) [0].Trim (); - } - - return mono_version; - } - } - - static string sw_version; - public static string OSVersion { - get { - lock (lock_obj) { - if (sw_version is not null) - return sw_version; - - sw_version = ProcessHelper.RunProcess ("sw_vers").Replace ('\n', ';').Replace ((char) 9, ' '); - } - - return sw_version; - } - } - } -} diff --git a/tests/sampletester/GitHub.cs b/tests/sampletester/GitHub.cs deleted file mode 100644 index ff0f8dcb4b55..000000000000 --- a/tests/sampletester/GitHub.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -using NUnit.Framework; - -using Xamarin.Tests; - -public static class GitHub { - public static string [] GetProjects (string user, string repo, string hash, string default_branch) - { - IEnumerable files; - - var dir = CloneRepository (user, repo, hash, default_branch); - files = Directory.GetFiles (dir, "*.*", SearchOption.AllDirectories); - files = files.Select ((v) => v.Substring (dir.Length).TrimStart ('/')); - - return files - .Where ((v) => { - var ext = Path.GetExtension (v).ToLowerInvariant (); - return ext == ".csproj" || ext == ".fsproj"; - }).ToArray (); - } - - public static string CloneRepository (string org, string repo, string hash, string default_branch, bool clean = true) - { - var repo_dir = Path.Combine (Configuration.SampleRootDirectory, repo); - - if (!Directory.Exists (repo_dir)) { - Console.WriteLine ($"Cloning https://github.com/{org}/{repo} (hash: {hash})"); - Directory.CreateDirectory (repo_dir); - Assert.AreEqual (0, ExecutionHelper.Execute ("git", new string [] { "init" }, working_directory: repo_dir, timeout: TimeSpan.FromSeconds (10)), "git init"); - Assert.AreEqual (0, ExecutionHelper.Execute ("git", new string [] { "remote", "add", "origin", $"https://github.com/{org}/{repo}" }, working_directory: repo_dir, timeout: TimeSpan.FromSeconds (10)), "git remote add"); - Assert.AreEqual (0, ExecutionHelper.Execute ("git", new string [] { "fetch" }, working_directory: repo_dir, timeout: TimeSpan.FromMinutes (10)), "git fetch"); - Assert.AreEqual (0, ExecutionHelper.Execute ("git", new string [] { "checkout", "-b", "temporary-sample-testing-branch", hash }, working_directory: repo_dir, timeout: TimeSpan.FromMinutes (1)), "git checkout"); - Assert.AreEqual (0, ExecutionHelper.Execute ("git", new string [] { "submodule", "update", "--init", "--recursive" }, working_directory: repo_dir, timeout: TimeSpan.FromMinutes (10)), "git submodule update"); - - ExecutionHelper.Execute ("git", new string [] { "log", "--oneline", "--pretty=* @%h %s", "HEAD", $"^origin/{default_branch}" }, out var output1, working_directory: repo_dir, timeout: TimeSpan.FromSeconds (10)); - if (output1.Length > 0) { - Console.WriteLine ($"Commits not in origin/{default_branch}:"); - Console.WriteLine (output1.ToString ().TrimEnd ('\n')); - } - ExecutionHelper.Execute ("git", new string [] { "log", "--oneline", "--pretty=* %h %s", $"origin/{default_branch}", "^HEAD" }, out var output2, working_directory: repo_dir, timeout: TimeSpan.FromSeconds (10)); - if (output2.Length > 0) { - Console.WriteLine ($"Commits in origin/{default_branch} not being tested:"); - Console.WriteLine (output2.ToString ().TrimEnd ('\n')); - } - - } else if (clean) { - Assert.AreEqual (0, ExecutionHelper.Execute ("git", new string [] { "reset", "--hard", hash }, working_directory: repo_dir, timeout: TimeSpan.FromMinutes (1)), "git checkout"); - CleanRepository (repo_dir); - } - - return repo_dir; - } - - public static void CleanRepository (string directory, bool submodules = true) - { - ExecutionHelper.Execute ("git", new string [] { "clean", "-xffdq" }, working_directory: directory, timeout: TimeSpan.FromSeconds (30)); - if (submodules) - ExecutionHelper.Execute ("git", new string [] { "submodule", "foreach", "--recursive", "clean -xffdq" }, working_directory: directory, timeout: TimeSpan.FromSeconds (60)); - } -} diff --git a/tests/sampletester/HtmlReport.xslt b/tests/sampletester/HtmlReport.xslt deleted file mode 100644 index 671bfb1b34f8..000000000000 --- a/tests/sampletester/HtmlReport.xslt +++ /dev/null @@ -1,284 +0,0 @@ - - - - - <!DOCTYPE html> - - - Test results - - - - - - - - - - - -

Command Line

-
-      
-    
- - -

Runtime Environment

- - - - - - - - - - - - - - - - - -
OS Version: - -
CLR Version: - -
- -
NUnit Version: - -
- - -
-

Test Files

- -
    - -
  1. - -
  2. -
    -
-
-
- - - -
- Successes -
    - -
-
-
- - - -
- Tests Not Run -
    - -
-
-
- - - -
- Errors and Failures -
    - -
-
-
- - - - -

Run Settings

-
    -
  • - DefaultTimeout: -
  • -
  • - WorkDirectory: -
  • -
  • - ImageRuntimeVersion: -
  • -
  • - ImageTargetFrameworkName: -
  • -
  • - ImageRequiresX86: -
  • -
  • - ImageRequiresDefaultAppDomainAssemblyResolver: -
  • -
  • - NumberOfTestWorkers: -
  • -
- -

Test Run Summary

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  • - -
    -
    -        
    -
    -        
    -          
    -            
    -
    - -
    -
    - -
    -
    -
    - - - - - -
    - - -
      - -
    • -
      -
    -
    -
  • -
    -
    \ No newline at end of file diff --git a/tests/sampletester/Makefile b/tests/sampletester/Makefile deleted file mode 100644 index c22c841f43f4..000000000000 --- a/tests/sampletester/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -TOP=../.. - -include $(TOP)/Make.config - -all-local:: run-tests - -ifneq ($(TEST_CATEGORY),) -WHERE_CONDITION=/where "cat == $(TEST_CATEGORY)" -endif - -TEST_RESULT:=TestResult-$(shell date "+%Y%m%d-%H%M%S") - -build: bin/Debug/sampletester.dll - -run-tests: bin/Debug/sampletester.dll - $(Q) rm -f .failed-stamp - $(Q) $(TOP)/tools/nunit3-console-3.11.1 $(WHERE_CONDITION) $(abspath $(CURDIR)/bin/Debug/sampletester.dll) "--result=$(abspath $(CURDIR)/$(TEST_RESULT).xml)" $${TEST_FIXTURE:+"$$TEST_FIXTURE"} --labels=After --inprocess || touch $(CURDIR)/.failed-stamp - $(Q) xsltproc HtmlReport.xslt "$(TEST_RESULT).xml" > "$(TEST_RESULT).html" - $(Q) $(CP) "$(TEST_RESULT).html" index.html - @[[ ! -e .failed-stamp ]] - -run-tests-system: bin/Debug/sampletester.dll - $(MAKE) TESTS_USE_SYSTEM=1 - -bin/Debug/sampletester.dll: $(wildcard *.cs */*.cs *.csproj Makefile) - $(Q) $(SYSTEM_MONO) /Library/Frameworks//Mono.framework/Versions/Current/lib/mono/nuget/NuGet.exe restore - $(Q_BUILD) $(SYSTEM_MSBUILD) sampletester.csproj $(MSBUILD_VERBOSITY) diff --git a/tests/sampletester/ProcessHelper.cs b/tests/sampletester/ProcessHelper.cs deleted file mode 100644 index 216939afc415..000000000000 --- a/tests/sampletester/ProcessHelper.cs +++ /dev/null @@ -1,308 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml; - -using NUnit.Framework; - -using Xamarin; -using Xamarin.Tests; -using Xamarin.Utils; - -public static class ProcessHelper { - static int counter; - - static string log_directory; - static string LogDirectory { - get { - if (log_directory is null) - log_directory = Cache.CreateTemporaryDirectory ("execution-logs"); - return log_directory; - } - - } - - public static void AssertRunProcess (string filename, string [] arguments, TimeSpan timeout, string workingDirectory, Dictionary environment_variables, string message) - { - AssertRunProcess (filename, arguments, timeout, workingDirectory, environment_variables, message, out _); - } - - public static void AssertRunProcess (string filename, string [] arguments, TimeSpan timeout, string workingDirectory, Dictionary environment_variables, string message, out string logfile) - { - var exitCode = 0; - var output = new List (); - - Action output_callback = (v) => { - lock (output) - output.Add ($"{DateTime.Now.ToString ("HH:mm:ss.fffffff")}: {v}"); - }; - - if (environment_variables is null) - environment_variables = new Dictionary (); - environment_variables ["XCODE_DEVELOPER_DIR_PATH"] = null; - environment_variables ["DEVELOPER_DIR"] = Configuration.XcodeLocation; - - var watch = Stopwatch.StartNew (); - exitCode = ExecutionHelper.Execute (filename, arguments, out var timed_out, workingDirectory, environment_variables, output_callback, output_callback, timeout); - watch.Stop (); - - output_callback ($"Exit code: {exitCode} Timed out: {timed_out} Total duration: {watch.Elapsed.ToString ()}"); - - // Write execution log to disk (and print the path) - logfile = Path.Combine (LogDirectory, $"{filename}-{Interlocked.Increment (ref counter)}.log"); - File.WriteAllLines (logfile, output); - TestContext.AddTestAttachment (logfile, $"Execution log for {filename}"); - Console.WriteLine ("Execution log for {0}: {1}", filename, logfile); - - var errors = new List (); - var errorMessage = ""; - if ((!timed_out || exitCode != 0) && output.Count > 0) { - var regex = new Regex (@"error\s*(MSB....)?(CS....)?(MT....)?(MM....)?:", RegexOptions.IgnoreCase | RegexOptions.Singleline); - foreach (var line in output) { - if (regex.IsMatch (line) && !errors.Contains (line)) - errors.Add (line); - } - if (errors.Count > 0) - errorMessage = "\n\t[Summary of errors from the build output below]\n\t" + string.Join ("\n\t", errors); - } - Assert.IsFalse (timed_out, $"{message} timed out after {timeout.TotalMinutes} minutes{errorMessage}"); - Assert.AreEqual (0, exitCode, $"{message} failed (unexpected exit code){errorMessage}"); - } - - public static void BuildSolution (string solution, string platform, string configuration, Dictionary environment_variables, TimeSpan timeout, string target = "", string codesignKey = null) - { - // nuget restore - var solution_dir = string.Empty; - var solutions = new string [] { solution }; - var nuget_args = new List (); - nuget_args.Add ("restore"); - nuget_args.Add ("sln"); // replaced later - nuget_args.Add ("-Verbosity"); - nuget_args.Add ("detailed"); - var slndir = Path.GetDirectoryName (solution); - if (!solution.EndsWith (".sln", StringComparison.Ordinal)) { - while ((solutions = Directory.GetFiles (slndir, "*.sln", SearchOption.TopDirectoryOnly)).Length == 0 && slndir.Length > 1) - slndir = Path.GetDirectoryName (slndir); - nuget_args.Add ("-SolutionDir"); - nuget_args.Add (slndir); - } - - foreach (var sln in solutions) { - nuget_args [1] = sln; // replacing here - AssertRunProcess ("nuget", nuget_args.ToArray (), timeout, Configuration.SampleRootDirectory, environment_variables, "nuget restore"); - } - - // msbuild - var sb = new List (); - sb.Add ("/verbosity:diag"); - if (!string.IsNullOrEmpty (platform)) - sb.Add ($"/p:Platform={platform}"); - if (!string.IsNullOrEmpty (configuration)) - sb.Add ($"/p:Configuration={configuration}"); - sb.Add (solution); - if (!string.IsNullOrEmpty (target)) - sb.Add ($"/t:{target}"); - if (!string.IsNullOrEmpty (codesignKey)) - sb.Add ($"/p:CodesignKey={codesignKey}"); - - environment_variables ["MTOUCH_ENV_OPTIONS"] = "--time --time --time --time -vvvv"; - environment_variables ["MMP_ENV_OPTIONS"] = "--time --time --time --time -vvvv"; - - var watch = Stopwatch.StartNew (); - var failed = false; - string msbuild_logfile; - try { - AssertRunProcess ("msbuild", sb.ToArray (), timeout, Configuration.SampleRootDirectory, environment_variables, "build", out msbuild_logfile); - } catch { - failed = true; - throw; - } finally { - watch.Stop (); - } - - // Write performance data to disk - var subdirs = Directory.GetDirectories (slndir, "*", SearchOption.AllDirectories); - - // First figure out which .app subdirectory is the actual .app. This is a bit more complicated than it would seem... - var apps = subdirs.Where ((v) => { - var names = v.Substring (slndir.Length).Split (Path.DirectorySeparatorChar); - if (names.Length < 2) - return false; - - if (!names [names.Length - 1].EndsWith (".app", StringComparison.Ordinal)) - return false; - - if (names.Any ((v2) => v2 == "copySceneKitAssets")) - return false; - - var bin_idx = Array.IndexOf (names, "bin"); - var conf_idx = Array.IndexOf (names, configuration); - if (bin_idx < 0 || conf_idx < 0) - return false; - - if (bin_idx > conf_idx) - return false; - - if (platform.Length > 0) { - var platform_idx = Array.IndexOf (names, platform); - if (platform_idx < 0) - return false; - - if (bin_idx > platform_idx) - return false; - } - - return true; - }).ToArray (); - - if (apps.Length > 1) { - // Found more than one .app subdirectory, use additional logic to choose between them. - var filtered_apps = apps.Where ((v) => { - // If one .app is a subdirectory of another .app, we don't care about the former. - if (apps.Any ((v2) => v2.Length < v.Length && v.StartsWith (v2, StringComparison.Ordinal))) - return false; - - // If one .app is contained within another .app, we don't care about the former. - var vname = Path.GetFileName (v); - var otherApps = apps.Where ((v2) => v != v2); - if (otherApps.Any ((v2) => { - var otherSubdirs = subdirs.Where ((v3) => v3.StartsWith (v2, StringComparison.Ordinal)); - return otherSubdirs.Any ((v3) => Path.GetFileName (v3) == vname); - })) - return false; - - return true; - }).ToArray (); - if (apps.Length == 0) - Assert.Fail ($"Filtered away all the .apps, from:\n\t{string.Join ("\n\t", apps)}"); - apps = filtered_apps; - } - - if (apps.Length > 1) { - Assert.Fail ($"Found more than one .app directory:\n\t{string.Join ("\n\t", apps)}"); - } else if (apps.Length == 0) { - Assert.Fail ($"Found no .app directories for platform: {platform} configuration: {configuration} target: {target}. All directories:\n\t{string.Join ("\n\t", subdirs)}"); - } - - var logfile = Path.Combine (LogDirectory, $"{Path.GetFileNameWithoutExtension (solution)}-perfdata-{Interlocked.Increment (ref counter)}.xml"); - - var xmlSettings = new XmlWriterSettings { - Indent = true, - }; - var xml = XmlWriter.Create (logfile, xmlSettings); - xml.WriteStartDocument (true); - xml.WriteStartElement ("performance"); - xml.WriteStartElement ("sample-build"); - xml.WriteAttributeString ("mono-version", Configuration.MonoVersion); - xml.WriteAttributeString ("os-version", Configuration.OSVersion); - xml.WriteAttributeString ("xamarin-macios-hash", Configuration.TestedHash); - xml.WriteAttributeString ("sample-repository", Configuration.GetCurrentRemoteUrl (slndir)); - xml.WriteAttributeString ("sample-hash", Configuration.GetCurrentHash (slndir)); - xml.WriteAttributeString ("agent-machinename", Environment.GetEnvironmentVariable ("AGENT_MACHINENAME")); - xml.WriteAttributeString ("agent-name", Environment.GetEnvironmentVariable ("AGENT_NAME")); - foreach (var app in apps) { - xml.WriteStartElement ("test"); - xml.WriteAttributeString ("name", TestContext.CurrentContext.Test.FullName); - xml.WriteAttributeString ("result", failed ? "failed" : "success"); - if (platform.Length > 0) - xml.WriteAttributeString ("platform", platform); - xml.WriteAttributeString ("configuration", configuration); - if (!failed) { - xml.WriteAttributeString ("duration", watch.ElapsedTicks.ToString ()); - xml.WriteAttributeString ("duration-formatted", watch.Elapsed.ToString ()); - - var files = Directory.GetFiles (app, "*", SearchOption.AllDirectories).OrderBy ((v) => v).ToArray (); - var lengths = files.Select ((v) => new FileInfo (v).Length).ToArray (); - var total_size = lengths.Sum (); - - xml.WriteAttributeString ("total-size", total_size.ToString ()); - var appstart = Path.GetDirectoryName (app).Length; - for (var i = 0; i < files.Length; i++) { - xml.WriteStartElement ("file"); - xml.WriteAttributeString ("name", files [i].Substring (appstart + 1)); - xml.WriteAttributeString ("size", lengths [i].ToString ()); - xml.WriteEndElement (); - } - - if (File.Exists (msbuild_logfile)) { - var lines = File.ReadAllLines (msbuild_logfile); - var target_perf_summary = new List (); - var task_perf_summary = new List (); - var timestamps = new List (); - for (var i = lines.Length - 1; i >= 0; i--) { - if (lines [i].EndsWith ("Target Performance Summary:", StringComparison.Ordinal)) { - for (var k = i + 1; k < lines.Length && lines [k].EndsWith ("calls", StringComparison.Ordinal); k++) { - target_perf_summary.Add (lines [k].Substring (18).Trim ()); - } - } else if (lines [i].EndsWith ("Task Performance Summary:", StringComparison.Ordinal)) { - for (var k = i + 1; k < lines.Length && lines [k].EndsWith ("calls", StringComparison.Ordinal); k++) { - task_perf_summary.Add (lines [k].Substring (18).Trim ()); - } - } else if (lines [i].Contains ("!Timestamp")) { - timestamps.Add (lines [i]); - } - } - foreach (var tps in target_perf_summary) { - var split = tps.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); - xml.WriteStartElement ("target"); - xml.WriteAttributeString ("name", split [2]); - xml.WriteAttributeString ("ms", split [0]); - xml.WriteAttributeString ("calls", split [3]); - xml.WriteEndElement (); - } - foreach (var tps in task_perf_summary) { - var split = tps.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); - xml.WriteStartElement ("task"); - xml.WriteAttributeString ("name", split [2]); - xml.WriteAttributeString ("ms", split [0]); - xml.WriteAttributeString ("calls", split [3]); - xml.WriteEndElement (); - } - foreach (var ts in timestamps) { - // Sample line: - // 15:04:50.4609520: !Timestamp Setup: 28 ms (TaskId:137) - var splitFirst = ts.Split (new char [] { ':' }, StringSplitOptions.RemoveEmptyEntries); - var splitSecondA = splitFirst [3].Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); - var splitSecondB = splitFirst [4].Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); - var name = string.Join (" ", splitSecondA.Skip (1)); - var level = splitSecondA [0].Count ((v) => v == '!').ToString (); - var ms = splitSecondB [0]; - xml.WriteStartElement ("timestamp"); - xml.WriteAttributeString ("name", name); - xml.WriteAttributeString ("level", level); - xml.WriteAttributeString ("ms", ms); - xml.WriteEndElement (); - } - } - - xml.WriteEndElement (); - } - - xml.WriteEndElement (); // sample-build - xml.WriteEndElement (); // performance - xml.WriteEndDocument (); - xml.Dispose (); - - TestContext.AddTestAttachment (logfile, $"Performance data"); - } - } - - internal static string RunProcess (string filename, string arguments = "", string working_directory = null) - { - using (var p = Process.Start (filename, arguments)) { - p.StartInfo.RedirectStandardOutput = true; - p.StartInfo.UseShellExecute = false; - if (!string.IsNullOrEmpty (working_directory)) - p.StartInfo.WorkingDirectory = working_directory; - p.Start (); - var output = p.StandardOutput.ReadToEnd (); - p.WaitForExit (); - return output; - } - } -} diff --git a/tests/sampletester/Properties/AssemblyInfo.cs b/tests/sampletester/Properties/AssemblyInfo.cs deleted file mode 100644 index 56f844cb81ba..000000000000 --- a/tests/sampletester/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,4 +0,0 @@ -using NUnit.Framework; - -// Two tests at the same time is enough: mtouch already parallelizes things, so we don't want to overload the bots either. -[assembly: LevelOfParallelism (2)] diff --git a/tests/sampletester/README.md b/tests/sampletester/README.md deleted file mode 100644 index fa561e44abc4..000000000000 --- a/tests/sampletester/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Sample testing - -These unit tests clone a series of known repositories that contain sample -projects, and build all the relevant projects in those repositories. - -It is executed automatically in [Azure DevOps][1] every [Saturday][2] for the listed branches. This includes: - -* `main` -* `d16-x` - i.e. one or many active release branches -* `xcodeY` - i.e. the current xcode *beta* feature branch -* `mono-202z-zz` - i.e. the mono integration branches (new one every two months) - -where `x`, `Y` and `z` needs to be periodically updated as new branches are created (e.g. `d16-x`) and old ones are merged into `main` (e.g. `xcodeY` and `mono-202z-zz`). - -It can also be triggered manually, but have in mind that the commit in -question must already have packages (as GitHub statuses). - -It's also possible to use the sample tests from one commit, and then test with -Xamarin.iOS/Xamarin.Mac a completely different commit, by setting the -`PROVISION_FROM_COMMIT` variable to the commit that's to be tested: - -![screenshot](images/provision_from_commit.png) - -The previous point is still required: the commit to provision from must have -packages. - -There are two ways to run these tests locally: - -* Launching xharness in server mode and execute the "Sample tests" (they're - disabled by default). -* Executing `make` in this directory. - -[1]: https://dev.azure.com/xamarin/internal/_build?definitionId=23 -[2]: https://dev.azure.com/xamarin/internal/_apps/hub/ms.vss-ciworkflow.build-ci-hub?_a=edit-build-definition&id=23&view=Tab_Triggers diff --git a/tests/sampletester/SampleTester.cs b/tests/sampletester/SampleTester.cs deleted file mode 100644 index d180095ce0f3..000000000000 --- a/tests/sampletester/SampleTester.cs +++ /dev/null @@ -1,319 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using System.Text.RegularExpressions; - -using NUnit.Framework; - -using Xamarin.Tests; - -namespace Samples { - public class SampleTest { - public ProjectInfo Project; - public string Solution; - public bool BuildSolution; - public string KnownFailure; - public string CodesignKey; - public string [] DebugConfigurations; - public string [] ReleaseConfigurations; - public string [] Platforms; - - // for various reasons (build'ability, compatibility, performance) it can be - // better to build a subset of a solution - // e.g. `nuget restore` requires removing the projects from the .sln - public string [] RemoveProjects; - } - - public class SampleTestData { - public SampleTest SampleTest; - public string Configuration; - public string Platform; - public TimeSpan Timeout; - - public override string ToString () - { - if (string.IsNullOrEmpty (Platform)) - return $"{SampleTest.Project.Title}: {Configuration}"; - return $"{SampleTest.Project.Title}: {Configuration}|{Platform}"; - } - } - - public class ProjectInfo { - public string Title; - public string RelativePath; - public string FullPath; - public bool IsExecutable; - public string [] Imports; - public TestPlatform Platform; - - public bool IsApplicable (bool assert) - { - if (!IsExecutable) { - if (assert) - Assert.Ignore ("Project is not an executable project"); - return false; - } - - if (Platform == TestPlatform.None) { - if (assert) - Assert.Ignore ("Project is not an Xamarin.iOS/Xamarin.Mac/Xamarin.WatchOS/Xamarin.TVOS project. Imports:\n\t{0}", string.Join ("\t\n", Imports)); - return false; - } - - if (Platform == TestPlatform.watchOS) { - if (assert) - Assert.Ignore ("Project is a watchOS app"); // no need to build watchOS apps, they're built as part of their containing iOS project. - - return false; - } - - return true; - } - } - - public abstract class SampleTester : BaseTester { - - public static TimeSpan DefaultTimeout { get; } = TimeSpan.FromMinutes (5); - - protected SampleTester () - { - } - - protected SampleTester (string repo, string hash) - : base (repo, hash) - { - } - - static ProjectInfo GetProjectInfo (string relative_path, string full_path) - { - var xml = File.ReadAllText (full_path); - var info = new ProjectInfo (); - info.FullPath = full_path; - info.RelativePath = relative_path; - info.IsExecutable = xml.Contains ("Exe"); - - var xml_lines = xml.Split ('\n'); - var xml_imports = xml_lines. - Where ((v) => v.Contains (" v.Contains ("Xamarin.iOS"))) { - test_platform = TestPlatform.iOS; - } else if (xml_imports.Any ((v) => v.Contains ("Xamarin.TVOS"))) { - test_platform = TestPlatform.tvOS; - } else if (xml_imports.Any ((v) => v.Contains ("Xamarin.WatchOS"))) { - test_platform = TestPlatform.watchOS; - } else if (xml_imports.Any ((v) => v.Contains ("Xamarin.Mac"))) { - test_platform = TestPlatform.macOS; - } else { - test_platform = TestPlatform.None; - } - info.Platform = test_platform; - - return info; - } - - public static Dictionary GetEnvironmentVariables (TestPlatform platform) - { - var environment_variables = new Dictionary (); - environment_variables ["MD_APPLE_SDK_ROOT"] = Path.GetDirectoryName (Path.GetDirectoryName (Configuration.XcodeLocation)); - switch (platform) { - case TestPlatform.iOS: - case TestPlatform.tvOS: - case TestPlatform.watchOS: - environment_variables ["MD_MTOUCH_SDK_ROOT"] = Path.Combine (Configuration.IOS_DESTDIR, "Library", "Frameworks", "Xamarin.iOS.framework", "Versions", "Current"); - environment_variables ["TargetFrameworkFallbackSearchPaths"] = Path.Combine (Configuration.IOS_DESTDIR, "Library", "Frameworks", "Mono.framework", "External", "xbuild-frameworks"); - environment_variables ["MSBuildExtensionsPathFallbackPathsOverride"] = Path.Combine (Configuration.IOS_DESTDIR, "Library", "Frameworks", "Mono.framework", "External", "xbuild"); - break; - case TestPlatform.macOS: - environment_variables ["TargetFrameworkFallbackSearchPaths"] = Path.Combine (Configuration.MAC_DESTDIR, "Library", "Frameworks", "Mono.framework", "External", "xbuild-frameworks"); - environment_variables ["MSBuildExtensionsPathFallbackPathsOverride"] = Path.Combine (Configuration.MAC_DESTDIR, "Library", "Frameworks", "Mono.framework", "External", "xbuild"); - environment_variables ["XamarinMacFrameworkRoot"] = Path.Combine (Configuration.MAC_DESTDIR, "Library", "Frameworks", "Xamarin.Mac.framework", "Versions", "Current"); - environment_variables ["XAMMAC_FRAMEWORK_PATH"] = Path.Combine (Configuration.MAC_DESTDIR, "Library", "Frameworks", "Xamarin.Mac.framework", "Versions", "Current"); - break; - default: - throw new NotImplementedException (platform.ToString ()); - } - return environment_variables; - } - - [Test] - public void BuildSample ([ValueSource ("GetSampleData")] SampleTestData sampleTestData) - { - try { - var data = sampleTestData.SampleTest; - if (!string.IsNullOrEmpty (data.KnownFailure)) - Assert.Ignore (data.KnownFailure); - - switch (data.Project.Platform) { - case TestPlatform.iOS: - if (!Configuration.include_ios) - Assert.Ignore ("iOS support has been disabled."); - break; - case TestPlatform.tvOS: - if (!Configuration.include_tvos) - Assert.Ignore ("tvOS support has been disabled"); - break; - case TestPlatform.watchOS: - if (!Configuration.include_watchos) - Assert.Ignore ("watchOS support has been disabled"); - break; - case TestPlatform.macOS: - if (!Configuration.include_mac) - Assert.Ignore ("macOS support has been disabled"); - break; - default: - throw new NotImplementedException (sampleTestData.Platform.ToString ()); - } - - var file_to_build = sampleTestData.SampleTest.Project.RelativePath; - var target = string.Empty; - if (data.BuildSolution) { - file_to_build = data.Solution; - target = Path.GetFileNameWithoutExtension (data.Project.RelativePath).Replace ('.', '_'); - } - - var repo = CloneRepo (); - file_to_build = Path.Combine (repo, file_to_build); - - if (data.RemoveProjects is not null) { - if (String.IsNullOrEmpty (data.Solution)) - Assert.Fail ("'RemoveProjects' used without a 'Solution' path!"); - var sln_path = Path.Combine (repo, data.Solution); - var filtered_sln = new List (File.ReadAllLines (sln_path)); - foreach (var p in data.RemoveProjects) { - for (int i = 0; i < filtered_sln.Count; i++) { - var line = filtered_sln [i]; - if (line.StartsWith ("Project(", StringComparison.Ordinal)) { - if (line.Contains ($") = \"{p}\", \"")) { - filtered_sln.RemoveAt (i); - filtered_sln.RemoveAt (i); // EndProject (same `i` as things moved up) - break; - } - } - } - } - File.WriteAllLines (sln_path, filtered_sln); - } - - ProcessHelper.BuildSolution (file_to_build, sampleTestData.Platform, sampleTestData.Configuration, GetEnvironmentVariables (data.Project.Platform), sampleTestData.Timeout, target, data.CodesignKey); - Console.WriteLine ("✅ {0} succeeded.", TestContext.CurrentContext.Test.FullName); - } catch (Exception e) { - Console.WriteLine ("❌ {0} failed: {1}", TestContext.CurrentContext.Test.FullName, e.Message); - throw; - } - } - - static Dictionary projects = new Dictionary (); - protected static ProjectInfo [] GetExecutableProjects (string org, string repo, string hash, string default_branch) - { - if (!projects.TryGetValue (repo, out var rv)) { - var project_paths = GitHub.GetProjects (org, repo, hash, default_branch); - - // We can filter out project we don't care about. - rv = project_paths. - Select ((v) => GetProjectInfo (v, Path.Combine (GitHub.CloneRepository (org, repo, hash, default_branch, false), v))). - Where ((v) => v.IsApplicable (false)). - ToArray (); - - projects [repo] = rv; - } - return rv; - } - - protected static IEnumerable GetSampleTestData (Dictionary samples, string org, string repo, string hash, string default_branch, TimeSpan timeout) - { - var defaultDebugConfigurations = new string [] { "Debug" }; - var defaultReleaseConfigurations = new string [] { "Release" }; - - if (samples is null) { - samples = new Dictionary (); - } else { - samples = new Dictionary (samples); - } - - // If a project's filename is unique in this repo, use the filename (without extension) as the name of the test. - // Otherwise use the project's relative path. - var executable_projects = GetExecutableProjects (org, repo, hash, default_branch); - var duplicateProjects = executable_projects.GroupBy ((v) => Path.GetFileNameWithoutExtension (v.RelativePath)).Where ((v) => v.Count () > 1); - foreach (var group in duplicateProjects) { - foreach (var proj in group) { - proj.Title = proj.RelativePath; - } - } - foreach (var proj in executable_projects) { - if (proj.Title is null) { - proj.Title = Path.GetFileNameWithoutExtension (proj.RelativePath); - } - } - - var platform_filter = Environment.GetEnvironmentVariable ("TEST_PLATFORM_FILTER_EXPRESSION"); - var config_filter = Environment.GetEnvironmentVariable ("TEST_CONFIG_FILTER_EXPRESSION"); - var name_filter = Environment.GetEnvironmentVariable ("TEST_NAME_FILTER_EXPRESSION"); - - IEnumerable filter (string name, string proj, IEnumerable input, string filter_expression, Func tostring) - { - if (string.IsNullOrEmpty (filter_expression)) - return input; - - var filtered = input.Where ((v) => Regex.IsMatch (tostring (v), filter_expression)); - var removed = input.Where ((v) => !filtered.Contains (v)); - if (removed.Any ()) { - return filtered; - } - return input; - } - - // Create the test variations for each project. - foreach (var proj in filter ("name", "*", executable_projects, name_filter, (v) => Path.GetFileName (v.RelativePath))) { - if (!samples.TryGetValue (proj.RelativePath, out var sample)) - samples [proj.RelativePath] = sample = new SampleTest (); - sample.Project = proj; - IEnumerable platforms = sample.Platforms; - if (platforms is null) { - switch (proj.Platform) { - case TestPlatform.iOS: - case TestPlatform.tvOS: - platforms = new string [] { "iPhone", "iPhoneSimulator" }; - break; - case TestPlatform.macOS: - platforms = new string [] { "" }; - break; - case TestPlatform.watchOS: - default: - throw new NotImplementedException (proj.Platform.ToString ()); - } - } - - foreach (var platform in filter ("platform", proj.Title, platforms, platform_filter, (v) => v)) { - var configs = new List (); - configs.AddRange (sample.DebugConfigurations ?? defaultDebugConfigurations); - configs.AddRange (sample.ReleaseConfigurations ?? defaultReleaseConfigurations); - foreach (var config in filter ("config", proj.Title, configs, config_filter, (v) => v)) { - yield return new SampleTestData { SampleTest = sample, Configuration = config, Platform = platform, Timeout = timeout }; - } - } - } - } - - string CloneRepo () - { - return GitHub.CloneRepository (Org, Repository, Hash, DefaultBranch); - } - } - - [TestFixture] - public class BaselineTester { - [Test] - public void DeviceDebug () - { - var sln = Path.Combine (Configuration.SourceRoot, "tests", "sampletester", "BaselineTest", "BaselineTest.sln"); - GitHub.CleanRepository (Path.GetDirectoryName (sln)); - ProcessHelper.BuildSolution (sln, "iPhone", "Debug", SampleTester.GetEnvironmentVariables (TestPlatform.iOS), SampleTester.DefaultTimeout); - } - - } -} diff --git a/tests/sampletester/Samples.cs b/tests/sampletester/Samples.cs deleted file mode 100644 index 31c59cc77e63..000000000000 --- a/tests/sampletester/Samples.cs +++ /dev/null @@ -1,254 +0,0 @@ -using System; -using System.Collections.Generic; - -using NUnit.Framework; - -namespace Samples { - [Category (CATEGORY)] - public class IosSampleTester : SampleTester { - const string ORG = "xamarin"; - const string REPO = "ios-samples"; // monotouch-samples redirects to ios-samples - const string CATEGORY = "iossamples"; // categories can't contain dashes - const string HASH = "0a6947d766ad71a711b62e10c2eee08b411057e4"; - const string DEFAULT_BRANCH = "main"; - - static Dictionary test_data = new Dictionary { - // Build solution instead of csproj - { "BindingSample/XMBindingLibrarySample/XMBindingLibrarySample.csproj", new SampleTest { BuildSolution = true, Solution = "BindingSample/BindingSample.sln" } }, - { "BouncingGameCompleteiOS/BouncingGame.iOS/BouncingGame.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "BouncingGameCompleteiOS/BouncingGame.sln" } }, - { "BouncingGameEmptyiOS/BouncingGame.iOS/BouncingGame.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "BouncingGameEmptyiOS/BouncingGame.sln" } }, - { "FileSystemSampleCode/FileSystem/FileSystem.csproj", new SampleTest { BuildSolution = true, Solution = "FileSystemSampleCode/WorkingWithTheFileSystem.sln" } }, - { "InfColorPicker/InfColorPickerBinding/InfColorPickerSample/InfColorPickerSample.csproj", new SampleTest { BuildSolution = true, Solution = "InfColorPicker/InfColorPickerBinding/InfColorPickerBinding.sln" } }, - { "ios10/ElizaChat/ElizaChat/ElizaChat.csproj", new SampleTest { BuildSolution = true, Solution = "ios10/ElizaChat/ElizaChat.sln" } }, - { "ios10/IceCreamBuilder/IceCreamBuilder/IceCreamBuilder.csproj", new SampleTest { BuildSolution = true, Solution = "ios10/IceCreamBuilder/IceCreamBuilder.sln" } }, - { "ios11/ARKitPlacingObjects/PlacingObjects/PlacingObjects.csproj", new SampleTest { BuildSolution = true, Solution = "ios11/ARKitPlacingObjects/PlacingObjects.sln" } }, - { "ios11/WeatherWidget/WeatherWidget/WeatherWidget.csproj", new SampleTest { BuildSolution = true, Solution = "ios11/WeatherWidget/WeatherWidget.sln" } }, - { "ios12/SoupChef/SoupChef/SoupChef.csproj", new SampleTest { BuildSolution = true, Solution = "ios12/SoupChef/SoupChef.sln" } }, - { "ios12/XamarinShot/XamarinShot/XamarinShot.csproj", new SampleTest { BuildSolution = true, Solution = "ios12/XamarinShot/XamarinShot.sln", Platforms = new string [] { "iPhone" } } }, // Requires Metal, which doesn't work/build in the simulator. - { "ios8/Lister/Lister/Lister.csproj", new SampleTest { BuildSolution = true, Solution = "ios8/Lister/Lister.sln" } }, - { "ios8/MetalBasic3D/MetalBasic3D/MetalBasic3D.csproj", new SampleTest { Platforms = new string [] { "iPhone" } } }, // Requires Metal, which doesn't work/build in the simulator. - { "ios8/MetalImageProcessing/MetalImageProcessing/MetalImageProcessing.csproj", new SampleTest { Platforms = new string [] { "iPhone" } } }, // Requires Metal, which doesn't work/build in the simulator. - { "ios8/MetalTexturedQuad/MetalTexturedQuad/MetalTexturedQuad.csproj", new SampleTest { Platforms = new string [] { "iPhone" } } }, // Requires Metal, which doesn't work/build in the simulator. - { "ios9/iTravel/iTravel/iTravel.csproj", new SampleTest { BuildSolution = true, Solution = "ios9/iTravel/iTravel.sln" } }, - { "Profiling/MemoryDemo/MemoryDemo/MemoryDemo.csproj", new SampleTest { BuildSolution = true, Solution = "Profiling/MemoryDemo/MemoryDemo.sln", DebugConfigurations = new string [] { "Before-Debug", "After-Debug" }, ReleaseConfigurations = new string [] { "Before-Release", "After-Release" } } }, - { "WalkingGameCompleteiOS/WalkingGame.iOS/WalkingGame.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "WalkingGameCompleteiOS/WalkingGame.sln" } }, - { "WalkingGameEmptyiOS/WalkingGame.iOS/WalkingGame.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "WalkingGameEmptyiOS/WalkingGame.sln" } }, - { "watchOS/WatchConnectivity/WatchConnectivity/WatchConnectivity.csproj", new SampleTest { BuildSolution = true, Solution = "watchOS/WatchConnectivity/WatchConnectivity.sln" } }, - { "watchOS/WatchKitCatalog/WatchKitCatalog/WatchKitCatalog.csproj", new SampleTest { BuildSolution = true, Solution = "watchOS/WatchKitCatalog/WatchKitCatalog.sln" } }, - - // known failures - { "ios9/Emporium/Emporium/Emporium.csproj", new SampleTest { BuildSolution = true, Solution = "ios9/Emporium/Emporium.sln", KnownFailure = "error : Xcode 10 does not support watchOS 1 apps. Either upgrade to watchOS 2 apps, or use an older version of Xcode." } }, - { "WatchKit/GpsWatch/GpsWatch/MainApp.csproj", new SampleTest { KnownFailure = "error : Xcode 10 does not support watchOS 1 apps. Either upgrade to watchOS 2 apps, or use an older version of Xcode." } }, - { "WatchKit/WatchNotifications/WatchNotifications_iOS/WatchNotifications_iOS.csproj", new SampleTest { KnownFailure = "error : Xcode 10 does not support watchOS 1 apps. Either upgrade to watchOS 2 apps, or use an older version of Xcode." } }, - { "PassKit/PassLibrary/PassLibrary.csproj", new SampleTest { BuildSolution = true, Solution = "PassKit/PassLibrary/PassLibrary.sln", KnownFailure = "Requires custom provisioning to get a proper pass." } }, - - }; - - static IEnumerable GetSampleData () - { - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, DefaultTimeout); - } - } - - [Category (CATEGORY)] - public class MacIosSampleTester : SampleTester { - const string ORG = "xamarin"; - const string REPO = "mac-ios-samples"; - const string CATEGORY = "maciossamples"; // categories can't contain dashes - const string HASH = "2ab4faf9254cecdf5766af573e508f9ac8691663"; - const string DEFAULT_BRANCH = "main"; - - static Dictionary test_data = new Dictionary { - // Build solution instead of csproj - { "ExceptionMarshaling/ExceptionMarshaling.Mac.csproj", new SampleTest { BuildSolution = true, Solution = "ExceptionMarshaling/ExceptionMarshaling.sln" } }, - { "Fox2/Fox2.macOS/Fox2.macOS.csproj", new SampleTest { BuildSolution = true, Solution = "Fox2/Fox2.sln" } }, - { "MetalKitEssentials/MetalKitEssentials.iOS/MetalKitEssentials.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "MetalKitEssentials/MetalKitEssentials.sln", Platforms = new string [] { "iPhone" } } }, // Requires Metal, which doesn't work/build in the simulator. - { "SceneKitReel/SceneKitReelMac/SceneKitReelMac.csproj", new SampleTest { BuildSolution = true, Solution = "SceneKitReel/SceneKitReel.sln" } }, - }; - - static IEnumerable GetSampleData () - { - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, DefaultTimeout); - } - } - - [Category (CATEGORY)] - public class MacSampleTester : SampleTester { - const string ORG = "xamarin"; - const string REPO = "mac-samples"; - const string CATEGORY = "macsamples"; // categories can't contain dashes - const string HASH = "6f905972c98e64759ff84a25e4e2b42366fa197b"; - const string DEFAULT_BRANCH = "main"; - - static Dictionary test_data = new Dictionary { - // Known failures - { "QTRecorder/QTRecorder.csproj", new SampleTest { KnownFailure = "The sample uses deprecated QTKit types (and .xib fails building)." } }, - { "StillMotion/StillMotion/StillMotion.csproj", new SampleTest { KnownFailure = "The sample uses deprecated QTKit types (and .xib fails building)." } }, - }; - - static IEnumerable GetSampleData () - { - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, DefaultTimeout); - } - } - - [Category (CATEGORY)] - public class MobileSampleTester : SampleTester { - const string ORG = "xamarin"; - const string REPO = "mobile-samples"; - const string CATEGORY = "mobilesamples"; // categories can't contain dashes - const string HASH = "257f7fe81e70b412d6a6b42e97019ecc2c46ed40"; - const string DEFAULT_BRANCH = "master"; - - static Dictionary test_data = new Dictionary { - // Build solution instead of csproj - { "BouncingGame/BouncingGame/BouncingGame.iOS/BouncingGame.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "BouncingGame/BouncingGame.sln" } }, - { "CCAction/ActionProject/ActionProject.iOS/ActionProject.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "CCAction/ActionProject.sln" } }, - { "CCRenderTexture/RenderTextureExample/RenderTextureExample.iOS/RenderTextureExample.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "CCRenderTexture/RenderTextureExample.sln" } }, - { "EmbeddedResources/EmbeddedResources/EmbeddedResources.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "EmbeddedResources/EmbeddedResources.sln" } }, - { "FruityFalls/FruityFalls/FruityFalls.iOS/FruityFalls.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "FruityFalls/FruityFalls.sln" } }, - { "LivePlayer/BasicCalculator/Calculator.iOS/Calculator.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "LivePlayer/BasicCalculator/Calculator.sln" } }, - { "MonoGameTvOs/MonoGameTvOs/MonoGameTvOs.csproj", new SampleTest { BuildSolution = true, Solution = "MonoGameTvOs/MonoGameTvOs.sln" } }, - { "SpriteSheetDemo/iOS/SpriteSheetDemo.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "SpriteSheetDemo/SpriteSheetDemo.sln" } }, - { "TaskyPortable/TaskyiOS/TaskyiOS.csproj", new SampleTest { BuildSolution = true, Solution = "TaskyPortable/TaskyPortable.sln" } }, - { "TipCalc/TipCalc-UI-iOS/TipCalc-UI-iOS.csproj", new SampleTest { BuildSolution = true, Solution = "TipCalc/TipCalc.sln" } }, - - // Known failures - { "RazorTodo/RazorNativeTodo/RazorNativeTodo.iOS/RazorNativeTodo.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "RazorTodo/RazorNativeTodo/RazorNativeTodo.sln", KnownFailure = "There's a Xamarin.Android project in the solution, and I can't figure out how to build only the Xamarin.iOS project." } }, - { "RazorTodo/RazorTodo/RazorTodo.iOS/RazorTodo.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "RazorTodo/RazorTodo/RazorTodo.sln", KnownFailure = "There's a Xamarin.Android project in the solution, and I can't figure out how to build only the Xamarin.iOS project." } }, - { "VisualBasic/TaskyPortableVB/TaskyiOS/TaskyiOS.csproj", new SampleTest { KnownFailure = "VisualBasic not supported on macOS: error MSB4057: The target \"Build\" does not exist in the project." } }, - { "VisualBasic/XamarinFormsVB/XamarinForms.iOS/XamarinForms.iOS.csproj", new SampleTest { KnownFailure = "VisualBasic not supported on macOS." } }, - { "WebServices/WebServiceSamples/WebServices.RxNorm/src/WebServices.RxNormSample/WebServices.RxNormSample.csproj", new SampleTest { KnownFailure = "Xamarin.iOS Classic isn't supported anymore." } }, - }; - - static IEnumerable GetSampleData () - { - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, DefaultTimeout); - } - } - - [Category (CATEGORY)] - public class PrebuiltAppTester : SampleTester { - const string ORG = "xamarin"; - const string REPO = "prebuilt-apps"; - const string CATEGORY = "prebuiltapps"; // categories can't contain dashes - const string HASH = "f111672bc6915ceb402abb47dedfe3480e111720"; - const string DEFAULT_BRANCH = "master"; - - static Dictionary test_data = new Dictionary { - // Known failures - { "FieldService/FieldService.iOS/FieldService.iOS.csproj", new SampleTest { KnownFailure = "The sample uses Xamarin Components which don't work anymore." } }, - }; - - static IEnumerable GetSampleData () - { - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, DefaultTimeout); - } - } - - [Category (CATEGORY)] - public class XamarinFormsTester : SampleTester { - const string ORG = "xamarin"; - const string REPO = "xamarin-forms-samples"; - const string CATEGORY = "xamarinformssamples"; // categories can't contain dashes - const string HASH = "d196d3f7ba418d06ef799074eb4f6120e26a9cf4"; - const string DEFAULT_BRANCH = "master"; - - static Dictionary test_data = new Dictionary { - // avoid building unneeded projects since they require a lot of nuget packages (and cause a lot of unrelated/network build issues) - { "WebServices/TodoREST/iOS/TodoREST.iOS.csproj", new SampleTest { Solution = "WebServices/TodoREST/TodoREST.sln", RemoveProjects = new [] { "TodoAPI", "TodoREST.Droid" } } }, - { "WorkingWithMaps/iOS/WorkingWithMaps.iOS.csproj", new SampleTest { Solution = "WorkingWithMaps/WorkingWithMaps.sln", RemoveProjects = new [] { "WorkingWithMaps.Android", "WorkingWithMaps.UWP" } } }, - // Build solution instead of csproj. - { "WebServices/TodoWCF/iOS/TodoWCF.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "WebServices/TodoWCF/TodoWCF.sln" } }, - }; - - static IEnumerable GetSampleData () - { - // Samples.XamarinFormsTester.BuildSample(MarkupExtensions.iOS: Debug|iPhone) needs some extra time 10 minutes - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, TimeSpan.FromMinutes (10)); - } - } - - [Category (CATEGORY)] - public class XamarinFormsBooksTester : SampleTester { - const string ORG = "xamarin"; - const string REPO = "xamarin-forms-book-samples"; - const string CATEGORY = "xamarinformsbookssamples"; // categories can't contain dashes - const string HASH = "c215bab3324d77e13bd80a0c20e60786d2bd344b"; - const string DEFAULT_BRANCH = "master"; - - static Dictionary test_data = new Dictionary { - // Build solution instead of csproj, - { "Chapter20/TextFileAsync/TextFileAsync/TextFileAsync.iOS/TextFileAsync.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "Chapter20/TextFileAsync/TextFileAsync.sln" } }, - { "Chapter24/NoteTaker/NoteTaker/NoteTaker.iOS/NoteTaker.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "Chapter24/NoteTaker/NoteTaker.sln" } }, - { "Chapter27/BouncingBall/BouncingBall/BouncingBall.iOS/BouncingBall.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "Chapter27/BouncingBall/BouncingBall.sln" } }, - { "Chapter27/EllipseDemo/EllipseDemo/EllipseDemo.iOS/EllipseDemo.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "Chapter27/EllipseDemo/EllipseDemo.sln" } }, - { "Chapter27/StepSliderDemo/StepSliderDemo/StepSliderDemo.iOS/StepSliderDemo.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "Chapter27/StepSliderDemo/StepSliderDemo.sln" } }, - { "Chapter28/MapDemos/MapDemos/MapDemos.iOS/MapDemos.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "Chapter28/MapDemos/MapDemos.sln" } }, - { "Chapter28/WhereAmI/WhereAmI/WhereAmI.iOS/WhereAmI.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "Chapter28/WhereAmI/WhereAmI.sln" } }, - }; - - static IEnumerable GetSampleData () - { - // Samples.XamarinFormsBooksTester.BuildSample(FormattedTextToggle.iOS: Release|iPhone) needs some extra time 10 minutes - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, TimeSpan.FromMinutes (10)); - } - } - - [Category (CATEGORY)] - public class EmbeddedFrameworksTester : SampleTester { - const string ORG = "rolfbjarne"; - const string REPO = "embedded-frameworks"; - const string CATEGORY = "embeddedframeworks"; // categories can't contain dashes - const string HASH = "faaad6f9dcda53b2c49cec567eca769cb534307f"; - const string DEFAULT_BRANCH = "main"; - - static Dictionary test_data = new Dictionary { - // Known failures - { "simpleapp-with-framework/simpleapp-with-framework/simpleapp-with-framework.csproj", new SampleTest { BuildSolution = true, Solution = "simpleapp-with-framework/simpleapp-with-framework.sln" } }, - }; - - static IEnumerable GetSampleData () - { - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, DefaultTimeout); - } - } - - [Category (CATEGORY)] - public class XappyTester : SampleTester { - const string ORG = "davidortinau"; - const string REPO = "Xappy"; - const string CATEGORY = "davidortinauxappy"; // categories can't contain dashes - const string HASH = "46e5897bac974e000fcc7e1d10d01ab8d3072eb2"; - const string DEFAULT_BRANCH = "master"; - - static Dictionary test_data = new Dictionary { - { "Xappy/Xappy.iOS/Xappy.iOS.csproj", new SampleTest { BuildSolution = true, Solution = "Xappy.sln", RemoveProjects = new [] { "Xappy.Android", "Xappy.UWP" } } }, - }; - - static IEnumerable GetSampleData () - { - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, DefaultTimeout); - } - } - - [Category (CATEGORY)] - public class SmartHotelTester : SampleTester { - const string ORG = "microsoft"; - const string REPO = "SmartHotel360-Mobile"; - const string CATEGORY = "microsoftsmarthotel"; // categories can't contain dashes - const string HASH = "4004b32c955f8340a0306bad2b180ecf5adaf117"; - const string DEFAULT_BRANCH = "master"; - - static Dictionary test_data = new Dictionary { - // Override CodesignKey key - { "Source/SmartHotel.Clients/SmartHotel.Clients.iOS/SmartHotel.Clients.iOS.csproj", new SampleTest { CodesignKey = "iPhone Developer" } }, - { "Source/SmartHotel.Clients.Maintenance/SmartHotel.Clients.Maintenance.iOS/SmartHotel.Clients.Maintenance.iOS.csproj", new SampleTest { CodesignKey = "iPhone Developer" } }, - }; - - static IEnumerable GetSampleData () - { - return GetSampleTestData (test_data, ORG, REPO, HASH, DEFAULT_BRANCH, timeout: TimeSpan.FromMinutes (10)); - } - } -} diff --git a/tests/sampletester/TestPlatform.cs b/tests/sampletester/TestPlatform.cs deleted file mode 100644 index 86f907489996..000000000000 --- a/tests/sampletester/TestPlatform.cs +++ /dev/null @@ -1,7 +0,0 @@ -public enum TestPlatform { - None, - iOS, - macOS, - watchOS, - tvOS, -} diff --git a/tests/sampletester/images/provision_from_commit.png b/tests/sampletester/images/provision_from_commit.png deleted file mode 100644 index b41db7250740d904a0f6635193186d4768c6bc09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99793 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 - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62} - Library - sampletester - sampletester - v4.7.2 - latest - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - - - true - bin\Release - prompt - 4 - - - - - - - - - - - - - - - - - external\Cache.cs - - - external\StringUtils.cs - - - external\Configuration.cs - - - external\Profile.cs - - - external\ExecutionHelper.cs - - - - - external\Execution.cs - - - external\ApplePlatform.cs - - - external\SdkVersions.cs - - - external\TargetFramework.cs - - - - - - - \ No newline at end of file diff --git a/tests/sampletester/sampletester.sln b/tests/sampletester/sampletester.sln deleted file mode 100644 index 42f569df45cc..000000000000 --- a/tests/sampletester/sampletester.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sampletester", "sampletester.csproj", "{7340A1C6-61A5-42D2-9DBC-6688D2E70F62}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Release|Any CPU.Build.0 = Release|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Debug|iPhone.Build.0 = Debug|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Release|iPhone.ActiveCfg = Release|Any CPU - {7340A1C6-61A5-42D2-9DBC-6688D2E70F62}.Release|iPhone.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/tools/devops/automation/scripts/TestResults.Tests.ps1 b/tools/devops/automation/scripts/TestResults.Tests.ps1 index e3e47a2ff656..f73f03020875 100644 --- a/tools/devops/automation/scripts/TestResults.Tests.ps1 +++ b/tools/devops/automation/scripts/TestResults.Tests.ps1 @@ -212,7 +212,6 @@ Describe "TestResults tests" { "configuration.BuildNugets": "True", "configuration.BuildPkgs": "True", "configuration.PR_ID": "20434", - "configuration.RunSampleTests": "", "configuration.SignPkgs": "True", "build.TESTS_BOT": "XAMBOT-1001.Sonoma" }, diff --git a/tools/devops/automation/scripts/VSTS.psm1 b/tools/devops/automation/scripts/VSTS.psm1 index 655df55a6600..716e2f070986 100644 --- a/tools/devops/automation/scripts/VSTS.psm1 +++ b/tools/devops/automation/scripts/VSTS.psm1 @@ -302,7 +302,6 @@ class BuildConfiguration { "skip-packages", "skip-nugets", "skip-signing", - "run-sample-tests", "skip-packaged-macos-tests", "run-packaged-macos-tests", "skip-api-comparison", diff --git a/tools/devops/automation/scripts/parse_pr_labels.ps1 b/tools/devops/automation/scripts/parse_pr_labels.ps1 index b637e99e4df4..eb730c236dc8 100644 --- a/tools/devops/automation/scripts/parse_pr_labels.ps1 +++ b/tools/devops/automation/scripts/parse_pr_labels.ps1 @@ -46,17 +46,12 @@ if ($BuildReason -eq "PullRequest" -or (($BuildReason -eq "Manual" -or $BuildRea $configVars.Add("SignPkgs", "True") } - $configVars.Add("RunSampleTests", $Env:RunSampleTests) - } else { # set the defaults, all the things! o/ # build pkg, nugets and sign them $configVars.Add("BuildPkgs", "True") $configVars.Add("BuildNugets", "True") $configVars.Add("SignPkgs", "True") - - # tests, run all of them, internal, external, mac but not sample tests - $configVars.Add("RunSampleTests", "False") } # write debugging and process of the vars foreach($key in $configVars.Keys) { diff --git a/tools/devops/automation/templates/build/build-stage.yml b/tools/devops/automation/templates/build/build-stage.yml index 8970b68b71e8..950196987a92 100644 --- a/tools/devops/automation/templates/build/build-stage.yml +++ b/tools/devops/automation/templates/build/build-stage.yml @@ -68,12 +68,10 @@ jobs: # skip-packages # skip-nugets # skip-signing - # run-sample-tests BuildPackage: $[ stageDependencies.configure_build.configure.outputs['labels.build_package'] ] SkipPackages: $[ stageDependencies.configure_build.configure.outputs['labels.skip_packages'] ] SkipNugets: $[ stageDependencies.configure_build.configure.outputs['labels.skip_nugets'] ] SkipSigning: $[ stageDependencies.configure_build.configure.outputs['labels.skip_signing'] ] - RunSampleTests: $[ stageDependencies.configure_build.configure.outputs['labels.run_sample_tests'] ] SkipApiComparison: $[ stageDependencies.configure_build.configure.outputs['labels.skip_api_comparison'] ] # old and ugly env var use by jenkins, we do have parts of the code that use it, contains the PR number PR_ID: $[ stageDependencies.configure_build.configure.outputs['labels.pr_number'] ] diff --git a/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml b/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml index bfa780b0c41e..1fde3871aaa4 100644 --- a/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml +++ b/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml @@ -45,11 +45,6 @@ parameters: type: boolean default: true - - name: runSamples - displayName: Run Samples - type: boolean - default: false - - name: testConfigurations displayName: Test configurations to run type: object @@ -128,7 +123,6 @@ stages: runTests: ${{ parameters.runTests }} runDeviceTests: ${{ parameters.runDeviceTests }} runWindowsIntegration: ${{ parameters.runWindowsIntegration }} - runSamples: ${{ parameters.runSamples }} ${{ if ne(length(parameters.testConfigurations), 0)}}: testConfigurations: ${{ parameters.testConfigurations }} deviceTestsConfigurations: ${{ parameters.deviceTestsConfigurations }} diff --git a/tools/devops/automation/templates/tests-stage.yml b/tools/devops/automation/templates/tests-stage.yml index 94d8f1c2dfc3..e54a23ee9cd7 100644 --- a/tools/devops/automation/templates/tests-stage.yml +++ b/tools/devops/automation/templates/tests-stage.yml @@ -24,10 +24,6 @@ parameters: type: boolean default: true -- name: runSamples - type: boolean - default: false - - name: isPR type: boolean @@ -271,20 +267,3 @@ stages: gitHubToken: $(Github.Token) xqaCertPass: $(xqa--certificates--password) postPipeline: true - -- ${{ if eq(parameters.runSamples, true) }}: - # TODO: Not the real step - - stage: sample_testing - displayName: '${{ stageDisplayNamePrefix }}Sample testing' - dependsOn: - - build_packages - condition: and(succeeded(), contains (stageDependencies.build_packages.build.outputs['configuration.RunSampleTests'], 'True')) - jobs: - - job: sample_testing - pool: - vmImage: ubuntu-latest - steps: - # TODO: do parse labels - - bash: | - echo "Samples!" - displayName: 'Sample testing' diff --git a/tools/devops/build-samples-report-to-github.sh b/tools/devops/build-samples-report-to-github.sh deleted file mode 100755 index 024c6d9580b5..000000000000 --- a/tools/devops/build-samples-report-to-github.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -ex - -# This script takes -# First argument: the github token to authenticate with -# Subsequent arguments: the names of each test variation in the test matrix. -# There is a corresponding environment variable with the result from each test variation. - - -# Print environment for debugging -env | sort - -TOKEN=$1 -shift 1 -STEPS="$*" - -EMOJII="✅" -GH_STATE=success -FILE=commit-comment.md - -for STEP in $STEPS; do - # The environment variable's name is the variation name in uppercase, and special symbols removed (|-_) - STEPNAME=JOBRESULT$(echo "$STEP" | tr '[:lower:]' '[:upper:]' | sed -e 's/|//g' -e 's/-//g' -e 's/_//g') - STEPSTATUS=${!STEPNAME} - if [[ "$STEPSTATUS" == "Succeeded" ]]; then - STEPEMOJII="✅" - else - STEPEMOJII="❌" - EMOJII="❌" - GH_STATE=failure - fi - echo "* $STEPEMOJII $STEP: $STEPSTATUS" >> "$FILE" -done - -printf "%s\n\n" "$EMOJII Status for '$BUILD_DEFINITIONNAME': [$GH_STATE]($AZURE_BUILD_URL)." | cat - "$FILE" > "$FILE.tmp" -mv "$FILE.tmp" "$FILE" - -./jenkins/add-commit-comment.sh "--token=$TOKEN" "--hash=$BUILD_SOURCEVERSION" "--file=$FILE" -./jenkins/add-commit-status.sh "--token=$TOKEN" "--hash=$BUILD_SOURCEVERSION" "--state=$GH_STATE" --target-url="$AZURE_BUILD_URL" --description="$BUILD_DEFINITIONNAME" --context="$BUILD_DEFINITIONNAME" -rm -f "$FILE" diff --git a/tools/devops/build-samples.csx b/tools/devops/build-samples.csx deleted file mode 100644 index cf183145e875..000000000000 --- a/tools/devops/build-samples.csx +++ /dev/null @@ -1,57 +0,0 @@ -#load "utils.csx" - -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading.Tasks; - -using Newtonsoft.Json.Linq; - -using Xamarin.Provisioning; -using Xamarin.Provisioning.Model; - -// Provision Mono, Mono, Objective-Sharpie, provisioning profiles. -// -// We get Mono from the current commit's MIN_MONO_URL value in Make.config -// -// Overrides: -// * Each download URL can be overriden by setting an environment variable (MIN_MONO_URL). -// * The current commit can be overridden by setting the PROVISION_FROM_COMMIT variable. This is usually easier than overriding each url. - -var commit = Environment.GetEnvironmentVariable ("BUILD_SOURCEVERSION"); -var provision_from_commit = Environment.GetEnvironmentVariable ("PROVISION_FROM_COMMIT") ?? commit; - -string FindVariable (string variable, bool throwIfNotFound = true) -{ - var value = FindConfigurationVariable (variable, provision_from_commit); - if (!string.IsNullOrEmpty (value)) - return value; - - if (!string.IsNullOrEmpty (value)) - return value; - - if (!throwIfNotFound) - return null; - - throw new Exception ($"Could not find {variable} in environment nor in the commit's ({commit}) manifest."); -} - -if (string.IsNullOrEmpty (provision_from_commit)) { - Console.Error.WriteLine ($"Either BUILD_SOURCEVERSION or PROVISION_FROM_COMMIT must be set."); - Environment.Exit (1); - return 1; -} -Console.WriteLine ($"Provisioning from {provision_from_commit}..."); - -InstallPackage ("Mono", FindVariable ("MIN_MONO_URL")); -InstallPackage ("Objective-Sharpie", FindVariable ("MIN_SHARPIE_URL")); - -// Provisioning profiles -Console.WriteLine ("Provisioning provisioning profiles..."); -Exec ($"../../../maccore/tools/install-qa-provisioning-profiles.sh"); - -// .NET core -// The version number here must match the one in Xamarin.Tests.Configuration:CreateGlobalConfig (tests/sampletester/Configuration.cs). -DotNetCoreSdk ("2.2.204"); diff --git a/tools/devops/build-samples.sh b/tools/devops/build-samples.sh deleted file mode 100755 index 50e3b95b87eb..000000000000 --- a/tools/devops/build-samples.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -eux - -cd "$(dirname "${BASH_SOURCE[0]}")/../.." - -make -C tests test-system.config -make -C tests/sampletester TESTS_USE_SYSTEM=1 \ No newline at end of file diff --git a/tools/devops/build-samples.yml b/tools/devops/build-samples.yml deleted file mode 100644 index dacde1aa5796..000000000000 --- a/tools/devops/build-samples.yml +++ /dev/null @@ -1,231 +0,0 @@ -# Xamarin -# Build samples - -variables: - azure_build_url: '$(System.CollectionUri)/$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)' - azpPoolName: 'Azure Pipelines' - macOSVersion: 'internal-macos-11' - debug_filter: '^.*Debug.*$' - release_filter: '^.*Release.*$' - iphone_filter: '^iPhone$' - iphonesimulator_filter: '^iPhoneSimulator$' - mac_platform_filter: '^$' - name_filter_af: '^[A-Fa-f].*$' - name_filter_gr: '^[G-Rg-r].*$' - name_filter_rest: '^[^A-Ra-r].*$' - -resources: - repositories: - - repository: xamarin-macios-data - type: github - name: xamarin/xamarin-macios-data - ref: refs/heads/main - endpoint: xamarin - - repository: maccore - type: github - name: xamarin/maccore - ref: refs/heads/main - endpoint: xamarin - -### -### Tell GitHub we're starting working on this commit -### - -jobs: -- job: ReportStartToGitHub - displayName: Set pending GitHub status - pool: - name: '$(azpPoolName)' - vmImage: '$(macOSVersion)' - steps: - - bash: ./jenkins/add-commit-status.sh "--token=$(github-pat)" "--hash=$BUILD_SOURCEVERSION" "--state=pending" --target-url="$AZURE_BUILD_URL" --description="$BUILD_DEFINITIONNAME" --context="$BUILD_DEFINITIONNAME" - displayName: Set pending GitHub status - -### -### Run the sample tests. -### -### They're split over multiple bots to make them run faster (and not hit the -### max job time duration for a single job). -### - -- job: macOS - dependsOn: ReportStartToGitHub - displayName: Build samples - timeoutInMinutes: 360 - strategy: - matrix: - # We have rougly 900 tests, which take a while to build for device. - # So in that case, we split them in 3 buckets of roughly 300 tests each, - # based on the first letter of the project's filename. - Debug_iPhone_AF: - TEST_PLATFORM_FILTER_EXPRESSION: $(iphone_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(debug_filter) - TEST_NAME_FILTER_EXPRESSION: $(name_filter_af) - Debug_iPhone_GR: - TEST_PLATFORM_FILTER_EXPRESSION: $(iphone_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(debug_filter) - TEST_NAME_FILTER_EXPRESSION: $(name_filter_gr) - Debug_iPhone_SZ: - TEST_PLATFORM_FILTER_EXPRESSION: $(iphone_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(debug_filter) - TEST_NAME_FILTER_EXPRESSION: $(name_filter_rest) - Debug_iPhoneSimulator: - TEST_PLATFORM_FILTER_EXPRESSION: $(iphonesimulator_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(debug_filter) - Release_iPhone_AF: - TEST_PLATFORM_FILTER_EXPRESSION: $(iphone_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(release_filter) - TEST_NAME_FILTER_EXPRESSION: $(name_filter_af) - Release_iPhone_GR: - TEST_PLATFORM_FILTER_EXPRESSION: $(iphone_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(release_filter) - TEST_NAME_FILTER_EXPRESSION: $(name_filter_gr) - Release_iPhone_SZ: - TEST_PLATFORM_FILTER_EXPRESSION: $(iphone_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(release_filter) - TEST_NAME_FILTER_EXPRESSION: $(name_filter_rest) - Release_iPhoneSimulator: - TEST_PLATFORM_FILTER_EXPRESSION: $(iphonesimulator_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(release_filter) - Debug_Mac: - TEST_PLATFORM_FILTER_EXPRESSION: $(mac_platform_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(debug_filter) - Release_Mac: - TEST_PLATFORM_FILTER_EXPRESSION: $(mac_platform_filter) - TEST_CONFIG_FILTER_EXPRESSION: $(release_filter) - - pool: - name: '$(azpPoolName)' - vmImage: '$(macOSVersion)' - - steps: - - checkout: self - path: s/xamarin-macios - - checkout: xamarin-macios-data - persistCredentials: true - - checkout: maccore - persistCredentials: true - - - bash: ./xamarin-macios/tools/devops/system-info.sh - displayName: System Info - - - bash: ./xamarin-macios/tools/devops/fetch-maccore.sh - displayName: Fetch correct maccore hash - - - bash: | - echo "Requested Xcode $XCODE_URL" - make -C $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/ provision-xcode.csx - displayName: 'Generate Xcode provisioning csx file' - - - task: provisionator@2 - displayName: Xcode - inputs: - provisionator_uri: '$(provisionator-uri)' - github_token: '$(github-pat)' - provisioning_script: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/provision-xcode.csx - - - task: provisionator@2 - displayName: Provision XI/XM/Mono/Objective-Sharpie - inputs: - provisionator_uri: '$(provisionator-uri)' - github_token: '$(github-pat)' - provisioning_script: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/build-samples.csx - - - bash: ./xamarin-macios/tools/devops/system-info.sh - displayName: System Info post provisioning - - - bash: ./xamarin-macios/tools/devops/build-samples.sh - displayName: Run tests - - - task: PublishTestResults@2 - displayName: Publish test results - condition: always() - inputs: - testResultsFormat: NUnit - testResultsFiles: '**/TestResult*.xml' - testRunTitle: Sample tests (build) - publishRunAttachments: true - mergeTestResults: true - - - bash: ./xamarin-macios/tools/devops/prepare-performance-data.sh - displayName: Prepare performance data - condition: always() - - - publish: logs - displayName: 'Upload perf data' - condition: always() - artifact: logs-$(System.JobId) - - - bash: echo "##vso[task.setvariable variable=JobStatus;isOutput=true]$AGENT_JOBSTATUS" - name: ExportedVariables - displayName: Export status - condition: always() - -### -### Push performance data to the xamarin-macios-data repository -### - -- job: PublishPerformanceData - displayName: Publish Performance Data - condition: always() - dependsOn: macOS - pool: - name: '$(azpPoolName)' - vmImage: '$(macOSVersion)' - steps: - - checkout: self - path: s/xamarin-macios - - checkout: xamarin-macios-data - persistCredentials: true - - - task: DownloadPipelineArtifact@2 - displayName: Download performance data - inputs: - source: current - path: logs - - - bash: ./xamarin-macios/tools/devops/push-performance-data.sh - displayName: Publish perf data - - - bash: echo "##vso[task.setvariable variable=JobStatus;isOutput=true]$AGENT_JOBSTATUS" - name: ExportedVariables - displayName: Export status - condition: always() - -### -### Report final results to GitHub -### - -- job: ReportResultsToGitHub - displayName: Report status/results to GitHub - dependsOn: - - PublishPerformanceData - - macOS - condition: always() - pool: - name: '$(azpPoolName)' - vmImage: '$(macOSVersion)' - variables: - jobResultDebugiPhoneAF: $[ dependencies.macOS.outputs['Debug_iPhone_AF.ExportedVariables.JobStatus'] ] - jobResultDebugiPhoneGR: $[ dependencies.macOS.outputs['Debug_iPhone_GR.ExportedVariables.JobStatus'] ] - jobResultDebugiPhoneSZ: $[ dependencies.macOS.outputs['Debug_iPhone_SZ.ExportedVariables.JobStatus'] ] - jobResultDebugiPhoneSimulator: $[ dependencies.macOS.outputs['Debug_iPhoneSimulator.ExportedVariables.JobStatus'] ] - jobResultReleaseiPhoneAF: $[ dependencies.macOS.outputs['Release_iPhone_AF.ExportedVariables.JobStatus'] ] - jobResultReleaseiPhoneGR: $[ dependencies.macOS.outputs['Release_iPhone_GR.ExportedVariables.JobStatus'] ] - jobResultReleaseiPhoneSZ: $[ dependencies.macOS.outputs['Release_iPhone_SZ.ExportedVariables.JobStatus'] ] - jobResultReleaseiPhoneSimulator: $[ dependencies.macOS.outputs['Release_iPhoneSimulator.ExportedVariables.JobStatus'] ] - jobResultDebugMac: $[ dependencies.macOS.outputs['Debug_Mac.ExportedVariables.JobStatus'] ] - jobResultReleaseMac: $[ dependencies.macOS.outputs['Release_Mac.ExportedVariables.JobStatus'] ] - jobResultPublishPerformanceData: $[ dependencies.PublishPerformanceData.outputs['ExportedVariables.JobStatus'] ] - steps: - - bash: | - ./tools/devops/build-samples-report-to-github.sh "$(github-pat)" \ - "Debug_iPhone_AF" "Debug_iPhone_GR" "Debug_iPhone_SZ" \ - "Debug_iPhoneSimulator" \ - "Release_iPhone_AF" "Release_iPhone_GR" "Release_iPhone_SZ" \ - "Release_iPhoneSimulator" \ - "Debug_Mac" \ - "Release_Mac" \ - "PublishPerformanceData" - displayName: Report results to GitHub as comment / status - condition: always() diff --git a/tools/devops/prepare-performance-data.sh b/tools/devops/prepare-performance-data.sh deleted file mode 100755 index 7d3764d38140..000000000000 --- a/tools/devops/prepare-performance-data.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -ex - -DIR=perf-data/samples/$BUILD_SOURCEBRANCHNAME/$BUILD_SOURCEVERSION/$SYSTEM_JOBID -mkdir -p "$DIR" - -XMLS=(xamarin-macios/tests/sampletester/bin/Debug/tmp-test-dir/execution-logs/*.xml) -if ! test -f "${XMLS[0]}"; then - echo "##vso[task.logissue type=warning]Could not find any performance data to publish" - exit 0 -fi -cp -c xamarin-macios/tests/sampletester/bin/Debug/tmp-test-dir/execution-logs/*.xml "$DIR/" - -mkdir -p logs -zip -9r "logs/execution-logs-$SYSTEM_JOBID.zip" perf-data From 28114fc5ed7c36b2c92abb1a941639b6383bef03 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 25 Sep 2024 17:51:40 +0200 Subject: [PATCH 15/23] [Foundation] NSCoding and NS[Mutable]Copying shouldn't be models. (#21257) It doesn't make sense for NSCoding and NS[Mutable]Copying to be models, so remove those attributes for XAMCORE_5_0. --- src/foundation.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/foundation.cs b/src/foundation.cs index ffc886f09cb9..9397e340eff5 100644 --- a/src/foundation.cs +++ b/src/foundation.cs @@ -2776,8 +2776,10 @@ interface NSFormatter : NSCoding, NSCopying { bool IsPartialStringValid (ref string partialString, out NSRange proposedSelRange, string origString, NSRange origSelRange, [NullAllowed] out string error); } +#if !XAMCORE_5_0 [BaseType (typeof (NSObject))] [Model] +#endif [Protocol] interface NSCoding { // [Abstract] @@ -2794,8 +2796,10 @@ interface NSSecureCoding : NSCoding { // note: +supportsSecureCoding being static it is not a good "generated" binding candidate } +#if !XAMCORE_5_0 [BaseType (typeof (NSObject))] [Model] +#endif [Protocol] interface NSCopying { [Abstract] @@ -2804,8 +2808,10 @@ interface NSCopying { NSObject Copy ([NullAllowed] NSZone zone); } +#if !XAMCORE_5_0 [BaseType (typeof (NSObject))] [Model] +#endif [Protocol] interface NSMutableCopying : NSCopying { [Abstract] From ec50934897ef1b98c1cd73ca780cdf5a3750faaa Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 25 Sep 2024 17:52:20 +0200 Subject: [PATCH 16/23] [src] Turn warnings into errors when compiling API definitions. (#21296) Also fix a couple of compiler warnings: passkit.cs(2797,15): warning CS0109: The member 'PKShareablePassMetadataPreview.PassThumbnailImage' does not hide an accessible member. The new keyword is not required. passkit.cs(2800,14): warning CS0109: The member 'PKShareablePassMetadataPreview.LocalizedDescription' does not hide an accessible member. The new keyword is not required. --- src/Makefile | 2 +- src/passkit.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index d21c1b00fd29..19c2027a39d3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -84,7 +84,7 @@ DOTNET_REFERENCES = \ /r:$(DOTNET_BCL_DIR)/System.Xml.ReaderWriter.dll \ DOTNET_OR_GREATER_DEFINES:=$(foreach version,$(shell seq 6 $(firstword $(subst ., ,$(subst net,,$(DOTNET_TFM))))),/define:NET$(version)_0_OR_GREATER) -DOTNET_FLAGS=/noconfig /nostdlib+ /deterministic /features:strict /nologo /target:library /debug /unsafe /define:NET /define:NET_TODO /define:XAMCORE_3_0 $(DOTNET_OR_GREATER_DEFINES) $(DOTNET_REFERENCES) +DOTNET_FLAGS=/warnaserror+ /noconfig /nostdlib+ /deterministic /features:strict /nologo /target:library /debug /unsafe /define:NET /define:NET_TODO /define:XAMCORE_3_0 $(DOTNET_OR_GREATER_DEFINES) $(DOTNET_REFERENCES) ifeq ($(XCODE_IS_STABLE),true) DOTNET_FLAGS+=/define:XCODE_IS_STABLE diff --git a/src/passkit.cs b/src/passkit.cs index 789f40a8e80c..530a88664221 100644 --- a/src/passkit.cs +++ b/src/passkit.cs @@ -2794,10 +2794,10 @@ interface PKShareablePassMetadataPreview // : NSCoding, NSCopying, NSSecureCodin PKShareablePassMetadataPreview PreviewWithTemplateIdentifier (string templateIdentifier); [NullAllowed, Export ("passThumbnailImage", ArgumentSemantic.Assign)] - new CGImage PassThumbnailImage { get; } + CGImage PassThumbnailImage { get; } [NullAllowed, Export ("localizedDescription", ArgumentSemantic.Strong)] - new string LocalizedDescription { get; } + string LocalizedDescription { get; } [NullAllowed, Export ("ownerDisplayName", ArgumentSemantic.Strong)] string OwnerDisplayName { get; set; } From 1850ef907c30e8809646eea9488b6fd8e5597ead Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 25 Sep 2024 19:02:38 +0200 Subject: [PATCH 17/23] [monotouch-test] Update usage of X509 API obsoleted in .NET 9. --- tests/monotouch-test/System.Net.Http/MessageHandlers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/monotouch-test/System.Net.Http/MessageHandlers.cs b/tests/monotouch-test/System.Net.Http/MessageHandlers.cs index db4134ece428..487ab0db12d0 100644 --- a/tests/monotouch-test/System.Net.Http/MessageHandlers.cs +++ b/tests/monotouch-test/System.Net.Http/MessageHandlers.cs @@ -703,7 +703,7 @@ public void TestNSUrlSessionHandlerSendClientCertificate () Assert.Inconclusive ("Request timedout."); } else { Assert.IsNull (ex, "Exception wasn't expected."); - X509Certificate2 certificate2 = X509CertificateLoader.LoadPkcs12 (global::System.Convert.FromBase64String (content), null); + X509Certificate2 certificate2 = X509CertificateLoader.LoadCertificate (global::System.Convert.FromBase64String (content)); Assert.AreEqual (certificate.Thumbprint, certificate2.Thumbprint); } } From 515f110699a1da1c56ada9bdda2fe35beb926b5a Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 25 Sep 2024 20:46:03 +0200 Subject: [PATCH 18/23] [net9.0] Bump to rtm. --- Make.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Make.config b/Make.config index c61e69ace7d2..74415d17d63c 100644 --- a/Make.config +++ b/Make.config @@ -140,7 +140,7 @@ endif ## ## Note that the prerelease identifier should be as short as possible, because otherwise ## the resulting package name can become too long for MSIs. -NUGET_HARDCODED_PRERELEASE_IDENTIFIER=net9-rc2 +NUGET_HARDCODED_PRERELEASE_IDENTIFIER=net9-rtm NUGET_HARDCODED_PRERELEASE_BRANCH=net9.0 # compute the alphanumeric version of branch names From ca9419af818614efc7b2a04b404e2a121ef710e5 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Wed, 25 Sep 2024 20:46:22 -0400 Subject: [PATCH 19/23] [CI] Add missing configuration stage for the macos tests pipeline. (#21303) --- .../devops/automation/templates/mac/stage.yml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tools/devops/automation/templates/mac/stage.yml b/tools/devops/automation/templates/mac/stage.yml index e2629e587a5a..31e0e1e0cfb8 100644 --- a/tools/devops/automation/templates/mac/stage.yml +++ b/tools/devops/automation/templates/mac/stage.yml @@ -40,6 +40,49 @@ parameters: default: false stages: +- stage: configure_build + displayName: '${{ parameters.stageDisplayNamePrefix }}Configure' + dependsOn: ${{ parameters.dependsOn }} + ${{ if and(ne(parameters.dependsOn, ''), ne(parameters.dependsOnResult, '')) }}: + condition: eq(dependencies.${{ parameters.dependsOn }}.result, '${{ parameters.dependsOnResult }}') + jobs: + + - ${{ if eq(parameters.pool, 'automatic') }}: + - job: AgentPoolSelector # https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml + pool: # Consider using an agentless (server) job here, but would need to host selection logic as an Azure function: https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#server + vmImage: ubuntu-latest + steps: + - checkout: none # https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#checkout + + # Selects appropriate agent pool based on trigger type (PR or CI); manually triggered builds target the PR pool + - template: azure-devops-pools/agent-pool-selector.yml@yaml-templates + parameters: + agentPoolPR: $(PRBuildPool) + agentPoolPRUrl: $(PRBuildPoolUrl) + agentPoolCI: $(CIBuildPool) + agentPoolCIUrl: $(CIBuildPoolUrl) + + - job: configure + displayName: 'Configure build' + pool: + vmImage: windows-latest + + variables: + isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] + isScheduled: $[eq(variables['Build.Reason'], 'Schedule')] + BRANCH_NAME: $[ replace(variables['Build.SourceBranch'], 'refs/heads/', '') ] + + steps: + - template: common/load_configuration.yml + parameters: + repositoryAlias: ${{ parameters.repositoryAlias }} + commit: ${{ parameters.commit }} + testConfigurations: ${{ parameters.testConfigurations }} + supportedPlatforms: ${{ parameters.supportedPlatforms }} + testsLabels: '--label=skip-all-tests,run-ios-tests,run-ios-simulator-tests,run-tvos-tests,run-watchos-tests,run-mac-tests,run-maccatalyst-tests,run-dotnet-tests,run-system-permission-tests,run-legacy-xamarin-tests' + statusContext: 'VSTS: simulator tests' + uploadArtifacts: true + - stage: ${{ parameters.stageName }} displayName: ${{ parameters.displayName }} dependsOn: From 6df33a86bb4e1ae499d75a603bb29c1695728100 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Thu, 26 Sep 2024 16:19:07 -0400 Subject: [PATCH 20/23] [CI] Fix the pipeline that runs the macOS tests. Fixed several issues with te yaml: * Missing config stage. * Missing parameters, * Hitting the same bug as Uno here: https://github.com/unoplatform/uno/pull/18243 related to https://github.com/microsoft/azure-pipelines-tasks/issues/17207 Co-authored-by: Rolf Bjarne Kvinge --- .../templates/build/build-mac-tests-stage.yml | 2 +- .../devops/automation/templates/mac/build.yml | 5 +- .../devops/automation/templates/mac/stage.yml | 45 +----- .../pipelines/run-macos-tests-pipeline.yml | 152 ++++++++++++++++++ 4 files changed, 159 insertions(+), 45 deletions(-) diff --git a/tools/devops/automation/templates/build/build-mac-tests-stage.yml b/tools/devops/automation/templates/build/build-mac-tests-stage.yml index a87b5dca3598..b365553f4a5d 100644 --- a/tools/devops/automation/templates/build/build-mac-tests-stage.yml +++ b/tools/devops/automation/templates/build/build-mac-tests-stage.yml @@ -39,7 +39,7 @@ jobs: # This job builds the macOS tests. - job: build_macos_tests_job displayName: 'Build macOS tests' - timeoutInMinutes: 120 + timeoutInMinutes: 180 variables: DOTNET_PLATFORMS: $[ stageDependencies.configure_build.configure.outputs['configure_platforms.DOTNET_PLATFORMS'] ] ENABLE_DOTNET: $[ stageDependencies.configure_build.configure.outputs['configure_platforms.ENABLE_DOTNET'] ] diff --git a/tools/devops/automation/templates/mac/build.yml b/tools/devops/automation/templates/mac/build.yml index 94ca35e2b3ba..00e08489a799 100644 --- a/tools/devops/automation/templates/mac/build.yml +++ b/tools/devops/automation/templates/mac/build.yml @@ -144,9 +144,8 @@ steps: # Go get the tests!, this depends on how the test was triggered - ${{ if or(contains(variables['Build.Reason'], 'ResourceTrigger'), contains(variables['Build.Reason'], 'BuildCompletion'), contains(variables['Build.DefinitionName'], 'xamarin-macios-ci-tests'), contains(variables['Build.DefinitionName'], 'xamarin-macios-pr-tests')) }}: - download: macios - artifact: mac-test-package displayName: Download Mac tests - patterns: '**/mac-test-package.7z' + artifact: 'mac-test-package' # the default location when downloading is $(Pipeline.Workspace)// - pwsh: | @@ -162,7 +161,7 @@ steps: - task: DownloadPipelineArtifact@2 displayName: Download Mac tests inputs: - patterns: '**/mac-test-package.7z' + artifact: 'mac-test-package' allowFailedBuilds: true path: $(Build.SourcesDirectory)/artifacts/tmp diff --git a/tools/devops/automation/templates/mac/stage.yml b/tools/devops/automation/templates/mac/stage.yml index 31e0e1e0cfb8..957435e1ea61 100644 --- a/tools/devops/automation/templates/mac/stage.yml +++ b/tools/devops/automation/templates/mac/stage.yml @@ -39,49 +39,12 @@ parameters: type: boolean default: false -stages: -- stage: configure_build - displayName: '${{ parameters.stageDisplayNamePrefix }}Configure' - dependsOn: ${{ parameters.dependsOn }} - ${{ if and(ne(parameters.dependsOn, ''), ne(parameters.dependsOnResult, '')) }}: - condition: eq(dependencies.${{ parameters.dependsOn }}.result, '${{ parameters.dependsOnResult }}') - jobs: - - - ${{ if eq(parameters.pool, 'automatic') }}: - - job: AgentPoolSelector # https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml - pool: # Consider using an agentless (server) job here, but would need to host selection logic as an Azure function: https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#server - vmImage: ubuntu-latest - steps: - - checkout: none # https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#checkout - - # Selects appropriate agent pool based on trigger type (PR or CI); manually triggered builds target the PR pool - - template: azure-devops-pools/agent-pool-selector.yml@yaml-templates - parameters: - agentPoolPR: $(PRBuildPool) - agentPoolPRUrl: $(PRBuildPoolUrl) - agentPoolCI: $(CIBuildPool) - agentPoolCIUrl: $(CIBuildPoolUrl) - - - job: configure - displayName: 'Configure build' - pool: - vmImage: windows-latest +- name: stageDisplayNamePrefix + type: string + default: '' - variables: - isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] - isScheduled: $[eq(variables['Build.Reason'], 'Schedule')] - BRANCH_NAME: $[ replace(variables['Build.SourceBranch'], 'refs/heads/', '') ] - steps: - - template: common/load_configuration.yml - parameters: - repositoryAlias: ${{ parameters.repositoryAlias }} - commit: ${{ parameters.commit }} - testConfigurations: ${{ parameters.testConfigurations }} - supportedPlatforms: ${{ parameters.supportedPlatforms }} - testsLabels: '--label=skip-all-tests,run-ios-tests,run-ios-simulator-tests,run-tvos-tests,run-watchos-tests,run-mac-tests,run-maccatalyst-tests,run-dotnet-tests,run-system-permission-tests,run-legacy-xamarin-tests' - statusContext: 'VSTS: simulator tests' - uploadArtifacts: true +stages: - stage: ${{ parameters.stageName }} displayName: ${{ parameters.displayName }} diff --git a/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml b/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml index e4f4672fb821..6ef60d9a706b 100644 --- a/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml +++ b/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml @@ -79,6 +79,117 @@ parameters: ] }] + - name: pool + type: string + default: automatic + values: + - pr + - ci + - automatic + + - name: supportedPlatforms + type: object + default: [ + { + platform: iOS, + isDotNetPlatform: true, + }, + { + platform: macOS, + isDotNetPlatform: true, + }, + { + platform: tvOS, + isDotNetPlatform: true, + }, + { + platform: MacCatalyst, + isDotNetPlatform: true, + }, + { + # when running platform-specific test runs, we also need a special test run that executes tests that only runs when multiple platforms are enabled + platform: Multiple, + isDotNetPlatform: true, + } + ] + + + - name: testConfigurations + type: object + default: [ + # Disabled by default # + # { + # label: bcl, + # splitByPlatforms: false, + # }, + { + label: cecil, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: dotnettests, + splitByPlatforms: true, + needsMultiplePlatforms: true, + testPrefix: 'simulator_tests', + }, + { + label: fsharp, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: framework, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: generator, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: interdependent-binding-projects, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: introspection, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: linker, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: mmp, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: monotouch, + splitByPlatforms: true, + needsMultiplePlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: msbuild, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: xcframework, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + { + label: xtro, + splitByPlatforms: false, + testPrefix: 'simulator_tests', + }, + ] resources: repositories: @@ -114,6 +225,47 @@ variables: value: true stages: + + - stage: configure_build + displayName: '${{ parameters.stageDisplayNamePrefix }}Configure' + jobs: + + - ${{ if eq(parameters.pool, 'automatic') }}: + - job: AgentPoolSelector # https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml + pool: # Consider using an agentless (server) job here, but would need to host selection logic as an Azure function: https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#server + vmImage: ubuntu-latest + steps: + - checkout: none # https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#checkout + + # Selects appropriate agent pool based on trigger type (PR or CI); manually triggered builds target the PR pool + - template: azure-devops-pools/agent-pool-selector.yml@yaml-templates + parameters: + agentPoolPR: $(PRBuildPool) + agentPoolPRUrl: $(PRBuildPoolUrl) + agentPoolCI: $(CIBuildPool) + agentPoolCIUrl: $(CIBuildPoolUrl) + + - job: configure + displayName: 'Configure build' + pool: + vmImage: windows-latest + + variables: + isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] + isScheduled: $[eq(variables['Build.Reason'], 'Schedule')] + BRANCH_NAME: $[ replace(variables['Build.SourceBranch'], 'refs/heads/', '') ] + + steps: + - template: ../common/load_configuration.yml + parameters: + repositoryAlias: ${{ parameters.repositoryAlias }} + commit: ${{ parameters.commit }} + testConfigurations: ${{ parameters.testConfigurations }} + supportedPlatforms: ${{ parameters.supportedPlatforms }} + testsLabels: '--label=skip-all-tests,run-ios-tests,run-ios-simulator-tests,run-tvos-tests,run-watchos-tests,run-mac-tests,run-maccatalyst-tests,run-dotnet-tests,run-system-permission-tests,run-legacy-xamarin-tests' + statusContext: 'VSTS: simulator tests' + uploadArtifacts: true + - ${{ each config in parameters.macTestsConfigurations }}: - template: ../mac/stage.yml parameters: From 57371ed10ed2d9ad8c19ac83c5b4a6c68004ab56 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:14:17 +0200 Subject: [PATCH 21/23] [net9.0] Update dependencies from dotnet/sdk (#21313) This pull request updates the following dependencies ## Coherency Updates The following updates ensure that dependencies with a *CoherentParentDependency* attribute were produced in a build used as input to the parent dependency's build. See [Dependency Description Format](https://github.com/dotnet/arcade/blob/master/Documentation/DependencyDescriptionFormat.md#dependency-description-overview) - **Coherency Updates**: - **Microsoft.NET.ILLink.Tasks**: from 9.0.0-rtm.24473.2 to 9.0.0-rtm.24475.3 (parent: Microsoft.NET.Sdk) - **Microsoft.AspNetCore.App.Ref**: from 9.0.0-rtm.24473.16 to 9.0.0-rtm.24474.6 (parent: Microsoft.NET.Sdk) - **Microsoft.NETCore.App.Ref**: from 9.0.0-rtm.24473.2 to 9.0.0-rtm.24475.3 (parent: Microsoft.NET.Sdk) - **Microsoft.NETCore.App.Ref**: from 9.0.0-rtm.24473.2 to 9.0.0-rtm.24475.3 (parent: Microsoft.NET.Sdk) ## From https://github.com/dotnet/sdk - **Subscription**: 3727984b-7a79-4ba3-37dd-08dbe6bddf31 - **Build**: 20240925.4 - **Date Produced**: September 26, 2024 6:31:53 AM UTC - **Commit**: f59e9ca09cb4d5b903b276c0d3d7825b6ddbc3a0 - **Branch**: refs/heads/release/9.0.1xx - **Updates**: - **Microsoft.NET.Sdk**: [from 9.0.100-rc.2.24474.4 to 9.0.100-rc.2.24475.4][1] - **Microsoft.NET.ILLink.Tasks**: [from 9.0.0-rtm.24473.2 to 9.0.0-rtm.24475.3][2] - **Microsoft.AspNetCore.App.Ref**: [from 9.0.0-rtm.24473.16 to 9.0.0-rtm.24474.6][3] - **Microsoft.NETCore.App.Ref**: [from 9.0.0-rtm.24473.2 to 9.0.0-rtm.24475.3][2] - **Microsoft.NETCore.App.Ref**: [from 9.0.0-rtm.24473.2 to 9.0.0-rtm.24475.3][2] [1]: https://github.com/dotnet/sdk/compare/42b2349ec2...f59e9ca09c [2]: https://github.com/dotnet/runtime/compare/3d9da91a97...2c4266c134 [3]: https://github.com/dotnet/aspnetcore/compare/91ef755ae0...afe2857bff --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 6 +++--- global.json | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1e2ae7fd263c..70438f62d6e0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,26 +1,26 @@ - + https://github.com/dotnet/sdk - 42b2349ec272dbb8bbc5d8df29adb7b77e3450cd + f59e9ca09cb4d5b903b276c0d3d7825b6ddbc3a0 https://github.com/dotnet/runtime cf47d9ff6827a3e1d6f2acbf925cd618418f20dd - + https://github.com/dotnet/runtime - 3d9da91a9720f7bda3e4cef127b8195441fb2580 + 2c4266c134aa02718179818098a11e825c9d1362 - + https://github.com/dotnet/runtime - 3d9da91a9720f7bda3e4cef127b8195441fb2580 + 2c4266c134aa02718179818098a11e825c9d1362 - + https://github.com/dotnet/aspnetcore - 91ef755ae08f27b395d73be00d245d8095f90143 + afe2857bffef08213d6f3c7688647c60d5d5e7bd https://github.com/dotnet/emsdk diff --git a/eng/Versions.props b/eng/Versions.props index 84ae54441252..b28e399fde38 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -2,12 +2,12 @@ - 9.0.100-rc.2.24474.4 - 9.0.0-rtm.24473.2 + 9.0.100-rc.2.24475.4 + 9.0.0-rtm.24475.3 9.0.0-alpha.1.23556.4 9.0.0-beta.24408.2 8.0.0-beta.24413.2 - 9.0.0-rtm.24473.2 + 9.0.0-rtm.24475.3 8.0.0-rtm.23511.3 9.0.0-rc.2.24462.10 7.0.100-alpha.1.21601.1 diff --git a/global.json b/global.json index e269bf2b2ff9..39529c36264e 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "9.0.100-rc.2.24474.4" + "version": "9.0.100-rc.2.24475.4" } } From 1dfff82b853791653191cf4a64d5ee60fff25a85 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 27 Sep 2024 11:19:55 +0200 Subject: [PATCH 22/23] [devops] Don't do anything on macOS 11 anymore. Our min macOS version is 12.0. --- tools/devops/automation/build-pipeline.yml | 14 -------------- .../pipelines/run-macos-tests-pipeline.yml | 14 -------------- 2 files changed, 28 deletions(-) diff --git a/tools/devops/automation/build-pipeline.yml b/tools/devops/automation/build-pipeline.yml index eeb88f0df7fc..a7d0d72d8484 100644 --- a/tools/devops/automation/build-pipeline.yml +++ b/tools/devops/automation/build-pipeline.yml @@ -88,20 +88,6 @@ parameters: displayName: macOS test configurations to run type: object default: [ - { - stageName: 'mac_11_m1', - displayName: 'M1 - Mac Big Sur (11)', - macPool: 'VSEng-VSMac-Xamarin-Shared', - useImage: false, - statusContext: 'M1 - Mac Big Sur (11)', - demands: [ - "Agent.OS -equals Darwin", - "macOS.Name -equals BigSur", - "macOS.Architecture -equals arm64", - "Agent.HasDevices -equals False", - "Agent.IsPaired -equals False" - ] - }, { stageName: 'mac_12_m1', displayName: 'M1 - Mac Ventura (12)', diff --git a/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml b/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml index 6ef60d9a706b..1bf2a4b2c6d3 100644 --- a/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml +++ b/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml @@ -22,20 +22,6 @@ parameters: displayName: macOS test configurations to run type: object default: [ - { - stageName: 'mac_11_m1', - displayName: 'M1 - Mac Big Sur (11)', - macPool: 'VSEng-VSMac-Xamarin-Shared', - useImage: false, - statusContext: 'M1 - Mac Big Sur (11)', - demands: [ - "Agent.OS -equals Darwin", - "macOS.Name -equals BigSur", - "macOS.Architecture -equals arm64", - "Agent.HasDevices -equals False", - "Agent.IsPaired -equals False" - ] - }, { stageName: 'mac_12_m1', displayName: 'M1 - Mac Ventura (12)', From 60a7ae157cd20447614611cdadfa3ff66f8b5f93 Mon Sep 17 00:00:00 2001 From: Alex Soto Date: Fri, 27 Sep 2024 16:52:04 -0400 Subject: [PATCH 23/23] [net9.0] Bring back missing change from #20790 to SignList (#21323) This change is missing from the last revert https://github.com/xamarin/xamarin-macios/pull/20790/commits/25509d79171fd5cb4ecb7c6db54bbecd83b297ec that happened on https://github.com/xamarin/xamarin-macios/pull/21264 --- dotnet/Workloads/SignList.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/Workloads/SignList.xml b/dotnet/Workloads/SignList.xml index 755a6c5268dc..fae12d42c701 100644 --- a/dotnet/Workloads/SignList.xml +++ b/dotnet/Workloads/SignList.xml @@ -122,7 +122,7 @@ - +