/// <inheritdoc />
        public async Task ProcessPayload(PullRequestEventPayload payload, CancellationToken cancellationToken)
        {
            if (payload == null)
            {
                throw new ArgumentNullException(nameof(payload));
            }

            if (payload.Action != "edited")
            {
                throw new NotSupportedException();
            }

            var signOff = await dataStore.ReadData <PullRequestSignOffs>(SignOffDataKey, cancellationToken).ConfigureAwait(false);

            if (!signOff.Entries.Remove(payload.PullRequest.Number))
            {
                return;
            }

            await dataStore.WriteData(SignOffDataKey, signOff, cancellationToken).ConfigureAwait(false);

            var botLoginTask = gitHubManager.GetUserLogin(null, cancellationToken);
            var reviews      = await gitHubManager.GetPullRequestReviews(payload.PullRequest).ConfigureAwait(false);

            var botLogin = await botLoginTask.ConfigureAwait(false);

            await Task.WhenAll(
                reviews.Where(
                    x => x.User.Id == botLogin.Id &&
                    x.State.Value == PullRequestReviewState.Approved
                    ).Select(
                    x => gitHubManager.DismissReview(payload.PullRequest, x, stringLocalizer["SignOffNulled"])
                    ));
        }
示例#2
0
        /// <summary>
        /// Erases the sign off and dismisses the 'approved' reviews
        /// </summary>
        /// <param name="pullRequest">The <see cref="PullRequest"/> to un-sign</param>
        /// <param name="message">The dismissal message</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
        /// <returns>A <see cref="Task"/> representing the running operation</returns>
        async Task EraseAndDismissReviews(PullRequest pullRequest, string message, CancellationToken cancellationToken)
        {
            var reviewsTask  = gitHubManager.GetPullRequestReviews(pullRequest);
            var botLoginTask = gitHubManager.GetUserLogin(null, cancellationToken);
            await dataStore.WriteData(pullRequest.Number.ToString(CultureInfo.InvariantCulture), new PullRequestSignOff(), cancellationToken).ConfigureAwait(false);

            var reviews = await reviewsTask.ConfigureAwait(false);

            var botLogin = await botLoginTask.ConfigureAwait(false);

            await Task.WhenAll(
                reviews.Where(
                    x => x.User.Id == botLogin.Id &&
                    x.State.Value == PullRequestReviewState.Approved
                    ).Select(
                    x => gitHubManager.DismissReview(pullRequest, x, message)
                    )).ConfigureAwait(false);
        }
示例#3
0
        /// <inheritdoc />
        public async Task <AutoMergeStatus> EvaluateFor(PullRequest pullRequest, CancellationToken cancellationToken)
        {
            if (gitHubManager == null)
            {
                throw new InvalidOperationException("Configure() wasn't called!");
            }

            var reviews = await gitHubManager.GetPullRequestReviews(pullRequest).ConfigureAwait(false);

            var approvers = new List <User>();
            var critics   = new List <User>();

            var userCheckups = new Dictionary <string, Task <bool> >();

            foreach (var I in reviews)
            {
                void CheckupUser()
                {
                    if (!userCheckups.ContainsKey(I.User.Login))
                    {
                        userCheckups.Add(I.User.Login, gitHubManager.UserHasWriteAccess(I.User));
                    }
                }

                if (I.State.Value == PullRequestReviewState.Approved)
                {
                    critics.RemoveAll(x => x.Id == I.User.Id);
                    approvers.Add(I.User);
                    CheckupUser();
                }
                else if (I.State.Value == PullRequestReviewState.ChangesRequested)
                {
                    approvers.RemoveAll(x => x.Id == I.User.Id);
                    critics.Add(I.User);
                    CheckupUser();
                }
            }

            var result = new AutoMergeStatus();

            await Task.WhenAll(userCheckups.Select(x => x.Value)).ConfigureAwait(false);

            foreach (var I in approvers)
            {
                if (!userCheckups[I.Login].Result)
                {
                    continue;
                }

                ++result.Progress;
                result.Notes.Add(stringLocalizer["ApprovedBy", I.Login]);
            }

            if (result.Progress == 0)
            {
                result.Notes.Add(stringLocalizer["NoApproval"]);
            }

            result.RequiredProgress = result.Progress;

            foreach (var I in critics)
            {
                if (!userCheckups[I.Login].Result)
                {
                    continue;
                }

                ++result.RequiredProgress;
                result.Notes.Add(stringLocalizer["RequestedChanges", I.Login]);
            }

            result.RequiredProgress = Math.Max(result.RequiredProgress, 1);

            return(result);
        }