{"action":"created","comment":{"url":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/comments/211334998","pull_request_review_id":147733603,"id":211334998,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIxMTMzNDk5OA==","diff_hunk":"@@ -0,0 +1,317 @@\n+// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.\n+using Microsoft.TeamFoundation.SourceControl.WebApi;\n+using NLog;\n+using System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Threading;\n+using System.Threading.Tasks;\n+\n+namespace VstsMergeTool\n+{\n+    public class VstsMergeTool\n+    {\n+        private static Logger Logger;\n+\n+        private const int Timeout = 1000 * 60;\n+\n+        private readonly GitHttpClient GitHttpClient;\n+\n+        private List<GitRef> RefsInfo;\n+\n+        private Settings settings = Settings.Default;\n+\n+        private readonly string SourceName;\n+\n+        private readonly string DestName;\n+\n+        private readonly string SourceBranch;\n+\n+        private readonly string DestBranch;\n+\n+        private readonly string DummyBranchName;\n+\n+        private int AutoPullRequestId;\n+\n+        private Guid RepositoryId;\n+\n+        private CancellationTokenSource Cts;\n+\n+        public VstsMergeTool(GitHttpClient gitHttpClient, string sourceBranch, string destBranch)\n+        {\n+            this.GitHttpClient = gitHttpClient;\n+            Logger = LogManager.GetCurrentClassLogger();\n+\n+            var source = sourceBranch.Split('/');\n+            SourceName = source[source.Length - 1];\n+\n+            var dest = destBranch.Split('/');\n+            DestName = dest[dest.Length - 1];\n+\n+            this.SourceBranch = sourceBranch;\n+            this.DestBranch = destBranch;\n+            \n+            this.DummyBranchName = $\"refs/heads/merge/{SourceName}-to-{DestName}\";\n+            this.Cts = new CancellationTokenSource();\n+        }\n+\n+        public async Task<bool> CreatePullRequest()\n+        {\n+            Cts.CancelAfter(Timeout);\n+            // Fetch the repository id according to repository name\n+            await GetRepositoryId(settings.RepositoryName, Cts.Token);\n+\n+            var getCurrentBranchInfo = await GetBranchInfoAsync(Cts.Token);\n+\n+            if (!getCurrentBranchInfo)\n+            {\n+                Logger.Error($\"Fail to get the branch and PR information about {settings.TFSProjectName}\");\n+                return false;\n+            }\n+\n+            // Check if source branch and target branch both exist\n+            if (!IsBranchExist(SourceBranch) || !IsBranchExist(DestBranch))\n+            {\n+                Logger.Error($\"{SourceBranch} or {DestBranch} doesn't exist\");\n+                return false;\n+            }\n+\n+            // Check if there are existing dummybranch and open PR\n+            var isDummyBranchAndOpenPrExisting = await IskDummyBranchAndOpenPrExists(Cts.Token);","path":"src/VstsMergeTool/VstsMergeTool.cs","position":80,"original_position":80,"commit_id":"329e605bfe3ed290f2cc9d740401ab93c34b4ae3","original_commit_id":"329e605bfe3ed290f2cc9d740401ab93c34b4ae3","user":{"login":"Cosifne","id":24360909,"node_id":"MDQ6VXNlcjI0MzYwOTA5","avatar_url":"https://avatars2.githubusercontent.com/u/24360909?v=4","gravatar_id":"","url":"https://api.github.com/users/Cosifne","html_url":"https://github.com/Cosifne","followers_url":"https://api.github.com/users/Cosifne/followers","following_url":"https://api.github.com/users/Cosifne/following{/other_user}","gists_url":"https://api.github.com/users/Cosifne/gists{/gist_id}","starred_url":"https://api.github.com/users/Cosifne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cosifne/subscriptions","organizations_url":"https://api.github.com/users/Cosifne/orgs","repos_url":"https://api.github.com/users/Cosifne/repos","events_url":"https://api.github.com/users/Cosifne/events{/privacy}","received_events_url":"https://api.github.com/users/Cosifne/received_events","type":"User","site_admin":false},"body":"Fixed","created_at":"2018-08-20T16:58:59Z","updated_at":"2018-08-20T16:59:00Z","html_url":"https://github.com/Cosifne/roslyn-tools/pull/1#discussion_r211334998","pull_request_url":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/1","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/comments/211334998"},"html":{"href":"https://github.com/Cosifne/roslyn-tools/pull/1#discussion_r211334998"},"pull_request":{"href":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/1"}},"in_reply_to_id":211041152},"pull_request":{"url":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/1","id":206516770,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA2NTE2Nzcw","html_url":"https://github.com/Cosifne/roslyn-tools/pull/1","diff_url":"https://github.com/Cosifne/roslyn-tools/pull/1.diff","patch_url":"https://github.com/Cosifne/roslyn-tools/pull/1.patch","issue_url":"https://api.github.com/repos/Cosifne/roslyn-tools/issues/1","number":1,"state":"open","locked":false,"title":"VSTS auto merge tool","user":{"login":"Cosifne","id":24360909,"node_id":"MDQ6VXNlcjI0MzYwOTA5","avatar_url":"https://avatars2.githubusercontent.com/u/24360909?v=4","gravatar_id":"","url":"https://api.github.com/users/Cosifne","html_url":"https://github.com/Cosifne","followers_url":"https://api.github.com/users/Cosifne/followers","following_url":"https://api.github.com/users/Cosifne/following{/other_user}","gists_url":"https://api.github.com/users/Cosifne/gists{/gist_id}","starred_url":"https://api.github.com/users/Cosifne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cosifne/subscriptions","organizations_url":"https://api.github.com/users/Cosifne/orgs","repos_url":"https://api.github.com/users/Cosifne/repos","events_url":"https://api.github.com/users/Cosifne/events{/privacy}","received_events_url":"https://api.github.com/users/Cosifne/received_events","type":"User","site_admin":false},"body":"This is an auto merge tool which aims to provide similar functions like [the GitHub tool here](https://github.com/dotnet/roslyn-tools/blob/master/src/GithubMergeTool/GithubMergeTool.cs) but targeting working on VSTS\r\n\r\n### Currently its logic:\r\n\r\n1.  Check the source and destination branch exist\r\n\r\n2. Check if there is existing PR between source and destination branch\r\n\r\n3. Create a dummy branch of destination branch\r\n\r\n4. Create a PR from source branch to dummy branch\r\n\r\n###  Lacking logic:\r\n\r\n- [Merge the the PR if there is no conflict. Then commit the changes from dummy branch to destination] \r\n\r\n- [If conflicts exist, wait until the user solves the conflict, then perform the same as previous step] \r\n\r\n- [ Clean dummy branch ] \r\n\r\nThe main problem at here is VSTS seems don't have a RESTful API for merging. Maybe possibly be done by using libgit2 or ask the help of VSTS people. Needs further investigation.\r\n\r\n\r\n**This is the first version so any comment or advice on the logic and code structure is welcome.**\r\n\r\nRevision 2:\r\n\r\n1. Delete the personal token logic.\r\n2. Source branch and Target branch are now fetched from command line.\r\n3. Delete some useless setting file.\r\n4. Details improvement. Add copyright, fix logger configuration file etc.\r\n\r\nRevision 3\r\n1. Add delete branch method. But current is not used in main logic.\r\n2. Add a method to fetch repository id by using repository name. So we don't need to hard code repository Id in setting file.\r\n\r\nRevision 4\r\n1. Add try /catch logic and time out\r\n2. Don't checking if there is an existing PR between source and dummy branch. Instead first check if the dummy branch exists, then check if there is an open PR. If not, remove the branch.\r\n3. Add many logger and fix some naming.","created_at":"2018-08-06T21:05:49Z","updated_at":"2018-08-20T16:59:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a4b24fbbdf6c0430ea799fb479b443c07d58a7eb","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/1/commits","review_comments_url":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/1/comments","review_comment_url":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Cosifne/roslyn-tools/issues/1/comments","statuses_url":"https://api.github.com/repos/Cosifne/roslyn-tools/statuses/329e605bfe3ed290f2cc9d740401ab93c34b4ae3","head":{"label":"Cosifne:VstsMergeTool","ref":"VstsMergeTool","sha":"329e605bfe3ed290f2cc9d740401ab93c34b4ae3","user":{"login":"Cosifne","id":24360909,"node_id":"MDQ6VXNlcjI0MzYwOTA5","avatar_url":"https://avatars2.githubusercontent.com/u/24360909?v=4","gravatar_id":"","url":"https://api.github.com/users/Cosifne","html_url":"https://github.com/Cosifne","followers_url":"https://api.github.com/users/Cosifne/followers","following_url":"https://api.github.com/users/Cosifne/following{/other_user}","gists_url":"https://api.github.com/users/Cosifne/gists{/gist_id}","starred_url":"https://api.github.com/users/Cosifne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cosifne/subscriptions","organizations_url":"https://api.github.com/users/Cosifne/orgs","repos_url":"https://api.github.com/users/Cosifne/repos","events_url":"https://api.github.com/users/Cosifne/events{/privacy}","received_events_url":"https://api.github.com/users/Cosifne/received_events","type":"User","site_admin":false},"repo":{"id":143763679,"node_id":"MDEwOlJlcG9zaXRvcnkxNDM3NjM2Nzk=","name":"roslyn-tools","full_name":"Cosifne/roslyn-tools","owner":{"login":"Cosifne","id":24360909,"node_id":"MDQ6VXNlcjI0MzYwOTA5","avatar_url":"https://avatars2.githubusercontent.com/u/24360909?v=4","gravatar_id":"","url":"https://api.github.com/users/Cosifne","html_url":"https://github.com/Cosifne","followers_url":"https://api.github.com/users/Cosifne/followers","following_url":"https://api.github.com/users/Cosifne/following{/other_user}","gists_url":"https://api.github.com/users/Cosifne/gists{/gist_id}","starred_url":"https://api.github.com/users/Cosifne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cosifne/subscriptions","organizations_url":"https://api.github.com/users/Cosifne/orgs","repos_url":"https://api.github.com/users/Cosifne/repos","events_url":"https://api.github.com/users/Cosifne/events{/privacy}","received_events_url":"https://api.github.com/users/Cosifne/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Cosifne/roslyn-tools","description":"Tools used in Roslyn based repos","fork":true,"url":"https://api.github.com/repos/Cosifne/roslyn-tools","forks_url":"https://api.github.com/repos/Cosifne/roslyn-tools/forks","keys_url":"https://api.github.com/repos/Cosifne/roslyn-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Cosifne/roslyn-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Cosifne/roslyn-tools/teams","hooks_url":"https://api.github.com/repos/Cosifne/roslyn-tools/hooks","issue_events_url":"https://api.github.com/repos/Cosifne/roslyn-tools/issues/events{/number}","events_url":"https://api.github.com/repos/Cosifne/roslyn-tools/events","assignees_url":"https://api.github.com/repos/Cosifne/roslyn-tools/assignees{/user}","branches_url":"https://api.github.com/repos/Cosifne/roslyn-tools/branches{/branch}","tags_url":"https://api.github.com/repos/Cosifne/roslyn-tools/tags","blobs_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Cosifne/roslyn-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/Cosifne/roslyn-tools/languages","stargazers_url":"https://api.github.com/repos/Cosifne/roslyn-tools/stargazers","contributors_url":"https://api.github.com/repos/Cosifne/roslyn-tools/contributors","subscribers_url":"https://api.github.com/repos/Cosifne/roslyn-tools/subscribers","subscription_url":"https://api.github.com/repos/Cosifne/roslyn-tools/subscription","commits_url":"https://api.github.com/repos/Cosifne/roslyn-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/Cosifne/roslyn-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/Cosifne/roslyn-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/Cosifne/roslyn-tools/contents/{+path}","compare_url":"https://api.github.com/repos/Cosifne/roslyn-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Cosifne/roslyn-tools/merges","archive_url":"https://api.github.com/repos/Cosifne/roslyn-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Cosifne/roslyn-tools/downloads","issues_url":"https://api.github.com/repos/Cosifne/roslyn-tools/issues{/number}","pulls_url":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/Cosifne/roslyn-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/Cosifne/roslyn-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Cosifne/roslyn-tools/labels{/name}","releases_url":"https://api.github.com/repos/Cosifne/roslyn-tools/releases{/id}","deployments_url":"https://api.github.com/repos/Cosifne/roslyn-tools/deployments","created_at":"2018-08-06T17:53:23Z","updated_at":"2018-08-06T17:53:26Z","pushed_at":"2018-08-16T23:45:46Z","git_url":"git://github.com/Cosifne/roslyn-tools.git","ssh_url":"git@github.com:Cosifne/roslyn-tools.git","clone_url":"https://github.com/Cosifne/roslyn-tools.git","svn_url":"https://github.com/Cosifne/roslyn-tools","homepage":"","size":20355,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"Cosifne:master","ref":"master","sha":"e99cb6ffb49dd384470f867890469a0e48e0125f","user":{"login":"Cosifne","id":24360909,"node_id":"MDQ6VXNlcjI0MzYwOTA5","avatar_url":"https://avatars2.githubusercontent.com/u/24360909?v=4","gravatar_id":"","url":"https://api.github.com/users/Cosifne","html_url":"https://github.com/Cosifne","followers_url":"https://api.github.com/users/Cosifne/followers","following_url":"https://api.github.com/users/Cosifne/following{/other_user}","gists_url":"https://api.github.com/users/Cosifne/gists{/gist_id}","starred_url":"https://api.github.com/users/Cosifne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cosifne/subscriptions","organizations_url":"https://api.github.com/users/Cosifne/orgs","repos_url":"https://api.github.com/users/Cosifne/repos","events_url":"https://api.github.com/users/Cosifne/events{/privacy}","received_events_url":"https://api.github.com/users/Cosifne/received_events","type":"User","site_admin":false},"repo":{"id":143763679,"node_id":"MDEwOlJlcG9zaXRvcnkxNDM3NjM2Nzk=","name":"roslyn-tools","full_name":"Cosifne/roslyn-tools","owner":{"login":"Cosifne","id":24360909,"node_id":"MDQ6VXNlcjI0MzYwOTA5","avatar_url":"https://avatars2.githubusercontent.com/u/24360909?v=4","gravatar_id":"","url":"https://api.github.com/users/Cosifne","html_url":"https://github.com/Cosifne","followers_url":"https://api.github.com/users/Cosifne/followers","following_url":"https://api.github.com/users/Cosifne/following{/other_user}","gists_url":"https://api.github.com/users/Cosifne/gists{/gist_id}","starred_url":"https://api.github.com/users/Cosifne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cosifne/subscriptions","organizations_url":"https://api.github.com/users/Cosifne/orgs","repos_url":"https://api.github.com/users/Cosifne/repos","events_url":"https://api.github.com/users/Cosifne/events{/privacy}","received_events_url":"https://api.github.com/users/Cosifne/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Cosifne/roslyn-tools","description":"Tools used in Roslyn based repos","fork":true,"url":"https://api.github.com/repos/Cosifne/roslyn-tools","forks_url":"https://api.github.com/repos/Cosifne/roslyn-tools/forks","keys_url":"https://api.github.com/repos/Cosifne/roslyn-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Cosifne/roslyn-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Cosifne/roslyn-tools/teams","hooks_url":"https://api.github.com/repos/Cosifne/roslyn-tools/hooks","issue_events_url":"https://api.github.com/repos/Cosifne/roslyn-tools/issues/events{/number}","events_url":"https://api.github.com/repos/Cosifne/roslyn-tools/events","assignees_url":"https://api.github.com/repos/Cosifne/roslyn-tools/assignees{/user}","branches_url":"https://api.github.com/repos/Cosifne/roslyn-tools/branches{/branch}","tags_url":"https://api.github.com/repos/Cosifne/roslyn-tools/tags","blobs_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Cosifne/roslyn-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/Cosifne/roslyn-tools/languages","stargazers_url":"https://api.github.com/repos/Cosifne/roslyn-tools/stargazers","contributors_url":"https://api.github.com/repos/Cosifne/roslyn-tools/contributors","subscribers_url":"https://api.github.com/repos/Cosifne/roslyn-tools/subscribers","subscription_url":"https://api.github.com/repos/Cosifne/roslyn-tools/subscription","commits_url":"https://api.github.com/repos/Cosifne/roslyn-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/Cosifne/roslyn-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/Cosifne/roslyn-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/Cosifne/roslyn-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/Cosifne/roslyn-tools/contents/{+path}","compare_url":"https://api.github.com/repos/Cosifne/roslyn-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Cosifne/roslyn-tools/merges","archive_url":"https://api.github.com/repos/Cosifne/roslyn-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Cosifne/roslyn-tools/downloads","issues_url":"https://api.github.com/repos/Cosifne/roslyn-tools/issues{/number}","pulls_url":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/Cosifne/roslyn-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/Cosifne/roslyn-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Cosifne/roslyn-tools/labels{/name}","releases_url":"https://api.github.com/repos/Cosifne/roslyn-tools/releases{/id}","deployments_url":"https://api.github.com/repos/Cosifne/roslyn-tools/deployments","created_at":"2018-08-06T17:53:23Z","updated_at":"2018-08-06T17:53:26Z","pushed_at":"2018-08-16T23:45:46Z","git_url":"git://github.com/Cosifne/roslyn-tools.git","ssh_url":"git@github.com:Cosifne/roslyn-tools.git","clone_url":"https://github.com/Cosifne/roslyn-tools.git","svn_url":"https://github.com/Cosifne/roslyn-tools","homepage":"","size":20355,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/1"},"html":{"href":"https://github.com/Cosifne/roslyn-tools/pull/1"},"issue":{"href":"https://api.github.com/repos/Cosifne/roslyn-tools/issues/1"},"comments":{"href":"https://api.github.com/repos/Cosifne/roslyn-tools/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Cosifne/roslyn-tools/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/Cosifne/roslyn-tools/statuses/329e605bfe3ed290f2cc9d740401ab93c34b4ae3"}},"author_association":"OWNER"}}
{"actor":{"display_login":"Cosifne"}}