| File: AnalysisPublicationQueries.cs | Web Access |
| Project: src\tools\AnalyzeCiFailure\AnalyzeCiFailure.csproj (AnalyzeCiFailure) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json.Nodes; namespace AnalyzeCiFailure; /// <summary>Reads fresh cause destinations, PR actionability and existing analysis comments before publication effects.</summary> internal sealed class AnalysisPublicationQueries(AnalysisGitHubClient github) { internal async Task<(JsonArray Open, JsonArray Closed)> GetCauseIssuesAsync(string repository) { async Task<JsonArray> State(string state) { try { var issues = await github.GetRowsAsync($"repos/{repository}/issues?state={state}&labels=ci-failure-cause&per_page=100"); return new JsonArray(issues.Where(issue => CiFailureJson.Field(issue, "pull_request") is null) .Select(issue => issue?.DeepClone()).ToArray()); } catch (Exception ex) when (ex is ValidationException or System.Text.Json.JsonException) { throw new ValidationException($"Failed to load {state} cause issues: {ex.Message}"); } } var open = await State("open"); var closed = await State("closed"); return (open, closed); } internal async Task<bool> IsPullRequestOpenAndUnlockedAsync(string repository, string pr) { JsonNode? response; try { response = await github.GetAsync($"repos/{repository}/pulls/{pr}"); } catch (Exception ex) when (ex is ValidationException or System.Text.Json.JsonException) { throw new ValidationException($"Unable to determine whether PR #{pr} is actionable: {ex.Message}"); } if (!(response is JsonObject && CiFailureJson.Text(response["state"]) is not null && response["locked"] is JsonValue locked && locked.TryGetValue<bool>(out _))) { throw new ValidationException($"Unable to determine whether PR #{pr} is actionable"); } return CiFailureJson.Text(response!["state"]) == "open" && CiFailureJson.IsFalse(response["locked"]); } internal async Task<string> FindAnalysisCommentIdAsync(string repository, string pr) { JsonArray comments; try { comments = await github.GetRowsAsync($"repos/{repository}/issues/{pr}/comments?per_page=100"); } catch (Exception ex) when (ex is ValidationException or System.Text.Json.JsonException) { throw new ValidationException($"Failed to list existing analysis comments: {ex.Message}"); } var match = comments.Where(comment => CiFailureJson.Text(CiFailureJson.Field(CiFailureJson.Field(comment, "user"), "login")) == "github-actions[bot]" && (CiFailureJson.Text(CiFailureJson.Field(comment, "body")) ?? "").StartsWith("<!-- analyze-ci-failure -->\n", StringComparison.Ordinal)) .OrderBy(comment => GitHubJson.ReadRequiredId(CiFailureJson.Field(comment, "id"))) .FirstOrDefault(); return match is null ? "" : CiFailureJson.GetValueText(CiFailureJson.Field(match, "id")); } }