public async Task <IActionResult> SignOff(int prNumber, CancellationToken cancellationToken)
        {
            var token = await gitHubManager.CheckAuthorization(Request.Cookies, cancellationToken).ConfigureAwait(false);

            if (token == null)
            {
                return(Unauthorized());
            }

            var user = await gitHubManager.GetUserLogin(token, cancellationToken).ConfigureAwait(false);

            if (!await gitHubManager.UserHasWriteAccess(user).ConfigureAwait(false))
            {
                return(Forbid());
            }

            var pr = await gitHubManager.GetPullRequest(prNumber).ConfigureAwait(false);

#if !ENABLE_SELF_SIGN
            //no self signing
            if (pr.User.Id == user.Id)
            {
                return(Forbid());
            }
#endif

            await signOffModule.SignOff(pr, user, token, cancellationToken).ConfigureAwait(false);

            autoMergeHandler.RecheckPullRequest(prNumber);

            return(Json(new object()));
        }
Beispiel #2
0
        public async Task <IActionResult> ReviewPullRequest(int number, CancellationToken cancellationToken)
        {
            var token = await gitHubManager.CheckAuthorization(Request.Cookies, cancellationToken).ConfigureAwait(false);

            ViewBag.Title     = stringLocalizer["PullRequest", number];
            ViewBag.PRNumber  = number;
            ViewBag.RepoOwner = gitHubConfiguration.RepoOwner;
            ViewBag.RepoName  = gitHubConfiguration.RepoName;

            var pr = await gitHubManager.GetPullRequest(number).ConfigureAwait(false);

            ViewBag.PullRequestAuthor   = pr.User.Login;
            ViewBag.PullRequestAuthorID = pr.User.Id;
            ViewBag.PullRequestTitle    = pr.Title;


            if (token == null)
            {
                ViewBag.AuthHref  = String.Concat(generalConfiguration.RootURL.ToString(), "Authorize/Login/", number);
                ViewBag.AuthTitle = stringLocalizer["SignIn"];
            }
            else
            {
                var user = await gitHubManager.GetUserLogin(token, cancellationToken).ConfigureAwait(false);

                ViewBag.AuthHref  = String.Concat(generalConfiguration.RootURL.ToString(), "Authorize/SignOut/", number);
                ViewBag.AuthTitle = stringLocalizer["SignOut", user.Login];
            }
            return(View());
        }
Beispiel #3
0
 /// <summary>
 /// Rechecks the <see cref="AutoMergeStatus"/>es of a given <paramref name="pullRequestNumber"/>
 /// </summary>
 /// <param name="pullRequestNumber">The <see cref="PullRequest.Number"/> <see cref="PullRequest"/> to check</param>
 /// <param name="jobCancellationToken">The <see cref="IJobCancellationToken"/> for the operation</param>
 /// <returns>A <see cref="Task"/> representing the running operation</returns>
 async Task RecheckPullRequest(int pullRequestNumber, IJobCancellationToken jobCancellationToken)
 {
     logger.LogDebug("Running scheduled recheck of pull request #{0}.", pullRequestNumber);
     try
     {
         var pullRequest = await gitHubManager.GetPullRequest(pullRequestNumber).ConfigureAwait(false);
         await CheckMergePullRequest(pullRequest, jobCancellationToken.ShutdownToken).ConfigureAwait(false);
     }
     catch (OperationCanceledException e)
     {
         logger.LogDebug(e, "Pull request recheck cancelled!");
     }
     catch (Exception e)
     {
         logger.LogError(e, "Pull request recheck failed!");
     }
 }
        public async Task <IActionResult> Receive(long repositoryId, int prNumber, CancellationToken cancellationToken)
        {
            logger.LogInformation("Triggering job for {0}/{1}", repositoryId, prNumber);
            var pr = await gitHubManager.GetPullRequest(repositoryId, prNumber, cancellationToken).ConfigureAwait(false);

            payloadProcessor.ProcessPullRequest(pr);
            return(Redirect(pr.HtmlUrl));
        }
Beispiel #5
0
        public async Task <IActionResult> ReviewPullRequest(int number, CancellationToken cancellationToken)
        {
            var token = await gitHubManager.CheckAuthorization(Request.Cookies, cancellationToken).ConfigureAwait(false);

            ViewBag.Title     = stringLocalizer["PullRequest", number];
            ViewBag.Modules   = stringLocalizer["ManageModules"];
            ViewBag.PRNumber  = number;
            ViewBag.RepoOwner = gitHubConfiguration.RepoOwner;
            ViewBag.RepoName  = gitHubConfiguration.RepoName;

            var pr = await gitHubManager.GetPullRequest(number).ConfigureAwait(false);

            ViewBag.PullRequestAuthor   = pr.User.Login;
            ViewBag.PullRequestAuthorID = pr.User.Id;
            ViewBag.PullRequestTitle    = pr.Title;
            ViewBag.PullRequestNumber   = pr.Number;

            if (token == null)
            {
                ViewBag.AuthHref     = String.Concat(generalConfiguration.RootURL.ToString(), "Authorize/Login/", number);
                ViewBag.AuthTitle    = stringLocalizer["SignIn"];
                ViewBag.IsMaintainer = false;
            }
            else
            {
                var user = await gitHubManager.GetUserLogin(token, cancellationToken).ConfigureAwait(false);

                ViewBag.IsMaintainer = await gitHubManager.UserHasWriteAccess(user).ConfigureAwait(false);

                ViewBag.AuthHref  = String.Concat(generalConfiguration.RootURL.ToString(), "Authorize/SignOut/", number);
                ViewBag.AuthTitle = stringLocalizer["SignOut", user.Login];
            }

            ViewBag.ModuleViews = new List <string>();

            await componentProvider.AddViewVars(pr, ViewBag, cancellationToken);

            return(View());
        }
Beispiel #6
0
        public async Task <IActionResult> ReviewPullRequest(int number, CancellationToken cancellationToken)
        {
            var prTask    = gitHubManager.GetPullRequest(number);
            var tokenTask = gitHubManager.CheckAuthorization(Request.Cookies, cancellationToken);
            var componentInitializeTask = componentProvider.Initialize(cancellationToken);
            var pr = await prTask.ConfigureAwait(false);

            await componentInitializeTask.ConfigureAwait(false);

            if (pr.State.Value == ItemState.Open)
            {
                var tasks = componentProvider.MergeRequirements.Select(x => x.EvaluateFor(pr, cancellationToken));
                await Task.WhenAll(tasks).ConfigureAwait(false);


                var resultDic = new Dictionary <IMergeRequirement, AutoMergeStatus>();
                foreach (var I in Enumerable.Zip(componentProvider.MergeRequirements, tasks, (x, y) => new Tuple <IMergeRequirement, AutoMergeStatus>(x, y.Result)))
                {
                    ++I.Item2.RequiredProgress;
                    ++I.Item2.Progress;
                    resultDic.Add(I.Item1, I.Item2);
                }

                ViewBag.Statuses          = resultDic;
                ViewBag.PullRequestClosed = false;
            }
            else
            {
                ViewBag.PullRequestClosed = true;
            }

            ViewBag.Title                  = stringLocalizer["PullRequest", number];
            ViewBag.Modules                = stringLocalizer["ManageModules"];
            ViewBag.PRNumber               = number;
            ViewBag.RepoOwner              = gitHubConfiguration.RepoOwner;
            ViewBag.RepoName               = gitHubConfiguration.RepoName;
            ViewBag.PullRequestAuthor      = pr.User.Login;
            ViewBag.PullRequestAuthorID    = pr.User.Id;
            ViewBag.PullRequestTitle       = pr.Title;
            ViewBag.PullRequestNumber      = pr.Number;
            ViewBag.PullRequestHref        = pr.HtmlUrl;
            ViewBag.PullRequestAuthorLogin = pr.User.Login;

            ViewBag.CloseMessage      = stringLocalizer["CloseMessage"];
            ViewBag.MergeRequirements = stringLocalizer["MergeRequirements"];


            var token = await tokenTask.ConfigureAwait(false);

            if (token == null)
            {
                ViewBag.AuthHref     = Url.Action("Begin", "Authorization", new { prNumber = number });
                ViewBag.AuthTitle    = stringLocalizer["SignIn"];
                ViewBag.IsMaintainer = false;
                ViewBag.UserIsAuthor = false;
            }
            else
            {
                var user = await gitHubManager.GetUserLogin(token, cancellationToken).ConfigureAwait(false);

                ViewBag.UserIsAuthor = pr.User.Id == user.Id;
                ViewBag.IsMaintainer = await gitHubManager.UserHasWriteAccess(user).ConfigureAwait(false);

                ViewBag.UserLogin = user.Login;
                ViewBag.AuthHref  = Url.Action("SignOut", "Authorization", new { prNumber = number });
                ViewBag.AuthTitle = stringLocalizer["SignOut", user.Login];
            }

            ViewBag.ModuleViews = new List <string>();

            await componentProvider.AddViewVars(pr, (object)ViewBag, cancellationToken).ConfigureAwait(false);

            return(View());
        }
        /// <summary>
        /// Label a pull request
        /// </summary>
        /// <param name="payload">The <see cref="PullRequestEventPayload"/> for the pull request</param>
        /// <param name="oneCheckTags"><see langword="true"/> if additional tags should be contionally applied, <see langword="false"/> otherwise</param>
        /// <returns>A <see cref="Task"/> representing the running operation</returns>
        async Task TagPR(PullRequestEventPayload payload, bool oneCheckTags)
        {
            async Task <bool?> MergeableCheck()
            {
                //check if the PR is mergeable, if not, don't tag it
                bool?mergeable = payload.PullRequest.Mergeable;

                for (var I = 0; !mergeable.HasValue && I < 3; ++I)
                {
                    await Task.Delay(I * 1000).ConfigureAwait(false);

                    mergeable = (await gitHubManager.GetPullRequest(payload.PullRequest.Number).ConfigureAwait(false)).Mergeable;
                }
                return(mergeable);
            };

            var mergeableTask     = MergeableCheck().ConfigureAwait(false);
            var filesChanged      = gitHubManager.GetPullRequestChangedFiles(payload.PullRequest.Number).ConfigureAwait(false);
            var currentLabelsTask = gitHubManager.GetIssueLabels(payload.PullRequest.Number).ConfigureAwait(false);

            var labelsToAdd    = new List <string>();
            var labelsToRemove = new List <string>();

            var lowerTitle = payload.PullRequest.Title.ToLower(CultureInfo.CurrentCulture);

            if (lowerTitle.Contains("refactor"))
            {
                labelsToAdd.Add("Refactor");
            }
            if (lowerTitle.Contains("[dnm]"))
            {
                labelsToAdd.Add("Do Not Merge");
            }
            if (lowerTitle.Contains("[wip]"))
            {
                labelsToAdd.Add("Work In Progress");
            }
            if (lowerTitle.Contains("revert"))
            {
                labelsToAdd.Add("Revert");
            }
            if (lowerTitle.Contains("removes"))
            {
                labelsToAdd.Add("Removal");
            }

            var mergeableCheck = await mergeableTask;

            if (mergeableCheck.HasValue)
            {
                if (!mergeableCheck.Value)
                {
                    labelsToAdd.Add("Merge Conflict");
                }
                else
                {
                    labelsToRemove.Add("Merge Conflict");
                }
            }

            var treeToLabelMappings = new Dictionary <string, string>
            {
                { "_maps", "Map Edit" },
                { "tools", "Tools" },
                { "SQL", "SQL" },
                { ".github", "GitHub" }
            };

            var addOnlyTreeToLabelMappings = new Dictionary <string, string>
            {
                { "icons", "Sprites" },
                { "sound", "Sounds" },
                { "config", "Config Update" },
                { "code/controllers/configuration/entries", "Config Update" },
                { "tgui", "UI" }
            };

            foreach (var I in await filesChanged)
            {
                foreach (var J in treeToLabelMappings)
                {
                    if (I.FileName.StartsWith(J.Key, StringComparison.CurrentCulture))
                    {
                        labelsToAdd.Add(J.Value);
                    }
                    else
                    {
                        labelsToRemove.Add(J.Value);
                    }
                }
                if (oneCheckTags)
                {
                    foreach (var J in addOnlyTreeToLabelMappings)
                    {
                        if (I.FileName.StartsWith(J.Key, StringComparison.CurrentCulture))
                        {
                            labelsToAdd.Add(J.Value);
                        }
                    }
                }
            }

            void UniqueAdd(string label)
            {
                if (!labelsToAdd.Contains(label))
                {
                    labelsToAdd.Add(label);
                }
            }

            //github close syntax (without "close" variants)
            if (Regex.IsMatch(payload.PullRequest.Body, "(?i)(fix|fixes|fixed|resolve|resolves|resolved)\\s*#[1-9][0-9]*"))
            {
                UniqueAdd("Fix");
            }

            //run through the changelog
            var changelog = Changelog.GetChangelog(payload.PullRequest, out bool malformed);

            if (changelog != null)
            {
                foreach (var I in changelog.Changes.Select(x => x.Type))
                {
                    switch (I)
                    {
                    case ChangelogEntryType.Admin:
                        UniqueAdd("Administration");
                        break;

                    case ChangelogEntryType.Balance:
                        UniqueAdd("Balance/Rebalance");
                        break;

                    case ChangelogEntryType.BugFix:
                        UniqueAdd("Fix");
                        break;

                    case ChangelogEntryType.Code_Imp:
                        UniqueAdd("Code Improvement");
                        break;

                    case ChangelogEntryType.Config:
                        UniqueAdd("Config Update");
                        break;

                    case ChangelogEntryType.ImageAdd:
                        UniqueAdd("Sprites");
                        break;

                    case ChangelogEntryType.ImageDel:
                        UniqueAdd("Sprites");
                        UniqueAdd("Removal");
                        break;

                    case ChangelogEntryType.Refactor:
                        UniqueAdd("Refactor");
                        break;

                    case ChangelogEntryType.RscAdd:
                        UniqueAdd("Feature");
                        break;

                    case ChangelogEntryType.RscDel:
                        UniqueAdd("Removal");
                        break;

                    case ChangelogEntryType.SoundAdd:
                        UniqueAdd("Sounds");
                        break;

                    case ChangelogEntryType.SoundDel:
                        UniqueAdd("Sounds");
                        UniqueAdd("Removal");
                        break;

                    case ChangelogEntryType.SpellCheck:
                        UniqueAdd("Grammar and Formatting");
                        break;

                    case ChangelogEntryType.Tweak:
                        UniqueAdd("Tweak");
                        break;
                    }
                }
            }

            labelsToAdd.RemoveAll(x => labelsToRemove.Contains(x));

            var newLabels = new List <string>();

            foreach (var I in labelsToAdd)
            {
                newLabels.Add(I);
            }

            var currentLabels = new List <Label>(await currentLabelsTask);

            currentLabels.RemoveAll(x => labelsToRemove.Contains(x.Name) || labelsToAdd.Contains(x.Name));
            foreach (var I in currentLabels)
            {
                newLabels.Add(I.Name);
            }

            await gitHubManager.SetIssueLabels(payload.PullRequest.Number, newLabels).ConfigureAwait(false);
        }