{"action":"created","comment":{"url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/comments/231299937","pull_request_review_id":172240303,"id":231299937,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMTI5OTkzNw==","diff_hunk":"@@ -0,0 +1,154 @@\n+#! /usr/bin/python3\n+\n+# github-push -- Push the local branch to a GitHub PR, with benefits\n+#\n+# This tool pushes your local changes to a PR and also adds a comment\n+# that summarizes what has changed.  The idea is to cement the actual\n+# history of the PR in its comments, regardless of rebases, rewrites,\n+# squashed fixups, etc.\n+#\n+# If you don't have a upstream tracking branch, you need to specify\n+# the pull request number as an argument.\n+#\n+# If you do have a upstream tracking branch, you can omit the pull\n+# request number.  The tool will find it by looking through all open\n+# pull requests on GitHub and picking the one that matches the\n+# tracking branch.  Once it has been found, the number is cached in\n+# the Git config file to speed up subsequent invocations.\n+\n+import subprocess\n+import argparse\n+import sys\n+import time\n+\n+from task import github\n+\n+def execute(*args):\n+    try:\n+        output = subprocess.check_output(args, universal_newlines=True)\n+    except subprocess.CalledProcessError as ex:\n+        sys.exit(ex.returncode)\n+    return output\n+\n+def git(*args):\n+    return execute(\"git\", *args)\n+\n+def git_config(name):\n+    try:\n+        output = subprocess.check_output([ \"git\", \"config\", name ], universal_newlines=True)\n+    except subprocess.CalledProcessError as ex:\n+        return None\n+    return output.strip()\n+\n+def push_and_comment(api, repo, pull_number, remote, local, push_dest, push_ref):\n+    if local == remote:\n+        sys.stderr.write(\"Nothing to push.\\n\")\n+        return 0\n+\n+    diff = git(\"diff\", remote, local)\n+    old_commits_link = \"https://github.com/\" + repo + \"/commits/\" + remote\n+    diff_link = \"https://github.com/\" + repo + \"/compare/\" + remote + \"..\" + local\n+\n+    def make_comment(title, include_old_commits=False):\n+        diff_lines = diff.count(\"\\n\")\n+        first_line_parts = [ ]\n+        if include_old_commits:\n+            first_line_parts.append(\"[Old commits](%s)\" % old_commits_link)\n+        if diff_lines > 0:\n+            first_line_parts.append(\"[Diff](%s)\" % (diff_link))\n+        first_line = \" | \".join(first_line_parts)\n+        if diff_lines > 0 and diff_lines < 500:\n+            return (\"<details><summary>%s</summary>\\n\\n%s\\n```diff\\n%s```\\n</details>\\n\"\n+                    % (title, first_line, diff))\n+        else:\n+            return \"%s\\n%s\\n\" % (title, first_line)\n+\n+    git(\"push\", \"--force-with-lease=%s:%s\" % (push_ref, remote), push_dest, \"%s:%s\" % (local, push_ref))\n+\n+    for n in range(100,0,-1):\n+        try:\n+            if api.get(\"commits/%s\" % local, verbose=False):\n+                break\n+        except RuntimeError as e:\n+            if not \"Unprocessable Entity\" in str(e) or n <= 1:\n+                raise\n+            print(\"(new commits not yet in the GiHub API...please stand by. *beep*)\")\n+        time.sleep(1)\n+\n+    if git(\"merge-base\", local, remote).strip() == remote:\n+        comment = make_comment(\"New commits.\")\n+\n+    elif diff == \"\":\n+        old_statuses = api.statuses(remote)\n+        copy_count = 0\n+        for key in old_statuses:\n+            api.post(\"statuses/\" + local, old_statuses[key])\n+            copy_count += 1","path":"bots/github-push","position":86,"original_position":86,"commit_id":"a5f6ddedf937c9f104e0c8c794c07537c3916425","original_commit_id":"a5f6ddedf937c9f104e0c8c794c07537c3916425","user":{"login":"martinpitt","id":200109,"node_id":"MDQ6VXNlcjIwMDEwOQ==","avatar_url":"https://avatars3.githubusercontent.com/u/200109?v=4","gravatar_id":"","url":"https://api.github.com/users/martinpitt","html_url":"https://github.com/martinpitt","followers_url":"https://api.github.com/users/martinpitt/followers","following_url":"https://api.github.com/users/martinpitt/following{/other_user}","gists_url":"https://api.github.com/users/martinpitt/gists{/gist_id}","starred_url":"https://api.github.com/users/martinpitt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/martinpitt/subscriptions","organizations_url":"https://api.github.com/users/martinpitt/orgs","repos_url":"https://api.github.com/users/martinpitt/repos","events_url":"https://api.github.com/users/martinpitt/events{/privacy}","received_events_url":"https://api.github.com/users/martinpitt/received_events","type":"User","site_admin":false},"body":"`copy_count` could just be replaced with `len(old_statuses)`. But nitpicking..","created_at":"2018-11-06T21:29:36Z","updated_at":"2018-11-06T21:32:02Z","html_url":"https://github.com/cockpit-project/cockpit/pull/10218#discussion_r231299937","pull_request_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/10218","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/comments/231299937"},"html":{"href":"https://github.com/cockpit-project/cockpit/pull/10218#discussion_r231299937"},"pull_request":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/10218"}}},"pull_request":{"url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/10218","id":220335588,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIwMzM1NTg4","html_url":"https://github.com/cockpit-project/cockpit/pull/10218","diff_url":"https://github.com/cockpit-project/cockpit/pull/10218.diff","patch_url":"https://github.com/cockpit-project/cockpit/pull/10218.patch","issue_url":"https://api.github.com/repos/cockpit-project/cockpit/issues/10218","number":10218,"state":"open","locked":false,"title":"bots: Add github-push tool","user":{"login":"mvollmer","id":3228183,"node_id":"MDQ6VXNlcjMyMjgxODM=","avatar_url":"https://avatars1.githubusercontent.com/u/3228183?v=4","gravatar_id":"","url":"https://api.github.com/users/mvollmer","html_url":"https://github.com/mvollmer","followers_url":"https://api.github.com/users/mvollmer/followers","following_url":"https://api.github.com/users/mvollmer/following{/other_user}","gists_url":"https://api.github.com/users/mvollmer/gists{/gist_id}","starred_url":"https://api.github.com/users/mvollmer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mvollmer/subscriptions","organizations_url":"https://api.github.com/users/mvollmer/orgs","repos_url":"https://api.github.com/users/mvollmer/repos","events_url":"https://api.github.com/users/mvollmer/events{/privacy}","received_events_url":"https://api.github.com/users/mvollmer/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-10-04T11:05:41Z","updated_at":"2018-11-06T21:32:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9450c215607eb99ddab43aae23e68fe0798579dc","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":989236553,"node_id":"MDU6TGFiZWw5ODkyMzY1NTM=","url":"https://api.github.com/repos/cockpit-project/cockpit/labels/test-external","name":"test-external","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/10218/commits","review_comments_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/10218/comments","review_comment_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cockpit-project/cockpit/issues/10218/comments","statuses_url":"https://api.github.com/repos/cockpit-project/cockpit/statuses/a5f6ddedf937c9f104e0c8c794c07537c3916425","head":{"label":"mvollmer:bots-github-push-tool","ref":"bots-github-push-tool","sha":"a5f6ddedf937c9f104e0c8c794c07537c3916425","user":{"login":"mvollmer","id":3228183,"node_id":"MDQ6VXNlcjMyMjgxODM=","avatar_url":"https://avatars1.githubusercontent.com/u/3228183?v=4","gravatar_id":"","url":"https://api.github.com/users/mvollmer","html_url":"https://github.com/mvollmer","followers_url":"https://api.github.com/users/mvollmer/followers","following_url":"https://api.github.com/users/mvollmer/following{/other_user}","gists_url":"https://api.github.com/users/mvollmer/gists{/gist_id}","starred_url":"https://api.github.com/users/mvollmer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mvollmer/subscriptions","organizations_url":"https://api.github.com/users/mvollmer/orgs","repos_url":"https://api.github.com/users/mvollmer/repos","events_url":"https://api.github.com/users/mvollmer/events{/privacy}","received_events_url":"https://api.github.com/users/mvollmer/received_events","type":"User","site_admin":false},"repo":{"id":20679941,"node_id":"MDEwOlJlcG9zaXRvcnkyMDY3OTk0MQ==","name":"cockpit","full_name":"mvollmer/cockpit","private":false,"owner":{"login":"mvollmer","id":3228183,"node_id":"MDQ6VXNlcjMyMjgxODM=","avatar_url":"https://avatars1.githubusercontent.com/u/3228183?v=4","gravatar_id":"","url":"https://api.github.com/users/mvollmer","html_url":"https://github.com/mvollmer","followers_url":"https://api.github.com/users/mvollmer/followers","following_url":"https://api.github.com/users/mvollmer/following{/other_user}","gists_url":"https://api.github.com/users/mvollmer/gists{/gist_id}","starred_url":"https://api.github.com/users/mvollmer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mvollmer/subscriptions","organizations_url":"https://api.github.com/users/mvollmer/orgs","repos_url":"https://api.github.com/users/mvollmer/repos","events_url":"https://api.github.com/users/mvollmer/events{/privacy}","received_events_url":"https://api.github.com/users/mvollmer/received_events","type":"User","site_admin":false},"html_url":"https://github.com/mvollmer/cockpit","description":"Cockpit, a user interface for GNU/Linux servers","fork":true,"url":"https://api.github.com/repos/mvollmer/cockpit","forks_url":"https://api.github.com/repos/mvollmer/cockpit/forks","keys_url":"https://api.github.com/repos/mvollmer/cockpit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mvollmer/cockpit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mvollmer/cockpit/teams","hooks_url":"https://api.github.com/repos/mvollmer/cockpit/hooks","issue_events_url":"https://api.github.com/repos/mvollmer/cockpit/issues/events{/number}","events_url":"https://api.github.com/repos/mvollmer/cockpit/events","assignees_url":"https://api.github.com/repos/mvollmer/cockpit/assignees{/user}","branches_url":"https://api.github.com/repos/mvollmer/cockpit/branches{/branch}","tags_url":"https://api.github.com/repos/mvollmer/cockpit/tags","blobs_url":"https://api.github.com/repos/mvollmer/cockpit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mvollmer/cockpit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mvollmer/cockpit/git/refs{/sha}","trees_url":"https://api.github.com/repos/mvollmer/cockpit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mvollmer/cockpit/statuses/{sha}","languages_url":"https://api.github.com/repos/mvollmer/cockpit/languages","stargazers_url":"https://api.github.com/repos/mvollmer/cockpit/stargazers","contributors_url":"https://api.github.com/repos/mvollmer/cockpit/contributors","subscribers_url":"https://api.github.com/repos/mvollmer/cockpit/subscribers","subscription_url":"https://api.github.com/repos/mvollmer/cockpit/subscription","commits_url":"https://api.github.com/repos/mvollmer/cockpit/commits{/sha}","git_commits_url":"https://api.github.com/repos/mvollmer/cockpit/git/commits{/sha}","comments_url":"https://api.github.com/repos/mvollmer/cockpit/comments{/number}","issue_comment_url":"https://api.github.com/repos/mvollmer/cockpit/issues/comments{/number}","contents_url":"https://api.github.com/repos/mvollmer/cockpit/contents/{+path}","compare_url":"https://api.github.com/repos/mvollmer/cockpit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mvollmer/cockpit/merges","archive_url":"https://api.github.com/repos/mvollmer/cockpit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mvollmer/cockpit/downloads","issues_url":"https://api.github.com/repos/mvollmer/cockpit/issues{/number}","pulls_url":"https://api.github.com/repos/mvollmer/cockpit/pulls{/number}","milestones_url":"https://api.github.com/repos/mvollmer/cockpit/milestones{/number}","notifications_url":"https://api.github.com/repos/mvollmer/cockpit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mvollmer/cockpit/labels{/name}","releases_url":"https://api.github.com/repos/mvollmer/cockpit/releases{/id}","deployments_url":"https://api.github.com/repos/mvollmer/cockpit/deployments","created_at":"2014-06-10T09:35:54Z","updated_at":"2016-07-01T17:36:24Z","pushed_at":"2018-11-06T14:38:52Z","git_url":"git://github.com/mvollmer/cockpit.git","ssh_url":"git@github.com:mvollmer/cockpit.git","clone_url":"https://github.com/mvollmer/cockpit.git","svn_url":"https://github.com/mvollmer/cockpit","homepage":"http://www.cockpit-project.org/","size":59892,"stargazers_count":2,"watchers_count":2,"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,"open_issues_count":1,"license":{"key":"lgpl-2.1","name":"GNU Lesser General Public License v2.1","spdx_id":"LGPL-2.1","url":"https://api.github.com/licenses/lgpl-2.1","node_id":"MDc6TGljZW5zZTEx"},"forks":0,"open_issues":1,"watchers":2,"default_branch":"master"}},"base":{"label":"cockpit-project:master","ref":"master","sha":"50b53bc209eeadf124d80a7b42cfad2ead11c2e1","user":{"login":"cockpit-project","id":5765104,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU3NjUxMDQ=","avatar_url":"https://avatars2.githubusercontent.com/u/5765104?v=4","gravatar_id":"","url":"https://api.github.com/users/cockpit-project","html_url":"https://github.com/cockpit-project","followers_url":"https://api.github.com/users/cockpit-project/followers","following_url":"https://api.github.com/users/cockpit-project/following{/other_user}","gists_url":"https://api.github.com/users/cockpit-project/gists{/gist_id}","starred_url":"https://api.github.com/users/cockpit-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cockpit-project/subscriptions","organizations_url":"https://api.github.com/users/cockpit-project/orgs","repos_url":"https://api.github.com/users/cockpit-project/repos","events_url":"https://api.github.com/users/cockpit-project/events{/privacy}","received_events_url":"https://api.github.com/users/cockpit-project/received_events","type":"Organization","site_admin":false},"repo":{"id":14049216,"node_id":"MDEwOlJlcG9zaXRvcnkxNDA0OTIxNg==","name":"cockpit","full_name":"cockpit-project/cockpit","private":false,"owner":{"login":"cockpit-project","id":5765104,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU3NjUxMDQ=","avatar_url":"https://avatars2.githubusercontent.com/u/5765104?v=4","gravatar_id":"","url":"https://api.github.com/users/cockpit-project","html_url":"https://github.com/cockpit-project","followers_url":"https://api.github.com/users/cockpit-project/followers","following_url":"https://api.github.com/users/cockpit-project/following{/other_user}","gists_url":"https://api.github.com/users/cockpit-project/gists{/gist_id}","starred_url":"https://api.github.com/users/cockpit-project/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cockpit-project/subscriptions","organizations_url":"https://api.github.com/users/cockpit-project/orgs","repos_url":"https://api.github.com/users/cockpit-project/repos","events_url":"https://api.github.com/users/cockpit-project/events{/privacy}","received_events_url":"https://api.github.com/users/cockpit-project/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/cockpit-project/cockpit","description":"There's code a goin' on","fork":false,"url":"https://api.github.com/repos/cockpit-project/cockpit","forks_url":"https://api.github.com/repos/cockpit-project/cockpit/forks","keys_url":"https://api.github.com/repos/cockpit-project/cockpit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cockpit-project/cockpit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cockpit-project/cockpit/teams","hooks_url":"https://api.github.com/repos/cockpit-project/cockpit/hooks","issue_events_url":"https://api.github.com/repos/cockpit-project/cockpit/issues/events{/number}","events_url":"https://api.github.com/repos/cockpit-project/cockpit/events","assignees_url":"https://api.github.com/repos/cockpit-project/cockpit/assignees{/user}","branches_url":"https://api.github.com/repos/cockpit-project/cockpit/branches{/branch}","tags_url":"https://api.github.com/repos/cockpit-project/cockpit/tags","blobs_url":"https://api.github.com/repos/cockpit-project/cockpit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cockpit-project/cockpit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cockpit-project/cockpit/git/refs{/sha}","trees_url":"https://api.github.com/repos/cockpit-project/cockpit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cockpit-project/cockpit/statuses/{sha}","languages_url":"https://api.github.com/repos/cockpit-project/cockpit/languages","stargazers_url":"https://api.github.com/repos/cockpit-project/cockpit/stargazers","contributors_url":"https://api.github.com/repos/cockpit-project/cockpit/contributors","subscribers_url":"https://api.github.com/repos/cockpit-project/cockpit/subscribers","subscription_url":"https://api.github.com/repos/cockpit-project/cockpit/subscription","commits_url":"https://api.github.com/repos/cockpit-project/cockpit/commits{/sha}","git_commits_url":"https://api.github.com/repos/cockpit-project/cockpit/git/commits{/sha}","comments_url":"https://api.github.com/repos/cockpit-project/cockpit/comments{/number}","issue_comment_url":"https://api.github.com/repos/cockpit-project/cockpit/issues/comments{/number}","contents_url":"https://api.github.com/repos/cockpit-project/cockpit/contents/{+path}","compare_url":"https://api.github.com/repos/cockpit-project/cockpit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cockpit-project/cockpit/merges","archive_url":"https://api.github.com/repos/cockpit-project/cockpit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cockpit-project/cockpit/downloads","issues_url":"https://api.github.com/repos/cockpit-project/cockpit/issues{/number}","pulls_url":"https://api.github.com/repos/cockpit-project/cockpit/pulls{/number}","milestones_url":"https://api.github.com/repos/cockpit-project/cockpit/milestones{/number}","notifications_url":"https://api.github.com/repos/cockpit-project/cockpit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cockpit-project/cockpit/labels{/name}","releases_url":"https://api.github.com/repos/cockpit-project/cockpit/releases{/id}","deployments_url":"https://api.github.com/repos/cockpit-project/cockpit/deployments","created_at":"2013-11-01T17:36:46Z","updated_at":"2018-11-06T21:21:49Z","pushed_at":"2018-11-06T21:21:41Z","git_url":"git://github.com/cockpit-project/cockpit.git","ssh_url":"git@github.com:cockpit-project/cockpit.git","clone_url":"https://github.com/cockpit-project/cockpit.git","svn_url":"https://github.com/cockpit-project/cockpit","homepage":"http://www.cockpit-project.org/","size":58208,"stargazers_count":3482,"watchers_count":3482,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":451,"mirror_url":null,"archived":false,"open_issues_count":677,"license":{"key":"lgpl-2.1","name":"GNU Lesser General Public License v2.1","spdx_id":"LGPL-2.1","url":"https://api.github.com/licenses/lgpl-2.1","node_id":"MDc6TGljZW5zZTEx"},"forks":451,"open_issues":677,"watchers":3482,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/10218"},"html":{"href":"https://github.com/cockpit-project/cockpit/pull/10218"},"issue":{"href":"https://api.github.com/repos/cockpit-project/cockpit/issues/10218"},"comments":{"href":"https://api.github.com/repos/cockpit-project/cockpit/issues/10218/comments"},"review_comments":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/10218/comments"},"review_comment":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cockpit-project/cockpit/pulls/10218/commits"},"statuses":{"href":"https://api.github.com/repos/cockpit-project/cockpit/statuses/a5f6ddedf937c9f104e0c8c794c07537c3916425"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"martinpitt"}}