diff --git a/src/dotnet-trx/Process.cs b/src/dotnet-trx/Process.cs index 9b863fc..f9b60d6 100644 --- a/src/dotnet-trx/Process.cs +++ b/src/dotnet-trx/Process.cs @@ -40,9 +40,6 @@ static bool TryExecuteCore(ProcessStartInfo info, string? input, out string? out try { info.StandardOutputEncoding = Encoding.UTF8; - //if (input != null) - // info.StandardInputEncoding = Encoding.UTF8; - var proc = System.Diagnostics.Process.Start(info); if (proc == null) { @@ -69,7 +66,7 @@ static bool TryExecuteCore(ProcessStartInfo info, string? input, out string? out } var error = proc.StandardError.ReadToEnd(); - gotError |= error.Length > 0; + gotError |= error.Trim().Length > 0; output = output.Trim(); if (string.IsNullOrEmpty(output)) output = null; diff --git a/src/dotnet-trx/TrxCommand.cs b/src/dotnet-trx/TrxCommand.cs index 7912c35..f9bae97 100644 --- a/src/dotnet-trx/TrxCommand.cs +++ b/src/dotnet-trx/TrxCommand.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -335,7 +336,41 @@ static void AppendBadges(Summary summary, StringBuilder builder, string elapsed, { // API requires a json payload File.WriteAllText(input, JsonSerializer.Serialize(new { body })); - TryExecute("gh", $"api repos/{repo}/issues/comments/{commentId} -X PATCH --input {input}", out _); + static bool TryGetETag(string repo, long comment, [NotNullWhen(true)] out string? etag) + { + etag = null; + if (TryExecute("gh", $"api -i repos/{repo}/issues/comments/{comment}", out var headers) && + headers?.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(x => x.StartsWith("Etag:", StringComparison.OrdinalIgnoreCase)) is { } etagHeader) + etag = etagHeader.Split(":")[1].Trim(); + + // TODO: this DOES NOT WORK FOR NOW + // See https://github.com/orgs/community/discussions/50084 + //return etag != null; + return false; + } + + if (TryGetETag(repo, commentId, out var etag)) + { + // If we're patching, we need to do optimistic concurrency check to avoid losing updates + while (!TryExecute("gh", + [ + "api", + "-H", $"if-match: {etag}", + "-X", "PATCH", + $"repos/{repo}/issues/comments/{commentId}", + "--input", input + ], out _)) + { + if (!TryGetETag(repo, commentId, out var newEtag) || newEtag == etag) + break; + + etag = newEtag; + } + } + else + { + TryExecute("gh", $"api repos/{repo}/issues/comments/{commentId} -X PATCH --input {input}", out _); + } } else {