diff --git a/.gitignore b/.gitignore index d7c8df4a40a7..94e9fb14e217 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +config.runsettings Build.props Make.config.inc Make.config.local diff --git a/Make.config b/Make.config index 4e06a8f25510..64a123c04566 100644 --- a/Make.config +++ b/Make.config @@ -313,10 +313,10 @@ MIN_TVOS_SIMULATOR_VERSION=15.0 EXTRA_SIMULATORS=com.apple.pkg.iPhoneSimulatorSDK15_0 com.apple.pkg.AppleTVSimulatorSDK15_0 com.apple.pkg.WatchSimulatorSDK8_0 INCLUDE_IOS=1 -INCLUDE_MAC=1 -INCLUDE_WATCH=1 -INCLUDE_TVOS=1 -INCLUDE_MACCATALYST=1 +INCLUDE_MAC= +INCLUDE_WATCH= +INCLUDE_TVOS= +INCLUDE_MACCATALYST= INCLUDE_DEVICE=1 INCLUDE_DOTNET_WATCHOS= INCLUDE_XAMARIN_LEGACY= diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets index dc7dff2aa87d..e72ab7ba795a 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.targets @@ -869,8 +869,6 @@ Condition="'$(IsMacEnabled)' == 'true'" AdditionalArguments="$(_DittoArchitectures)" CopyFromWindows="true" - ToolExe="$(DittoExe)" - ToolPath="$(DittoPath)" Source="%(_DirectoriesToPublish.SourceDirectory)" Destination="%(_DirectoriesToPublish.TargetDirectory)" TouchDestinationFiles="true" diff --git a/msbuild/Directory.Build.props b/msbuild/Directory.Build.props index 11a037ed2134..034239166571 100644 --- a/msbuild/Directory.Build.props +++ b/msbuild/Directory.Build.props @@ -10,8 +10,12 @@ interesting ways. So in order to get the exact version, they're enclosed in brackets. + Lists of versions can be found here: + + https://dev.azure.com/azure-public/vside/_artifacts/feed/xamarin-impl/NuGet/Xamarin.Messaging.Client/ + --> - [2.1.15] + [2.1.59-pushpackage-diagnose-cancelled-posts] [1.1.7] diff --git a/msbuild/Messaging/Xamarin.Messaging.Build/Handlers/ExecuteTaskMessageHandler.cs b/msbuild/Messaging/Xamarin.Messaging.Build/Handlers/ExecuteTaskMessageHandler.cs index 6e905dcbb12c..e44efbe1eacf 100644 --- a/msbuild/Messaging/Xamarin.Messaging.Build/Handlers/ExecuteTaskMessageHandler.cs +++ b/msbuild/Messaging/Xamarin.Messaging.Build/Handlers/ExecuteTaskMessageHandler.cs @@ -1,3 +1,4 @@ +using System; using System.Diagnostics; using System.IO; using System.Threading.Tasks; @@ -25,6 +26,10 @@ public ExecuteTaskMessageHandler () protected override async Task ExecuteAsync (ExecuteTaskMessage message) { + var msg = $"{System.DateTime.UtcNow.ToString ("o")} ExecuteTaskMessageHandler.ExecuteAsync ({message.TaskName})\n{System.Environment.StackTrace}"; + Console.WriteLine (msg); + Console.Error.WriteLine (msg); + tracer.Info (msg); return await Task.Run (() => { // We need to lock in order to change the current directory lock (lockObject) { diff --git a/msbuild/Xamarin.MacDev.Tasks/Decompress.cs b/msbuild/Xamarin.MacDev.Tasks/Decompress.cs index ed47c46bf98d..4f2f8d5c0636 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Decompress.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Decompress.cs @@ -4,6 +4,7 @@ using System.IO; using System.IO.Compression; using System.Reflection; +using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -81,9 +82,10 @@ public static bool IsCompressed (string path) /// The zip to search in /// The relative path inside the zip to extract (may be a file or a directory). /// The location on disk to store the extracted results + /// The cancellation token (if any= /// The location on disk to the extracted resource /// - public static bool TryDecompress (TaskLoggingHelper log, string zip, string resource, string decompressionDir, List createdFiles, [NotNullWhen (true)] out string? decompressedResource) + public static bool TryDecompress (TaskLoggingHelper log, string zip, string resource, string decompressionDir, List createdFiles, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? decompressedResource) { decompressedResource = Path.Combine (decompressionDir, resource); @@ -101,11 +103,11 @@ public static bool TryDecompress (TaskLoggingHelper log, string zip, string reso bool rv; if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - rv = TryDecompressUsingSystemIOCompression (log, zip, resource, decompressionDir); + rv = TryDecompressUsingSystemIOCompression (log, zip, resource, decompressionDir, cancellationToken); } else if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("XAMARIN_USE_SYSTEM_IO_COMPRESSION"))) { - rv = TryDecompressUsingSystemIOCompression (log, zip, resource, decompressionDir); + rv = TryDecompressUsingSystemIOCompression (log, zip, resource, decompressionDir, cancellationToken); } else { - rv = TryDecompressUsingUnzip (log, zip, resource, decompressionDir); + rv = TryDecompressUsingUnzip (log, zip, resource, decompressionDir, cancellationToken); } if (rv) { @@ -128,7 +130,7 @@ public static bool TryDecompress (TaskLoggingHelper log, string zip, string reso // The dir separator character in zip files is always "/", even on Windows const char zipDirectorySeparator = '/'; - static bool TryDecompressUsingUnzip (TaskLoggingHelper log, string zip, string resource, string decompressionDir) + static bool TryDecompressUsingUnzip (TaskLoggingHelper log, string zip, string resource, string decompressionDir, CancellationToken? cancellationToken) { Directory.CreateDirectory (decompressionDir); var args = new List { @@ -157,11 +159,11 @@ static bool TryDecompressUsingUnzip (TaskLoggingHelper log, string zip, string r args.Add (zipPattern); } - var rv = XamarinTask.ExecuteAsync (log, "unzip", args).Result; + var rv = XamarinTask.ExecuteAsync (log, "unzip", args, cancellationToken: cancellationToken).Result; return rv.ExitCode == 0; } - static bool TryDecompressUsingSystemIOCompression (TaskLoggingHelper log, string zip, string resource, string decompressionDir) + static bool TryDecompressUsingSystemIOCompression (TaskLoggingHelper log, string zip, string resource, string decompressionDir, CancellationToken? cancellationToken) { var rv = true; @@ -172,6 +174,7 @@ static bool TryDecompressUsingSystemIOCompression (TaskLoggingHelper log, string using var archive = ZipFile.OpenRead (zip); foreach (var entry in archive.Entries) { + cancellationToken?.ThrowIfCancellationRequested (); var entryPath = entry.FullName; if (entryPath.Length == 0) continue; @@ -207,7 +210,11 @@ static bool TryDecompressUsingSystemIOCompression (TaskLoggingHelper log, string Directory.CreateDirectory (Path.GetDirectoryName (targetPath)); using var streamWrite = File.OpenWrite (targetPath); using var streamRead = entry.Open (); - streamRead.CopyTo (streamWrite); +#if NET + streamRead.CopyToAsync (streamWrite, cancellationToken ?? CancellationToken.None).Wait (); +#else + streamRead.CopyToAsync (streamWrite, 81920 /* default buffer size according to docs */, cancellationToken ?? CancellationToken.None).Wait (); +#endif log.LogMessage (MessageImportance.Low, "Extracted {0} into {1}", entryPath, targetPath); } } diff --git a/msbuild/Xamarin.MacDev.Tasks/MsBuildTasks/Copy.cs b/msbuild/Xamarin.MacDev.Tasks/MsBuildTasks/Copy.cs index 3679d861f69e..fa3515a4eea8 100644 --- a/msbuild/Xamarin.MacDev.Tasks/MsBuildTasks/Copy.cs +++ b/msbuild/Xamarin.MacDev.Tasks/MsBuildTasks/Copy.cs @@ -13,16 +13,23 @@ public class Copy : Microsoft_Build_Tasks_Core::Microsoft.Build.Tasks.Copy { public string SessionId { get; set; } = string.Empty; public override bool Execute () { - if (!this.ShouldExecuteRemotely (SessionId)) - return base.Execute (); + try { + if (!this.ShouldExecuteRemotely (SessionId)) + return base.Execute (); - var taskRunner = new TaskRunner (SessionId, BuildEngine4); + var taskRunner = new TaskRunner (SessionId, BuildEngine4); - if (SourceFiles?.Any () == true) { - taskRunner.FixReferencedItems (this, SourceFiles); - } + if (SourceFiles?.Any () == true) { + taskRunner.FixReferencedItems (this, SourceFiles); + } - return taskRunner.RunAsync (this).Result; + return taskRunner.RunAsync (this).Result; + } catch (Exception ex) { + Log.LogError ($"Copy failed due to exception: {ex.Message}"); + Log.LogError ($"Stack trace:\n{ex.StackTrace}"); + Log.LogErrorFromException (ex); + return false; + } } } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs index a4a849dfd7df..5fd8f2c6c8e3 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs @@ -2,16 +2,19 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; +using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using Xamarin.Messaging.Build.Client; +using Xamarin.Utils; namespace Xamarin.MacDev.Tasks { - public class Ditto : XamarinToolTask, ITaskCallback { + public class Ditto : XamarinTask, ITaskCallback, ICancelableTask { #region Inputs public string? AdditionalArguments { get; set; } @@ -40,44 +43,53 @@ public class Ditto : XamarinToolTask, ITaskCallback { #endregion - protected override string ToolName { - get { return "ditto"; } - } - - protected override string GenerateFullPathToTool () - { - if (!string.IsNullOrEmpty (ToolPath)) - return Path.Combine (ToolPath, ToolExe); - - var path = Path.Combine ("/usr/bin", ToolExe); - - return File.Exists (path) ? path : ToolExe; - } - - protected override string GenerateCommandLineCommands () - { - var args = new CommandLineArgumentBuilder (); - - args.AddQuoted (Path.GetFullPath (Source!.ItemSpec)); - args.AddQuoted (Path.GetFullPath (Destination!.ItemSpec)); - if (!string.IsNullOrEmpty (AdditionalArguments)) - args.Add (AdditionalArguments); - - return args.ToString (); - } + CancellationTokenSource? cancellationTokenSource; + static int counter; public override bool Execute () { + var id = Interlocked.Increment (ref counter); + if (ShouldExecuteRemotely ()) { + LogLine ($"{id} Ditto.Execute () will execute remotely"); var taskRunner = new TaskRunner (SessionId, BuildEngine4); taskRunner.FixReferencedItems (this, new ITaskItem [] { Source! }); - return taskRunner.RunAsync (this).Result; + LogLine ($"{id} Ditto.Execute () about to execute remotely"); + var rv = taskRunner.RunAsync (this).Result; + LogLine ($"{id} Ditto.Execute () executed remotely: {rv}"); + return rv; } - if (!base.Execute ()) + var src = Source!.ItemSpec; + if (!File.Exists (src) && !Directory.Exists (src)) { + Log.LogError ($"The source {src} does not exist."); return false; + } + + var args = new List (); + args.Add (Path.GetFullPath (Source!.ItemSpec)); + args.Add (Path.GetFullPath (Destination!.ItemSpec)); +#if NET + if (!string.IsNullOrEmpty (AdditionalArguments)) { +#else + if (AdditionalArguments is not null && !string.IsNullOrEmpty (AdditionalArguments)) { +#endif + if (StringUtils.TryParseArguments (AdditionalArguments, out var additionalArgs, out var ex)) { + args.AddRange (additionalArgs); + } else { + Log.LogError ("Unable to parse the AdditionalArguments: {0}", AdditionalArguments); + return false; + } + } + + LogLine ($"{id} Ditto.Execute () about to execute locally. Args: {string.Join (" ", args)}\n{Environment.StackTrace}"); + var watch = Stopwatch.StartNew (); + cancellationTokenSource = new CancellationTokenSource (); + cancellationTokenSource.CancelAfter (TimeSpan.FromSeconds (30)); // FIXME: remove this + ExecuteAsync (Log, "/usr/bin/ditto", args, cancellationToken: cancellationTokenSource.Token).Wait (); + LogLine ($"{id} Ditto.Execute () executed locally in {watch.Elapsed.TotalSeconds} seconds. Args: {string.Join (" ", args)}"); // Create a list of all the files we've copied var copiedFiles = new List (); @@ -96,18 +108,13 @@ public override bool Execute () return !Log.HasLoggedErrors; } - protected override void LogEventsFromTextOutput (string singleLine, MessageImportance messageImportance) - { - // TODO: do proper parsing of error messages and such - Log.LogMessage (messageImportance, "{0}", singleLine); - } - - public override void Cancel () + public void Cancel () { - base.Cancel (); - - if (ShouldExecuteRemotely ()) + if (ShouldExecuteRemotely ()) { BuildConnection.CancelAsync (BuildEngine4).Wait (); + } else { + cancellationTokenSource?.Cancel (); + } } public IEnumerable GetAdditionalItemsToBeCopied () diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ResolveNativeReferences.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ResolveNativeReferences.cs index 60cdf434d23b..0678e53c7823 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ResolveNativeReferences.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ResolveNativeReferences.cs @@ -5,6 +5,7 @@ using System.IO.Compression; using System.Linq; using System.Reflection; +using System.Threading; using System.Xml; using Microsoft.Build.Framework; @@ -70,6 +71,8 @@ public class ResolveNativeReferences : XamarinTask, ITaskCallback { #endregion + CancellationTokenSource? cancellationTokenSource; + string GetIntermediateDecompressionDir (ITaskItem item) { return GetIntermediateDecompressionDir (item.ItemSpec); @@ -112,9 +115,11 @@ bool ExecuteLocally () var native_frameworks = new List (); var createdFiles = new List (); + cancellationTokenSource = new CancellationTokenSource (); + // there can be direct native references inside a project foreach (var nr in NativeReferences) { - ProcessNativeReference (nr, native_frameworks, createdFiles); + ProcessNativeReference (nr, native_frameworks, createdFiles, cancellationTokenSource.Token); } // or (managed) reference to an assembly that bind a framework @@ -122,11 +127,11 @@ bool ExecuteLocally () // look for sidecar's manifest var resources = Path.ChangeExtension (r.ItemSpec, ".resources"); if (Directory.Exists (resources)) { - ProcessNativeReference (r, resources, native_frameworks, createdFiles); + ProcessNativeReference (r, resources, native_frameworks, createdFiles, cancellationTokenSource.Token); } else { resources = resources + ".zip"; if (File.Exists (resources)) - ProcessNativeReference (r, resources, native_frameworks, createdFiles); + ProcessNativeReference (r, resources, native_frameworks, createdFiles, cancellationTokenSource.Token); } } @@ -136,12 +141,12 @@ bool ExecuteLocally () return !Log.HasLoggedErrors; } - void ProcessNativeReference (ITaskItem item, List native_frameworks, List createdFiles) + void ProcessNativeReference (ITaskItem item, List native_frameworks, List createdFiles, CancellationToken? cancellationTokenSource) { - ProcessNativeReference (item, item.ItemSpec, native_frameworks, createdFiles); + ProcessNativeReference (item, item.ItemSpec, native_frameworks, createdFiles, cancellationTokenSource); } - void ProcessNativeReference (ITaskItem item, string name, List native_frameworks, List createdFiles) + void ProcessNativeReference (ITaskItem item, string name, List native_frameworks, List createdFiles, CancellationToken? cancellationToken) { // '.' can be used to represent a file (instead of the directory) if (Path.GetFileName (name) == ".") @@ -190,7 +195,7 @@ void ProcessNativeReference (ITaskItem item, string name, List native // (compressed) xcframework if (name.EndsWith (".xcframework", StringComparison.OrdinalIgnoreCase) || name.EndsWith (".xcframework.zip", StringComparison.OrdinalIgnoreCase)) { - if (!TryResolveXCFramework (Log, TargetFrameworkMoniker, SdkIsSimulator, Architectures, name, GetIntermediateDecompressionDir (item), createdFiles, out var nativeLibraryPath)) + if (!TryResolveXCFramework (Log, TargetFrameworkMoniker, SdkIsSimulator, Architectures, name, GetIntermediateDecompressionDir (item), createdFiles, cancellationToken, out var nativeLibraryPath)) return; var nr = new TaskItem (item); SetMetadataNativeLibrary (nr, nativeLibraryPath); @@ -200,7 +205,7 @@ void ProcessNativeReference (ITaskItem item, string name, List native // compressed framework if (name.EndsWith (".framework.zip", StringComparison.OrdinalIgnoreCase)) { - if (!CompressionHelper.TryDecompress (Log, name, Path.GetFileNameWithoutExtension (name), GetIntermediateDecompressionDir (item), createdFiles, out var frameworkPath)) + if (!CompressionHelper.TryDecompress (Log, name, Path.GetFileNameWithoutExtension (name), GetIntermediateDecompressionDir (item), createdFiles, cancellationToken, out var frameworkPath)) return; var nr = new TaskItem (item); nr.ItemSpec = GetActualLibrary (frameworkPath); @@ -213,13 +218,13 @@ void ProcessNativeReference (ITaskItem item, string name, List native // sidecar / binding resource package if (name.EndsWith (".resources", StringComparison.OrdinalIgnoreCase)) { - ProcessSidecar (item, name, native_frameworks, createdFiles); + ProcessSidecar (item, name, native_frameworks, createdFiles, cancellationToken); return; } // compressed sidecar / binding resource package if (name.EndsWith (".resources.zip", StringComparison.OrdinalIgnoreCase)) { - ProcessSidecar (item, name, native_frameworks, createdFiles); + ProcessSidecar (item, name, native_frameworks, createdFiles, cancellationToken); return; } @@ -289,7 +294,7 @@ void SetMetadataNativeLibrary (ITaskItem item, string nativeLibraryPath) item.SetMetadata ("RelativePath", Path.Combine (FrameworksDirectory, Path.GetFileName (Path.GetDirectoryName (item.ItemSpec)))); } - void ProcessSidecar (ITaskItem r, string resources, List native_frameworks, List createdFiles) + void ProcessSidecar (ITaskItem r, string resources, List native_frameworks, List createdFiles, CancellationToken? cancellationToken) { if (!TryGetSidecarManifest (Log, resources, out var manifestContents)) return; @@ -302,7 +307,7 @@ void ProcessSidecar (ITaskItem r, string resources, List native_frame var name = referenceNode.Attributes ["Name"].Value.Trim ('\\', '/'); switch (Path.GetExtension (name)) { case ".xcframework": { - if (!TryResolveXCFramework (Log, TargetFrameworkMoniker, SdkIsSimulator, Architectures, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, out var nativeLibraryPath)) + if (!TryResolveXCFramework (Log, TargetFrameworkMoniker, SdkIsSimulator, Architectures, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out var nativeLibraryPath)) continue; SetMetadataNativeLibrary (t, nativeLibraryPath); break; @@ -311,7 +316,7 @@ void ProcessSidecar (ITaskItem r, string resources, List native_frame string? frameworkPath; if (!isCompressed) { frameworkPath = Path.Combine (resources, name); - } else if (!CompressionHelper.TryDecompress (Log, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, out frameworkPath)) { + } else if (!CompressionHelper.TryDecompress (Log, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out frameworkPath)) { continue; } t.ItemSpec = GetActualLibrary (frameworkPath); @@ -324,7 +329,7 @@ void ProcessSidecar (ITaskItem r, string resources, List native_frame string? dylibPath; if (!isCompressed) { dylibPath = Path.Combine (resources, name); - } else if (!CompressionHelper.TryDecompress (Log, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, out dylibPath)) { + } else if (!CompressionHelper.TryDecompress (Log, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out dylibPath)) { continue; } t.ItemSpec = dylibPath; @@ -335,7 +340,7 @@ void ProcessSidecar (ITaskItem r, string resources, List native_frame string? aPath; if (!isCompressed) { aPath = Path.Combine (resources, name); - } else if (!CompressionHelper.TryDecompress (Log, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, out aPath)) { + } else if (!CompressionHelper.TryDecompress (Log, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out aPath)) { continue; } t.ItemSpec = aPath; @@ -374,7 +379,7 @@ void ProcessSidecar (ITaskItem r, string resources, List native_frame /// A full path to the resolved native library within the xcframework. If 'resourcePath' is compressed, this will point to where the native library is decompressed on disk. /// /// True if a native library was successfully found. Otherwise false, and an error will have been printed to the log. - public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFrameworkMoniker, bool isSimulator, string? architectures, string path, string intermediateDecompressionDir, List createdFiles, [NotNullWhen (true)] out string? nativeLibraryPath) + public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFrameworkMoniker, bool isSimulator, string? architectures, string path, string intermediateDecompressionDir, List createdFiles, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? nativeLibraryPath) { string resourcePath; string xcframework; @@ -386,7 +391,7 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFr resourcePath = Path.GetDirectoryName (path); xcframework = Path.GetFileName (path); } - return TryResolveXCFramework (log, targetFrameworkMoniker, isSimulator, architectures, resourcePath, xcframework, intermediateDecompressionDir, createdFiles, out nativeLibraryPath); + return TryResolveXCFramework (log, targetFrameworkMoniker, isSimulator, architectures, resourcePath, xcframework, intermediateDecompressionDir, createdFiles, cancellationToken, out nativeLibraryPath); } /// @@ -401,7 +406,7 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFr /// A full path to the resolved native library within the xcframework. If 'resourcePath' is compressed, this will point to where the native library is decompressed on disk. /// /// True if a native library was successfully found. Otherwise false, and an error will have been printed to the log. - public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFrameworkMoniker, bool isSimulator, string? architectures, string resourcePath, string xcframework, string intermediateDecompressionDir, List createdFiles, [NotNullWhen (true)] out string? nativeLibraryPath) + public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFrameworkMoniker, bool isSimulator, string? architectures, string resourcePath, string xcframework, string intermediateDecompressionDir, List createdFiles, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? nativeLibraryPath) { nativeLibraryPath = null; @@ -411,7 +416,7 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFr var isCompressed = CompressionHelper.IsCompressed (resourcePath); var xcframeworkPath = isCompressed ? resourcePath : Path.Combine (resourcePath, xcframework); - if (!TryResolveXCFramework (log, plist, xcframeworkPath, targetFrameworkMoniker, isSimulator, architectures!, out var nativeLibraryRelativePath)) + if (!TryResolveXCFramework (log, plist, xcframeworkPath, targetFrameworkMoniker, isSimulator, architectures!, cancellationToken, out var nativeLibraryRelativePath)) return false; if (!isCompressed) { @@ -420,7 +425,7 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFr } var zipResource = Path.Combine (xcframework, Path.GetDirectoryName (nativeLibraryRelativePath)); - if (!CompressionHelper.TryDecompress (log, resourcePath, zipResource, intermediateDecompressionDir, createdFiles, out var decompressedPath)) + if (!CompressionHelper.TryDecompress (log, resourcePath, zipResource, intermediateDecompressionDir, createdFiles, cancellationToken, out var decompressedPath)) return false; nativeLibraryPath = Path.Combine (intermediateDecompressionDir, xcframework, nativeLibraryRelativePath); @@ -444,7 +449,7 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFr /// The target architectures /// A relative path to the resolved native library within the xcframework. /// True if a native library was successfully found. Otherwise false, and an error will have been printed to the log. - public static bool TryResolveXCFramework (TaskLoggingHelper log, PDictionary plist, string xcframeworkPath, string targetFrameworkMoniker, bool isSimulator, string architectures, [NotNullWhen (true)] out string? nativeLibraryPath) + public static bool TryResolveXCFramework (TaskLoggingHelper log, PDictionary plist, string xcframeworkPath, string targetFrameworkMoniker, bool isSimulator, string architectures, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? nativeLibraryPath) { nativeLibraryPath = null; var platform = PlatformFrameworkHelper.GetFramework (targetFrameworkMoniker); @@ -519,8 +524,11 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, PDictionary pli public void Cancel () { - if (ShouldExecuteRemotely ()) + if (ShouldExecuteRemotely ()) { BuildConnection.CancelAsync (BuildEngine4).Wait (); + } else { + cancellationTokenSource?.Cancel (); + } } public bool ShouldCopyToBuildServer (ITaskItem item) => true; diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Unzip.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Unzip.cs index 6dc4ced90781..c6d6ef4187ef 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Unzip.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Unzip.cs @@ -5,6 +5,7 @@ using System.IO.Compression; using System.Linq; using System.Reflection; +using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -38,25 +39,37 @@ public class Unzip : XamarinTask, ITaskCallback { [Output] public ITaskItem [] TouchedFiles { get; set; } = Array.Empty (); + CancellationTokenSource? cancellationTokenSource; + static int counter; public override bool Execute () { + var id = Interlocked.Increment (ref counter); + if (ShouldExecuteRemotely ()) { + LogLine ($"{id} Unzip.Execute () about to execute remotely"); var taskRunner = new TaskRunner (SessionId, BuildEngine4); var rv = taskRunner.RunAsync (this).Result; if (rv && CopyToWindows) CopyFilesToWindowsAsync (taskRunner, TouchedFiles).Wait (); + LogLine ($"{id} Unzip.Execute () executed remotely: {rv}"); return rv; } - return ExecuteLocally (); + LogLine ($"{id} Unzip.Execute () about to execute locally. ZipFilePath: {ZipFilePath} ExtractionPath: {ExtractionPath} Resource: {Resource}"); + var rv2 = ExecuteLocally (); + LogLine ($"{id} Unzip.Execute () executed locally"); + return rv2; } public void Cancel () { - if (ShouldExecuteRemotely ()) + if (ShouldExecuteRemotely ()) { BuildConnection.CancelAsync (BuildEngine4).Wait (); + } else { + cancellationTokenSource?.Cancel (); + } } public bool ShouldCopyToBuildServer (ITaskItem item) => true; @@ -73,7 +86,8 @@ public bool ShouldCreateOutputFile (ITaskItem item) bool ExecuteLocally () { var createdFiles = new List (); - if (!CompressionHelper.TryDecompress (Log, ZipFilePath!.ItemSpec, Resource, ExtractionPath, createdFiles, out var _)) + cancellationTokenSource = new CancellationTokenSource (); + if (!CompressionHelper.TryDecompress (Log, ZipFilePath!.ItemSpec, Resource, ExtractionPath, createdFiles, cancellationTokenSource.Token, out var _)) return false; TouchedFiles = createdFiles.Select (v => new TaskItem (v)).ToArray (); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index e17775c17c75..94db2fdee3d7 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; +using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Tasks; @@ -29,6 +31,19 @@ void VerifyTargetFrameworkMoniker () Log.LogError ($"The task {GetType ().Name} requires TargetFrameworkMoniker to be set."); } + static XamarinTask () + { + AppDomain.CurrentDomain.FirstChanceException += (object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs fceea) => { + LogLine (null, "XamarinTask", $"FirstChanceException: {fceea.GetType ().FullName}\n" + + $"Exception.Message: {fceea.Exception.Message}\n" + + $"Exception.StackTrace: {fceea.Exception.StackTrace}\n" + + $"Exception.ToString (): {fceea.Exception}\n" + + $"Environment.StackTrace: {Environment.StackTrace}\n" + + $"FirstChanceException END"); + }; + LogLine (null, "XamarinTask", "Added FirstChanceException handler"); + } + public string Product { get { if (IsDotNet) @@ -120,23 +135,68 @@ protected System.Threading.Tasks.Task ExecuteAsync (string fileName, return ExecuteAsync (Log, fileName, arguments, sdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory); } - internal protected static async System.Threading.Tasks.Task ExecuteAsync (TaskLoggingHelper log, string fileName, IList arguments, string? sdkDevPath = null, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null) + protected void LogLine (string msg) + { + LogLine (Log, GetType ().Name, msg); + } + + + protected static void LogLine (TaskLoggingHelper? log, string type, string? msg) + { + log?.LogMessage (MessageImportance.Low, msg ?? string.Empty); + Console.WriteLine ($"{DateTime.UtcNow.ToString ("o")} {type} stdout: {msg}"); + Console.Error.WriteLine ($"{DateTime.UtcNow.ToString ("o")} {type} stderr: {msg}"); + } + + class CallbackWriter : TextWriter { + public Action? Callback; + public override void WriteLine (string? value) + { + if (value is not null) + Callback?.Invoke (value); + } + + public override Encoding Encoding => Encoding.UTF8; + } + + internal protected static async System.Threading.Tasks.Task ExecuteAsync (TaskLoggingHelper log, string fileName, IList arguments, string? sdkDevPath = null, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) { // Create a new dictionary if we're given one, to make sure we don't change the caller's dictionary. var launchEnvironment = environment is null ? new Dictionary () : new Dictionary (environment); if (!string.IsNullOrEmpty (sdkDevPath)) launchEnvironment ["DEVELOPER_DIR"] = sdkDevPath; - log.LogMessage (MessageImportance.Normal, MSBStrings.M0001, fileName, StringUtils.FormatArguments (arguments)); - var rv = await Execution.RunAsync (fileName, arguments, environment: launchEnvironment, mergeOutput: mergeOutput, workingDirectory: workingDirectory); - log.LogMessage (rv.ExitCode == 0 ? MessageImportance.Low : MessageImportance.High, MSBStrings.M0002, fileName, rv.ExitCode); + var execLogger = new CallbackWriter (); + execLogger.Callback = new Action (v => { + LogLine (log, "XamarinTask|log", v); + }); + var stdOutput = new StringBuilder (); + var stdOutputCallback = new Action ((v) => { + LogLine (log, "XamarinTask|stdout", v); + if (v is not null) { + lock (stdOutput) + stdOutput.AppendLine (v); + } + }); + StringBuilder stdError = mergeOutput ? stdOutput : new StringBuilder (); + var stdErrorCallback = new Action ((v) => { + LogLine (log, "XamarinTask|stderr", v); + if (v is not null) { + lock (stdError) + stdError.AppendLine (v); + } + }); + + LogLine (log, "XamarinTask", string.Format (MSBStrings.M0001, fileName, StringUtils.FormatArguments (arguments))); + var rv = await Execution.RunWithCallbacksAsync (fileName, arguments, environment: launchEnvironment, standardOutput: stdOutputCallback, standardError: stdErrorCallback, workingDirectory: workingDirectory, cancellationToken: cancellationToken, log: execLogger, timeout: TimeSpan.FromMinutes (1)); + LogLine (log, "XamarinTask", string.Format (MSBStrings.M0002, fileName, rv.ExitCode)); // Show the output - var output = rv.StandardOutput!.ToString (); + var output = stdOutput.ToString ();// rv.StandardOutput!.ToString (); if (!mergeOutput) { if (output.Length > 0) output += Environment.NewLine; - output += rv.StandardError!.ToString (); + output += stdError.ToString (); // rv.StandardError!.ToString (); } if (output.Length > 0) { var importance = MessageImportance.Low; diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 34adc65727dd..a41c54f971e0 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -2502,8 +2502,6 @@ Copyright (C) 2018 Microsoft. All rights reserved. @@ -93,8 +91,6 @@ Copyright (C) 2015-2016 Xamarin. All rights reserved. SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)'" AdditionalArguments="$(WKDittoArchitectures)" - ToolExe="$(DittoExe)" - ToolPath="$(DittoPath)" Source="$(_NativeWatchApp)" Destination="$(_AppBundlePath)_WatchKitStub\WK" /> diff --git a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets index ffefb06341a4..98b7e72ebc98 100644 --- a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets +++ b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets @@ -371,8 +371,6 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. @@ -391,8 +389,6 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. @@ -481,8 +477,6 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. diff --git a/tests/bindings-xcframework-test/dotnet/shared.csproj b/tests/bindings-xcframework-test/dotnet/shared.csproj index c04de55618f9..af7801fc3a63 100644 --- a/tests/bindings-xcframework-test/dotnet/shared.csproj +++ b/tests/bindings-xcframework-test/dotnet/shared.csproj @@ -59,6 +59,6 @@ - + diff --git a/tests/common/DotNet.cs b/tests/common/DotNet.cs index 15be67b95b77..2825f316d99f 100644 --- a/tests/common/DotNet.cs +++ b/tests/common/DotNet.cs @@ -244,7 +244,8 @@ public static ExecutionResult Execute (string verb, string project, Dictionary diff --git a/tests/dotnet/Windows/collect-binlogs.sh b/tests/dotnet/Windows/collect-binlogs.sh index 903097dbba82..58f5ed337e0e 100755 --- a/tests/dotnet/Windows/collect-binlogs.sh +++ b/tests/dotnet/Windows/collect-binlogs.sh @@ -7,6 +7,15 @@ cd "$(dirname "${BASH_SOURCE[0]}")" TOPLEVEL="$(git rev-parse --show-toplevel)" +# Abort any agents that are still alive. +# Aborting creates a crash report, and we can investigate why they got stuck. +ps auxww || true +pkill -6 -f Broker.exe || true +pkill -6 -f Build.exe || true +pkill -6 -f Broker.dll || true +pkill -6 -f Build.dll || true +ps auxww || true + # Collect and zip up all the binlogs mkdir -p ~/remote_build_testing/binlogs rsync -avv --prune-empty-dirs --exclude 'artifacts/' --include '*/' --include '*.binlog' --exclude '*' "$TOPLEVEL/.." ~/remote_build_testing/binlogs @@ -35,6 +44,12 @@ fi ps auxww > ~/remote_build_testing/processes.txt || true +sudo log collect --last 3h || true +zip -9r ~/remote_build_testing/windows-remote-logs.zip system_logs.logarchive || true + +# Collect any crash reports. +zip -9r ~/remote_build_testing/windows-remote-logs.zip ~/Library/Logs/DiagnosticReports || true + ls -la ~/Library/Caches/Xamarin/XMA/SDKs/dotnet/ >> ~/remote_build_testing/dotnet-debug.txt 2>&1 || true cat ~/Library/Caches/Xamarin/XMA/SDKs/dotnet/NuGet.config >> ~/remote_build_testing/dotnet-debug.txt 2>&1 || true cat ~/Library/Caches/Xamarin/XMA/SDKs/.home/.nuget/NuGet/NuGet.Config >> ~/remote_build_testing/dotnet-debug.txt 2>&1 || true diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ResolveNativeReferencesTaskTest.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ResolveNativeReferencesTaskTest.cs index 148849779358..431fc489d2cd 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ResolveNativeReferencesTaskTest.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ResolveNativeReferencesTaskTest.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Threading; using Microsoft.Build.Utilities; using NUnit.Framework; @@ -40,7 +41,7 @@ public void Xcode12_x (string targetFrameworkMoniker, bool isSimulator, string a // on Xcode 12.2+ you get arm64 for all (iOS, tvOS and watchOS) simulators var path = Path.Combine (Path.GetDirectoryName (GetType ().Assembly.Location)!, "Resources", "xcf-xcode12.2.plist"); var plist = PDictionary.FromFile (path)!; - var result = ResolveNativeReferences.TryResolveXCFramework (log, plist, "N/A", targetFrameworkMoniker, isSimulator, architecture, out var frameworkPath); + var result = ResolveNativeReferences.TryResolveXCFramework (log, plist, "N/A", targetFrameworkMoniker, isSimulator, architecture, null, out var frameworkPath); Assert.AreEqual (result, !string.IsNullOrEmpty (expected), "result"); Assert.That (frameworkPath, Is.EqualTo (expected), "frameworkPath"); } @@ -53,7 +54,7 @@ public void PreXcode12 (string targetFrameworkMoniker, bool isSimulator, string { var path = Path.Combine (Path.GetDirectoryName (GetType ().Assembly.Location)!, "Resources", "xcf-prexcode12.plist"); var plist = PDictionary.FromFile (path)!; - var result = ResolveNativeReferences.TryResolveXCFramework (log, plist, "N/A", targetFrameworkMoniker, isSimulator, architecture, out var frameworkPath); + var result = ResolveNativeReferences.TryResolveXCFramework (log, plist, "N/A", targetFrameworkMoniker, isSimulator, architecture, null, out var frameworkPath); Assert.AreEqual (result, !string.IsNullOrEmpty (expected), "result"); Assert.That (frameworkPath, Is.EqualTo (expected), "frameworkPath"); } @@ -62,7 +63,7 @@ public void PreXcode12 (string targetFrameworkMoniker, bool isSimulator, string public void BadInfoPlist () { var plist = new PDictionary (); - var result = ResolveNativeReferences.TryResolveXCFramework (log, plist, "N/A", TargetFramework.DotNet_iOS_String, false, "x86_64", out var frameworkPath); + var result = ResolveNativeReferences.TryResolveXCFramework (log, plist, "N/A", TargetFramework.DotNet_iOS_String, false, "x86_64", null, out var frameworkPath); Assert.IsFalse (result, "Invalid Info.plist"); } } diff --git a/tools/common/Execution.cs b/tools/common/Execution.cs index 8cc66b1c256b..ef6b7b5203ef 100644 --- a/tools/common/Execution.cs +++ b/tools/common/Execution.cs @@ -57,10 +57,12 @@ static Thread StartOutputThread (TaskCompletionSource tcs, object loc return thread; } + static int counter; public Task RunAsync () { var tcs = new TaskCompletionSource (); var lockobj = new object (); + var id = Interlocked.Increment (ref counter); try { var p = new Process (); @@ -100,9 +102,30 @@ public Task RunAsync () Log.WriteLine ("{0} {1}", p.StartInfo.FileName, p.StartInfo.Arguments); } + var watch = Stopwatch.StartNew (); p.Start (); var pid = p.Id; + if (Log is not null) { + var ticker = new Thread (() => { + Log.WriteLine ($"{id} Ticker for {p.StartInfo.FileName} with pid {pid} and timeout {(Timeout is null ? "" : Timeout.Value.ToString ())}"); + while (true) { + Thread.Sleep (TimeSpan.FromSeconds (1)); + if (tcs.Task.IsCompleted) { + Log.WriteLine ($"{id} Ticker for {p.StartInfo.FileName} with pid {pid}: task completed with status '{tcs.Task.Status}'"); + break; + } else { + Log.WriteLine ($"{id} Ticker for {p.StartInfo.FileName} with pid {pid}: task not complete yet (status = '{tcs.Task.Status}')"); + } + } + Log.WriteLine ($"{id} Ticker for {p.StartInfo.FileName} with pid {pid}: Done"); + }) { + IsBackground = true, + Name = $"{id} Thread ticker for {p.StartInfo.FileName}", + }; + ticker.Start (); + } + var stdoutThread = StartOutputThread (tcs, lockobj, p.StandardOutput, StandardOutput, $"StandardOutput reader for {p.StartInfo.FileName} (PID: {pid})"); var stderrThread = StartOutputThread (tcs, lockobj, p.StandardError, StandardError, $"StandardError reader for {p.StartInfo.FileName} (PID: {pid})"); @@ -112,26 +135,28 @@ public Task RunAsync () p.Kill (); } catch (Exception ex) { // The process could be disposed already. Just ignore any exceptions here. - Log?.WriteLine ($"Failed to cancel and kill PID {pid}: {ex.Message}"); + Log?.WriteLine ($"{id} Failed to cancel and kill PID {pid}: {ex.Message}"); } }); if (Timeout.HasValue) { if (!p.WaitForExit ((int) Timeout.Value.TotalMilliseconds)) { - Log?.WriteLine ($"Command '{p.StartInfo.FileName} {p.StartInfo.Arguments}' didn't finish in {Timeout.Value.TotalMilliseconds} ms, and will be killed."); + Log?.WriteLine ($"{id} Command '{p.StartInfo.FileName} {p.StartInfo.Arguments}' didn't finish in {Timeout.Value.TotalMilliseconds} ms, and will be killed."); TimedOut = true; try { p.Kill (); } catch (Exception ex) { // According to the documentation, there can be exceptions here we can't prepare for, so just ignore them. - Log?.WriteLine ($"Failed to kill PID {pid}: {ex.Message}"); + Log?.WriteLine ($"{id} Failed to kill PID {pid}: {ex.Message}"); } } } // Always call this WaitForExit overload to be make sure the stdout/stderr buffers have been flushed, // even if we've called the WaitForExit (int) overload p.WaitForExit (); + watch.Stop (); ExitCode = p.ExitCode; + Log?.WriteLine ($"{id} Command '{p.StartInfo.FileName} {p.StartInfo.Arguments}' finished in {watch.Elapsed} with exit code {ExitCode}."); stdoutThread.Join (TimeSpan.FromSeconds (1)); stderrThread.Join (TimeSpan.FromSeconds (1)); @@ -144,7 +169,7 @@ public Task RunAsync () } }) { IsBackground = true, - Name = $"Thread waiting for {p.StartInfo.FileName} to finish", + Name = $"{id} Thread waiting for {p.StartInfo.FileName} to finish", }; thread.Start (); } catch (Exception e) { diff --git a/tools/devops/automation/scripts/bash/clean-bot.sh b/tools/devops/automation/scripts/bash/clean-bot.sh index 923d353c1a8d..c48e4d5895f7 100755 --- a/tools/devops/automation/scripts/bash/clean-bot.sh +++ b/tools/devops/automation/scripts/bash/clean-bot.sh @@ -12,6 +12,15 @@ df -h # We don't care about errors in this section, we just want to clean as much as possible set +e +# Clean workspace +( + REPO_PATH="SYSTEM_DEFAULTWORKINGDIRECTORY/$(basename "$BUILD_REPOSITORY_NAME")" + if test -d "$REPO_PATH"; then + cd "$REPO_PATH" + git clean -xfd + fi +) + # Delete all the simulator devices. These can take up a lot of space over time (I've seen 100+GB on the bots) /Applications/Xcode.app/Contents/Developer/usr/bin/simctl delete all @@ -118,7 +127,9 @@ XCODE_SELECT=$(xcode-select -p) for oldXcode in "${oldXcodes[@]}"; do if [ "$XCODE_SELECT" != "$oldXcode/Contents/Developer" ]; then - sudo rm -Rf "$oldXcode" + if test -d "$oldXcode"; then + sudo rm -Rf "$oldXcode" + fi else echo "Not removing $oldXcode because is the currently selected one." fi @@ -126,6 +137,13 @@ done DIR="$(dirname "${BASH_SOURCE[0]}")" "$DIR"/clean-simulator-runtime.sh +"$DIR"/kill-deadlocked-processes.sh + +# Remove legacy Xamarin/MonoTouch stuff +sudo rm -Rf /Developer/MonoTouch +sudo rm -Rf /Library/Frameworks/Xamarin.iOS.framework +sudo rm -Rf /Library/Frameworks/Xamarin.Mac.framework +ls -R /Library/Frameworks # Print disk status after cleaning df -h diff --git a/tools/devops/automation/scripts/bash/clean-results-dir.sh b/tools/devops/automation/scripts/bash/clean-results-dir.sh deleted file mode 100755 index 3e1aa2dfb4e1..000000000000 --- a/tools/devops/automation/scripts/bash/clean-results-dir.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -ex - -rm -Rvf package -time make -C xamarin-macios/ git-clean-all diff --git a/tools/devops/automation/scripts/bash/clean-simulator-runtime.sh b/tools/devops/automation/scripts/bash/clean-simulator-runtime.sh index ed23cf1193c2..dfddf64f38d9 100755 --- a/tools/devops/automation/scripts/bash/clean-simulator-runtime.sh +++ b/tools/devops/automation/scripts/bash/clean-simulator-runtime.sh @@ -5,6 +5,11 @@ set -o pipefail IFS=$'\n\t' +# delete all watchOS simulators, we don't need them anymore +for i in $(xcrun simctl runtime list | grep "watchOS.*Ready" | sed -e 's/.* - //' -e 's/ .*//'); do + xcrun simctl runtime delete "$i" +done + xcrun simctl runtime list -j > simruntime.json cat simruntime.json diff --git a/tools/devops/automation/scripts/bash/delete-library-dirs.sh b/tools/devops/automation/scripts/bash/delete-library-dirs.sh deleted file mode 100755 index 3c647824f72b..000000000000 --- a/tools/devops/automation/scripts/bash/delete-library-dirs.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -ex - -sudo rm -Rf /Developer/MonoTouch -sudo rm -Rf /Library/Frameworks/Xamarin.iOS.framework -sudo rm -Rf /Library/Frameworks/Xamarin.Mac.framework -ls -R /Library/Frameworks diff --git a/tools/devops/automation/scripts/bash/kill-deadlocked-processes.sh b/tools/devops/automation/scripts/bash/kill-deadlocked-processes.sh new file mode 100755 index 000000000000..7610d51a7200 --- /dev/null +++ b/tools/devops/automation/scripts/bash/kill-deadlocked-processes.sh @@ -0,0 +1,27 @@ +#!/bin/bash -e + +echo "Looking for processes that have been stuck for more than a day, and will try to kill them." + +# Collect the list of processes for the current user, including the CPU time. +# We then split the CPU time into separate fields, so that it's easier to figure out the total number of minutes later on. +IFS=$'\n' +PROCESSES=() +while IFS='' read -r line; do PROCESSES+=("$line"); done < <(ps -o cputime=,pid=,user=,lstart=,args= -U "$USER" -w -w -w | sed -e 's/\([0-9]*\):\([0-9][0-9]\)\.\([0-9][0-9]\)/\1 m \2 s \3 ms/' | sort -nr) + +IFS=' ' +for process in "${PROCESSES[@]}"; do + IFS=" " read -r -a FIELDS <<< "$process" + minutes=${FIELDS[0]} + pid=${FIELDS[6]} + + echo "$process" + + # looking for processes that have spent more than a day using the CPU (24h * 60min = 1440min) + if (( minutes > 1440 )); then + echo " This process has been stuck for more than $minutes minutes, so assuming it's deadlocked and we'll try to kill it:" + echo " kill -9 $pid" + kill -9 "$pid" | sed 's/^/ /' || true + fi +done + +echo "No (more) processes stuck for more than a day." diff --git a/tools/devops/automation/scripts/clean-for-remote-tests.sh b/tools/devops/automation/scripts/clean-for-remote-tests.sh index d05b9e0ec1a2..f796367149c4 100755 --- a/tools/devops/automation/scripts/clean-for-remote-tests.sh +++ b/tools/devops/automation/scripts/clean-for-remote-tests.sh @@ -18,6 +18,8 @@ rm -rf ~/remote_build_testing # Kill any existing brokers and builders ps auxww || true -pkill -f Broker.exe || true -pkill -f Build.exe || true +pkill -6 -f Broker.exe || true +pkill -6 -f Build.exe || true +pkill -6 -f Broker.dll || true +pkill -6 -f Build.dll || true ps auxww || true diff --git a/tools/devops/automation/scripts/prepare-for-remote-tests.sh b/tools/devops/automation/scripts/prepare-for-remote-tests.sh index bf60da1366dc..f7a3aa1495aa 100755 --- a/tools/devops/automation/scripts/prepare-for-remote-tests.sh +++ b/tools/devops/automation/scripts/prepare-for-remote-tests.sh @@ -1,10 +1,12 @@ #!/bin/bash -eux +cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." + # Install the local .NET we're using into XMA's directory # (we can't point XMA to our local directory) mkdir -p ~/Library/Caches/Xamarin/XMA/SDKs -cp -cRH "$BUILD_SOURCESDIRECTORY"/xamarin-macios/builds/downloads/dotnet ~/Library/Caches/Xamarin/XMA/SDKs -sed '/local-tests-feed/d' "$BUILD_SOURCESDIRECTORY"/xamarin-macios/NuGet.config > ~/Library/Caches/Xamarin/XMA/SDKs/dotnet/NuGet.config +cp -cRH ./builds/downloads/dotnet ~/Library/Caches/Xamarin/XMA/SDKs +sed '/local-tests-feed/d' ./NuGet.config > ~/Library/Caches/Xamarin/XMA/SDKs/dotnet/NuGet.config mkdir -p ~/Library/Caches/Xamarin/XMA/SDKs/.home/.nuget/NuGet/ cp ~/Library/Caches/Xamarin/XMA/SDKs/dotnet/NuGet.config ~/Library/Caches/Xamarin/XMA/SDKs/.home/.nuget/NuGet/NuGet.Config diff --git a/tools/devops/automation/scripts/run-generator-tests-on-windows.ps1 b/tools/devops/automation/scripts/run-generator-tests-on-windows.ps1 index 493b3026c0c2..a59e58043535 100644 --- a/tools/devops/automation/scripts/run-generator-tests-on-windows.ps1 +++ b/tools/devops/automation/scripts/run-generator-tests-on-windows.ps1 @@ -1,5 +1,5 @@ # Dump the environment to see what we're working with. -& "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\show_env.ps1" +& "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY\$($Env:BUILD_REPOSITORY_NAME.Split('/')[1])\tools\devops\automation\scripts\show_bot_info.ps1" # Set a few variables $Env:DOTNET = "$Env:BUILD_SOURCESDIRECTORY\xamarin-macios\tests\dotnet\Windows\bin\dotnet\dotnet.exe" diff --git a/tools/devops/automation/scripts/run-remote-windows-tests.ps1 b/tools/devops/automation/scripts/run-remote-windows-tests.ps1 index e90cc2457028..b366a6536bfd 100644 --- a/tools/devops/automation/scripts/run-remote-windows-tests.ps1 +++ b/tools/devops/automation/scripts/run-remote-windows-tests.ps1 @@ -1,9 +1,13 @@ -$Env:DOTNET = "$Env:BUILD_SOURCESDIRECTORY\xamarin-macios\tests\dotnet\Windows\bin\dotnet\dotnet.exe" +if ("$Env:DOTNET" -eq "") { + $Env:DOTNET = "$Env:BUILD_SOURCESDIRECTORY\xamarin-macios\tests\dotnet\Windows\bin\dotnet\dotnet.exe" +} $Env:ServerAddress = $Env:MAC_AGENT_IP $Env:ServerUser = $Env:MAC_AGENT_USER $Env:ServerPassword = $Env:XMA_PASSWORD $Env:_DotNetRootRemoteDirectory = "/Users/$Env:MAC_AGENT_USER/Library/Caches/Xamarin/XMA/SDKs/dotnet/" +$Env:SkipCompatibleRuntimeCheck = "true" + & $Env:DOTNET ` test ` "$Env:BUILD_SOURCESDIRECTORY/xamarin-macios/tests/dotnet/UnitTests/DotNetUnitTests.csproj" ` diff --git a/tools/devops/automation/scripts/show_env.ps1 b/tools/devops/automation/scripts/show_bot_info.ps1 similarity index 51% rename from tools/devops/automation/scripts/show_env.ps1 rename to tools/devops/automation/scripts/show_bot_info.ps1 index 7852d1ad7c7a..0369422be80e 100644 --- a/tools/devops/automation/scripts/show_env.ps1 +++ b/tools/devops/automation/scripts/show_bot_info.ps1 @@ -8,13 +8,14 @@ if ($IsMacOS -or $IsLinux) { Write-Host "COMPUTERNAME: ${env:COMPUTERNAME}" } -gci env: | format-table -autosize - -gci env: | format-table -autosize | Out-String -Width 8192 - -gci env: | format-table -autosize -wrap +Get-ChildItem env: | Sort-Object -Property Name | Format-Table -AutoSize | Out-String -Width 81920 if ($IsMacOS) { + Write-Host "" + Write-Host "## Uptime" + Write-Host "" + uptime + Write-Host "" Write-Host "## System profile" Write-Host "" @@ -25,10 +26,24 @@ if ($IsMacOS) { Write-Host "" ifconfig | grep 'inet ' + Write-Host "" + Write-Host "## Top processes (ps)" + Write-Host "" + ps aux + + Write-Host "" + Write-Host "## Python3 location:" + Write-Host "" + which python3 + + Write-Host "" + Write-Host "## Pip3 version:" + Write-Host "" + pip3 -V Write-Host "" - Write-Host "## Top processes" + Write-Host "## Hardware info" Write-Host "" - top -l 1 -o TIME + ioreg -l | grep -e Manufacturer -e 'Vendor Name' } diff --git a/tools/devops/automation/scripts/show_python_env.ps1 b/tools/devops/automation/scripts/show_python_env.ps1 deleted file mode 100644 index 79873375cf32..000000000000 --- a/tools/devops/automation/scripts/show_python_env.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -Write-Host "Python3 location" -which python3 - -Write-Host "Pip3 version" -pip3 -V - diff --git a/tools/devops/automation/templates/build/api-diff-process-results.yml b/tools/devops/automation/templates/build/api-diff-process-results.yml index c8b3bf3cc8bb..233054ab53cc 100644 --- a/tools/devops/automation/templates/build/api-diff-process-results.yml +++ b/tools/devops/automation/templates/build/api-diff-process-results.yml @@ -27,8 +27,8 @@ steps: repositoryAlias: ${{ parameters.repositoryAlias }} commit: ${{ parameters.commit }} - - pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 - displayName: 'Show Environment' + - pwsh: '"$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"' + displayName: 'Show Bot Info' - pwsh: | if (Test-Path "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/Artifacts" -PathType Container) { diff --git a/tools/devops/automation/templates/common/configure.yml b/tools/devops/automation/templates/common/configure.yml index e909e535fe88..dadaa98f1dc1 100644 --- a/tools/devops/automation/templates/common/configure.yml +++ b/tools/devops/automation/templates/common/configure.yml @@ -65,8 +65,8 @@ steps: name: decisions displayName: 'Make decisions' -- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 - displayName: 'Show Environment' +- pwsh: '"$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"' + displayName: 'Show Bot Info' - pwsh: | Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY/xamarin-macios/tools/devops/automation/scripts/MaciosCI.psd1 diff --git a/tools/devops/automation/templates/common/load_configuration.yml b/tools/devops/automation/templates/common/load_configuration.yml index 5ecac652b11f..f59efce0113f 100644 --- a/tools/devops/automation/templates/common/load_configuration.yml +++ b/tools/devops/automation/templates/common/load_configuration.yml @@ -75,8 +75,8 @@ steps: name: decisions displayName: 'Make decisions' - - pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 - displayName: 'Show Environment' + - pwsh: '"$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"' + displayName: 'Show Bot Info' - pwsh: | Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY/xamarin-macios/tools/devops/automation/scripts/MaciosCI.psd1 diff --git a/tools/devops/automation/templates/common/setup.yml b/tools/devops/automation/templates/common/setup.yml index 91df3be177c1..8811f43cb03b 100644 --- a/tools/devops/automation/templates/common/setup.yml +++ b/tools/devops/automation/templates/common/setup.yml @@ -17,30 +17,14 @@ steps: - bash: $(Build.SourcesDirectory)/xamarin-macios/tools/devops/automation/scripts/bash/fix-github-ssh-key.sh displayName: 'Fix GitHub SSH host key' -- bash: cd $(System.DefaultWorkingDirectory)/xamarin-macios/ && git clean -xdf - displayName: 'Clean workspace' +- pwsh: '& "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"' + displayName: 'Show Bot Info' -- bash: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/bash/clean-bot.sh +- bash: '$SYSTEM_DEFAULTWORKINGDIRECTORY/${BUILD_REPOSITORY_NAME/#*\//}/tools/devops/automation/scripts/bash/clean-bot.sh' displayName: 'Clean bot' continueOnError: true timeoutInMinutes: 60 -- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 - displayName: 'Show Environment' - -- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_python_env.ps1 - displayName: 'Show Python information' - -- bash: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/bash/delete-library-dirs.sh - displayName: 'Delete library folders' - timeoutInMinutes: 5 - -- bash: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/bash/clean-results-dir.sh - workingDirectory: $(System.DefaultWorkingDirectory) - displayName: 'Clear results directory' - timeoutInMinutes: 5 - continueOnError: true - - bash: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/bash/remove-ui-prompt.sh env: OSX_KEYCHAIN_PASS: ${{ parameters.keyringPass }} diff --git a/tools/devops/automation/templates/mac/build.yml b/tools/devops/automation/templates/mac/build.yml index 504c68d79372..a2311ebeb463 100644 --- a/tools/devops/automation/templates/mac/build.yml +++ b/tools/devops/automation/templates/mac/build.yml @@ -64,18 +64,16 @@ steps: condition: succeededOrFailed() # we do not care about the previous process cleanup continueOnError: true -- 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. -- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 - displayName: 'Show Environment' +- pwsh: '"$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"' + displayName: 'Show Bot Info' -- bash: | - ioreg -l | grep -e Manufacturer -e 'Vendor Name' - displayName: 'Dump Hardware' +- bash: '$SYSTEM_DEFAULTWORKINGDIRECTORY/${BUILD_REPOSITORY_NAME/#*\//}/tools/devops/automation/scripts/bash/clean-bot.sh' + displayName: 'Clean bot' + continueOnError: true + timeoutInMinutes: 60 - bash: | if [[ $(ioreg -l | grep -e 'VMware' | wc -l) -ne 0 ]]; then @@ -95,11 +93,6 @@ steps: displayName: 'Set VM Vendor' -- bash: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/bash/clean-bot.sh - displayName: 'Clean bot' - continueOnError: true - timeoutInMinutes: 60 - # Use a cmdlet to check if the space available in the devices root system is larger than 50 gb. If there is not # enough space available it: # 1. Set the status of the build to error. It is not a failure since no tests have been ran. @@ -109,7 +102,7 @@ steps: Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\xamarin-macios\tools\devops\automation\scripts\MaciosCI.psd1 if ( -not (Test-HDFreeSpace -Size 5)) { - Set-Content -Path "$GITHUB_FAILURE_COMMENT_FILE" -Value "Not enough free space in the host." + Set-Content -Path "$GITHUB_FAILURE_COMMENT_FILE" -Value "Not enough free space in the host $Env:AGENT_MACHINENAME." exit 1 } env: 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 30aefb1eabde..2a5ff8660580 100644 --- a/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml +++ b/tools/devops/automation/templates/pipelines/run-macos-tests-pipeline.yml @@ -21,49 +21,7 @@ parameters: - name: macTestsConfigurations displayName: macOS test configurations to run type: object - default: [ - { - 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" - ] - }] + default: [] - name: pool type: string diff --git a/tools/devops/automation/templates/tests-stage.yml b/tools/devops/automation/templates/tests-stage.yml index 8916e575cf35..48adaa0e5030 100644 --- a/tools/devops/automation/templates/tests-stage.yml +++ b/tools/devops/automation/templates/tests-stage.yml @@ -206,42 +206,6 @@ stages: statusContext: 'VSTS: simulator tests' uploadArtifacts: true -# always run simulator tests -- template: ./tests/stage.yml - parameters: - xcodeChannel: ${{ parameters.xcodeChannel }} - macOSName: ${{ parameters.macOSName }} - isPR: ${{ parameters.isPR }} - repositoryAlias: ${{ parameters.repositoryAlias }} - commit: ${{ parameters.commit }} - testConfigurations: ${{ parameters.testConfigurations }} - supportedPlatforms: ${{ parameters.supportedPlatforms }} - stageName: 'simulator_tests' - displayName: '${{ parameters.stageDisplayNamePrefix }}Simulator tests' - testPool: '' # use the default - statusContext: 'VSTS: simulator tests' - makeTarget: 'jenkins' - vsdropsPrefix: ${{ variables.vsdropsPrefix }} - keyringPass: $(pass--lab--mac--builder--keychain) - gitHubToken: $(Github.Token) - xqaCertPass: $(xqa--certificates--password) - condition: ${{ parameters.runTests }} - postPipeline: true - -- template: ./tests/publish-results.yml - parameters: - displayName: '${{ parameters.stageDisplayNamePrefix }}Publish Test Results' - stageName: 'publish_test_results' - statusContext: 'VSTS: test results' - vsdropsPrefix: ${{ variables.vsdropsPrefix }} - condition: ${{ parameters.runTests }} - testConfigurations: ${{ parameters.testConfigurations }} - supportedPlatforms: ${{ parameters.supportedPlatforms }} - isPR: ${{ parameters.isPR }} - repositoryAlias: ${{ parameters.repositoryAlias }} - commit: ${{ parameters.commit }} - postPipeline: true - - ${{ if eq(parameters.runWindowsIntegration, true) }}: - template: ./windows/stage.yml parameters: diff --git a/tools/devops/automation/templates/tests/build.yml b/tools/devops/automation/templates/tests/build.yml index 58396ef89bd5..98c2482478b9 100644 --- a/tools/devops/automation/templates/tests/build.yml +++ b/tools/devops/automation/templates/tests/build.yml @@ -99,7 +99,7 @@ steps: Import-Module ./MaciosCI.psd1 if ( -not (Test-HDFreeSpace -Size 20)) { - New-GitHubComment -Header "Tests failed catastrophically on $Env:CONTEXT" -Emoji ":fire:" -Description "Not enough free space in the host." + New-GitHubComment -Header "Tests failed catastrophically on $Env:CONTEXT" -Emoji ":fire:" -Description "Not enough free space in the host $Env:AGENT_MACHINENAME." Stop-Pipeline } env: diff --git a/tools/devops/automation/templates/tests/publish-html.yml b/tools/devops/automation/templates/tests/publish-html.yml index 79d44e48d23f..f87874c68f70 100644 --- a/tools/devops/automation/templates/tests/publish-html.yml +++ b/tools/devops/automation/templates/tests/publish-html.yml @@ -49,8 +49,8 @@ steps: - template: download-artifacts.yml -- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 - displayName: 'Show Environment' +- pwsh: '"$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"' + displayName: 'Show Bot Info' # build a message with all the content of all tests, to do so, we get the labels and to pass them to pwsh we do a join with ; # as the separator diff --git a/tools/devops/automation/templates/windows/build.yml b/tools/devops/automation/templates/windows/build.yml index c8c39389992f..80c95b91f2d2 100644 --- a/tools/devops/automation/templates/windows/build.yml +++ b/tools/devops/automation/templates/windows/build.yml @@ -37,8 +37,8 @@ steps: repositoryAlias: ${{ parameters.repositoryAlias }} commit: ${{ parameters.commit }} -- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 - displayName: 'Dump Environment' +- pwsh: '"$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"' + displayName: 'Show Bot Info' - ${{ 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 @@ -127,9 +127,6 @@ steps: displayName: "Write and verify id_rsa" continueOnError: true -- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 - displayName: 'Show Environment' - - pwsh: | Import-Module $Env:SYSTEM_DEFAULTWORKINGDIRECTORY\\xamarin-macios\\tools\\devops\\automation\\scripts\\MaciosCI.psd1 ssh -v -i "$(ID_RSA_PATH)" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no builder@$Env:MAC_AGENT_IP pwd diff --git a/tools/devops/automation/templates/windows/reenable-mac.yml b/tools/devops/automation/templates/windows/reenable-mac.yml index 269802117011..bc9f0474b0a6 100644 --- a/tools/devops/automation/templates/windows/reenable-mac.yml +++ b/tools/devops/automation/templates/windows/reenable-mac.yml @@ -19,8 +19,8 @@ steps: repositoryAlias: ${{ parameters.repositoryAlias }} commit: ${{ parameters.commit }} -- pwsh: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts/show_env.ps1 - displayName: 'Dump Environment' +- pwsh: '"$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"' + displayName: 'Show Bot Info' - task: AzureKeyVault@2 inputs: diff --git a/tools/devops/automation/templates/windows/reserve-mac.yml b/tools/devops/automation/templates/windows/reserve-mac.yml index 9c8710d9b619..83ab5a98fb4a 100644 --- a/tools/devops/automation/templates/windows/reserve-mac.yml +++ b/tools/devops/automation/templates/windows/reserve-mac.yml @@ -33,6 +33,14 @@ steps: - checkout: maccore persistCredentials: true # hugely important, else there are some scripts that check a single file from maccore that will fail +- pwsh: '& "$Env:SYSTEM_DEFAULTWORKINGDIRECTORY/$($Env:BUILD_REPOSITORY_NAME.Split(''/'')[1])/tools/devops/automation/scripts/show_bot_info.ps1"' + displayName: 'Show Bot Info' + +- bash: '$SYSTEM_DEFAULTWORKINGDIRECTORY/${BUILD_REPOSITORY_NAME/#*\//}/tools/devops/automation/scripts/bash/clean-bot.sh' + displayName: 'Clean bot' + continueOnError: true + timeoutInMinutes: 60 + - bash: $(Build.SourcesDirectory)/xamarin-macios/tools/devops/automation/scripts/disable-codeql-arm64.sh displayName: 'Disable CodeQL on arm64' name: disableCodeQLOnArm64