{"action":"created","comment":{"url":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/comments/228527975","pull_request_review_id":168824184,"id":228527975,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyODUyNzk3NQ==","diff_hunk":"@@ -0,0 +1,157 @@\n+#!/usr/bin/env python\n+# -*- coding: UTF-8 -*-\n+# authors:\n+# Tony Vattathil <tonynv@amazon.com>, <avattathil@gmail.com>\n+# Santiago Cardenas <sancard@amazon.com>, <santiago[dot]cardenas[at]outlook[dot]com>\n+# Shivansh Singh <sshvans@amazon.com>,\n+# Jay McConnell <jmmccon@amazon.com>,\n+# Andrew Glenn <andglenn@amazon.com>\n+from __future__ import print_function\n+\n+import hashlib\n+import fnmatch\n+import os\n+import time\n+from functools import partial\n+from multiprocessing.dummy import Pool as ThreadPool\n+from taskcat.colored_console import PrintMsg\n+\n+\n+class S3Sync(object):\n+    \"\"\"Syncronizes local project files with S3 based on checksums.\n+\n+    Excludes hidden files, unpackaged lambda source and taskcat /ci/ files.\n+    Uses the Etag as an md5 which introduces the following limitations\n+        * Uses undocumented etag algorithm for multipart uploads\n+        * Does not work wil files uploaded in the console that use SSE encryption\n+        * see https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html for more info\n+    Does not support buckets with versioning enabled\n+    \"\"\"\n+\n+    _exclude_files = [\n+        \".*\",\n+        \"*.md\"\n+    ]\n+    _exclude_path_prefixes = [\n+        \"functions/source/\",\n+        \".\",\n+        \"ci/\"\n+    ]\n+\n+    def __init__(self, s3_client, bucket, prefix, path, acl=None):\n+        \"\"\"Syncronizes local file system with an s3 bucket/prefix\n+\n+        \"\"\"\n+        if prefix != \"\" and not prefix.endswith('/'):\n+            prefix = prefix + '/'\n+        self.s3_client = s3_client\n+        fl = self._get_local_file_list(path)\n+        s3fl = self._get_s3_file_list(bucket, prefix)\n+        self._sync(fl, s3fl, bucket, prefix, acl=acl)\n+        return\n+\n+    def _hash_file(self, file_path, chunk_size=8 * 1024 * 1024):\n+        # This is a bit funky because of the way multipart upload etags are done, they are a md5 of the md5's from each part with the number of parts appended\n+        # credit to hyperknot https://github.com/aws/aws-cli/issues/2585#issue-226758933\n+        md5s = []\n+\n+        with open(file_path, 'rb') as fp:\n+            while True:\n+                data = fp.read(chunk_size)\n+                if not data:\n+                    break\n+                md5s.append(hashlib.md5(data))\n+\n+        if len(md5s) == 1:\n+            return '\"{}\"'.format(md5s[0].hexdigest())\n+\n+        digests = b''.join(m.digest() for m in md5s)\n+        digests_md5 = hashlib.md5(digests)\n+        return '\"{}-{}\"'.format(digests_md5.hexdigest(), len(md5s))\n+\n+    def _get_local_file_list(self, path, include_checksums=True):\n+        file_list = []\n+        path = os.path.abspath(os.path.expanduser(path))\n+        for root, dirs, files in os.walk(path):\n+            relpath = os.path.relpath(root, path) + \"/\"\n+            exclude_path = False\n+            if relpath == './':\n+                relpath = \"\"\n+            for p in S3Sync._exclude_path_prefixes:\n+                if relpath.startswith(p):\n+                    exclude_path = True\n+                    break\n+            if not exclude_path:\n+                for file in files:\n+                    exclude = False\n+                    for p in S3Sync._exclude_files:","path":"taskcat/s3_sync.py","position":87,"original_position":87,"commit_id":"6a3d29a7f25a5677e605f9ff5aa7de964554b256","original_commit_id":"6a3d29a7f25a5677e605f9ff5aa7de964554b256","user":{"login":"agamzn","id":29951057,"node_id":"MDQ6VXNlcjI5OTUxMDU3","avatar_url":"https://avatars2.githubusercontent.com/u/29951057?v=4","gravatar_id":"","url":"https://api.github.com/users/agamzn","html_url":"https://github.com/agamzn","followers_url":"https://api.github.com/users/agamzn/followers","following_url":"https://api.github.com/users/agamzn/following{/other_user}","gists_url":"https://api.github.com/users/agamzn/gists{/gist_id}","starred_url":"https://api.github.com/users/agamzn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agamzn/subscriptions","organizations_url":"https://api.github.com/users/agamzn/orgs","repos_url":"https://api.github.com/users/agamzn/repos","events_url":"https://api.github.com/users/agamzn/events{/privacy}","received_events_url":"https://api.github.com/users/agamzn/received_events","type":"User","site_admin":false},"body":"Can this be refactored? Looping over the `S3Sync._exclude_files` list for each file seems costly.","created_at":"2018-10-26T13:32:44Z","updated_at":"2018-10-26T13:40:01Z","html_url":"https://github.com/aws-quickstart/taskcat/pull/151#discussion_r228527975","pull_request_url":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/151","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/comments/228527975"},"html":{"href":"https://github.com/aws-quickstart/taskcat/pull/151#discussion_r228527975"},"pull_request":{"href":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/151"}}},"pull_request":{"url":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/151","id":225948323,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI1OTQ4MzIz","html_url":"https://github.com/aws-quickstart/taskcat/pull/151","diff_url":"https://github.com/aws-quickstart/taskcat/pull/151.diff","patch_url":"https://github.com/aws-quickstart/taskcat/pull/151.patch","issue_url":"https://api.github.com/repos/aws-quickstart/taskcat/issues/151","number":151,"state":"open","locked":false,"title":"sync with S3","user":{"login":"jaymccon","id":20962883,"node_id":"MDQ6VXNlcjIwOTYyODgz","avatar_url":"https://avatars0.githubusercontent.com/u/20962883?v=4","gravatar_id":"","url":"https://api.github.com/users/jaymccon","html_url":"https://github.com/jaymccon","followers_url":"https://api.github.com/users/jaymccon/followers","following_url":"https://api.github.com/users/jaymccon/following{/other_user}","gists_url":"https://api.github.com/users/jaymccon/gists{/gist_id}","starred_url":"https://api.github.com/users/jaymccon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jaymccon/subscriptions","organizations_url":"https://api.github.com/users/jaymccon/orgs","repos_url":"https://api.github.com/users/jaymccon/repos","events_url":"https://api.github.com/users/jaymccon/events{/privacy}","received_events_url":"https://api.github.com/users/jaymccon/received_events","type":"User","site_admin":false},"body":"## Overview\r\n\r\nCurrently taskcat simply pushes all local files to a bucket on each run, regardless of whether files have changed, it also leaves files in s3 that are no longer in the local project.\r\n\r\nThis changes behavior to upload only changed files, and delete files not present locally. Speeds up upload when only small changes have been made.\r\n\r\nadds `--upload-only` switch that syncs s3 and then exits.\r\n\r\n## Testing/Steps taken to ensure quality\r\n\r\nlaunched a quickstart\r\n\r\n### Notes\r\n\r\nUses undocumented behavior for checksums of multipart uploads, see https://github.com/aws/aws-cli/issues/2585#issue-226758933\r\n\r\nNo longer fetching template and parameters from s3, but fetching locally instead. \r\n\r\nenforces template path to `templates/` and parameters to `ci/`, not sure if there are any existing quick starts that don't follow this pattern.\r\n\r\nNo unit tests yet 😞\r\n\r\nCould use a global override option for bucket name, this way a user can use a single bucket for all their taskcat work.\r\n\r\n## Testing Instructions\r\n\r\ntested against the openshift quick start.\r\n","created_at":"2018-10-26T01:06:59Z","updated_at":"2018-10-26T13:40:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"47768d3911bc092217942a6b8fde1e47c20fc63c","assignee":null,"assignees":[],"requested_reviewers":[{"login":"vsnyc","id":624297,"node_id":"MDQ6VXNlcjYyNDI5Nw==","avatar_url":"https://avatars1.githubusercontent.com/u/624297?v=4","gravatar_id":"","url":"https://api.github.com/users/vsnyc","html_url":"https://github.com/vsnyc","followers_url":"https://api.github.com/users/vsnyc/followers","following_url":"https://api.github.com/users/vsnyc/following{/other_user}","gists_url":"https://api.github.com/users/vsnyc/gists{/gist_id}","starred_url":"https://api.github.com/users/vsnyc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vsnyc/subscriptions","organizations_url":"https://api.github.com/users/vsnyc/orgs","repos_url":"https://api.github.com/users/vsnyc/repos","events_url":"https://api.github.com/users/vsnyc/events{/privacy}","received_events_url":"https://api.github.com/users/vsnyc/received_events","type":"User","site_admin":false},{"login":"avattathil","id":5912128,"node_id":"MDQ6VXNlcjU5MTIxMjg=","avatar_url":"https://avatars3.githubusercontent.com/u/5912128?v=4","gravatar_id":"","url":"https://api.github.com/users/avattathil","html_url":"https://github.com/avattathil","followers_url":"https://api.github.com/users/avattathil/followers","following_url":"https://api.github.com/users/avattathil/following{/other_user}","gists_url":"https://api.github.com/users/avattathil/gists{/gist_id}","starred_url":"https://api.github.com/users/avattathil/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/avattathil/subscriptions","organizations_url":"https://api.github.com/users/avattathil/orgs","repos_url":"https://api.github.com/users/avattathil/repos","events_url":"https://api.github.com/users/avattathil/events{/privacy}","received_events_url":"https://api.github.com/users/avattathil/received_events","type":"User","site_admin":false},{"login":"sshvans","id":24257501,"node_id":"MDQ6VXNlcjI0MjU3NTAx","avatar_url":"https://avatars1.githubusercontent.com/u/24257501?v=4","gravatar_id":"","url":"https://api.github.com/users/sshvans","html_url":"https://github.com/sshvans","followers_url":"https://api.github.com/users/sshvans/followers","following_url":"https://api.github.com/users/sshvans/following{/other_user}","gists_url":"https://api.github.com/users/sshvans/gists{/gist_id}","starred_url":"https://api.github.com/users/sshvans/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sshvans/subscriptions","organizations_url":"https://api.github.com/users/sshvans/orgs","repos_url":"https://api.github.com/users/sshvans/repos","events_url":"https://api.github.com/users/sshvans/events{/privacy}","received_events_url":"https://api.github.com/users/sshvans/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/151/commits","review_comments_url":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/151/comments","review_comment_url":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/comments{/number}","comments_url":"https://api.github.com/repos/aws-quickstart/taskcat/issues/151/comments","statuses_url":"https://api.github.com/repos/aws-quickstart/taskcat/statuses/6a3d29a7f25a5677e605f9ff5aa7de964554b256","head":{"label":"aws-quickstart:feature/s3_sync","ref":"feature/s3_sync","sha":"6a3d29a7f25a5677e605f9ff5aa7de964554b256","user":{"login":"aws-quickstart","id":17076214,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE3MDc2MjE0","avatar_url":"https://avatars2.githubusercontent.com/u/17076214?v=4","gravatar_id":"","url":"https://api.github.com/users/aws-quickstart","html_url":"https://github.com/aws-quickstart","followers_url":"https://api.github.com/users/aws-quickstart/followers","following_url":"https://api.github.com/users/aws-quickstart/following{/other_user}","gists_url":"https://api.github.com/users/aws-quickstart/gists{/gist_id}","starred_url":"https://api.github.com/users/aws-quickstart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aws-quickstart/subscriptions","organizations_url":"https://api.github.com/users/aws-quickstart/orgs","repos_url":"https://api.github.com/users/aws-quickstart/repos","events_url":"https://api.github.com/users/aws-quickstart/events{/privacy}","received_events_url":"https://api.github.com/users/aws-quickstart/received_events","type":"Organization","site_admin":false},"repo":{"id":73759774,"node_id":"MDEwOlJlcG9zaXRvcnk3Mzc1OTc3NA==","name":"taskcat","full_name":"aws-quickstart/taskcat","private":false,"owner":{"login":"aws-quickstart","id":17076214,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE3MDc2MjE0","avatar_url":"https://avatars2.githubusercontent.com/u/17076214?v=4","gravatar_id":"","url":"https://api.github.com/users/aws-quickstart","html_url":"https://github.com/aws-quickstart","followers_url":"https://api.github.com/users/aws-quickstart/followers","following_url":"https://api.github.com/users/aws-quickstart/following{/other_user}","gists_url":"https://api.github.com/users/aws-quickstart/gists{/gist_id}","starred_url":"https://api.github.com/users/aws-quickstart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aws-quickstart/subscriptions","organizations_url":"https://api.github.com/users/aws-quickstart/orgs","repos_url":"https://api.github.com/users/aws-quickstart/repos","events_url":"https://api.github.com/users/aws-quickstart/events{/privacy}","received_events_url":"https://api.github.com/users/aws-quickstart/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/aws-quickstart/taskcat","description":"Test all the CloudFormation things! (with TaskCat)","fork":false,"url":"https://api.github.com/repos/aws-quickstart/taskcat","forks_url":"https://api.github.com/repos/aws-quickstart/taskcat/forks","keys_url":"https://api.github.com/repos/aws-quickstart/taskcat/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aws-quickstart/taskcat/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aws-quickstart/taskcat/teams","hooks_url":"https://api.github.com/repos/aws-quickstart/taskcat/hooks","issue_events_url":"https://api.github.com/repos/aws-quickstart/taskcat/issues/events{/number}","events_url":"https://api.github.com/repos/aws-quickstart/taskcat/events","assignees_url":"https://api.github.com/repos/aws-quickstart/taskcat/assignees{/user}","branches_url":"https://api.github.com/repos/aws-quickstart/taskcat/branches{/branch}","tags_url":"https://api.github.com/repos/aws-quickstart/taskcat/tags","blobs_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/refs{/sha}","trees_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aws-quickstart/taskcat/statuses/{sha}","languages_url":"https://api.github.com/repos/aws-quickstart/taskcat/languages","stargazers_url":"https://api.github.com/repos/aws-quickstart/taskcat/stargazers","contributors_url":"https://api.github.com/repos/aws-quickstart/taskcat/contributors","subscribers_url":"https://api.github.com/repos/aws-quickstart/taskcat/subscribers","subscription_url":"https://api.github.com/repos/aws-quickstart/taskcat/subscription","commits_url":"https://api.github.com/repos/aws-quickstart/taskcat/commits{/sha}","git_commits_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/commits{/sha}","comments_url":"https://api.github.com/repos/aws-quickstart/taskcat/comments{/number}","issue_comment_url":"https://api.github.com/repos/aws-quickstart/taskcat/issues/comments{/number}","contents_url":"https://api.github.com/repos/aws-quickstart/taskcat/contents/{+path}","compare_url":"https://api.github.com/repos/aws-quickstart/taskcat/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aws-quickstart/taskcat/merges","archive_url":"https://api.github.com/repos/aws-quickstart/taskcat/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aws-quickstart/taskcat/downloads","issues_url":"https://api.github.com/repos/aws-quickstart/taskcat/issues{/number}","pulls_url":"https://api.github.com/repos/aws-quickstart/taskcat/pulls{/number}","milestones_url":"https://api.github.com/repos/aws-quickstart/taskcat/milestones{/number}","notifications_url":"https://api.github.com/repos/aws-quickstart/taskcat/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aws-quickstart/taskcat/labels{/name}","releases_url":"https://api.github.com/repos/aws-quickstart/taskcat/releases{/id}","deployments_url":"https://api.github.com/repos/aws-quickstart/taskcat/deployments","created_at":"2016-11-15T00:29:01Z","updated_at":"2018-10-26T02:21:47Z","pushed_at":"2018-10-26T01:06:59Z","git_url":"git://github.com/aws-quickstart/taskcat.git","ssh_url":"git@github.com:aws-quickstart/taskcat.git","clone_url":"https://github.com/aws-quickstart/taskcat.git","svn_url":"https://github.com/aws-quickstart/taskcat","homepage":"","size":3500,"stargazers_count":111,"watchers_count":111,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":38,"mirror_url":null,"archived":false,"open_issues_count":15,"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":38,"open_issues":15,"watchers":111,"default_branch":"develop"}},"base":{"label":"aws-quickstart:develop","ref":"develop","sha":"39c27e14e7626639b0f2ff9b752961aa1c675163","user":{"login":"aws-quickstart","id":17076214,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE3MDc2MjE0","avatar_url":"https://avatars2.githubusercontent.com/u/17076214?v=4","gravatar_id":"","url":"https://api.github.com/users/aws-quickstart","html_url":"https://github.com/aws-quickstart","followers_url":"https://api.github.com/users/aws-quickstart/followers","following_url":"https://api.github.com/users/aws-quickstart/following{/other_user}","gists_url":"https://api.github.com/users/aws-quickstart/gists{/gist_id}","starred_url":"https://api.github.com/users/aws-quickstart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aws-quickstart/subscriptions","organizations_url":"https://api.github.com/users/aws-quickstart/orgs","repos_url":"https://api.github.com/users/aws-quickstart/repos","events_url":"https://api.github.com/users/aws-quickstart/events{/privacy}","received_events_url":"https://api.github.com/users/aws-quickstart/received_events","type":"Organization","site_admin":false},"repo":{"id":73759774,"node_id":"MDEwOlJlcG9zaXRvcnk3Mzc1OTc3NA==","name":"taskcat","full_name":"aws-quickstart/taskcat","private":false,"owner":{"login":"aws-quickstart","id":17076214,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE3MDc2MjE0","avatar_url":"https://avatars2.githubusercontent.com/u/17076214?v=4","gravatar_id":"","url":"https://api.github.com/users/aws-quickstart","html_url":"https://github.com/aws-quickstart","followers_url":"https://api.github.com/users/aws-quickstart/followers","following_url":"https://api.github.com/users/aws-quickstart/following{/other_user}","gists_url":"https://api.github.com/users/aws-quickstart/gists{/gist_id}","starred_url":"https://api.github.com/users/aws-quickstart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aws-quickstart/subscriptions","organizations_url":"https://api.github.com/users/aws-quickstart/orgs","repos_url":"https://api.github.com/users/aws-quickstart/repos","events_url":"https://api.github.com/users/aws-quickstart/events{/privacy}","received_events_url":"https://api.github.com/users/aws-quickstart/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/aws-quickstart/taskcat","description":"Test all the CloudFormation things! (with TaskCat)","fork":false,"url":"https://api.github.com/repos/aws-quickstart/taskcat","forks_url":"https://api.github.com/repos/aws-quickstart/taskcat/forks","keys_url":"https://api.github.com/repos/aws-quickstart/taskcat/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aws-quickstart/taskcat/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aws-quickstart/taskcat/teams","hooks_url":"https://api.github.com/repos/aws-quickstart/taskcat/hooks","issue_events_url":"https://api.github.com/repos/aws-quickstart/taskcat/issues/events{/number}","events_url":"https://api.github.com/repos/aws-quickstart/taskcat/events","assignees_url":"https://api.github.com/repos/aws-quickstart/taskcat/assignees{/user}","branches_url":"https://api.github.com/repos/aws-quickstart/taskcat/branches{/branch}","tags_url":"https://api.github.com/repos/aws-quickstart/taskcat/tags","blobs_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/refs{/sha}","trees_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aws-quickstart/taskcat/statuses/{sha}","languages_url":"https://api.github.com/repos/aws-quickstart/taskcat/languages","stargazers_url":"https://api.github.com/repos/aws-quickstart/taskcat/stargazers","contributors_url":"https://api.github.com/repos/aws-quickstart/taskcat/contributors","subscribers_url":"https://api.github.com/repos/aws-quickstart/taskcat/subscribers","subscription_url":"https://api.github.com/repos/aws-quickstart/taskcat/subscription","commits_url":"https://api.github.com/repos/aws-quickstart/taskcat/commits{/sha}","git_commits_url":"https://api.github.com/repos/aws-quickstart/taskcat/git/commits{/sha}","comments_url":"https://api.github.com/repos/aws-quickstart/taskcat/comments{/number}","issue_comment_url":"https://api.github.com/repos/aws-quickstart/taskcat/issues/comments{/number}","contents_url":"https://api.github.com/repos/aws-quickstart/taskcat/contents/{+path}","compare_url":"https://api.github.com/repos/aws-quickstart/taskcat/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aws-quickstart/taskcat/merges","archive_url":"https://api.github.com/repos/aws-quickstart/taskcat/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aws-quickstart/taskcat/downloads","issues_url":"https://api.github.com/repos/aws-quickstart/taskcat/issues{/number}","pulls_url":"https://api.github.com/repos/aws-quickstart/taskcat/pulls{/number}","milestones_url":"https://api.github.com/repos/aws-quickstart/taskcat/milestones{/number}","notifications_url":"https://api.github.com/repos/aws-quickstart/taskcat/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aws-quickstart/taskcat/labels{/name}","releases_url":"https://api.github.com/repos/aws-quickstart/taskcat/releases{/id}","deployments_url":"https://api.github.com/repos/aws-quickstart/taskcat/deployments","created_at":"2016-11-15T00:29:01Z","updated_at":"2018-10-26T02:21:47Z","pushed_at":"2018-10-26T01:06:59Z","git_url":"git://github.com/aws-quickstart/taskcat.git","ssh_url":"git@github.com:aws-quickstart/taskcat.git","clone_url":"https://github.com/aws-quickstart/taskcat.git","svn_url":"https://github.com/aws-quickstart/taskcat","homepage":"","size":3500,"stargazers_count":111,"watchers_count":111,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":38,"mirror_url":null,"archived":false,"open_issues_count":15,"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":38,"open_issues":15,"watchers":111,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/151"},"html":{"href":"https://github.com/aws-quickstart/taskcat/pull/151"},"issue":{"href":"https://api.github.com/repos/aws-quickstart/taskcat/issues/151"},"comments":{"href":"https://api.github.com/repos/aws-quickstart/taskcat/issues/151/comments"},"review_comments":{"href":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/151/comments"},"review_comment":{"href":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/aws-quickstart/taskcat/pulls/151/commits"},"statuses":{"href":"https://api.github.com/repos/aws-quickstart/taskcat/statuses/6a3d29a7f25a5677e605f9ff5aa7de964554b256"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"agamzn"}}