From af00cc664ba1f9eda74a4a451765cc7c093d5d7b Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Mon, 28 Mar 2022 11:52:04 -0400 Subject: [PATCH 01/11] [nnyeah] Update usage to dotnet. (#14514) --- tools/nnyeah/nnyeah/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nnyeah/nnyeah/Program.cs b/tools/nnyeah/nnyeah/Program.cs index 058924bdec..57b713518d 100644 --- a/tools/nnyeah/nnyeah/Program.cs +++ b/tools/nnyeah/nnyeah/Program.cs @@ -8,7 +8,7 @@ namespace nnyeah { static void Main (string [] args) { if (args.Length != 2) { - Console.Error.WriteLine ("Usage: mono nnyeah.exe /path/to/input/file.dll /path/to/output/file.dll"); + Console.Error.WriteLine ("Usage: dotnet nnyeah.dll /path/to/input/file.dll /path/to/output/file.dll"); Environment.Exit (1); } using var stm = new FileStream (args [0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite); From 3f698c47d9b4bd504b34277b61ecf0365d00c025 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Mon, 28 Mar 2022 11:52:59 -0400 Subject: [PATCH 02/11] [nnyeah] Add tool to be made via makefiles. (#14513) Adding the needed Makefile and the dir to the parent one so that the tool is also built in the CI. Co-authored-by: Rolf Bjarne Kvinge --- tools/Makefile | 2 +- tools/nnyeah/Makefile | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tools/nnyeah/Makefile diff --git a/tools/Makefile b/tools/Makefile index 77cd4f2af1..78d7fa0b23 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -6,7 +6,7 @@ ifdef INCLUDE_MAC SUBDIRS+=mmp endif -SUBDIRS+=mtouch xibuild mlaunch siminstaller +SUBDIRS+=mtouch xibuild mlaunch siminstaller nnyeah ifdef ENABLE_INSTALL_SOURCE SUBDIRS += install-source diff --git a/tools/nnyeah/Makefile b/tools/nnyeah/Makefile new file mode 100644 index 0000000000..fb37dfb911 --- /dev/null +++ b/tools/nnyeah/Makefile @@ -0,0 +1,12 @@ +TOP=../.. +include $(TOP)/Make.config + +all-local:: bin/Debug/net5.0/nnyeah.dll + +install-local:: all-local + +bin/Debug/net5.0/nnyeah.dll: $(wildcard **/*.cs) $(wildcard **/*.csproj) $(wildcard *.sln) Makefile + $(Q_BUILD) $(SYSTEM_DOTNET) build "/bl:$@.binlog" /restore $(MSBUILD_VERBOSITY) $(wildcard *.sln) + +clean: + $(Q_BUILD) $(SYSTEM_DOTNET) build "/bl:$@.binlog" /restore $(MSBUILD_VERBOSITY) /t:Clean $(wildcard *.sln) From f2c9749d4d6c8e71607678e0fef697cbddb36762 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Mon, 28 Mar 2022 11:54:04 -0400 Subject: [PATCH 03/11] [CI] Add the job id tot he agent logs. (#14505) It can happen that we use the same agent for more than one bot, if that is the case, we need to make sure that we do not have the same name for the logs. We use the job id + job name for that. --- tools/devops/automation/templates/common/mac-agent-logs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/devops/automation/templates/common/mac-agent-logs.yml b/tools/devops/automation/templates/common/mac-agent-logs.yml index 91111ed1f2..7c25b818ef 100644 --- a/tools/devops/automation/templates/common/mac-agent-logs.yml +++ b/tools/devops/automation/templates/common/mac-agent-logs.yml @@ -80,5 +80,5 @@ steps: targetPath: ${{ parameters.outputPath }} ${{ else }}: targetPath: ${{ parameters.workingDirectory }}/${{ parameters.outputPath }} - artifactName: $(Agent.Name)-${{ parameters.outputPath }} + artifactName: $(Agent.Name)-$(System.JobName)-$(System.JobId)-${{ parameters.outputPath }} continueOnError: true From b8cb374aee92006042f1e8472bfdf2bcbe1ea95e Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Mon, 28 Mar 2022 12:15:43 -0400 Subject: [PATCH 04/11] [CI] Disable the windows integration tests until we have the lab setup. (#14507) --- tools/devops/automation/build-pipeline.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/devops/automation/build-pipeline.yml b/tools/devops/automation/build-pipeline.yml index e5dce480d6..2a883b66d2 100644 --- a/tools/devops/automation/build-pipeline.yml +++ b/tools/devops/automation/build-pipeline.yml @@ -36,6 +36,11 @@ parameters: type: boolean default: true +- name: runWindowsIntegration + displayName: Run Windows integration tests + type: boolean + default: false + - name: runGovernanceTests displayName: Run Governance Checks type: boolean @@ -370,6 +375,7 @@ stages: keyringPass: $(pass--lab--mac--builder--keychain) demands: ${{ config.demands }} +- ${{ if eq(parameters.runWindowsIntegration, true) }}: - template: templates/windows/stage.yml parameters: stageName: windows_integration From 622a1c9d6175b3de4594e9bec33d551d8118a025 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 28 Mar 2022 20:36:00 +0200 Subject: [PATCH 05/11] [devops] Keep dependency selection logic together. (#14519) --- tests/test-dependencies.sh | 4 ++-- tools/devops/automation/templates/mac/build.yml | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/test-dependencies.sh b/tests/test-dependencies.sh index 2e8e60cfd8..0bbd1693b4 100755 --- a/tests/test-dependencies.sh +++ b/tests/test-dependencies.sh @@ -1,4 +1,4 @@ #!/bin/bash -ex -cd $(dirname $0) -./system-dependencies.sh --provision-mono --ignore-autotools --ignore-xamarin-studio --ignore-xcode --ignore-osx --ignore-cmake +cd "$(dirname "$0")" +./system-dependencies.sh --provision-mono --ignore-autotools --ignore-xamarin-studio --ignore-xcode --ignore-osx --ignore-cmake --ignore-dotnet diff --git a/tools/devops/automation/templates/mac/build.yml b/tools/devops/automation/templates/mac/build.yml index 650acc1cce..96a28de6ce 100644 --- a/tools/devops/automation/templates/mac/build.yml +++ b/tools/devops/automation/templates/mac/build.yml @@ -36,7 +36,6 @@ steps: - bash: cd $(System.DefaultWorkingDirectory)/xamarin-macios/ && git clean -xdf displayName: 'Clean workspace' - # download the packages that have been created, install them, later download the zip files that contain the already built # tests and execute them. @@ -182,8 +181,6 @@ steps: $(Build.SourcesDirectory)/artifacts/mac-test-package/test-dependencies.sh displayName: Install dependencies. timeoutInMinutes: 60 - env: - IGNORE_DOTNET: 1 # Not needed for the tests. - pwsh: | Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\GitHub.psm1 From 6487ec485e416e803a2e5bad48f9e11c6a6a0415 Mon Sep 17 00:00:00 2001 From: Steve Hawley Date: Mon, 28 Mar 2022 16:06:54 -0400 Subject: [PATCH 06/11] Lets do warnings (#14510) * Remove existing attributes * Attribute Conversion * Added some events * init only properties and uint * propagation error --- tools/nnyeah/nnyeah/BaseTransformEventArgs.cs | 20 +++++++++++++ tools/nnyeah/nnyeah/Enums.cs | 1 + tools/nnyeah/nnyeah/Reworker.cs | 11 +++++++- tools/nnyeah/nnyeah/TransformEventArgs.cs | 28 +++++++++++++++++++ tools/nnyeah/nnyeah/Transformation.cs | 14 +++++++++- tools/nnyeah/nnyeah/WarningEventArgs.cs | 20 +++++++++++++ 6 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 tools/nnyeah/nnyeah/BaseTransformEventArgs.cs create mode 100644 tools/nnyeah/nnyeah/TransformEventArgs.cs create mode 100644 tools/nnyeah/nnyeah/WarningEventArgs.cs diff --git a/tools/nnyeah/nnyeah/BaseTransformEventArgs.cs b/tools/nnyeah/nnyeah/BaseTransformEventArgs.cs new file mode 100644 index 0000000000..989ecc8163 --- /dev/null +++ b/tools/nnyeah/nnyeah/BaseTransformEventArgs.cs @@ -0,0 +1,20 @@ +using System; + +#nullable enable + +namespace nnyeah { + public abstract class BaseTransformEventArgs : EventArgs { + public BaseTransformEventArgs (string containerName, string methodName, string targetOperand) + { + ContainerName = containerName; + MethodName = methodName; + TargetOperand = targetOperand; + } + + public string ContainerName { get; init; } + public string MethodName { get; init; } + public string TargetOperand { get; init; } + + public abstract string HelpfulMessage (); + } +} diff --git a/tools/nnyeah/nnyeah/Enums.cs b/tools/nnyeah/nnyeah/Enums.cs index 4977b8ed87..6b2b4e2f6d 100644 --- a/tools/nnyeah/nnyeah/Enums.cs +++ b/tools/nnyeah/nnyeah/Enums.cs @@ -5,5 +5,6 @@ namespace nnyeah { Replace, Insert, Append, + Warn, } } diff --git a/tools/nnyeah/nnyeah/Reworker.cs b/tools/nnyeah/nnyeah/Reworker.cs index efebdde1be..88b75390c9 100644 --- a/tools/nnyeah/nnyeah/Reworker.cs +++ b/tools/nnyeah/nnyeah/Reworker.cs @@ -24,6 +24,9 @@ namespace nnyeah { Dictionary methodSubs = new Dictionary (); Dictionary fieldSubs = new Dictionary (); + public event EventHandler? WarningIssued; + public event EventHandler? Transformed; + public Reworker (Stream stm) { this.stm = stm; @@ -255,7 +258,13 @@ namespace nnyeah { } foreach (var (instr, trans) in changes) { - trans.PerformTransform (instr, body); + if (!trans.TryPerformTransform (instr, body)) { + WarningIssued?.Invoke (this, new WarningEventArgs (body.Method.DeclaringType.FullName, body.Method.Name, trans.Operand, trans.Message!)); + } else { + var added = (uint)trans.Instructions.Count; + var removed = trans.Action == TransformationAction.Remove || trans.Action == TransformationAction.Replace ? (uint)1 : 0; + Transformed?.Invoke (this, new TransformEventArgs (body.Method.DeclaringType.FullName, body.Method.Name, trans.Operand, added, removed)); + } } } diff --git a/tools/nnyeah/nnyeah/TransformEventArgs.cs b/tools/nnyeah/nnyeah/TransformEventArgs.cs new file mode 100644 index 0000000000..83e41ff437 --- /dev/null +++ b/tools/nnyeah/nnyeah/TransformEventArgs.cs @@ -0,0 +1,28 @@ +using System; +using System.Text; + +#nullable enable + +namespace nnyeah { + public class TransformEventArgs : BaseTransformEventArgs { + public TransformEventArgs (string containerName, string methodName, string targetOperand, uint addedCount, uint removedCount) + : base (containerName, methodName, targetOperand) + { + AddedCount = addedCount; + RemovedCount = removedCount; + } + + public uint AddedCount { get; init; } + public uint RemovedCount { get; init; } + + public override string HelpfulMessage () + { + var sb = new StringBuilder (); + sb.Append ($"In {ContainerName}.{MethodName}, found reference to {TargetOperand}. Added {AddedCount} IL instructions"); + if (RemovedCount > 0) + sb.Append ($" and removed {RemovedCount} IL instructions"); + sb.Append ('.'); + return sb.ToString (); + } + } +} diff --git a/tools/nnyeah/nnyeah/Transformation.cs b/tools/nnyeah/nnyeah/Transformation.cs index eac649314b..92ca0d0d2c 100644 --- a/tools/nnyeah/nnyeah/Transformation.cs +++ b/tools/nnyeah/nnyeah/Transformation.cs @@ -26,11 +26,20 @@ namespace nnyeah { { } + public Transformation (string operand, string warningMessage) + { + Operand = operand; + Action = TransformationAction.Warn; + Instructions = new List (); + Message = warningMessage; + } + public string Operand { get; private set; } public TransformationAction Action { get; private set; } public List Instructions { get; private set; } + public string? Message { get; private set; } - public void PerformTransform (Instruction old, MethodBody body) + public bool TryPerformTransform (Instruction old, MethodBody body) { var il = body.GetILProcessor (); switch (Action) { @@ -53,7 +62,10 @@ namespace nnyeah { } il.Remove (old); break; + case TransformationAction.Warn: + return false; } + return true; } static Instruction AddVariableIfNeeded (MethodBody body, Instruction instr) diff --git a/tools/nnyeah/nnyeah/WarningEventArgs.cs b/tools/nnyeah/nnyeah/WarningEventArgs.cs new file mode 100644 index 0000000000..828f0c1b9b --- /dev/null +++ b/tools/nnyeah/nnyeah/WarningEventArgs.cs @@ -0,0 +1,20 @@ +using System; + +#nullable enable + +namespace nnyeah { + public class WarningEventArgs : BaseTransformEventArgs { + public WarningEventArgs (string containerName, string methodName, string targetOperand, string message) + : base (containerName, methodName, targetOperand) + { + Message = message; + } + + public string Message { get; init; } + + public override string HelpfulMessage () + { + return $"In {ContainerName}.{MethodName}, found reference to {TargetOperand} - this is not transformable and will likely not work if invoked."; + } + } +} From 073165fef6f08eb277137e7213a8bf5e0d95878b Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Mon, 28 Mar 2022 16:54:56 -0400 Subject: [PATCH 07/11] [nnyeah] Fix makefile to use msbuild. (#14533) --- tools/nnyeah/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nnyeah/Makefile b/tools/nnyeah/Makefile index fb37dfb911..cb7427f42d 100644 --- a/tools/nnyeah/Makefile +++ b/tools/nnyeah/Makefile @@ -6,7 +6,7 @@ all-local:: bin/Debug/net5.0/nnyeah.dll install-local:: all-local bin/Debug/net5.0/nnyeah.dll: $(wildcard **/*.cs) $(wildcard **/*.csproj) $(wildcard *.sln) Makefile - $(Q_BUILD) $(SYSTEM_DOTNET) build "/bl:$@.binlog" /restore $(MSBUILD_VERBOSITY) $(wildcard *.sln) + $(Q_BUILD) $(SYSTEM_MSBUILD) "/bl:$@.binlog" /restore $(MSBUILD_VERBOSITY) $(wildcard *.sln) clean: - $(Q_BUILD) $(SYSTEM_DOTNET) build "/bl:$@.binlog" /restore $(MSBUILD_VERBOSITY) /t:Clean $(wildcard *.sln) + $(Q_BUILD) $(SYSTEM_MSBUILD) "/bl:$@.binlog" /restore $(MSBUILD_VERBOSITY) /t:Clean $(wildcard *.sln) From 2f099ea61dd9818f050e8c28636da9c046aa3b1c Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 29 Mar 2022 07:12:00 +0200 Subject: [PATCH 08/11] [dotnet] Complete rename of DOTNET to SYSTEM_DOTNET. (#14535) This was supposed to happen in d3643414e7900134df13f1962f0ffba85965c25e, but it looks like due to a merge conflict, this remaining part disappeared. --- Make.config | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Make.config b/Make.config index 077b95ac84..f3db1d0b1e 100644 --- a/Make.config +++ b/Make.config @@ -529,12 +529,12 @@ $(TOP)/dotnet.config: $(TOP)/eng/Versions.props $(Q) mv $@.tmp $@ ifneq ("$(wildcard /usr/local/share/dotnet/dotnet)","") -DOTNET=/usr/local/share/dotnet/dotnet +SYSTEM_DOTNET=/usr/local/share/dotnet/dotnet else ifneq ("$(wildcard /usr/local/share/dotnet/x64/dotnet)","") -DOTNET=/usr/local/share/dotnet/x64/dotnet +SYSTEM_DOTNET=/usr/local/share/dotnet/x64/dotnet else -DOTNET=/must/install/dotnet +SYSTEM_DOTNET=/must/install/dotnet endif endif From 50192c9f962e4be753b8c14190ca913451ec3d3a Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 29 Mar 2022 07:37:57 +0200 Subject: [PATCH 09/11] [msbuild] Deduplicate items in ComputeCodesignItems. Fixes #14522. (#14525) We may end up trying to codesign the same item multiple times when codesigning universal .NET apps. Avoid this by deduplicating items to codesign. Fixes https://github.com/xamarin/xamarin-macios/issues/14522. --- .../MSBStrings.Designer.cs | 27 ++ .../MSBStrings.resx | 12 + .../Tasks/ComputeCodesignItemsTaskBase.cs | 30 ++ .../ComputeCodesignItemsTaskTests.cs | 264 ++++++++++++++---- 4 files changed, 277 insertions(+), 56 deletions(-) diff --git a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.Designer.cs b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.Designer.cs index 3e62a91f91..8d0d80d6b0 100644 --- a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.Designer.cs +++ b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.Designer.cs @@ -2636,5 +2636,32 @@ namespace Xamarin.Localization.MSBuild { return ResourceManager.GetString("W7093", resourceCulture); } } + + /// + /// Looks up a localized string similar to Code signing has been requested multiple times for '{0}', with different metadata. The metadata for one are: '{1}', while the metadata for the other are: '{2}'. + /// + public static string W7095 { + get { + return ResourceManager.GetString("W7095", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Code signing has been requested multiple times for '{0}', with different metadata. The metadata '{1}={2}' has been set for one item, but not the other.. + /// + public static string W7096 { + get { + return ResourceManager.GetString("W7096", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Code signing has been requested multiple times for '{0}', with different metadata. The metadata '{1}' has been values for each item (once it's '{2}', another time it's '{3}').. + /// + public static string W7097 { + get { + return ResourceManager.GetString("W7097", resourceCulture); + } + } } } diff --git a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx index 3935d1365d..e1f7331997 100644 --- a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx +++ b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx @@ -1395,4 +1395,16 @@ The file or directory '{0}' is not a framework nor a file within a framework. + + + Code signing has been requested multiple times for '{0}', with different metadata. The metadata for one are: '{1}', while the metadata for the other are: '{2}' + + + + Code signing has been requested multiple times for '{0}', with different metadata. The metadata '{1}={2}' has been set for one item, but not the other. + + + + Code signing has been requested multiple times for '{0}', with different metadata. The metadata '{1}' has been values for each item (once it's '{2}', another time it's '{3}'). + diff --git a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/ComputeCodesignItemsTaskBase.cs b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/ComputeCodesignItemsTaskBase.cs index b17f77a6a0..38deef5328 100644 --- a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/ComputeCodesignItemsTaskBase.cs +++ b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/ComputeCodesignItemsTaskBase.cs @@ -135,6 +135,36 @@ namespace Xamarin.MacDev.Tasks { output.Add (item); } + // We may be asked to sign the same item multiple times (in particular for universal .NET builds) + // Here we de-duplicate (based on itemspec). We also verify that the metadata is the same between + // all deduplicated items, and if not, we show a warning. + var grouped = output.GroupBy (v => v.ItemSpec); + foreach (var group in grouped) { + if (group.Count () < 2) + continue; + + var all = group.ToArray (); + var firstMetadata = all [0].CloneCustomMetadataToDictionary (); + for (var i = 1; i < all.Length; i++) { + var nextMetadata = all [i].CloneCustomMetadataToDictionary (); + if (nextMetadata.Count != firstMetadata.Count) { + Log.LogWarning (MSBStrings.W7095, /* Code signing has been requested multiple times for '{0}', with different metadata. The metadata for one are: '{1}', while the metadata for the other are: '{2}' */ group.Key, string.Join (", ", firstMetadata.Keys), string.Join (", ", nextMetadata.Keys)); + } else { + foreach (var kvp in firstMetadata) { + if (!nextMetadata.TryGetValue (kvp.Key, out var nextValue)) { + Log.LogWarning (MSBStrings.W7096, /* Code signing has been requested multiple times for '{0}', with different metadata. The metadata '{1}={2}' has been set for one item, but not the other. */ group.Key, kvp.Key, kvp.Value); + continue; + } + if (nextValue != kvp.Value) { + Log.LogWarning (MSBStrings.W7097, /* Code signing has been requested multiple times for '{0}', with different metadata. The metadata '{1}' has been values for each item (once it's '{2}', another time it's '{3}'). */ group.Key, kvp.Key, kvp.Value, nextValue); + continue; + } + } + } + output.Remove (all [i]); + } + } + OutputCodesignItems = output.ToArray (); return !Log.HasLoggedErrors; diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ComputeCodesignItemsTaskTests.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ComputeCodesignItemsTaskTests.cs index d7b23d1125..9d006de1c7 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ComputeCodesignItemsTaskTests.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ComputeCodesignItemsTaskTests.cs @@ -355,68 +355,220 @@ namespace Xamarin.MacDev.Tasks { task.NativeStripItems = nativeStripItems.ToArray (); task.TargetFrameworkMoniker = TargetFramework.GetTargetFramework (platform, isDotNet).ToString (); Assert.IsTrue (task.Execute (), "Execute"); + Assert.AreEqual (0, Engine.Logger.WarningsEvents.Count, "Warning Count"); - var outputCodesignItems = task.OutputCodesignItems; - Assert.That (outputCodesignItems.Select (v => v.ItemSpec), Is.Unique, "Uniqueness"); - - var failures = new List (); - var itemsFound = new List (); - foreach (var info in infos) { - var item = outputCodesignItems.SingleOrDefault (v => string.Equals (v.ItemSpec, info.ItemSpec, StringComparison.OrdinalIgnoreCase)); - info.CodesignItem = item; - if (IsPlatform (info.SignedOn, platform)) { - if (item is null) { - failures.Add ($"Expected '{info.ItemSpec}' to be signed."); - continue; - } - } else { - if (item is not null) { - failures.Add ($"Did not expect '{info.ItemSpec}' to be signed."); - continue; - } - } - - if (item is null) - continue; - itemsFound.Add (item); - - foreach (var kvp in info.Metadata) { - var metadata = item.GetMetadata (kvp.Key); - if (metadata == string.Empty && kvp.Value != string.Empty) { - failures.Add ($"Item '{info.ItemSpec}': Expected metadata '{kvp.Key}' not found (with value '{kvp.Value}')."); - } else if (!string.Equals (metadata, kvp.Value)) { - failures.Add ($"Item '{info.ItemSpec}': Expected value '{kvp.Value}' for metadata '{kvp.Key}', but got '{metadata}' instead.\nExpected: {kvp.Value}\nActual: {metadata}"); - } - } - - var customMetadata = item.CopyCustomMetadata (); - var unexpectedMetadata = customMetadata.Keys.ToHashSet (); - unexpectedMetadata.ExceptWith (info.Metadata.Keys); - unexpectedMetadata.Remove ("OriginalItemSpec"); - foreach (var unexpected in unexpectedMetadata) { - if (string.IsNullOrEmpty (customMetadata [unexpected])) - continue; - failures.Add ($"Item '{info.ItemSpec}': Unexpected metadata '{unexpected}' with value '{customMetadata [unexpected]}'."); - } - } - - var itemsNotFound = outputCodesignItems.Where (v => !itemsFound.Contains (v)).ToArray (); - foreach (var itemNotFound in itemsNotFound) { - failures.Add ($"Did not expect '{itemNotFound.ItemSpec}' to be signed."); - } - - if (failures.Count > 0) { - Console.WriteLine ($"{failures.Count} failures"); - foreach (var f in failures) - Console.WriteLine (f); - Console.WriteLine ($"{failures.Count} failures"); - } - Assert.That (failures, Is.Empty, "Failures"); + VerifyCodesigningResults (infos, task.OutputCodesignItems, platform); } finally { Environment.CurrentDirectory = currentDir; } } + [Test] + [TestCase (ApplePlatform.iOS, true)] + [TestCase (ApplePlatform.iOS, false)] + [TestCase (ApplePlatform.TVOS, true)] + [TestCase (ApplePlatform.TVOS, false)] + [TestCase (ApplePlatform.WatchOS, false)] + [TestCase (ApplePlatform.MacOSX, true)] + [TestCase (ApplePlatform.MacOSX, false)] + [TestCase (ApplePlatform.MacCatalyst, true)] + public void Duplicated (ApplePlatform platform, bool isDotNet) + { + var tmpdir = Cache.CreateTemporaryDirectory (); + + var currentDir = Environment.CurrentDirectory; + try { + Environment.CurrentDirectory = tmpdir; + var codesignItems = new List (); + var codesignBundle = new List (); + + string codeSignatureSubdirectory = string.Empty; + switch (platform) { + case ApplePlatform.MacCatalyst: + case ApplePlatform.MacOSX: + codeSignatureSubdirectory = "Contents/"; + break; + } + + var bundleAppMetadata = new Dictionary { + { "RequireCodeSigning", "true" }, + }; + + var createDumpMetadata = new Dictionary { + { "RequireCodeSigning", "true" }, + }; + + codesignItems = new List { + new TaskItem ("Bundle.app/Contents/MonoBundle/createdump", createDumpMetadata), + new TaskItem ("Bundle.app/Contents/MonoBundle/createdump", createDumpMetadata), + }; + + codesignBundle = new List { + new TaskItem ("Bundle.app", bundleAppMetadata), + }; + + var infos = new CodesignInfo [] { + new CodesignInfo ("Bundle.app", Platforms.All, bundleAppMetadata.Set ("CodesignStampFile", $"Bundle.app/{codeSignatureSubdirectory}_CodeSignature/CodeResources")), + new CodesignInfo ("Bundle.app/Contents/MonoBundle/createdump", Platforms.All, createDumpMetadata.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Contents/MonoBundle/createdump")), + }; + + var allFiles = infos.Select (v => v.ItemSpec).ToArray (); + Touch (tmpdir, allFiles); + + var task = CreateTask (); + task.AppBundleDir = "Bundle.app"; + task.CodesignBundle = codesignBundle.ToArray (); + task.CodesignItems = codesignItems.ToArray (); + task.CodesignStampPath = "codesign-stamp-path/"; + task.TargetFrameworkMoniker = TargetFramework.GetTargetFramework (platform, isDotNet).ToString (); + Assert.IsTrue (task.Execute (), "Execute"); + Assert.AreEqual (0, Engine.Logger.WarningsEvents.Count, "Warning Count"); + + VerifyCodesigningResults (infos, task.OutputCodesignItems, platform); + } finally { + Environment.CurrentDirectory = currentDir; + } + } + + [Test] + [TestCase (ApplePlatform.iOS, true)] + [TestCase (ApplePlatform.iOS, false)] + [TestCase (ApplePlatform.TVOS, true)] + [TestCase (ApplePlatform.TVOS, false)] + [TestCase (ApplePlatform.WatchOS, false)] + [TestCase (ApplePlatform.MacOSX, true)] + [TestCase (ApplePlatform.MacOSX, false)] + [TestCase (ApplePlatform.MacCatalyst, true)] + public void DuplicatedWithDifferentMetadata (ApplePlatform platform, bool isDotNet) + { + var tmpdir = Cache.CreateTemporaryDirectory (); + + var currentDir = Environment.CurrentDirectory; + try { + Environment.CurrentDirectory = tmpdir; + var codesignItems = new List (); + var codesignBundle = new List (); + + string codeSignatureSubdirectory = string.Empty; + switch (platform) { + case ApplePlatform.MacCatalyst: + case ApplePlatform.MacOSX: + codeSignatureSubdirectory = "Contents/"; + break; + } + + var bundleAppMetadata = new Dictionary { + { "RequireCodeSigning", "true" }, + }; + + var createDumpMetadata1 = new Dictionary { + { "RequireCodeSigning", "true" }, + { "OnlyIn1", "true" }, + { "InOneAndTwoWithDifferentValues", "1" }, + }; + var createDumpMetadata2 = new Dictionary { + { "RequireCodeSigning", "true" }, + { "OnlyIn2", "true" }, + { "InOneAndTwoWithDifferentValues", "2" }, + }; + var createDumpMetadata3 = new Dictionary { + { "RequireCodeSigning", "true" }, + }; + + codesignItems = new List { + new TaskItem ("Bundle.app/Contents/MonoBundle/createdump", createDumpMetadata1), + new TaskItem ("Bundle.app/Contents/MonoBundle/createdump", createDumpMetadata2), + new TaskItem ("Bundle.app/Contents/MonoBundle/createdump", createDumpMetadata3), + }; + + codesignBundle = new List { + new TaskItem ("Bundle.app", bundleAppMetadata), + }; + + var infos = new CodesignInfo [] { + new CodesignInfo ("Bundle.app", Platforms.All, bundleAppMetadata.Set ("CodesignStampFile", $"Bundle.app/{codeSignatureSubdirectory}_CodeSignature/CodeResources")), + new CodesignInfo ("Bundle.app/Contents/MonoBundle/createdump", Platforms.All, createDumpMetadata1.Set ("CodesignStampFile", "codesign-stamp-path/Bundle.app/Contents/MonoBundle/createdump")), + }; + + var allFiles = infos.Select (v => v.ItemSpec).ToArray (); + Touch (tmpdir, allFiles); + + var task = CreateTask (); + task.AppBundleDir = "Bundle.app"; + task.CodesignBundle = codesignBundle.ToArray (); + task.CodesignItems = codesignItems.ToArray (); + task.CodesignStampPath = "codesign-stamp-path/"; + task.TargetFrameworkMoniker = TargetFramework.GetTargetFramework (platform, isDotNet).ToString (); + Assert.IsTrue (task.Execute (), "Execute"); + Assert.AreEqual (3, Engine.Logger.WarningsEvents.Count, "Warning Count"); + Assert.AreEqual ("Code signing has been requested multiple times for 'Bundle.app/Contents/MonoBundle/createdump', with different metadata. The metadata 'OnlyIn1=true' has been set for one item, but not the other.", Engine.Logger.WarningsEvents [0].Message, "Message #0"); + Assert.AreEqual ("Code signing has been requested multiple times for 'Bundle.app/Contents/MonoBundle/createdump', with different metadata. The metadata 'InOneAndTwoWithDifferentValues' has been values for each item (once it's '1', another time it's '2').", Engine.Logger.WarningsEvents [1].Message, "Message #1"); + Assert.AreEqual ("Code signing has been requested multiple times for 'Bundle.app/Contents/MonoBundle/createdump', with different metadata. The metadata for one are: 'RequireCodeSigning, OnlyIn1, InOneAndTwoWithDifferentValues, CodesignStampFile', while the metadata for the other are: 'RequireCodeSigning, CodesignStampFile'", Engine.Logger.WarningsEvents [2].Message, "Message #2"); + + VerifyCodesigningResults (infos, task.OutputCodesignItems, platform); + } finally { + Environment.CurrentDirectory = currentDir; + } + } + void VerifyCodesigningResults (CodesignInfo [] infos, ITaskItem[] outputCodesignItems, ApplePlatform platform) + { + Assert.That (outputCodesignItems.Select (v => v.ItemSpec), Is.Unique, "Uniqueness"); + + var failures = new List (); + var itemsFound = new List (); + foreach (var info in infos) { + var item = outputCodesignItems.SingleOrDefault (v => string.Equals (v.ItemSpec, info.ItemSpec, StringComparison.OrdinalIgnoreCase)); + info.CodesignItem = item; + if (IsPlatform (info.SignedOn, platform)) { + if (item is null) { + failures.Add ($"Expected '{info.ItemSpec}' to be signed."); + continue; + } + } else { + if (item is not null) { + failures.Add ($"Did not expect '{info.ItemSpec}' to be signed."); + continue; + } + } + + if (item is null) + continue; + itemsFound.Add (item); + + foreach (var kvp in info.Metadata) { + var metadata = item.GetMetadata (kvp.Key); + if (metadata == string.Empty && kvp.Value != string.Empty) { + failures.Add ($"Item '{info.ItemSpec}': Expected metadata '{kvp.Key}' not found (with value '{kvp.Value}')."); + } else if (!string.Equals (metadata, kvp.Value)) { + failures.Add ($"Item '{info.ItemSpec}': Expected value '{kvp.Value}' for metadata '{kvp.Key}', but got '{metadata}' instead.\nExpected: {kvp.Value}\nActual: {metadata}"); + } + } + + var customMetadata = item.CopyCustomMetadata (); + var unexpectedMetadata = customMetadata.Keys.ToHashSet (); + unexpectedMetadata.ExceptWith (info.Metadata.Keys); + unexpectedMetadata.Remove ("OriginalItemSpec"); + foreach (var unexpected in unexpectedMetadata) { + if (string.IsNullOrEmpty (customMetadata [unexpected])) + continue; + failures.Add ($"Item '{info.ItemSpec}': Unexpected metadata '{unexpected}' with value '{customMetadata [unexpected]}'."); + } + } + + var itemsNotFound = outputCodesignItems.Where (v => !itemsFound.Contains (v)).ToArray (); + foreach (var itemNotFound in itemsNotFound) { + failures.Add ($"Did not expect '{itemNotFound.ItemSpec}' to be signed."); + } + + if (failures.Count > 0) { + Console.WriteLine ($"{failures.Count} failures"); + foreach (var f in failures) + Console.WriteLine (f); + Console.WriteLine ($"{failures.Count} failures"); + } + Assert.That (failures, Is.Empty, "Failures"); + } + bool IsPlatform (Platforms platforms, ApplePlatform platform) { switch (platform) { From 2af5fc3c561fd654e94d734d41ba1dc991c0d803 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 29 Mar 2022 07:51:40 +0200 Subject: [PATCH 10/11] [monotouch-test] Attempt to fix monotouch-tests on macOS 10.15. (#14520) --- .../HealthKit/CdaDocumentSampleTest.cs | 4 ++++ .../MediaAccessibility/ImageCaptioningTest.cs | 20 ++----------------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/tests/monotouch-test/HealthKit/CdaDocumentSampleTest.cs b/tests/monotouch-test/HealthKit/CdaDocumentSampleTest.cs index 5fcf3f388c..39d41b2faf 100644 --- a/tests/monotouch-test/HealthKit/CdaDocumentSampleTest.cs +++ b/tests/monotouch-test/HealthKit/CdaDocumentSampleTest.cs @@ -37,7 +37,11 @@ namespace MonoTouchFixtures.HealthKit { Assert.That (details.ValidationError.Length, Is.EqualTo ((nint) 0), "Length"); } }; +#if __MACCATALYST__ + var throwsException = TestRuntime.CheckXcodeVersion (12, 0); +#else var throwsException = TestRuntime.CheckXcodeVersion (11, 0); +#endif if (throwsException) { #if NET diff --git a/tests/monotouch-test/MediaAccessibility/ImageCaptioningTest.cs b/tests/monotouch-test/MediaAccessibility/ImageCaptioningTest.cs index ba00c26cf5..bee771dc14 100644 --- a/tests/monotouch-test/MediaAccessibility/ImageCaptioningTest.cs +++ b/tests/monotouch-test/MediaAccessibility/ImageCaptioningTest.cs @@ -95,11 +95,7 @@ namespace MonoTouchFixtures.MediaAccessibility { Assert.Null (e, "ro / set / no error"); // weird, it can't be saved back to the file metadata var s = MAImageCaptioning.GetCaption (url, out e); -#if __MACCATALYST__ - if (true) { -#else if (TestRuntime.CheckXcodeVersion (12, TestRuntime.MinorXcode12APIMismatch)) { -#endif Assert.AreEqual ("xamarin", s, "ro / roundtrip 2"); } else { Assert.Null (s, "ro / roundtrip 3"); // not very surprising since Set can't save it @@ -108,11 +104,7 @@ namespace MonoTouchFixtures.MediaAccessibility { Assert.True (MAImageCaptioning.SetCaption (url, "xamarin", out e), "Set 2"); s = MAImageCaptioning.GetCaption (url, out e); -#if __MACCATALYST__ - if (true) { -#else if (TestRuntime.CheckXcodeVersion (12, TestRuntime.MinorXcode12APIMismatch)) { -#endif Assert.AreEqual ("xamarin", s, "ro / back to original"); } else { Assert.Null (s, "ro / back to original"); @@ -135,11 +127,7 @@ namespace MonoTouchFixtures.MediaAccessibility { Assert.Null (e, "rw / set / no error"); // weird, it can't be saved back to the file metadata var s = MAImageCaptioning.GetCaption (rw_url, out e); -#if __MACCATALYST__ - if (true) { -#else - if (TestRuntime.CheckXcodeVersion (12, TestRuntime.MinorXcode12APIMismatch)) { -#endif + if (TestRuntime.CheckXcodeVersion (12, TestRuntime.MinorXcode12APIMismatch)) { Assert.AreEqual ("xamarin", s, "rw / roundtrip"); // :) } else { Assert.Null (s, "rw / roundtrip"); // :( @@ -148,11 +136,7 @@ namespace MonoTouchFixtures.MediaAccessibility { Assert.True (MAImageCaptioning.SetCaption (rw_url, "xamarin", out e), "Set 2"); s = MAImageCaptioning.GetCaption (rw_url, out e); -#if __MACCATALYST__ - if (true) { -#else - if (TestRuntime.CheckXcodeVersion (12, TestRuntime.MinorXcode12APIMismatch)) { -#endif + if (TestRuntime.CheckXcodeVersion (12, TestRuntime.MinorXcode12APIMismatch)) { Assert.AreEqual ("xamarin", s, "rw / back to original"); } else { Assert.Null (s, "rw / back to original"); From 345a518239309953bf99b6ec62c6d1a141bac473 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 29 Mar 2022 08:56:44 +0200 Subject: [PATCH 11/11] Bump .NET in main to RC 2 (#14528) --- Make.config | 2 +- Make.versions | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Make.config b/Make.config index f3db1d0b1e..6160471ba1 100644 --- a/Make.config +++ b/Make.config @@ -80,7 +80,7 @@ endif # For release branches, modify the following variables to hardcode a version name # Set the NUGET_HARDCODED_PRERELEASE_IDENTIFIER variable to the prerelease identifer you want (say "rc.1") -NUGET_HARDCODED_PRERELEASE_IDENTIFIER=rc.1 +NUGET_HARDCODED_PRERELEASE_IDENTIFIER=rc.2 # Set the NUGET_HARDCODED_PRERELEASE_BRANCH variable to the exact name for the branch the above variable should apply to (so that any other branches won't pick it up by accident). # For the previous example, this would be "release/6.0.2xx-rc1" # When creating a release branch from main, this must be changed from "main" to the new release branch. diff --git a/Make.versions b/Make.versions index a478f5e9c8..dcbd47bdfa 100644 --- a/Make.versions +++ b/Make.versions @@ -66,11 +66,11 @@ MAC_PACKAGE_VERSION=8.9.0.$(MAC_COMMIT_DISTANCE) # WARNING: Do **not** use versions higher than the available Xcode SDK or else we will have issues with mtouch (See https://github.com/xamarin/xamarin-macios/issues/7705) # When bumping the major macOS version in MACOS_NUGET_VERSION also update the macOS version where we execute on bots in jenkins/Jenkinsfile (in the 'node' element) -IOS_NUGET_VERSION=15.4.100 -TVOS_NUGET_VERSION=15.4.100 -WATCHOS_NUGET_VERSION=8.5.100 -MACOS_NUGET_VERSION=12.3.100 -MACCATALYST_NUGET_VERSION=15.4.100 +IOS_NUGET_VERSION=15.4.200 +TVOS_NUGET_VERSION=15.4.200 +WATCHOS_NUGET_VERSION=8.5.200 +MACOS_NUGET_VERSION=12.3.200 +MACCATALYST_NUGET_VERSION=15.4.200 # Defines the default platform version if it's not specified in the TFM. The default should not change for a given .NET version: