{"action":"created","comment":{"url":"https://api.github.com/repos/travis-ci/dpl/pulls/comments/153052792","pull_request_review_id":79009965,"id":153052792,"diff_hunk":"@@ -48,29 +57,70 @@ def check_auth\n       end\n \n       def needs_key?\n+        # Provider's generic support for keys is about provisioning and\n+        # deprovisioning them, while this provider needs to install an encrypted\n+        # key provided by the caller.\n         false\n       end\n \n+      def create_git_dir(gitdir)\n+        if @gh_token\n+          target_repo = \"https://#{@gh_token}@#{@gh_ref}\"\n+        else\n+          # Depend on the key set up in push_app.\n+          target_repo = \"git@github.com:#{slug}.git\"\n+        end\n+        unless context.shell \"git clone --branch '#{@target_branch}' --depth 1 '#{target_repo}' '#{gitdir}'\"\n+          FileUtils.mkdir(gitdir)\n+          FileUtils.cd(gitdir) do\n+            context.shell \"git init\" or error 'Could not create new git repo'\n+            context.shell \"git remote add origin '#{target_repo}'\"\n+            context.shell \"git checkout -b '#{@target_branch}'\"\n+          end\n+        end\n+        FileUtils.cd(gitdir) do\n+          context.shell \"git config user.email '#{@gh_email}'\"\n+          context.shell \"git config user.name '#{@gh_name}'\"\n+        end\n+        return true\n+      end\n+\n       def github_deploy\n-        context.shell 'rm -rf .git > /dev/null 2>&1'\n-        context.shell \"touch \\\"deployed at `date` by #{@gh_name}\\\"\"\n-        context.shell 'git init' or raise 'Could not create new git repo'\n-        context.shell \"git config user.email '#{@gh_email}'\"\n-        context.shell \"git config user.name '#{@gh_name}'\"\n         context.shell \"echo '#{@gh_fqdn}' > CNAME\" if @gh_fqdn\n         context.shell 'git add .'\n+        if context.shell \"git diff --cached --quiet\"\n+          log \"No changes; skipping deploy.\"\n+          return true\n+        end\n         context.shell \"FILES=\\\"`git commit -m 'Deploy #{@project_name} to #{@gh_ref}:#{@target_branch}' | tail`\\\"; echo \\\"$FILES\\\"; echo \\\"$FILES\\\" | [ `wc -l` -lt 10 ] || echo '...'\"\n-        context.shell \"git push --force --quiet 'https://#{@gh_token}@#{@gh_ref}' master:#{@target_branch} > /dev/null 2>&1\"\n+        # The following line will fail if another deploy happened concurrently.\n+        # We'd rather have the deploy for the later revision succeed, but that\n+        # takes a lot more code.\n+        context.shell \"git push --quiet origin #{@target_branch}\"\n       end\n \n       def push_app\n-        Dir.mktmpdir {|tmpdir|\n-            FileUtils.cp_r(\"#{@build_dir}/.\", tmpdir)\n+        Dir.mktmpdir {|gitdir|\n+          if @gh_deploy_key\n+            # Decrypt the key and install it.\n+            context.shell \"openssl aes-256-cbc -k '#{@gh_deploy_key_key}' -in '#{@gh_deploy_key}' -out #{gitdir}/deploykey -d\"\n+            File.chmod(0600, \"#{gitdir}/deploykey\")\n+            setup_git_ssh(\"#{gitdir}/git-ssh\", \"#{gitdir}/deploykey\")\n+          end\n+          Dir.mktmpdir {|tmpdir|\n+            # A failed `git clone` removes its target directory, so use a\n+            # subdirectory to make sure we can safely re-create it.\n+            tmpdir = \"#{tmpdir}/deploy\"\n+            unless create_git_dir(tmpdir)\n+              error \"Couldn't create checkout to push to #{@gh_ref}:#{@target_branch}\"\n+            end\n+            context.shell \"rsync -r --exclude .git --delete #{@build_dir}/ #{tmpdir}\" or error \"Could not copy #{@build_dir}.\"","path":"lib/dpl/provider/pages.rb","position":96,"original_position":96,"commit_id":"434e2db1434463b7ea6fc14279bb9b90a67ff4dc","original_commit_id":"434e2db1434463b7ea6fc14279bb9b90a67ff4dc","user":{"login":"webknjaz","id":578543,"avatar_url":"https://avatars2.githubusercontent.com/u/578543?v=4","gravatar_id":"","url":"https://api.github.com/users/webknjaz","html_url":"https://github.com/webknjaz","followers_url":"https://api.github.com/users/webknjaz/followers","following_url":"https://api.github.com/users/webknjaz/following{/other_user}","gists_url":"https://api.github.com/users/webknjaz/gists{/gist_id}","starred_url":"https://api.github.com/users/webknjaz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/webknjaz/subscriptions","organizations_url":"https://api.github.com/users/webknjaz/orgs","repos_url":"https://api.github.com/users/webknjaz/repos","events_url":"https://api.github.com/users/webknjaz/events{/privacy}","received_events_url":"https://api.github.com/users/webknjaz/received_events","type":"User","site_admin":false},"body":"why rsync?","created_at":"2017-11-25T19:41:53Z","updated_at":"2017-11-25T19:41:53Z","html_url":"https://github.com/travis-ci/dpl/pull/715#discussion_r153052792","pull_request_url":"https://api.github.com/repos/travis-ci/dpl/pulls/715","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/travis-ci/dpl/pulls/comments/153052792"},"html":{"href":"https://github.com/travis-ci/dpl/pull/715#discussion_r153052792"},"pull_request":{"href":"https://api.github.com/repos/travis-ci/dpl/pulls/715"}}},"pull_request":{"url":"https://api.github.com/repos/travis-ci/dpl/pulls/715","id":153475919,"html_url":"https://github.com/travis-ci/dpl/pull/715","diff_url":"https://github.com/travis-ci/dpl/pull/715.diff","patch_url":"https://github.com/travis-ci/dpl/pull/715.patch","issue_url":"https://api.github.com/repos/travis-ci/dpl/issues/715","number":715,"state":"open","locked":false,"title":"Preserve history when deploying to gh-pages.","user":{"login":"jyasskin","id":83420,"avatar_url":"https://avatars1.githubusercontent.com/u/83420?v=4","gravatar_id":"","url":"https://api.github.com/users/jyasskin","html_url":"https://github.com/jyasskin","followers_url":"https://api.github.com/users/jyasskin/followers","following_url":"https://api.github.com/users/jyasskin/following{/other_user}","gists_url":"https://api.github.com/users/jyasskin/gists{/gist_id}","starred_url":"https://api.github.com/users/jyasskin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jyasskin/subscriptions","organizations_url":"https://api.github.com/users/jyasskin/orgs","repos_url":"https://api.github.com/users/jyasskin/repos","events_url":"https://api.github.com/users/jyasskin/events{/privacy}","received_events_url":"https://api.github.com/users/jyasskin/received_events","type":"User","site_admin":false},"body":"Fixes #704.\r\n\r\nThis change sits on top of #695, which is mostly reviewed.\r\n\r\n@webknjaz, does this look reasonable to you?\r\n\r\nTest deploys:\r\n* https://travis-ci.org/jyasskin/testing/builds/304151299 testing a deploy with no existing gh-pages branch.\r\n* https://travis-ci.org/jyasskin/testing/builds/304151521 testing a deploy with an existing gh-pages branch\r\n* https://travis-ci.org/jyasskin/testing/builds/304151699 testing that a no-op deploy is skipped.\r\n\r\nYou can see the resulting gh-pages branch at https://github.com/jyasskin/testing/commits/gh-pages.","created_at":"2017-11-19T01:11:26Z","updated_at":"2017-11-25T19:41:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b8e44ad100ddf432c28d51da63893a970fcc2f59","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/travis-ci/dpl/pulls/715/commits","review_comments_url":"https://api.github.com/repos/travis-ci/dpl/pulls/715/comments","review_comment_url":"https://api.github.com/repos/travis-ci/dpl/pulls/comments{/number}","comments_url":"https://api.github.com/repos/travis-ci/dpl/issues/715/comments","statuses_url":"https://api.github.com/repos/travis-ci/dpl/statuses/434e2db1434463b7ea6fc14279bb9b90a67ff4dc","head":{"label":"jyasskin:retain-history","ref":"retain-history","sha":"434e2db1434463b7ea6fc14279bb9b90a67ff4dc","user":{"login":"jyasskin","id":83420,"avatar_url":"https://avatars1.githubusercontent.com/u/83420?v=4","gravatar_id":"","url":"https://api.github.com/users/jyasskin","html_url":"https://github.com/jyasskin","followers_url":"https://api.github.com/users/jyasskin/followers","following_url":"https://api.github.com/users/jyasskin/following{/other_user}","gists_url":"https://api.github.com/users/jyasskin/gists{/gist_id}","starred_url":"https://api.github.com/users/jyasskin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jyasskin/subscriptions","organizations_url":"https://api.github.com/users/jyasskin/orgs","repos_url":"https://api.github.com/users/jyasskin/repos","events_url":"https://api.github.com/users/jyasskin/events{/privacy}","received_events_url":"https://api.github.com/users/jyasskin/received_events","type":"User","site_admin":false},"repo":{"id":105317935,"name":"dpl","full_name":"jyasskin/dpl","owner":{"login":"jyasskin","id":83420,"avatar_url":"https://avatars1.githubusercontent.com/u/83420?v=4","gravatar_id":"","url":"https://api.github.com/users/jyasskin","html_url":"https://github.com/jyasskin","followers_url":"https://api.github.com/users/jyasskin/followers","following_url":"https://api.github.com/users/jyasskin/following{/other_user}","gists_url":"https://api.github.com/users/jyasskin/gists{/gist_id}","starred_url":"https://api.github.com/users/jyasskin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jyasskin/subscriptions","organizations_url":"https://api.github.com/users/jyasskin/orgs","repos_url":"https://api.github.com/users/jyasskin/repos","events_url":"https://api.github.com/users/jyasskin/events{/privacy}","received_events_url":"https://api.github.com/users/jyasskin/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jyasskin/dpl","description":"Dpl (dee-pee-ell) is a deploy tool made for continuous deployment.","fork":true,"url":"https://api.github.com/repos/jyasskin/dpl","forks_url":"https://api.github.com/repos/jyasskin/dpl/forks","keys_url":"https://api.github.com/repos/jyasskin/dpl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jyasskin/dpl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jyasskin/dpl/teams","hooks_url":"https://api.github.com/repos/jyasskin/dpl/hooks","issue_events_url":"https://api.github.com/repos/jyasskin/dpl/issues/events{/number}","events_url":"https://api.github.com/repos/jyasskin/dpl/events","assignees_url":"https://api.github.com/repos/jyasskin/dpl/assignees{/user}","branches_url":"https://api.github.com/repos/jyasskin/dpl/branches{/branch}","tags_url":"https://api.github.com/repos/jyasskin/dpl/tags","blobs_url":"https://api.github.com/repos/jyasskin/dpl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jyasskin/dpl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jyasskin/dpl/git/refs{/sha}","trees_url":"https://api.github.com/repos/jyasskin/dpl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jyasskin/dpl/statuses/{sha}","languages_url":"https://api.github.com/repos/jyasskin/dpl/languages","stargazers_url":"https://api.github.com/repos/jyasskin/dpl/stargazers","contributors_url":"https://api.github.com/repos/jyasskin/dpl/contributors","subscribers_url":"https://api.github.com/repos/jyasskin/dpl/subscribers","subscription_url":"https://api.github.com/repos/jyasskin/dpl/subscription","commits_url":"https://api.github.com/repos/jyasskin/dpl/commits{/sha}","git_commits_url":"https://api.github.com/repos/jyasskin/dpl/git/commits{/sha}","comments_url":"https://api.github.com/repos/jyasskin/dpl/comments{/number}","issue_comment_url":"https://api.github.com/repos/jyasskin/dpl/issues/comments{/number}","contents_url":"https://api.github.com/repos/jyasskin/dpl/contents/{+path}","compare_url":"https://api.github.com/repos/jyasskin/dpl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jyasskin/dpl/merges","archive_url":"https://api.github.com/repos/jyasskin/dpl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jyasskin/dpl/downloads","issues_url":"https://api.github.com/repos/jyasskin/dpl/issues{/number}","pulls_url":"https://api.github.com/repos/jyasskin/dpl/pulls{/number}","milestones_url":"https://api.github.com/repos/jyasskin/dpl/milestones{/number}","notifications_url":"https://api.github.com/repos/jyasskin/dpl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jyasskin/dpl/labels{/name}","releases_url":"https://api.github.com/repos/jyasskin/dpl/releases{/id}","deployments_url":"https://api.github.com/repos/jyasskin/dpl/deployments","created_at":"2017-09-29T21:17:00Z","updated_at":"2017-09-29T21:17:03Z","pushed_at":"2017-11-23T06:56:54Z","git_url":"git://github.com/jyasskin/dpl.git","ssh_url":"git@github.com:jyasskin/dpl.git","clone_url":"https://github.com/jyasskin/dpl.git","svn_url":"https://github.com/jyasskin/dpl","homepage":"","size":2288,"stargazers_count":0,"watchers_count":0,"language":"Ruby","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":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"travis-ci:master","ref":"master","sha":"5f87d05aa63fab081d60d176fc54fd66aae716f3","user":{"login":"travis-ci","id":639823,"avatar_url":"https://avatars2.githubusercontent.com/u/639823?v=4","gravatar_id":"","url":"https://api.github.com/users/travis-ci","html_url":"https://github.com/travis-ci","followers_url":"https://api.github.com/users/travis-ci/followers","following_url":"https://api.github.com/users/travis-ci/following{/other_user}","gists_url":"https://api.github.com/users/travis-ci/gists{/gist_id}","starred_url":"https://api.github.com/users/travis-ci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/travis-ci/subscriptions","organizations_url":"https://api.github.com/users/travis-ci/orgs","repos_url":"https://api.github.com/users/travis-ci/repos","events_url":"https://api.github.com/users/travis-ci/events{/privacy}","received_events_url":"https://api.github.com/users/travis-ci/received_events","type":"Organization","site_admin":false},"repo":{"id":10312708,"name":"dpl","full_name":"travis-ci/dpl","owner":{"login":"travis-ci","id":639823,"avatar_url":"https://avatars2.githubusercontent.com/u/639823?v=4","gravatar_id":"","url":"https://api.github.com/users/travis-ci","html_url":"https://github.com/travis-ci","followers_url":"https://api.github.com/users/travis-ci/followers","following_url":"https://api.github.com/users/travis-ci/following{/other_user}","gists_url":"https://api.github.com/users/travis-ci/gists{/gist_id}","starred_url":"https://api.github.com/users/travis-ci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/travis-ci/subscriptions","organizations_url":"https://api.github.com/users/travis-ci/orgs","repos_url":"https://api.github.com/users/travis-ci/repos","events_url":"https://api.github.com/users/travis-ci/events{/privacy}","received_events_url":"https://api.github.com/users/travis-ci/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/travis-ci/dpl","description":"Dpl (dee-pee-ell) is a deploy tool made for continuous deployment.","fork":false,"url":"https://api.github.com/repos/travis-ci/dpl","forks_url":"https://api.github.com/repos/travis-ci/dpl/forks","keys_url":"https://api.github.com/repos/travis-ci/dpl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/travis-ci/dpl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/travis-ci/dpl/teams","hooks_url":"https://api.github.com/repos/travis-ci/dpl/hooks","issue_events_url":"https://api.github.com/repos/travis-ci/dpl/issues/events{/number}","events_url":"https://api.github.com/repos/travis-ci/dpl/events","assignees_url":"https://api.github.com/repos/travis-ci/dpl/assignees{/user}","branches_url":"https://api.github.com/repos/travis-ci/dpl/branches{/branch}","tags_url":"https://api.github.com/repos/travis-ci/dpl/tags","blobs_url":"https://api.github.com/repos/travis-ci/dpl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/travis-ci/dpl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/travis-ci/dpl/git/refs{/sha}","trees_url":"https://api.github.com/repos/travis-ci/dpl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/travis-ci/dpl/statuses/{sha}","languages_url":"https://api.github.com/repos/travis-ci/dpl/languages","stargazers_url":"https://api.github.com/repos/travis-ci/dpl/stargazers","contributors_url":"https://api.github.com/repos/travis-ci/dpl/contributors","subscribers_url":"https://api.github.com/repos/travis-ci/dpl/subscribers","subscription_url":"https://api.github.com/repos/travis-ci/dpl/subscription","commits_url":"https://api.github.com/repos/travis-ci/dpl/commits{/sha}","git_commits_url":"https://api.github.com/repos/travis-ci/dpl/git/commits{/sha}","comments_url":"https://api.github.com/repos/travis-ci/dpl/comments{/number}","issue_comment_url":"https://api.github.com/repos/travis-ci/dpl/issues/comments{/number}","contents_url":"https://api.github.com/repos/travis-ci/dpl/contents/{+path}","compare_url":"https://api.github.com/repos/travis-ci/dpl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/travis-ci/dpl/merges","archive_url":"https://api.github.com/repos/travis-ci/dpl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/travis-ci/dpl/downloads","issues_url":"https://api.github.com/repos/travis-ci/dpl/issues{/number}","pulls_url":"https://api.github.com/repos/travis-ci/dpl/pulls{/number}","milestones_url":"https://api.github.com/repos/travis-ci/dpl/milestones{/number}","notifications_url":"https://api.github.com/repos/travis-ci/dpl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/travis-ci/dpl/labels{/name}","releases_url":"https://api.github.com/repos/travis-ci/dpl/releases{/id}","deployments_url":"https://api.github.com/repos/travis-ci/dpl/deployments","created_at":"2013-05-27T10:26:39Z","updated_at":"2017-11-24T05:36:14Z","pushed_at":"2017-11-23T06:56:56Z","git_url":"git://github.com/travis-ci/dpl.git","ssh_url":"git@github.com:travis-ci/dpl.git","clone_url":"https://github.com/travis-ci/dpl.git","svn_url":"https://github.com/travis-ci/dpl","homepage":"","size":2326,"stargazers_count":659,"watchers_count":659,"language":"Ruby","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":276,"mirror_url":null,"archived":false,"open_issues_count":178,"forks":276,"open_issues":178,"watchers":659,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/travis-ci/dpl/pulls/715"},"html":{"href":"https://github.com/travis-ci/dpl/pull/715"},"issue":{"href":"https://api.github.com/repos/travis-ci/dpl/issues/715"},"comments":{"href":"https://api.github.com/repos/travis-ci/dpl/issues/715/comments"},"review_comments":{"href":"https://api.github.com/repos/travis-ci/dpl/pulls/715/comments"},"review_comment":{"href":"https://api.github.com/repos/travis-ci/dpl/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/travis-ci/dpl/pulls/715/commits"},"statuses":{"href":"https://api.github.com/repos/travis-ci/dpl/statuses/434e2db1434463b7ea6fc14279bb9b90a67ff4dc"}},"author_association":"NONE"}}
{"actor":{"display_login":"webknjaz"}}