|
12 | 12 | using System.Runtime.InteropServices; |
13 | 13 | using System.Text.RegularExpressions; |
14 | 14 | using System.Threading; |
| 15 | +using System.Threading.Tasks; |
15 | 16 | using System.Xml.Linq; |
16 | | -using Task = System.Threading.Tasks.Task; |
| 17 | +using Microsoft.DotNet.UnifiedBuild.Tasks.Services; |
| 18 | +using BuildTask = Microsoft.Build.Utilities.Task; |
17 | 19 |
|
18 | 20 | namespace Microsoft.DotNet.UnifiedBuild.Tasks; |
19 | 21 |
|
20 | | -public class SigningValidation : Microsoft.Build.Utilities.Task |
| 22 | +public class SigningValidation : BuildTask |
21 | 23 | { |
22 | 24 | /// <summary> |
23 | 25 | /// Directory where the blobs and packages were downloaded to |
@@ -58,21 +60,24 @@ public class SigningValidation : Microsoft.Build.Utilities.Task |
58 | 60 | /// </summary> |
59 | 61 | private static readonly string _signCheckFilesDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName(), "SignCheckFiles"); |
60 | 62 |
|
| 63 | + private const string _signCheckBinLogFileName = "signing-validation.binlog"; |
61 | 64 | private const string _signCheckExclusionsFileName = "SignCheckExclusionsFile.txt"; |
62 | 65 | private const string _signCheckStdoutLogFileName = "signcheck.log"; |
63 | 66 | private const string _signCheckStderrLogFileName = "signcheck.error.log"; |
64 | 67 | private const string _signCheckResultsXmlFileName = "signcheck.xml"; |
65 | 68 | private const int _signCheckTimeout = 60 * 60 * 1000 * 2; // 2 hours |
66 | 69 |
|
67 | | - public override bool Execute() |
| 70 | + public override bool Execute() => ExecuteAsync().GetAwaiter().GetResult(); |
| 71 | + |
| 72 | + private async Task<bool> ExecuteAsync() |
68 | 73 | { |
69 | 74 | try |
70 | 75 | { |
71 | 76 | ForceDirectory(OutputLogsDirectory); |
72 | 77 |
|
73 | 78 | PrepareFilesToSignCheck(); |
74 | 79 |
|
75 | | - RunSignCheck(); |
| 80 | + await RunSignCheckAsync(); |
76 | 81 |
|
77 | 82 | ProcessSignCheckResults(); |
78 | 83 |
|
@@ -184,56 +189,33 @@ private void PrepareFilesToSignCheck() |
184 | 189 | /// <summary> |
185 | 190 | /// Runs the signcheck task on the specified package base path |
186 | 191 | /// </summary> |
187 | | - private void RunSignCheck() |
| 192 | + private async Task RunSignCheckAsync() |
188 | 193 | { |
189 | | - using (var process = new Process()) |
| 194 | + (string command, string arguments) = GetSignCheckCommandAndArguments(); |
| 195 | + Log.LogMessage(MessageImportance.High, $"Running SignCheck..."); |
| 196 | + |
| 197 | + var processService = new ProcessService(Log, timeout: _signCheckTimeout); |
| 198 | + ProcessResult result = await processService.RunProcessAsync( |
| 199 | + command, |
| 200 | + arguments, |
| 201 | + printOutput: false); |
| 202 | + |
| 203 | + string errorLog = GetLogPath(_signCheckStderrLogFileName); |
| 204 | + string errorLogContent = File.Exists(errorLog) ? File.ReadAllText(errorLog).Trim() : string.Empty; |
| 205 | + if (result.ExitCode != 0 || !string.IsNullOrWhiteSpace(errorLogContent)) |
190 | 206 | { |
191 | | - (string command, string arguments) = GetSignCheckCommandAndArguments(); |
192 | | - |
193 | | - process.StartInfo = new ProcessStartInfo() |
194 | | - { |
195 | | - FileName = command, |
196 | | - Arguments = arguments, |
197 | | - UseShellExecute = false, |
198 | | - RedirectStandardOutput = true, |
199 | | - RedirectStandardError = true, |
200 | | - }; |
201 | | - |
202 | | - // SignCheck writes console output to log files and the output stream. |
203 | | - // To avoid cluttering the console, redirect the output to empty handlers. |
204 | | - process.OutputDataReceived += (sender, args) => { }; |
205 | | - process.ErrorDataReceived += (sender, args) => { }; |
206 | | - |
207 | | - Log.LogMessage(MessageImportance.High, $"Running SignCheck..."); |
208 | | - |
209 | | - process.Start(); |
210 | | - |
211 | | - process.BeginOutputReadLine(); |
212 | | - process.BeginErrorReadLine(); |
213 | | - |
214 | | - bool hasExited = process.WaitForExit(_signCheckTimeout); |
215 | | - if (!hasExited) |
216 | | - { |
217 | | - throw new TimeoutException($"SignCheck timed out after {_signCheckTimeout / 1000} seconds."); |
218 | | - } |
219 | | - |
220 | | - string errorLog = GetLogPath(_signCheckStderrLogFileName); |
221 | | - string errorLogContent = File.Exists(errorLog) ? File.ReadAllText(errorLog).Trim() : string.Empty; |
222 | | - if (process.ExitCode != 0 || !string.IsNullOrWhiteSpace(errorLogContent)) |
223 | | - { |
224 | | - // We don't want to throw here because SignCheck will fail for unsigned files |
225 | | - Log.LogError($"SignCheck failed with exit code {process.ExitCode}: {errorLogContent}"); |
226 | | - } |
227 | | - |
228 | | - string stdoutLog = GetLogPath(_signCheckStdoutLogFileName); |
229 | | - string stdoutLogContent = File.Exists(stdoutLog) ? File.ReadAllText(stdoutLog).Trim() : string.Empty; |
230 | | - if (!string.IsNullOrWhiteSpace(stdoutLogContent) && stdoutLogContent.Contains("No files were processed")) |
231 | | - { |
232 | | - Log.LogError("SignCheck did not process any files."); |
233 | | - } |
| 207 | + // We don't want to throw here because SignCheck will fail for unsigned files |
| 208 | + Log.LogError($"SignCheck failed with exit code {result.ExitCode}: {errorLogContent}"); |
| 209 | + } |
234 | 210 |
|
235 | | - Log.LogMessage(MessageImportance.High, $"SignCheck completed."); |
| 211 | + string stdoutLog = GetLogPath(_signCheckStdoutLogFileName); |
| 212 | + string stdoutLogContent = File.Exists(stdoutLog) ? File.ReadAllText(stdoutLog).Trim() : string.Empty; |
| 213 | + if (!string.IsNullOrWhiteSpace(stdoutLogContent) && stdoutLogContent.Contains("No files were processed")) |
| 214 | + { |
| 215 | + Log.LogError("SignCheck did not process any files."); |
236 | 216 | } |
| 217 | + |
| 218 | + Log.LogMessage(MessageImportance.High, $"SignCheck completed."); |
237 | 219 | } |
238 | 220 |
|
239 | 221 | private void ProcessSignCheckResults() |
@@ -322,6 +304,7 @@ private bool LogAndCheckResults(IEnumerable<string> results, string issueType) |
322 | 304 | $"/p:SignCheckErrorLog='{GetLogPath(_signCheckStderrLogFileName)}' " + |
323 | 305 | $"/p:SignCheckResultsXmlFile='{GetLogPath(_signCheckResultsXmlFileName)}' " + |
324 | 306 | $"/p:SignCheckExclusionsFile='{GetSignCheckExclusionsFile()}' " + |
| 307 | + $"/bl:{GetLogPath(_signCheckBinLogFileName)} " + |
325 | 308 | $"$additionalArgs$"; |
326 | 309 |
|
327 | 310 | string command = string.Empty; |
|
0 commit comments