| File: GenerateTestDevCert.cs | Web Access |
| Project: src\aspnetcore\eng\tools\RepoTasks\RepoTasks.csproj (RepoTasks) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Linq; using System.Text.Json; using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; namespace RepoTasks; /// <summary> /// Generates the test HTTPs certificate used by the template tests /// </summary> public class GenerateTestDevCert : Microsoft.Build.Utilities.Task { [Required] public string CertificatePath { get; private set; } public override bool Execute() { Mutex mutex = null; try { // MSBuild will potentially invoke this task in parallel across different subprocesses/nodes. // The build is configured to generate the certificate in a single location, but multiple projects // import the same targets that will use this task, which will result in multiple calls. // To avoid issues where we try to generate multiple certificates on the same location, we wrap the // usage in a named mutex which guarantees that only one instance will run at a time. mutex = new(initiallyOwned: true, "Global\\GenerateTestDevCert", out var createdNew); if (!createdNew) { // The mutex already exists, wait for it to be released. mutex.WaitOne(); } if (File.Exists(CertificatePath)) { Log.LogMessage(MessageImportance.Normal, $"A test certificate already exists at {CertificatePath}"); return true; } var cert = DevelopmentCertificate.Create(CertificatePath); var devCertJsonFile = Path.ChangeExtension(CertificatePath, ".json"); var devCertJson = new CertificateInfo { Password = cert.CertificatePassword, Thumbprint = cert.CertificateThumbprint }; using var file = File.OpenWrite(devCertJsonFile); file.SetLength(0); JsonSerializer.Serialize(file, devCertJson); } catch (Exception e) { Log.LogErrorFromException(e, showStackTrace: true); } finally { mutex.ReleaseMutex(); } return !Log.HasLoggedErrors; } private class CertificateInfo { public string Password { get; set; } public string Thumbprint { get; set; } } }