Beispiel #1
0
        public static async Task DoWork(RebaseCommandSettings settings, CommonSettings commonSettings, Parameters parameters, Jira jira)
        {
            var prUrl = parameters.Get("PR url: ");

            GithubHelper.ParsePrUrl(prUrl, out var repoName, out var prNumber);

            Console.Write("Getting PR... ");
            var query = @"query {
                repository(owner:""trilogy-group"", name:""" + repoName + @"""){
                    pullRequest(number: " + prNumber + @"){
                        headRefName
                    }
                }  
            }";

            var repoData = await GithubHelper.Query(query, commonSettings.GithubToken);

            var branchName = repoData["repository"]["pullRequest"]["headRefName"].Value <string>();

            Console.WriteLine("done");

            var repoSettings = SettingsHelper.GetRepoSettings(commonSettings, repoName);
            var mainBranch   = SettingsHelper.GetMainBranch(repoSettings);

            Console.Write($"Rebase {mainBranch} to {branchName}... ");
            GitHelper.Exec(
                $"git checkout {mainBranch} && git pull && git checkout {branchName} && git pull && git merge develop --no-edit && git push",
                repoSettings,
                commonSettings.ProjectsPath);
            Console.WriteLine("done");

            Console.Write($"Checkout {mainBranch}... ");
            GitHelper.Exec($"git checkout {mainBranch}", repoSettings, commonSettings.ProjectsPath);
            Console.WriteLine("done");
        }
Beispiel #2
0
        public static async Task DoWork(CrnCommandSettings settings, CommonSettings commonSettings, Parameters parameters, Jira jira)
        {
            throw new CcException("Crn command isn't implemented yet");

            var prUrl = parameters.GetPrUrl();

            GithubHelper.ParsePrUrl(prUrl, out var repoName, out var prNumber);

            Console.Write("Getting PR... ");
            var query = @"query {
                repository(owner:""trilogy-group"", name:""" + repoName + @"""){
                    pullRequest(number: " + prNumber + @"){
                        headRefName
                    }
                }  
            }";

            var repoData = await GithubHelper.Query(query, commonSettings.GithubToken);

            var branchName = repoData["repository"]["pullRequest"]["headRefName"].Value <string>();

            Console.WriteLine("done");

            //Console.Write($"Checkout branch {branchName}... ");
            //GitHelper.Exec($"git checkout {branchName}", repoName, commonSettings.ProjectsPath);
            //Console.WriteLine("done");
        }
Beispiel #3
0
        private static async Task AssignLabelToPR(CommonSettings commonSettings, string repoName, string reviewLabel, JToken jPullRequest)
        {
            Console.Write("Get CRN review label id... ");

            var getRepoLabels = string.Format(QueryGetRepoLabelsFormat, "trilogy-group", repoName);
            var repoLabels    = await GithubHelper.Query(getRepoLabels, commonSettings.GithubToken);

            var repoLabelsNode = repoLabels["repository"]["labels"]["nodes"] as JArray;
            var prId           = jPullRequest["id"].Value <string>();

            if (repoLabelsNode == null)
            {
                Console.Write("No labels found in repo");
                return;
            }

            if (!repoLabelsNode.Any(
                    x => x["name"].Value <string>().Equals(reviewLabel, StringComparison.OrdinalIgnoreCase)))
            {
                Console.Write("No review label found in repo");
                return;
            }

            var crnReviewLabelId = repoLabelsNode.First(
                x => x["name"].Value <string>().Equals(reviewLabel, StringComparison.OrdinalIgnoreCase))
                                   ["id"]
                                   .Value <string>();

            Console.WriteLine("done");

            var labelNodes = jPullRequest["labels"]["nodes"] as JArray ?? new JArray();

            if (labelNodes.Any())
            {
                if (labelNodes.Any(x => x["id"].Value <string>().Equals(crnReviewLabelId)))
                {
                    Console.Write($@"""{reviewLabel}"" already assigned... ");
                    Console.WriteLine("done");
                    return;
                }

                Console.Write("Clear labels... ");
                var mutationClearLabels = string.Format(MutationClearLabelsPRFormat, prId);
                await GithubHelper.Query(mutationClearLabels, commonSettings.GithubToken);

                Console.WriteLine("done");
            }

            Console.Write("Add label... ");
            var mutationAddLabels = string.Format(MutationAddLabelsFormat, prId, crnReviewLabelId);
            await GithubHelper.Query(mutationAddLabels, commonSettings.GithubToken);

            Console.WriteLine("done");
        }
Beispiel #4
0
        public static async Task DoWork(PrCommandSettings settings, CommonSettings commonSettings, Parameters parameters, Jira jira)
        {
            var ticketUrl = parameters.Get("Enter Jira ticket: ");
            var issueKey  = JiraHelper.GetIssueKey(ticketUrl);

            var comment = GetComment(settings, parameters);

            var noteForReviewer = parameters.Get("Note for reviewer: ");

            if (settings.NotesAliases.ContainsKey(noteForReviewer))
            {
                noteForReviewer = settings.NotesAliases[noteForReviewer];
            }

            bool isOnlyPr = false;

            if (parameters.Any())
            {
                var str = parameters.Get(string.Empty);
                if (str == "--onlyPr")
                {
                    isOnlyPr = true;
                }
                else
                {
                    throw new CcException($"Unknown argument: {str}");
                }
            }

            Console.Write("Get ticket... ");
            var issue = await jira.Issues.GetIssueAsync(issueKey);

            var repoUrl = issue.GetScmUrl();

            if (string.IsNullOrWhiteSpace(repoUrl))
            {
                Console.WriteLine("Can't get repo name");
                return;
            }

            Console.WriteLine("done");

            var repoName = repoUrl.Split('/')[4];

            if (repoName.EndsWith(".git", StringComparison.OrdinalIgnoreCase))
            {
                repoName = Path.GetFileNameWithoutExtension(repoName);
            }

            var repoSettings = SettingsHelper.GetRepoSettings(commonSettings, repoName);
            var branchPrefix = string.IsNullOrWhiteSpace(repoSettings?.BranchPrefix)
                ? "feature"
                : repoSettings.BranchPrefix;

            var mainBranch = SettingsHelper.GetMainBranch(repoSettings);

            var key        = issue.Key.ToString();
            var ticketType = GetTicketType(issue);

            if (!isOnlyPr)
            {
                var stagedFiles  = GitHelper.Exec("git diff --name-only --cached", repoSettings, commonSettings.ProjectsPath);
                var changedFiles = GitHelper.Exec("git diff --name-only", repoSettings, commonSettings.ProjectsPath);

                if (!stagedFiles.Any() && !changedFiles.Any())
                {
                    throw new CcException("No changed files found");
                }

                var filesForCheck = stagedFiles.Any() ? stagedFiles : changedFiles;

                if (filesForCheck.Any(f => f.EndsWith(".sln", StringComparison.OrdinalIgnoreCase)))
                {
                    ConsoleHelper.WriteColor("You are going to commit changes in sln-file. Do you really want to do it? [y/N]: ", ConsoleColor.Yellow);
                    var answer = Console.ReadLine() ?? string.Empty;

                    if (!answer.Equals("y", StringComparison.OrdinalIgnoreCase))
                    {
                        return;
                    }
                }

                var currentBranch = GitHelper.GetCurrentBranch(repoSettings, commonSettings.ProjectsPath);

                if (currentBranch != mainBranch)
                {
                    ConsoleHelper.WriteColor(
                        $"Your current branch is {currentBranch}, but usually it should be {mainBranch}. Do you really want to create new branch from this one? [y/N]: ",
                        ConsoleColor.Yellow);
                    var answer = Console.ReadLine() ?? string.Empty;

                    if (!answer.Equals("y", StringComparison.OrdinalIgnoreCase))
                    {
                        return;
                    }
                }

                Console.Write("Set assignee... ");

                if (issue.Assignee == null)
                {
                    issue.Assignee = commonSettings.JiraUserName;
                    await issue.SaveChangesAsync();

                    Console.WriteLine("done");
                }
                else
                {
                    if (issue.Assignee != commonSettings.JiraUserName)
                    {
                        throw new CcException($"Ticket is already assigned to \"{issue.Assignee}\"!");
                    }
                    else
                    {
                        Console.WriteLine("already assigned");
                    }
                }

                Console.Write("Move ticket to \"In progress\"... ");
                if (issue.Status.ToString().Equals("To Do", StringComparison.InvariantCultureIgnoreCase))
                {
                    await issue.WorkflowTransitionAsync("Not False Positive");
                }

                if (issue.Status.ToString().Equals("Writing Test Code", StringComparison.InvariantCultureIgnoreCase))
                {
                    await issue.WorkflowTransitionAsync("Test coverage available");
                }

                if (issue.Status.ToString().Equals("Ready to refactor", StringComparison.InvariantCultureIgnoreCase))
                {
                    await issue.WorkflowTransitionAsync("Start progress");
                }

                Console.WriteLine("done");

                Console.Write("Push changes... ");
                var createBranchCommand = $"git checkout -b {branchPrefix}/{key}";
                var commitOption        = stagedFiles.Any() ? string.Empty : "a";
                var commitCommand       = $"git commit -{commitOption}m  \"{key}: Fixes {ticketType}\"";
                var pushCommand         = $"git push --set-upstream origin {branchPrefix}/{key}";
                GitHelper.Exec(
                    $"{createBranchCommand} && {commitCommand} && {pushCommand}",
                    repoSettings,
                    commonSettings.ProjectsPath);

                Console.WriteLine("done");

                Console.Write($"Checkout {mainBranch}... ");
                try
                {
                    GitHelper.Exec($"git checkout {mainBranch} && git pull", repoSettings, commonSettings.ProjectsPath);
                    Console.WriteLine("done");
                }
                catch (GitException)
                {
                    ConsoleHelper.WriteLineColor("failed", ConsoleColor.Yellow);
                }

                Console.Write("Waiting... ");
                Thread.Sleep(TimeSpan.FromSeconds(3));
                Console.WriteLine("done");
            }

            Console.Write("Create PR... ");
            var query    = @"query { repository(owner:""trilogy-group"", name:""" + repoName + @"""){ id }}";
            var repoData = await GithubHelper.Query(query, commonSettings.GithubToken);

            var repoId = repoData["repository"]["id"].Value <string>();

            var fullNote = string.IsNullOrWhiteSpace(noteForReviewer)
                ? string.Empty
                : $@"# Note for Reviewers\r\n- {noteForReviewer}\r\n\r\n";

            var(testCoverageMessage, coverageWarning) = GetTestCoverageMessage(issue);

            var mutation = @"mutation
                {
                  createPullRequest(input:{
                    title:""[" + key + "] " + issue.Summary.Replace("\"", "\\\"") + @""", 
                    baseRefName: """ + mainBranch + @""", 
                    body: ""# Links\r\nhttps://jira.devfactory.com/browse/" + key + @"\r\n\r\n# Changes\r\n- " + comment + @"\r\n\r\n" + fullNote + testCoverageMessage + @""", 
                    headRefName: """ + branchPrefix + "/" + key + @""", 
                    repositoryId: """ + repoId + @"""
                  }){
                    pullRequest{
                      id,
                      url
                    }
                  }
                }";

            var resultJson = await GithubHelper.Query(mutation, commonSettings.GithubToken);

            var jPullRequest = resultJson["createPullRequest"]["pullRequest"];
            var prUrl        = jPullRequest["url"].Value <string>();

            Console.WriteLine("done");

            if (coverageWarning)
            {
                Console.WriteLine("Please don't forget to fill test coverage manually");
            }

            if (settings.AssignPr)
            {
                Console.Write("Assign PR... ");

                var prId = jPullRequest["id"].Value <string>();

                var currentUserIdJson = await GithubHelper.Query("query {viewer {id}}", commonSettings.GithubToken);

                var userId = currentUserIdJson["viewer"]["id"].Value <string>();

                var assignPrMutation = @"mutation
                    {
                      addAssigneesToAssignable(input: {
                        assignableId: """ + prId + @""", 
                        assigneeIds: [""" + userId + @"""]}) { clientMutationId }}";

                await GithubHelper.Query(assignPrMutation, commonSettings.GithubToken);

                Console.WriteLine("done");
            }

            Console.Write("Write PR url to ticket... ");
            const string codeReviewUrl = "Code Review Ticket URL";

            if (issue.CustomFields.Any(f => f.Name == codeReviewUrl))
            {
                issue.CustomFields[codeReviewUrl].Values = new [] { prUrl };
            }
            else
            {
                issue.CustomFields.Add(codeReviewUrl, prUrl);
            }

            issue.SaveChanges();
            Console.WriteLine("done");

            Console.WriteLine("New PR url: " + prUrl);
        }
Beispiel #5
0
        private async Task <bool> ReviewPr(string qbLink, bool approve, IReadOnlyCollection <string> failedItems)
        {
            // Get user login
            var loginQuery = @"query { viewer { login }}";
            var loginData  = await GithubHelper.Query(loginQuery, _settings.GithubToken);

            var login = loginData["viewer"]["login"].Value <string>();


            // Get pending review
            var pendingReviewQuery = @"query q { 
  repository(owner:""" + _prInfo.OwnerName + @""", name:""" + _prInfo.RepoName + @""") {
            pullRequest(number: " + _prInfo.PrNumber + @") {
                id
                reviews(last: 20, author: """ + login + @""") {
                    nodes{
                        id
                        state
                    }
                }
            }
        }
    }";
            var pendingReviewData  = await GithubHelper.Query(pendingReviewQuery, _settings.GithubToken);

            var pendingReviews = pendingReviewData["repository"]["pullRequest"]["reviews"]["nodes"] as JArray;
            var pendingReview  = pendingReviews?.FirstOrDefault(r => r["state"].Value <string>() == "PENDING");

            string reviewId;

            if (pendingReview == null)
            {
                var prId = pendingReviewData["repository"]["pullRequest"]["id"].Value <string>();

                var addReviewMutation = @"mutation w{ 
                addPullRequestReview(input: {pullRequestId: """ + prId + @"""}) { 
                    pullRequestReview {id}
                }
            }";

                var reviewData = await GithubHelper.Query(addReviewMutation, _settings.GithubToken);

                reviewId = reviewData["addPullRequestReview"]["pullRequestReview"]["id"].Value <string>();
            }
            else
            {
                reviewId = pendingReview["id"].Value <string>();
            }

            string reviewBody;
            string reviewEvent;

            if (approve)
            {
                if (_settings.ApprovePrAction == "approve")
                {
                    reviewBody  = $"body: \"QB: {qbLink}\"";
                    reviewEvent = "APPROVE";
                }
                else
                {
                    reviewBody  = $"body: \"Approved\\r\\nQB: {qbLink}\"";
                    reviewEvent = "COMMENT";
                }
            }
            else
            {
                reviewEvent = "REQUEST_CHANGES";
                var failedItemsText = string.Join("\\r\\n", failedItems.Select(i => $"**{i}**"));
                reviewBody = $"body: \"{failedItemsText}\\r\\nQB: {qbLink}\"";
            }

            var submitReviewMutation = @"mutation e { 
                submitPullRequestReview(input: {
                    " + reviewBody + @"
                    pullRequestReviewId: """ + reviewId + @""",
                    event: " + reviewEvent + @"}) { 
                        clientMutationId
                }
            }";

            var submitData = await GithubHelper.Query(submitReviewMutation, _settings.GithubToken);

            return(submitData["submitPullRequestReview"]["clientMutationId"] != null);
        }
Beispiel #6
0
        public static async Task DoWork(ReviewCommandSettings settings, CommonSettings commonSettings, Parameters parameters, Jira jira)
        {
            var prUrl = parameters.Get("PR url: ");

            GithubHelper.ParsePrUrl(prUrl, out var repoName, out var prNumber);

            var timeSpent = parameters.Get("Time spent: ");

            if (string.IsNullOrWhiteSpace(timeSpent) || timeSpent.Trim() == "0")
            {
                throw new CcException("Time spent should not be empty");
            }

            //var coverage = parameters.Get("Coverage percentage: ");
            //if (string.IsNullOrWhiteSpace(coverage))
            //{
            //    throw new CcException("Coverage should not be empty");
            //}

            Console.Write("Getting PR... ");
            var prDetails = string.Format(QueryGetPRDetailsFormat, repoName, prNumber);
            var prInfo    = await GithubHelper.Query(prDetails, commonSettings.GithubToken);

            var jPullRequest = prInfo["repository"]["pullRequest"];
            var bodyHtml     = jPullRequest["bodyHTML"].Value <string>();

            Console.WriteLine("done");
            Console.Write("Getting ticket... ");
            var regex = new Regex(@"https://jira\.devfactory\.com/browse/(CC-\d+)");
            var m     = regex.Match(bodyHtml);

            if (!m.Success)
            {
                throw new CcException("Ticket not found");
            }

            var issue = await jira.Issues.GetIssueAsync(m.Groups[1].Value);

            Console.WriteLine("done");

            var issueStatus = issue.Status.ToString();

            if (!issueStatus.Equals("In progress", StringComparison.InvariantCultureIgnoreCase))
            {
                throw new CcException("Ticket should be in \"In progress\" state");
            }

            var repoSettings = SettingsHelper.GetRepoSettings(commonSettings, repoName);

            if (string.IsNullOrWhiteSpace(repoSettings?.Pca))
            {
                throw new CcException($"PCA isn't defined for repo \"{repoName}\" in settings.json");
            }

            Console.Write("Moving to review... ");
            SetCustomField(issue, "Reviewer", repoSettings.Pca);
            SetCustomField(issue, "Code Review Ticket URL", prUrl);
            await issue.WorkflowTransitionAsync("Submit for Review", new WorkflowTransitionUpdates()
            {
                TimeSpent = timeSpent
            });

            Console.WriteLine("done");

            if (settings.AssignPr)
            {
                Console.Write("Assigning PR... ");

                var currentUserIdJson = await GithubHelper.Query("query {viewer {id}}", commonSettings.GithubToken);

                var userId = currentUserIdJson["viewer"]["id"].Value <string>();
                var nodes  = jPullRequest["assignees"]["nodes"] as JArray ?? new JArray();

                if (nodes.Any(node => node["id"].Value <string>() == userId))
                {
                    Console.WriteLine("already assigned");
                }
                else
                {
                    var assignPrMutation = string.Format(MutationAddAssigneePRFormat, jPullRequest["id"].Value <string>(), userId);
                    await GithubHelper.Query(assignPrMutation, commonSettings.GithubToken);

                    Console.WriteLine("done");
                }
            }

            if (settings.AssignReviewLabel)
            {
                await AssignLabelToPR(commonSettings, repoName, settings.ReviewLabelName, jPullRequest);
            }
        }