Ejemplo n.º 1
0
 private string GetUpdateBlockedReason(
     GitHubPullRequest pr,
     GitCommit headCommit,
     string upgradeBranchPrefix,
     GitHubProject origin)
 {
     if (pr.Head.User.Login != origin.Owner)
     {
         return($"Owner of head repo '{pr.Head.User.Login}' is not '{origin.Owner}'");
     }
     if (!pr.Head.Ref.StartsWith(upgradeBranchPrefix))
     {
         return($"Ref name '{pr.Head.Ref}' does not start with '{upgradeBranchPrefix}'");
     }
     if (headCommit.Author.Name != GitAuthorName)
     {
         return($"Head commit author '{headCommit.Author.Name}' is not '{GitAuthorName}'");
     }
     if (headCommit.Committer.Name != GitAuthorName)
     {
         return($"Head commit committer '{headCommit.Committer.Name}' is not '{GitAuthorName}'");
     }
     if (pr.Labels?.Any(IsMaestroStopUpdatesLabel) ?? false)
     {
         return($"Label `{MaestroStopUpdatesLabel}` is attached");
     }
     return(null);
 }
        private string GetUpdateBlockedReason(
            GitHubClient client,
            GitHubPullRequest pullRequest,
            string upgradeBranchPrefix)
        {
            if (pullRequest.Head.User.Login != Origin.Owner)
            {
                return($"Owner of head repo '{pullRequest.Head.User.Login}' is not '{Origin.Owner}'");
            }
            if (!pullRequest.Head.Ref.StartsWith(upgradeBranchPrefix))
            {
                return($"Ref name '{pullRequest.Head.Ref}' does not start with '{upgradeBranchPrefix}'");
            }

            GitCommit commit = client.GetCommitAsync(Origin, pullRequest.Head.Sha).Result;

            if (commit.Author.Name != GitAuthorName)
            {
                return($"Head commit author '{commit.Author.Name}' is not '{GitAuthorName}'");
            }
            if (commit.Committer.Name != GitAuthorName)
            {
                return($"Head commit committer '{commit.Committer.Name}' is not '{GitAuthorName}'");
            }
            return(null);
        }
Ejemplo n.º 3
0
        public MergeRequestAdapterTests()
        {
            // Given
            string gitHubResponse = "[{'url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls/1','id':315229289,'node_id':'MDExOlB1bGxSZXF1ZXN0MzE1MjI5Mjg5','html_url':'https://github.com/gonzalocozzi/rest-api-test/pull/1','diff_url':'https://github.com/gonzalocozzi/rest-api-test/pull/1.diff','patch_url':'https://github.com/gonzalocozzi/rest-api-test/pull/1.patch','issue_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues/1','number':1,'state':'open','locked':false,'title':'Test','user':{'login':'******','id':13871650,'node_id':'MDQ6VXNlcjEzODcxNjUw','avatar_url':'https://avatars0.githubusercontent.com/u/13871650?v=4','gravatar_id':'','url':'https://api.github.com/users/gonzalocozzi','html_url':'https://github.com/gonzalocozzi','followers_url':'https://api.github.com/users/gonzalocozzi/followers','following_url':'https://api.github.com/users/gonzalocozzi/following{/other_user}','gists_url':'https://api.github.com/users/gonzalocozzi/gists{/gist_id}','starred_url':'https://api.github.com/users/gonzalocozzi/starred{/owner}{/repo}','subscriptions_url':'https://api.github.com/users/gonzalocozzi/subscriptions','organizations_url':'https://api.github.com/users/gonzalocozzi/orgs','repos_url':'https://api.github.com/users/gonzalocozzi/repos','events_url':'https://api.github.com/users/gonzalocozzi/events{/privacy}','received_events_url':'https://api.github.com/users/gonzalocozzi/received_events','type':'User','site_admin':false},'body':'','created_at':'2019-09-07T22:26:59Z','updated_at':'2019-09-23T23:46:10Z','closed_at':null,'merged_at':null,'merge_commit_sha':'63ab265e0edecce1ad0b32a136ce363bfc45d856','assignee':null,'assignees':[],'requested_reviewers':[],'requested_teams':[],'labels':[],'milestone':null,'commits_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls/1/commits','review_comments_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls/1/comments','review_comment_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls/comments{/number}','comments_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues/1/comments','statuses_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/statuses/abb48e2541a6f1da6c50783dbe2eb7a80e6e4256','head':{'label':'gonzalocozzi:test','ref':'test','sha':'abb48e2541a6f1da6c50783dbe2eb7a80e6e4256','user':{'login':'******','id':13871650,'node_id':'MDQ6VXNlcjEzODcxNjUw','avatar_url':'https://avatars0.githubusercontent.com/u/13871650?v=4','gravatar_id':'','url':'https://api.github.com/users/gonzalocozzi','html_url':'https://github.com/gonzalocozzi','followers_url':'https://api.github.com/users/gonzalocozzi/followers','following_url':'https://api.github.com/users/gonzalocozzi/following{/other_user}','gists_url':'https://api.github.com/users/gonzalocozzi/gists{/gist_id}','starred_url':'https://api.github.com/users/gonzalocozzi/starred{/owner}{/repo}','subscriptions_url':'https://api.github.com/users/gonzalocozzi/subscriptions','organizations_url':'https://api.github.com/users/gonzalocozzi/orgs','repos_url':'https://api.github.com/users/gonzalocozzi/repos','events_url':'https://api.github.com/users/gonzalocozzi/events{/privacy}','received_events_url':'https://api.github.com/users/gonzalocozzi/received_events','type':'User','site_admin':false},'repo':{'id':207030759,'node_id':'MDEwOlJlcG9zaXRvcnkyMDcwMzA3NTk=','name':'rest-api-test','full_name':'gonzalocozzi/rest-api-test','private':true,'owner':{'login':'******','id':13871650,'node_id':'MDQ6VXNlcjEzODcxNjUw','avatar_url':'https://avatars0.githubusercontent.com/u/13871650?v=4','gravatar_id':'','url':'https://api.github.com/users/gonzalocozzi','html_url':'https://github.com/gonzalocozzi','followers_url':'https://api.github.com/users/gonzalocozzi/followers','following_url':'https://api.github.com/users/gonzalocozzi/following{/other_user}','gists_url':'https://api.github.com/users/gonzalocozzi/gists{/gist_id}','starred_url':'https://api.github.com/users/gonzalocozzi/starred{/owner}{/repo}','subscriptions_url':'https://api.github.com/users/gonzalocozzi/subscriptions','organizations_url':'https://api.github.com/users/gonzalocozzi/orgs','repos_url':'https://api.github.com/users/gonzalocozzi/repos','events_url':'https://api.github.com/users/gonzalocozzi/events{/privacy}','received_events_url':'https://api.github.com/users/gonzalocozzi/received_events','type':'User','site_admin':false},'html_url':'https://github.com/gonzalocozzi/rest-api-test','description':null,'fork':false,'url':'https://api.github.com/repos/gonzalocozzi/rest-api-test','forks_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/forks','keys_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/keys{/key_id}','collaborators_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/collaborators{/collaborator}','teams_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/teams','hooks_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/hooks','issue_events_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues/events{/number}','events_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/events','assignees_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/assignees{/user}','branches_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/branches{/branch}','tags_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/tags','blobs_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/blobs{/sha}','git_tags_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/tags{/sha}','git_refs_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/refs{/sha}','trees_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/trees{/sha}','statuses_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/statuses/{sha}','languages_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/languages','stargazers_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/stargazers','contributors_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/contributors','subscribers_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/subscribers','subscription_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/subscription','commits_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/commits{/sha}','git_commits_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/commits{/sha}','comments_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/comments{/number}','issue_comment_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues/comments{/number}','contents_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/contents/{+path}','compare_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/compare/{base}...{head}','merges_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/merges','archive_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/{archive_format}{/ref}','downloads_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/downloads','issues_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues{/number}','pulls_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls{/number}','milestones_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/milestones{/number}','notifications_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/notifications{?since,all,participating}','labels_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/labels{/name}','releases_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/releases{/id}','deployments_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/deployments','created_at':'2019-09-07T22:04:22Z','updated_at':'2019-12-19T01:46:19Z','pushed_at':'2019-09-23T23:46:11Z','git_url':'git://github.com/gonzalocozzi/rest-api-test.git','ssh_url':'[email protected]:gonzalocozzi/rest-api-test.git','clone_url':'https://github.com/gonzalocozzi/rest-api-test.git','svn_url':'https://github.com/gonzalocozzi/rest-api-test','homepage':null,'size':3258,'stargazers_count':0,'watchers_count':0,'language':'JavaScript','has_issues':true,'has_projects':true,'has_downloads':true,'has_wiki':true,'has_pages':false,'forks_count':0,'mirror_url':null,'archived':false,'disabled':false,'open_issues_count':1,'license':null,'forks':0,'open_issues':1,'watchers':0,'default_branch':'master'}},'base':{'label':'gonzalocozzi:master','ref':'master','sha':'f63a5480b0591692da53f24044acd941c89be724','user':{'login':'******','id':13871650,'node_id':'MDQ6VXNlcjEzODcxNjUw','avatar_url':'https://avatars0.githubusercontent.com/u/13871650?v=4','gravatar_id':'','url':'https://api.github.com/users/gonzalocozzi','html_url':'https://github.com/gonzalocozzi','followers_url':'https://api.github.com/users/gonzalocozzi/followers','following_url':'https://api.github.com/users/gonzalocozzi/following{/other_user}','gists_url':'https://api.github.com/users/gonzalocozzi/gists{/gist_id}','starred_url':'https://api.github.com/users/gonzalocozzi/starred{/owner}{/repo}','subscriptions_url':'https://api.github.com/users/gonzalocozzi/subscriptions','organizations_url':'https://api.github.com/users/gonzalocozzi/orgs','repos_url':'https://api.github.com/users/gonzalocozzi/repos','events_url':'https://api.github.com/users/gonzalocozzi/events{/privacy}','received_events_url':'https://api.github.com/users/gonzalocozzi/received_events','type':'User','site_admin':false},'repo':{'id':207030759,'node_id':'MDEwOlJlcG9zaXRvcnkyMDcwMzA3NTk=','name':'rest-api-test','full_name':'gonzalocozzi/rest-api-test','private':true,'owner':{'login':'******','id':13871650,'node_id':'MDQ6VXNlcjEzODcxNjUw','avatar_url':'https://avatars0.githubusercontent.com/u/13871650?v=4','gravatar_id':'','url':'https://api.github.com/users/gonzalocozzi','html_url':'https://github.com/gonzalocozzi','followers_url':'https://api.github.com/users/gonzalocozzi/followers','following_url':'https://api.github.com/users/gonzalocozzi/following{/other_user}','gists_url':'https://api.github.com/users/gonzalocozzi/gists{/gist_id}','starred_url':'https://api.github.com/users/gonzalocozzi/starred{/owner}{/repo}','subscriptions_url':'https://api.github.com/users/gonzalocozzi/subscriptions','organizations_url':'https://api.github.com/users/gonzalocozzi/orgs','repos_url':'https://api.github.com/users/gonzalocozzi/repos','events_url':'https://api.github.com/users/gonzalocozzi/events{/privacy}','received_events_url':'https://api.github.com/users/gonzalocozzi/received_events','type':'User','site_admin':false},'html_url':'https://github.com/gonzalocozzi/rest-api-test','description':null,'fork':false,'url':'https://api.github.com/repos/gonzalocozzi/rest-api-test','forks_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/forks','keys_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/keys{/key_id}','collaborators_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/collaborators{/collaborator}','teams_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/teams','hooks_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/hooks','issue_events_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues/events{/number}','events_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/events','assignees_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/assignees{/user}','branches_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/branches{/branch}','tags_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/tags','blobs_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/blobs{/sha}','git_tags_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/tags{/sha}','git_refs_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/refs{/sha}','trees_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/trees{/sha}','statuses_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/statuses/{sha}','languages_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/languages','stargazers_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/stargazers','contributors_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/contributors','subscribers_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/subscribers','subscription_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/subscription','commits_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/commits{/sha}','git_commits_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/git/commits{/sha}','comments_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/comments{/number}','issue_comment_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues/comments{/number}','contents_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/contents/{+path}','compare_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/compare/{base}...{head}','merges_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/merges','archive_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/{archive_format}{/ref}','downloads_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/downloads','issues_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues{/number}','pulls_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls{/number}','milestones_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/milestones{/number}','notifications_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/notifications{?since,all,participating}','labels_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/labels{/name}','releases_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/releases{/id}','deployments_url':'https://api.github.com/repos/gonzalocozzi/rest-api-test/deployments','created_at':'2019-09-07T22:04:22Z','updated_at':'2019-12-19T01:46:19Z','pushed_at':'2019-09-23T23:46:11Z','git_url':'git://github.com/gonzalocozzi/rest-api-test.git','ssh_url':'[email protected]:gonzalocozzi/rest-api-test.git','clone_url':'https://github.com/gonzalocozzi/rest-api-test.git','svn_url':'https://github.com/gonzalocozzi/rest-api-test','homepage':null,'size':3258,'stargazers_count':0,'watchers_count':0,'language':'JavaScript','has_issues':true,'has_projects':true,'has_downloads':true,'has_wiki':true,'has_pages':false,'forks_count':0,'mirror_url':null,'archived':false,'disabled':false,'open_issues_count':1,'license':null,'forks':0,'open_issues':1,'watchers':0,'default_branch':'master'}},'_links':{'self':{'href':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls/1'},'html':{'href':'https://github.com/gonzalocozzi/rest-api-test/pull/1'},'issue':{'href':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues/1'},'comments':{'href':'https://api.github.com/repos/gonzalocozzi/rest-api-test/issues/1/comments'},'review_comments':{'href':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls/1/comments'},'review_comment':{'href':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls/comments{/number}'},'commits':{'href':'https://api.github.com/repos/gonzalocozzi/rest-api-test/pulls/1/commits'},'statuses':{'href':'https://api.github.com/repos/gonzalocozzi/rest-api-test/statuses/abb48e2541a6f1da6c50783dbe2eb7a80e6e4256'}},'author_association':'OWNER'}]";

            IEnumerable <GitHubPullRequest> gitHubPullRequest = JsonConvert.DeserializeObject <IEnumerable <GitHubPullRequest> >(gitHubResponse);

            this.adaptee = gitHubPullRequest.FirstOrDefault();

            // When
            MergeRequestAdapter adapter = new MergeRequestAdapter();

            this.expectedMergeRequest = adapter.GetMergeRequest(this.adaptee);
        }
Ejemplo n.º 4
0
        private static async Task CreatePullRequestAsync(GitHubClient client, GitRepo gitRepo, Config config)
        {
            GitHubProject project       = new GitHubProject(gitRepo.Name, gitRepo.Owner);
            GitHubProject forkedProject = new GitHubProject(gitRepo.Name, Options.GitUser);
            GitHubBranch  baseBranch    = new GitHubBranch(gitRepo.Branch, project);
            GitHubBranch  headBranch    = new GitHubBranch(
                $"{gitRepo.Name}-{gitRepo.Branch}{config.WorkingBranchSuffix}",
                forkedProject);

            IEnumerable <GitObject> changes = await GetUpdatedFiles(config.SourcePath, client, baseBranch);

            if (!changes.Any())
            {
                return;
            }

            GitReference currentRef = await client.GetReferenceAsync(project, $"heads/{baseBranch.Name}");

            string  parentSha = currentRef.Object.Sha;
            GitTree tree      = await client.PostTreeAsync(forkedProject, parentSha, changes.ToArray());

            GitCommit commit = await client.PostCommitAsync(forkedProject, config.CommitMessage, tree.Sha, new[] { parentSha });

            string workingReference = $"heads/{headBranch.Name}";

            if (await BranchExists(client, forkedProject, workingReference))
            {
                await client.PatchReferenceAsync(forkedProject, workingReference, commit.Sha, force : true);
            }
            else
            {
                await client.PostReferenceAsync(forkedProject, workingReference, commit.Sha);
            }

            GitHubPullRequest pullRequestToUpdate = await client.SearchPullRequestsAsync(
                project,
                headBranch.Name,
                await client.GetMyAuthorIdAsync());

            if (pullRequestToUpdate == null)
            {
                await client.PostGitHubPullRequestAsync(
                    $"[{gitRepo.Branch}] {config.PullRequestTitle}",
                    config.PullRequestDescription,
                    headBranch,
                    baseBranch,
                    maintainersCanModify : true);
            }
        }
Ejemplo n.º 5
0
        protected virtual GitHubPullRequest ToGitHubPullRequest(PullRequest pullRequest)
        {
            var openPullRequest = new GitHubPullRequest()
            {
                Id           = pullRequest.Id,
                Title        = pullRequest.Title,
                Status       = pullRequest.State.ToString(),
                Number       = pullRequest.Number,
                JiraKey      = GetJiraKeyFromTitle(pullRequest.Title),
                IsReadyForQA = pullRequest.Labels.Any(l => l.Name == "Ready For QA"),
                IsPatch      = pullRequest.Labels.Any(l => l.Name == "Patch Included"),
                IsOnHold     = pullRequest.Labels.Any(l => l.Name == "On Hold")
            };

            return(openPullRequest);
        }
Ejemplo n.º 6
0
        private async Task PostDiscardedCommitCommentAsync(
            GitHubProject baseProject,
            GitHubPullRequest pullRequestToUpdate,
            GitCommit oldCommit,
            GitHubClient client)
        {
            GitHubCombinedStatus combinedStatus = await client.GetStatusAsync(
                baseProject,
                oldCommit.Sha);

            CiStatusLine[] statuses = combinedStatus
                                      .Statuses
                                      .OrderBy(s => s.State)
                                      .ThenBy(s => s.Context)
                                      .Select(CiStatusLine.Create)
                                      .ToArray();

            string statusLines = statuses
                                 .Aggregate(string.Empty, (acc, line) => acc + line.MarkdownLine + "\r\n");

            string ciSummary = string.Join(
                " ",
                statuses
                .GroupBy(s => s.Emoticon)
                .Select(g => $"{g.Count()}{g.Key}")
                .ToArray());

            string commentBody =
                $"Discarded [`{oldCommit.Sha.Substring(0, 7)}`]({oldCommit.HtmlUrl}): " +
                $"`{oldCommit.Message}`";

            if (statuses.Any())
            {
                commentBody += "\r\n\r\n" +
                               "<details>" +
                               "<summary>" +
                               $"CI Status: {ciSummary} (click to expand)\r\n" +
                               "</summary>" +
                               $"\r\n\r\n{statusLines}\r\n" +
                               "</details>";
            }

            await client.PostCommentAsync(
                baseProject,
                pullRequestToUpdate.Number,
                commentBody);
        }
Ejemplo n.º 7
0
        private async Task <string> CreateDiscardedCommitListBodyAsync(
            GitHubProject baseProject,
            GitHubPullRequest pullRequestToUpdate,
            GitCommit oldCommit,
            GitHubClient client)
        {
            // GitHub returns the HTML "commit" url, but we want "commits" so that CI results show.
            string oldCommitsUrl = oldCommit.HtmlUrl.Replace("commit", "commits");

            GitHubCombinedStatus combinedStatus = await client.GetStatusAsync(
                baseProject,
                oldCommit.Sha);

            string statusLines = combinedStatus
                                 .Statuses
                                 .OrderBy(s => s.State)
                                 .ThenBy(s => s.Context)
                                 .Select(GetStatusLine)
                                 .Aggregate(string.Empty, (acc, line) => acc + line + "\r\n");

            string oldCommitEntry =
                $" * [`{oldCommit.Sha.Substring(0, 7)}`]({oldCommitsUrl}) {oldCommit.Message}\r\n" +
                $"{statusLines}";

            // Find insertion point. GitHub always returns \r\n.
            string insertionMarker    = $"<{DiscardedCommitElementName}>\r\n\r\n";
            string endInsertionMarker = $"\r\n</{DiscardedCommitElementName}>";

            int elementBegin = pullRequestToUpdate.Body.IndexOf(
                insertionMarker,
                StringComparison.Ordinal);

            if (elementBegin != -1)
            {
                return(pullRequestToUpdate.Body.Insert(
                           elementBegin + insertionMarker.Length,
                           oldCommitEntry));
            }
            return(pullRequestToUpdate.Body +
                   "<details><summary>Discarded auto-update commits (click to expand)</summary>" +
                   $"{insertionMarker}{oldCommitEntry}{endInsertionMarker}" +
                   "</details>");
        }
Ejemplo n.º 8
0
        private static async Task CreatePullRequestAsync()
        {
            // Replace slashes with hyphens for use in naming the branch
            string versionSourceNameForBranch = Options.VersionSourceName.Replace("/", "-");

            GitHubAuth         gitHubAuth = new GitHubAuth(Options.GitHubPassword, Options.GitHubUser, Options.GitHubEmail);
            PullRequestCreator prCreator  = new PullRequestCreator(gitHubAuth, Options.GitHubUser);

            string             branchSuffix = $"UpdateDependencies-{Options.GitHubUpstreamBranch}-From-{versionSourceNameForBranch}";
            PullRequestOptions prOptions    = new PullRequestOptions()
            {
                BranchNamingStrategy = new SingleBranchNamingStrategy(branchSuffix)
            };

            string        commitMessage   = $"[{Options.GitHubUpstreamBranch}] Update dependencies from {Options.VersionSourceName}";
            GitHubProject upstreamProject = new GitHubProject(Options.GitHubProject, Options.GitHubUpstreamOwner);
            GitHubBranch  upstreamBranch  = new GitHubBranch(Options.GitHubUpstreamBranch, upstreamProject);

            using (GitHubClient client = new GitHubClient(gitHubAuth))
            {
                GitHubPullRequest pullRequestToUpdate = await client.SearchPullRequestsAsync(
                    upstreamProject,
                    upstreamBranch.Name,
                    await client.GetMyAuthorIdAsync());

                if (pullRequestToUpdate == null || pullRequestToUpdate.Head.Ref != $"{upstreamBranch.Name}-{branchSuffix}")
                {
                    await prCreator.CreateOrUpdateAsync(
                        commitMessage,
                        commitMessage,
                        string.Empty,
                        upstreamBranch,
                        new GitHubProject(Options.GitHubProject, gitHubAuth.User),
                        prOptions);
                }
                else
                {
                    UpdateExistingPullRequest(gitHubAuth, prOptions, commitMessage, upstreamBranch);
                }
            }
        }
Ejemplo n.º 9
0
        protected virtual IList <GitHubPullRequest> ToGitHubPullRequests(IReadOnlyList <PullRequest> pullRequests)
        {
            IList <GitHubPullRequest> openPullRequests = new List <GitHubPullRequest>();

            foreach (PullRequest pullRequest in pullRequests)
            {
                var openPullRequest = new GitHubPullRequest()
                {
                    Id           = pullRequest.Id,
                    Title        = pullRequest.Title,
                    Status       = pullRequest.State.ToString(),
                    Number       = pullRequest.Number,
                    JiraKey      = GetJiraKeyFromTitle(pullRequest.Title),
                    IsReadyForQA = pullRequest.Labels.Any(l => l.Name == "Ready For QA"),
                    IsPatch      = pullRequest.Labels.Any(l => l.Name == "Patch Included"),
                    IsOnHold     = pullRequest.Labels.Any(l => l.Name == "On Hold")
                };

                openPullRequests.Add(openPullRequest);
            }

            return(openPullRequests);
        }
Ejemplo n.º 10
0
        private static async Task CreatePullRequestAsync()
        {
            GitHubAuth         gitHubAuth = new GitHubAuth(Options.GitHubPassword, Options.GitHubUser, Options.GitHubEmail);
            PullRequestCreator prCreator  = new PullRequestCreator(gitHubAuth, Options.GitHubUser);
            PullRequestOptions prOptions  = new PullRequestOptions()
            {
                BranchNamingStrategy = new SingleBranchNamingStrategy($"UpdateDependencies-{Options.GitHubUpstreamBranch}")
            };

            string        commitMessage   = $"[{Options.GitHubUpstreamBranch}] Update dependencies from dotnet/core-sdk";
            GitHubProject upstreamProject = new GitHubProject(Options.GitHubProject, Options.GitHubUpstreamOwner);
            GitHubBranch  upstreamBranch  = new GitHubBranch(Options.GitHubUpstreamBranch, upstreamProject);

            using (GitHubClient client = new GitHubClient(gitHubAuth))
            {
                GitHubPullRequest pullRequestToUpdate = await client.SearchPullRequestsAsync(
                    upstreamProject,
                    upstreamBranch.Name,
                    await client.GetMyAuthorIdAsync());

                if (pullRequestToUpdate == null)
                {
                    await prCreator.CreateOrUpdateAsync(
                        commitMessage,
                        commitMessage,
                        string.Empty,
                        upstreamBranch,
                        new GitHubProject(Options.GitHubProject, gitHubAuth.User),
                        prOptions);
                }
                else
                {
                    UpdateExistingPullRequest(gitHubAuth, prOptions, commitMessage, upstreamBranch);
                }
            }
        }
Ejemplo n.º 11
0
        private void dgvPullRequests_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            dgvPullRequests.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

            foreach (DataGridViewRow row in dgvPullRequests.Rows)
            {
                GitHubPullRequest pullRequest = row.DataBoundItem as GitHubPullRequest;

                if (pullRequest.IsApproved)
                {
                    row.Cells["Status"].Style.BackColor = Color.LimeGreen;
                }
                if (pullRequest.HasRequestedChanges)
                {
                    row.Cells["Status"].Style.BackColor = Color.Red;
                }
                if (pullRequest.IsOnHold)
                {
                    row.Cells["Status"].Style.BackColor = Color.Gold;
                }
                row.Cells["Status"].Style.SelectionBackColor = row.Cells["Status"].Style.BackColor;
                row.Cells["Status"].Style.SelectionForeColor = row.Cells["Status"].Style.ForeColor;
            }
        }
Ejemplo n.º 12
0
        public async Task CreateOrUpdateAsync(
            string commitMessage,
            string title,
            string description,
            GitHubBranch baseBranch,
            GitHubProject origin,
            PullRequestOptions options)
        {
            options = options ?? new PullRequestOptions();

            var upstream = baseBranch.Project;

            using (var client = new GitHubClient(_auth))
            {
                GitHubBranch      originBranch        = null;
                GitHubPullRequest pullRequestToUpdate = null;

                IUpdateBranchNamingStrategy namingStrategy = options.BranchNamingStrategy
                                                             ?? new SingleBranchNamingStrategy("UpdateDependencies");

                string upgradeBranchPrefix = namingStrategy.Prefix(baseBranch.Name);

                if (!options.ForceCreate)
                {
                    pullRequestToUpdate = await client.SearchPullRequestsAsync(
                        upstream,
                        upgradeBranchPrefix,
                        _auth.User);

                    if (pullRequestToUpdate == null)
                    {
                        Trace.TraceInformation($"No existing pull request found.");
                    }
                    else
                    {
                        Trace.TraceInformation(
                            $"Pull request already exists for {upgradeBranchPrefix} in {upstream.Segments}. " +
                            $"#{pullRequestToUpdate.Number}, '{pullRequestToUpdate.Title}'");

                        GitCommit headCommit = await client.GetCommitAsync(
                            origin,
                            pullRequestToUpdate.Head.Sha);

                        string blockedReason = GetUpdateBlockedReason(
                            pullRequestToUpdate,
                            headCommit,
                            upgradeBranchPrefix,
                            origin);

                        if (blockedReason == null)
                        {
                            if (options.TrackDiscardedCommits)
                            {
                                await PostDiscardedCommitCommentAsync(
                                    baseBranch.Project,
                                    pullRequestToUpdate,
                                    headCommit,
                                    client);
                            }

                            originBranch = new GitHubBranch(
                                pullRequestToUpdate.Head.Ref,
                                origin);
                        }
                        else
                        {
                            string comment =
                                $"Couldn't update this pull request: {blockedReason}\n" +
                                $"Would have applied '{commitMessage}'";

                            await client.PostCommentAsync(upstream, pullRequestToUpdate.Number, comment);

                            return;
                        }
                    }
                }

                // No existing branch to update: push to a new one.
                if (originBranch == null)
                {
                    string newBranchName =
                        namingStrategy.Prefix(baseBranch.Name) +
                        namingStrategy.CreateFreshBranchNameSuffix(baseBranch.Name);

                    originBranch = new GitHubBranch(newBranchName, origin);
                }

                PushNewCommit(originBranch, commitMessage);

                if (pullRequestToUpdate != null)
                {
                    await client.UpdateGitHubPullRequestAsync(
                        upstream,
                        pullRequestToUpdate.Number,
                        title,
                        description,
                        maintainersCanModify : options.MaintainersCanModify);
                }
                else
                {
                    await client.PostGitHubPullRequestAsync(
                        title,
                        description,
                        originBranch,
                        baseBranch,
                        options.MaintainersCanModify);
                }
            }
        }
Ejemplo n.º 13
0
 public void Dispose()
 {
     this.adaptee = null;
 }
        private static IPullRequestRetriever GetPullRequestRetriever()
        {
            var client = new Mock<IPullRequestsClient>();

            var repository = new GitHubRepository("OlegKleyman", "OctoStyle");

            var commits = new List<PullRequestCommit>
                              {
                                  GetPullRequestCommit("123"),
                                  GetPullRequestCommit("124"),
                                  GetPullRequestCommit("125"),
                                  GetPullRequestCommit(LastCommitId)
                              };
            client.Setup(requestsClient => requestsClient.Commits(repository.Owner, repository.Name, PullRequestNumber))
                .ReturnsAsync(commits);

            var files = new List<PullRequestFile>
                            {
                                GetPullRequestFile(
                                    "321",
                                    RenamedFileName,
                                    "renamed",
                                    RenamedContentUrl,
                                    RenamedChanges),
                                GetPullRequestFile(
                                    "421",
                                    AddedFileName,
                                    "added",
                                    AddedContentUrl,
                                    AddedChanges),
                                GetPullRequestFile(
                                    "521",
                                    FirstModifiedFileName,
                                    "modified",
                                    FirstModifiedContentUrl,
                                    FirstModifiedChanges),
                                GetPullRequestFile(
                                    "621",
                                    SecondModifiedFileName,
                                    "modified",
                                    SecondModifiedContentUrl,
                                    SecondModifiedChanges)
                            };

            client.Setup(requestsClient => requestsClient.Files(repository.Owner, repository.Name, PullRequestNumber))
                .ReturnsAsync(files);

            var pullRequestUrl =
                new Uri(
                    String.Format(
                        CultureInfo.InvariantCulture,
                        "https://api.github.com/repos/{0}/{1}/pulls/{2}",
                        repository.Owner,
                        repository.Name,
                        PullRequestNumber));

            client.Setup(requestsClient => requestsClient.Get(repository.Owner, repository.Name, PullRequestNumber))
                .ReturnsAsync(
                    new PullRequest(
                        pullRequestUrl,
                        null,
                        null,
                        null,
                        null,
                        null,
                        PullRequestNumber,
                        ItemState.Open,
                        null,
                        null,
                        default(DateTimeOffset),
                        default(DateTimeOffset),
                        null,
                        null,
                        new GitReference(null, null, PullRequestBranch, null, null, null),
                        new GitReference(null, null, PullRequestMergeBranch, null, null, null),
                        null,
                        null,
                        true,
                        null,
                        null,
                        0,
                        0,
                        0,
                        0,
                        0));

            var connection = new Mock<IConnection>();
            var builder = new Mock<IPullRequestBuilder>();
            var mockResponse = new Mock<IResponse>();

            connection.Setup(
                con =>
                con.Get<string>(
                    It.Is<Uri>(uri => uri.AbsoluteUri == pullRequestUrl.AbsoluteUri),
                    null,
                    "application/vnd.github.VERSION.diff"))
                .ReturnsAsync(new ApiResponse<string>(mockResponse.Object, FileContents.FullDiff));

            var pullRequestFiles = new List<GitHubPullRequestFile>
                                       {
                                           new GitHubPullRequestFile(
                                               RenamedFileName,
                                               GitHubPullRequestFileStatus.Renamed,
                                               RenamedChanges,
                                               FileContents.TestClass2CsDiff),
                                           new GitHubPullRequestFile(
                                               AddedFileName,
                                               GitHubPullRequestFileStatus.Added,
                                               AddedChanges,
                                               FileContents.TestClass3CsDiff),
                                           new GitHubPullRequestFile(
                                               FirstModifiedFileName,
                                               GitHubPullRequestFileStatus.Modified,
                                               FirstModifiedChanges,
                                               FileContents.TestClassCsDiff),
                                           new GitHubPullRequestFile(
                                               SecondModifiedFileName,
                                               GitHubPullRequestFileStatus.Modified,
                                               SecondModifiedChanges,
                                               FileContents.TestLibraryCsprojDiff),
                                       };

            var pullRequest = new GitHubPullRequest(
                PullRequestNumber,
                LastCommitId,
                pullRequestFiles,
                FileContents.FullDiff,
                new GitHubPullRequestBranches(PullRequestBranch, PullRequestMergeBranch));

            builder.Setup(
                requestBuilder =>
                requestBuilder.Build(
                    PullRequestNumber,
                    LastCommitId,
                    files,
                    FileContents.FullDiff,
                    It.Is<GitHubPullRequestBranches>(
                        branches =>
                        branches.Branch == PullRequestBranch & branches.MergeBranch == PullRequestMergeBranch)))
                .Returns(pullRequest);

            return new PullRequestRetriever(builder.Object, client.Object, connection.Object, repository);
        }
Ejemplo n.º 15
0
        public async Task CreateOrUpdateAsync(
            string commitMessage,
            string title,
            string description,
            bool forceCreate = false)
        {
            var upstream = UpstreamBranch.Project;

            using (var client = new GitHubClient(_auth))
            {
                GitHubBranch      originBranch        = null;
                GitHubPullRequest pullRequestToUpdate = null;

                string upgradeBranchPrefix = _namingStrategy.Prefix(UpstreamBranch.Name);

                if (!forceCreate)
                {
                    pullRequestToUpdate = await client.SearchPullRequestsAsync(
                        upstream,
                        upgradeBranchPrefix,
                        _auth.User);

                    if (pullRequestToUpdate == null)
                    {
                        Trace.TraceInformation($"No existing pull request found.");
                    }
                    else
                    {
                        Trace.TraceInformation(
                            $"Pull request already exists for {upgradeBranchPrefix} in {upstream.Segments}. " +
                            $"#{pullRequestToUpdate.Number}, '{pullRequestToUpdate.Title}'");

                        string blockedReason = GetUpdateBlockedReason(client, pullRequestToUpdate, upgradeBranchPrefix);

                        if (blockedReason == null)
                        {
                            originBranch = new GitHubBranch(
                                pullRequestToUpdate.Head.Ref,
                                Origin);
                        }
                        else
                        {
                            string comment =
                                $"Couldn't update this pull request: {blockedReason}\n" +
                                $"Would have applied '{commitMessage}'";

                            await client.PostCommentAsync(upstream, pullRequestToUpdate.Number, comment);

                            return;
                        }
                    }
                }

                // No existing branch to update: push to a new one.
                if (originBranch == null)
                {
                    string newBranchName =
                        _namingStrategy.Prefix(UpstreamBranch.Name) +
                        _namingStrategy.CreateFreshBranchNameSuffix(UpstreamBranch.Name);

                    originBranch = new GitHubBranch(newBranchName, Origin);
                }

                PushNewCommit(originBranch, commitMessage);

                if (pullRequestToUpdate != null)
                {
                    await client.UpdateGitHubPullRequestAsync(upstream, pullRequestToUpdate.Number, title, description);
                }
                else
                {
                    await client.PostGitHubPullRequestAsync(title, description, originBranch, UpstreamBranch);
                }
            }
        }