/// <summary>
        ///     Update a check run based on a NewCheckRun and evaluation
        /// </summary>
        /// <param name="newCheckRun">The NewCheckRun that needs to be updated</param>
        /// <param name="eval">The result of that updated check run</param>
        /// <returns>The updated CheckRun</returns>
        private CheckRunUpdate CheckRunForUpdate(MergePolicyEvaluationResult eval)
        {
            CheckRunUpdate updatedCheckRun = new CheckRunUpdate();

            UpdateCheckRun(updatedCheckRun, eval);
            return(updatedCheckRun);
        }
        public async Task CreateOrUpdatePullRequestMergeStatusInfoAsync(string pullRequestUrl, IReadOnlyList <MergePolicyEvaluationResult> evaluations)
        {
            (string owner, string repo, int id) = ParsePullRequestUri(pullRequestUrl);
            // Get the sha of the latest commit for the current PR
            string prSha = (await Client.PullRequest.Get(owner, repo, id))?.Head?.Sha;

            if (prSha == null)
            {
                throw new InvalidOperationException("We cannot find the sha of the pull request");
            }

            // Get a list of all the merge policies checks runs for the current PR
            List <CheckRun> existingChecksRuns =
                (await Client.Check.Run.GetAllForReference(owner, repo, prSha))
                .CheckRuns.Where(e => e.ExternalId.StartsWith(MergePolicyConstants.MaestroMergePolicyCheckRunPrefix)).ToList();

            var toBeAdded   = evaluations.Where(e => existingChecksRuns.All(c => c.ExternalId != CheckRunId(e, prSha)));
            var toBeUpdated = existingChecksRuns.Where(c => evaluations.Any(e => c.ExternalId == CheckRunId(e, prSha)));
            var toBeDeleted = existingChecksRuns.Where(c => evaluations.All(e => c.ExternalId != CheckRunId(e, prSha)));

            foreach (var newCheckRunValidation in toBeAdded)
            {
                await Client.Check.Run.Create(owner, repo, CheckRunForAdd(newCheckRunValidation, prSha));
            }
            foreach (var updatedCheckRun in toBeUpdated)
            {
                MergePolicyEvaluationResult eval           = evaluations.Single(e => updatedCheckRun.ExternalId == CheckRunId(e, prSha));
                CheckRunUpdate newCheckRunUpdateValidation = CheckRunForUpdate(eval);
                await Client.Check.Run.Update(owner, repo, updatedCheckRun.Id, newCheckRunUpdateValidation);
            }
            foreach (var deletedCheckRun in toBeDeleted)
            {
                await Client.Check.Run.Update(owner, repo, deletedCheckRun.Id, CheckRunForDelete(deletedCheckRun));
            }
        }
        /// <summary>
        ///     Create a NewCheckRun based on the result of the merge policy
        /// </summary>
        /// <param name="result">The evaluation of the merge policy</param>
        /// <param name="sha">Sha of the latest commit</param>
        /// <returns>The new check run</returns>
        private NewCheckRun CheckRunForAdd(MergePolicyEvaluationResult result, string sha)
        {
            var newCheckRun = new NewCheckRun($"{MergePolicyConstants.MaestroMergePolicyDisplayName} - {result.MergePolicyInfo.DisplayName}", sha);

            newCheckRun.ExternalId = CheckRunId(result, sha);
            UpdateCheckRun(newCheckRun, result);
            return(newCheckRun);
        }
        /// <summary>
        ///     Update some properties of a CheckRunUpdate
        /// </summary>
        /// <param name="newUpdateCheckRun">The CheckRunUpdate that needs to be updated</param>
        /// <param name="result">The result of that new check run</param>
        private void UpdateCheckRun(CheckRunUpdate newUpdateCheckRun, MergePolicyEvaluationResult result)
        {
            var output = FormatOutput(result);

            newUpdateCheckRun.Output = output;
            newUpdateCheckRun.Status = CheckStatus.Completed;

            if (result.Status == MergePolicyEvaluationStatus.Pending)
            {
                newUpdateCheckRun.Status = CheckStatus.InProgress;
            }
            else if (result.Status == MergePolicyEvaluationStatus.Success)
            {
                newUpdateCheckRun.Conclusion  = "success";
                newUpdateCheckRun.CompletedAt = DateTime.Now;
            }
            else
            {
                newUpdateCheckRun.Conclusion  = "failure";
                newUpdateCheckRun.CompletedAt = DateTime.UtcNow;
            }
        }
 private static NewCheckRunOutput FormatOutput(MergePolicyEvaluationResult result)
 {
     return(new NewCheckRunOutput(result.Message ?? "no details", string.Empty));
 }
 /// <summary>
 ///     Returns the ID used to identify the maestro merge policies checks in a PR
 /// </summary>
 /// <param name="mergePolicyName">Name of the merge policy</param>
 /// <param name="sha">Sha of the latest commit in the PR</param>
 private string CheckRunId(MergePolicyEvaluationResult result, string sha)
 {
     return($"{MergePolicyConstants.MaestroMergePolicyCheckRunPrefix}{result.MergePolicyInfo.Name}-{sha}");
 }