txgh 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +202 -0
  3. data/README.md +64 -0
  4. data/lib/ext/zipline/output_stream.rb +62 -0
  5. data/lib/txgh.rb +53 -0
  6. data/lib/txgh/app.rb +135 -0
  7. data/lib/txgh/category_support.rb +31 -0
  8. data/lib/txgh/config.rb +11 -0
  9. data/lib/txgh/config/config_pair.rb +36 -0
  10. data/lib/txgh/config/key_manager.rb +54 -0
  11. data/lib/txgh/config/provider_instance.rb +20 -0
  12. data/lib/txgh/config/provider_support.rb +26 -0
  13. data/lib/txgh/config/providers.rb +9 -0
  14. data/lib/txgh/config/providers/file_provider.rb +19 -0
  15. data/lib/txgh/config/providers/git_provider.rb +58 -0
  16. data/lib/txgh/config/providers/raw_provider.rb +19 -0
  17. data/lib/txgh/config/tx_config.rb +77 -0
  18. data/lib/txgh/config/tx_manager.rb +15 -0
  19. data/lib/txgh/diff_calculator.rb +90 -0
  20. data/lib/txgh/empty_resource_contents.rb +43 -0
  21. data/lib/txgh/errors.rb +9 -0
  22. data/lib/txgh/github_api.rb +83 -0
  23. data/lib/txgh/github_repo.rb +88 -0
  24. data/lib/txgh/github_request_auth.rb +28 -0
  25. data/lib/txgh/handlers.rb +12 -0
  26. data/lib/txgh/handlers/download_handler.rb +84 -0
  27. data/lib/txgh/handlers/github.rb +10 -0
  28. data/lib/txgh/handlers/github/delete_handler.rb +65 -0
  29. data/lib/txgh/handlers/github/handler.rb +20 -0
  30. data/lib/txgh/handlers/github/push_handler.rb +108 -0
  31. data/lib/txgh/handlers/github/request_handler.rb +106 -0
  32. data/lib/txgh/handlers/response.rb +17 -0
  33. data/lib/txgh/handlers/stream_response.rb +39 -0
  34. data/lib/txgh/handlers/tgz_stream_response.rb +41 -0
  35. data/lib/txgh/handlers/transifex.rb +8 -0
  36. data/lib/txgh/handlers/transifex/hook_handler.rb +77 -0
  37. data/lib/txgh/handlers/transifex/request_handler.rb +78 -0
  38. data/lib/txgh/handlers/triggers.rb +9 -0
  39. data/lib/txgh/handlers/triggers/handler.rb +66 -0
  40. data/lib/txgh/handlers/triggers/pull_handler.rb +29 -0
  41. data/lib/txgh/handlers/triggers/push_handler.rb +21 -0
  42. data/lib/txgh/handlers/zip_stream_response.rb +21 -0
  43. data/lib/txgh/merge_calculator.rb +74 -0
  44. data/lib/txgh/parse_config.rb +24 -0
  45. data/lib/txgh/resource_committer.rb +39 -0
  46. data/lib/txgh/resource_contents.rb +118 -0
  47. data/lib/txgh/resource_downloader.rb +141 -0
  48. data/lib/txgh/resource_updater.rb +104 -0
  49. data/lib/txgh/response_helpers.rb +30 -0
  50. data/lib/txgh/transifex_api.rb +165 -0
  51. data/lib/txgh/transifex_project.rb +37 -0
  52. data/lib/txgh/transifex_request_auth.rb +53 -0
  53. data/lib/txgh/tx_branch_resource.rb +59 -0
  54. data/lib/txgh/tx_logger.rb +12 -0
  55. data/lib/txgh/tx_resource.rb +66 -0
  56. data/lib/txgh/utils.rb +44 -0
  57. data/lib/txgh/version.rb +3 -0
  58. data/spec/app_spec.rb +346 -0
  59. data/spec/category_support_spec.rb +43 -0
  60. data/spec/config/config_pair_spec.rb +47 -0
  61. data/spec/config/key_manager_spec.rb +48 -0
  62. data/spec/config/provider_instance_spec.rb +30 -0
  63. data/spec/config/provider_support_spec.rb +55 -0
  64. data/spec/config/tx_config_spec.rb +49 -0
  65. data/spec/config/tx_manager_spec.rb +57 -0
  66. data/spec/diff_calculator_spec.rb +90 -0
  67. data/spec/github_api_spec.rb +148 -0
  68. data/spec/github_repo_spec.rb +178 -0
  69. data/spec/github_request_auth_spec.rb +39 -0
  70. data/spec/handlers/download_handler_spec.rb +81 -0
  71. data/spec/handlers/github/delete_handler_spec.rb +71 -0
  72. data/spec/handlers/github/push_handler_spec.rb +76 -0
  73. data/spec/handlers/tgz_stream_response_spec.rb +59 -0
  74. data/spec/handlers/transifex/hook_handler_spec.rb +115 -0
  75. data/spec/handlers/zip_stream_response_spec.rb +58 -0
  76. data/spec/helpers/github_payload_builder.rb +141 -0
  77. data/spec/helpers/integration_setup.rb +47 -0
  78. data/spec/helpers/nil_logger.rb +10 -0
  79. data/spec/helpers/standard_txgh_setup.rb +92 -0
  80. data/spec/helpers/test_provider.rb +12 -0
  81. data/spec/integration/cassettes/github_l10n_hook_endpoint.yml +536 -0
  82. data/spec/integration/cassettes/pull.yml +47 -0
  83. data/spec/integration/cassettes/push.yml +544 -0
  84. data/spec/integration/cassettes/transifex_hook_endpoint.yml +560 -0
  85. data/spec/integration/config/tx.config +10 -0
  86. data/spec/integration/hooks_spec.rb +158 -0
  87. data/spec/integration/payloads/github_postbody.json +161 -0
  88. data/spec/integration/payloads/github_postbody_l10n.json +136 -0
  89. data/spec/integration/payloads/github_postbody_release.json +136 -0
  90. data/spec/integration/triggers_spec.rb +45 -0
  91. data/spec/merge_calculator_spec.rb +112 -0
  92. data/spec/parse_config_spec.rb +52 -0
  93. data/spec/resource_committer_spec.rb +42 -0
  94. data/spec/resource_contents_spec.rb +212 -0
  95. data/spec/resource_downloader_spec.rb +205 -0
  96. data/spec/resource_updater_spec.rb +147 -0
  97. data/spec/spec_helper.rb +32 -0
  98. data/spec/transifex_api_spec.rb +345 -0
  99. data/spec/transifex_project_spec.rb +45 -0
  100. data/spec/transifex_request_auth_spec.rb +39 -0
  101. data/spec/tx_branch_resource_spec.rb +99 -0
  102. data/spec/tx_resource_spec.rb +47 -0
  103. data/spec/utils_spec.rb +58 -0
  104. data/txgh.gemspec +29 -0
  105. metadata +296 -0
@@ -0,0 +1,10 @@
1
+ [main]
2
+ host = https://www.transifex.com
3
+ lang_map =
4
+
5
+ # Create one such section per resource
6
+ [test-project-88.samplepo]
7
+ file_filter = translations/<lang>/sample.po
8
+ source_file = sample.po
9
+ source_lang = en
10
+ type = PO
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+
3
+ require 'base64'
4
+ require 'json'
5
+ require 'pathname'
6
+ require 'rack/test'
7
+ require 'helpers/integration_setup'
8
+ require 'uri'
9
+ require 'yaml'
10
+
11
+ include Txgh
12
+
13
+ describe 'hook integration tests', integration: true do
14
+ include Rack::Test::Methods
15
+ include IntegrationSetup
16
+
17
+ def app
18
+ @app ||= Txgh::Hooks.new
19
+ end
20
+
21
+ around(:each) do |example|
22
+ Dir.chdir('./spec/integration') do
23
+ example.run
24
+ end
25
+ end
26
+
27
+ let(:base_config) do
28
+ {
29
+ 'github' => {
30
+ 'repos' => {
31
+ 'txgh-bot/txgh-test-resources' => {
32
+ 'api_username' => 'txgh-bot',
33
+ # github will auto-revoke a token if they notice it in one of your commits ;)
34
+ 'api_token' => Base64.decode64('YjViYWY3Nzk5NTdkMzVlMmI0OGZmYjk4YThlY2M1ZDY0NzAwNWRhZA=='),
35
+ 'push_source_to' => 'test-project-88',
36
+ 'branch' => 'master',
37
+ 'webhook_secret' => '18d3998f576dfe933357104b87abfd61'
38
+ }
39
+ }
40
+ },
41
+ 'transifex' => {
42
+ 'projects' => {
43
+ 'test-project-88' => {
44
+ 'tx_config' => 'file://./config/tx.config',
45
+ 'api_username' => 'txgh.bot',
46
+ 'api_password' => '2aqFGW99fPRKWvXBPjbrxkdiR',
47
+ 'push_translations_to' => 'txgh-bot/txgh-test-resources',
48
+ 'webhook_secret' => 'fce95b1748fd638c22174d34200f10cf'
49
+ }
50
+ }
51
+ }
52
+ }
53
+ end
54
+
55
+ before(:all) do
56
+ VCR.configure do |config|
57
+ config.filter_sensitive_data('<GITHUB_TOKEN>') do
58
+ base_config['github']['repos']['txgh-bot/txgh-test-resources']['api_token']
59
+ end
60
+
61
+ config.filter_sensitive_data('<TRANSIFEX_PASSWORD>') do
62
+ base_config['transifex']['projects']['test-project-88']['api_password']
63
+ end
64
+ end
65
+ end
66
+
67
+ before(:each) do
68
+ allow(Txgh::Config::KeyManager).to(
69
+ receive(:raw_config).and_return("raw://#{YAML.dump(base_config)}")
70
+ )
71
+ end
72
+
73
+ let(:payload_path) do
74
+ Pathname(File.dirname(__FILE__)).join('payloads')
75
+ end
76
+
77
+ let(:github_postbody) do
78
+ File.read(payload_path.join('github_postbody.json'))
79
+ end
80
+
81
+ let(:github_postbody_release) do
82
+ File.read(payload_path.join('github_postbody_release.json'))
83
+ end
84
+
85
+ let(:github_postbody_l10n) do
86
+ File.read(payload_path.join('github_postbody_l10n.json'))
87
+ end
88
+
89
+ let(:project_name) { 'test-project-88' }
90
+ let(:repo_name) { 'txgh-bot/txgh-test-resources' }
91
+
92
+ let(:config) do
93
+ Txgh::Config::KeyManager.config_from(project_name, repo_name)
94
+ end
95
+
96
+ def sign_github_request(body)
97
+ header(
98
+ GithubRequestAuth::GITHUB_HEADER,
99
+ GithubRequestAuth.header_value(body, config.github_repo.webhook_secret)
100
+ )
101
+ end
102
+
103
+ def sign_transifex_request(body)
104
+ header(
105
+ TransifexRequestAuth::TRANSIFEX_HEADER,
106
+ TransifexRequestAuth.header_value(body, config.transifex_project.webhook_secret)
107
+ )
108
+ end
109
+
110
+ it 'loads correct project config' do
111
+ expect(config.project_config).to_not be_nil
112
+ end
113
+
114
+ it 'verifies the transifex hook endpoint works' do
115
+ VCR.use_cassette('transifex_hook_endpoint') do
116
+ params = {
117
+ 'project' => 'test-project-88', 'resource' => 'samplepo',
118
+ 'language' => 'el_GR', 'translated' => 100
119
+ }
120
+
121
+ payload = URI.encode_www_form(params.to_a)
122
+
123
+ sign_transifex_request(payload)
124
+ post '/transifex', payload
125
+ expect(last_response).to be_ok
126
+ end
127
+ end
128
+
129
+ it 'verifies the github hook endpoint works' do
130
+ VCR.use_cassette('github_hook_endpoint') do
131
+ sign_github_request(github_postbody)
132
+ header 'X-GitHub-Event', 'push'
133
+ header 'content-type', 'application/x-www-form-urlencoded'
134
+ post '/github', github_postbody
135
+ expect(last_response).to be_ok
136
+ end
137
+ end
138
+
139
+ it 'verifies the github release hook endpoint works' do
140
+ VCR.use_cassette('github_release_hook_endpoint') do
141
+ sign_github_request(github_postbody_release)
142
+ header 'X-GitHub-Event', 'push'
143
+ header 'content-type', 'application/x-www-form-urlencoded'
144
+ post '/github', github_postbody_release
145
+ expect(last_response).to be_ok
146
+ end
147
+ end
148
+
149
+ it 'verifies the github l10n hook endpoint works' do
150
+ VCR.use_cassette('github_l10n_hook_endpoint') do
151
+ sign_github_request(github_postbody_l10n)
152
+ header 'X-GitHub-Event', 'push'
153
+ header 'content-type', 'application/x-www-form-urlencoded'
154
+ post '/github', github_postbody_l10n
155
+ expect(last_response).to be_ok
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,161 @@
1
+ {
2
+ "ref": "refs/heads/test",
3
+ "before": "0000000000000000000000000000000000000000",
4
+ "after": "fd2696fdb0c38d7a2bb4478b62423a701ad8f5fc",
5
+ "created": true,
6
+ "deleted": false,
7
+ "forced": true,
8
+ "base_ref": null,
9
+ "compare": "https://github.com/txgh-bot/txgh-test-resources/commit/fd2696fdb0c3",
10
+ "commits": [
11
+ {
12
+ "id": "fd2696fdb0c38d7a2bb4478b62423a701ad8f5fc",
13
+ "distinct": true,
14
+ "message": "Testing branch functionality",
15
+ "timestamp": "2015-10-10T22:03:14-07:00",
16
+ "url": "https://github.com/txgh-bot/txgh-test-resources/commit/fd2696fdb0c38d7a2bb4478b62423a701ad8f5fc",
17
+ "author": {
18
+ "name": "Txgh Bot",
19
+ "email": "txgh.bot@gmail.com",
20
+ "username": "txgh-bot"
21
+ },
22
+ "committer": {
23
+ "name": "Txgh Bot",
24
+ "email": "txgh.bot@gmail.com",
25
+ "username": "txgh-bot"
26
+ },
27
+ "added": [
28
+
29
+ ],
30
+ "removed": [
31
+
32
+ ],
33
+ "modified": [
34
+ "sample.po"
35
+ ]
36
+ }
37
+ ],
38
+ "head_commit": {
39
+ "id": "fd2696fdb0c38d7a2bb4478b62423a701ad8f5fc",
40
+ "distinct": true,
41
+ "message": "Testing branch functionality",
42
+ "timestamp": "2015-10-10T22:03:14-07:00",
43
+ "url": "https://github.com/txgh-bot/txgh-test-resources/commit/fd2696fdb0c38d7a2bb4478b62423a701ad8f5fc",
44
+ "author": {
45
+ "name": "Txgh Bot",
46
+ "email": "txgh.bot@gmail.com",
47
+ "username": "txgh-bot"
48
+ },
49
+ "committer": {
50
+ "name": "Txgh Bot",
51
+ "email": "txgh.bot@gmail.com",
52
+ "username": "txgh-bot"
53
+ },
54
+ "added": [
55
+
56
+ ],
57
+ "removed": [
58
+
59
+ ],
60
+ "modified": [
61
+ "sample.po"
62
+ ]
63
+ },
64
+ "repository": {
65
+ "id": 41740726,
66
+ "name": "txgh-test-resources",
67
+ "full_name": "txgh-bot/txgh-test-resources",
68
+ "owner": {
69
+ "name": "txgh-bot",
70
+ "email": "txgh.bot@gmail.com"
71
+ },
72
+ "private": false,
73
+ "html_url": "https://github.com/txgh-bot/txgh-test-resources",
74
+ "description": "Translation test repo for txgh",
75
+ "fork": false,
76
+ "url": "https://github.com/txgh-bot/txgh-test-resources",
77
+ "forks_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/forks",
78
+ "keys_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/keys{/key_id}",
79
+ "collaborators_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/collaborators{/collaborator}",
80
+ "teams_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/teams",
81
+ "hooks_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/hooks",
82
+ "issue_events_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/issues/events{/number}",
83
+ "events_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/events",
84
+ "assignees_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/assignees{/user}",
85
+ "branches_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/branches{/branch}",
86
+ "tags_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/tags",
87
+ "blobs_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/blobs{/sha}",
88
+ "git_tags_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/tags{/sha}",
89
+ "git_refs_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/refs{/sha}",
90
+ "trees_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/trees{/sha}",
91
+ "statuses_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/statuses/{sha}",
92
+ "languages_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/languages",
93
+ "stargazers_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/stargazers",
94
+ "contributors_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/contributors",
95
+ "subscribers_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/subscribers",
96
+ "subscription_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/subscription",
97
+ "commits_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/commits{/sha}",
98
+ "git_commits_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/commits{/sha}",
99
+ "comments_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/comments{/number}",
100
+ "issue_comment_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/issues/comments{/number}",
101
+ "contents_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/contents/{+path}",
102
+ "compare_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/compare/{base}...{head}",
103
+ "merges_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/merges",
104
+ "archive_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/{archive_format}{/ref}",
105
+ "downloads_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/downloads",
106
+ "issues_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/issues{/number}",
107
+ "pulls_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/pulls{/number}",
108
+ "milestones_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/milestones{/number}",
109
+ "notifications_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/notifications{?since,all,participating}",
110
+ "labels_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/labels{/name}",
111
+ "releases_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/releases{/id}",
112
+ "created_at": 1441114620,
113
+ "updated_at": "2015-09-01T13:37:00Z",
114
+ "pushed_at": 1444539817,
115
+ "git_url": "git://github.com/txgh-bot/txgh-test-resources.git",
116
+ "ssh_url": "git@github.com:txgh-bot/txgh-test-resources.git",
117
+ "clone_url": "https://github.com/txgh-bot/txgh-test-resources.git",
118
+ "svn_url": "https://github.com/txgh-bot/txgh-test-resources",
119
+ "homepage": null,
120
+ "size": 204,
121
+ "stargazers_count": 0,
122
+ "watchers_count": 0,
123
+ "language": null,
124
+ "has_issues": true,
125
+ "has_downloads": true,
126
+ "has_wiki": true,
127
+ "has_pages": false,
128
+ "forks_count": 0,
129
+ "mirror_url": null,
130
+ "open_issues_count": 0,
131
+ "forks": 0,
132
+ "open_issues": 0,
133
+ "watchers": 0,
134
+ "default_branch": "master",
135
+ "stargazers": 0,
136
+ "master_branch": "master"
137
+ },
138
+ "pusher": {
139
+ "name": "txgh-bot",
140
+ "email": "txgh.bot@gmail.com"
141
+ },
142
+ "sender": {
143
+ "login": "txgh-bot",
144
+ "id": 974299,
145
+ "avatar_url": "https://avatars.githubusercontent.com/u/974299?v=3",
146
+ "gravatar_id": "",
147
+ "url": "https://api.github.com/users/txgh-bot",
148
+ "html_url": "https://github.com/txgh-bot",
149
+ "followers_url": "https://api.github.com/users/txgh-bot/followers",
150
+ "following_url": "https://api.github.com/users/txgh-bot/following{/other_user}",
151
+ "gists_url": "https://api.github.com/users/txgh-bot/gists{/gist_id}",
152
+ "starred_url": "https://api.github.com/users/txgh-bot/starred{/owner}{/repo}",
153
+ "subscriptions_url": "https://api.github.com/users/txgh-bot/subscriptions",
154
+ "organizations_url": "https://api.github.com/users/txgh-bot/orgs",
155
+ "repos_url": "https://api.github.com/users/txgh-bot/repos",
156
+ "events_url": "https://api.github.com/users/txgh-bot/events{/privacy}",
157
+ "received_events_url": "https://api.github.com/users/txgh-bot/received_events",
158
+ "type": "User",
159
+ "site_admin": false
160
+ }
161
+ }
@@ -0,0 +1,136 @@
1
+ {
2
+ "ref": "refs/tags/L10N",
3
+ "before": "0000000000000000000000000000000000000000",
4
+ "after": "6eebc3eee49e8d46f6dbec16fe3360961bfdd8ed",
5
+ "created": true,
6
+ "deleted": false,
7
+ "forced": true,
8
+ "base_ref": "refs/heads/master",
9
+ "compare": "https://github.com/txgh-bot/txgh-test-resources/compare/L10N",
10
+ "commits": [
11
+
12
+ ],
13
+ "head_commit": {
14
+ "id": "6eebc3eee49e8d46f6dbec16fe3360961bfdd8ed",
15
+ "distinct": true,
16
+ "message": "10",
17
+ "timestamp": "2015-11-19T12:56:33-08:00",
18
+ "url": "https://github.com/txgh-bot/txgh-test-resources/commit/6eebc3eee49e8d46f6dbec16fe3360961bfdd8ed",
19
+ "author": {
20
+ "name": "Txgh Bot",
21
+ "email": "txgh.bot@gmail.com",
22
+ "username": "txgh-bot"
23
+ },
24
+ "committer": {
25
+ "name": "Txgh Bot",
26
+ "email": "txgh.bot@gmail.com",
27
+ "username": "txgh-bot"
28
+ },
29
+ "added": [
30
+
31
+ ],
32
+ "removed": [
33
+
34
+ ],
35
+ "modified": [
36
+ "sample.po"
37
+ ]
38
+ },
39
+ "repository": {
40
+ "id": 41740726,
41
+ "name": "txgh-test-resources",
42
+ "full_name": "txgh-bot/txgh-test-resources",
43
+ "owner": {
44
+ "name": "txgh-bot",
45
+ "email": "txgh.bot@gmail.com"
46
+ },
47
+ "private": false,
48
+ "html_url": "https://github.com/txgh-bot/txgh-test-resources",
49
+ "description": "Translation test repo for txgh",
50
+ "fork": false,
51
+ "url": "https://github.com/txgh-bot/txgh-test-resources",
52
+ "forks_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/forks",
53
+ "keys_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/keys{/key_id}",
54
+ "collaborators_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/collaborators{/collaborator}",
55
+ "teams_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/teams",
56
+ "hooks_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/hooks",
57
+ "issue_events_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/issues/events{/number}",
58
+ "events_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/events",
59
+ "assignees_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/assignees{/user}",
60
+ "branches_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/branches{/branch}",
61
+ "tags_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/tags",
62
+ "blobs_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/blobs{/sha}",
63
+ "git_tags_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/tags{/sha}",
64
+ "git_refs_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/refs{/sha}",
65
+ "trees_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/trees{/sha}",
66
+ "statuses_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/statuses/{sha}",
67
+ "languages_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/languages",
68
+ "stargazers_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/stargazers",
69
+ "contributors_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/contributors",
70
+ "subscribers_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/subscribers",
71
+ "subscription_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/subscription",
72
+ "commits_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/commits{/sha}",
73
+ "git_commits_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/git/commits{/sha}",
74
+ "comments_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/comments{/number}",
75
+ "issue_comment_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/issues/comments{/number}",
76
+ "contents_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/contents/{+path}",
77
+ "compare_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/compare/{base}...{head}",
78
+ "merges_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/merges",
79
+ "archive_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/{archive_format}{/ref}",
80
+ "downloads_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/downloads",
81
+ "issues_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/issues{/number}",
82
+ "pulls_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/pulls{/number}",
83
+ "milestones_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/milestones{/number}",
84
+ "notifications_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/notifications{?since,all,participating}",
85
+ "labels_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/labels{/name}",
86
+ "releases_url": "https://api.github.com/repos/txgh-bot/txgh-test-resources/releases{/id}",
87
+ "created_at": 1441114620,
88
+ "updated_at": "2015-09-01T13:37:00Z",
89
+ "pushed_at": 1447966674,
90
+ "git_url": "git://github.com/txgh-bot/txgh-test-resources.git",
91
+ "ssh_url": "git@github.com:txgh-bot/txgh-test-resources.git",
92
+ "clone_url": "https://github.com/txgh-bot/txgh-test-resources.git",
93
+ "svn_url": "https://github.com/txgh-bot/txgh-test-resources",
94
+ "homepage": null,
95
+ "size": 12,
96
+ "stargazers_count": 0,
97
+ "watchers_count": 0,
98
+ "language": null,
99
+ "has_issues": true,
100
+ "has_downloads": true,
101
+ "has_wiki": true,
102
+ "has_pages": false,
103
+ "forks_count": 0,
104
+ "mirror_url": null,
105
+ "open_issues_count": 0,
106
+ "forks": 0,
107
+ "open_issues": 0,
108
+ "watchers": 0,
109
+ "default_branch": "master",
110
+ "stargazers": 0,
111
+ "master_branch": "master"
112
+ },
113
+ "pusher": {
114
+ "name": "txgh-bot",
115
+ "email": "txgh.bot@gmail.com"
116
+ },
117
+ "sender": {
118
+ "login": "txgh-bot",
119
+ "id": 974299,
120
+ "avatar_url": "https://avatars.githubusercontent.com/u/974299?v=3",
121
+ "gravatar_id": "",
122
+ "url": "https://api.github.com/users/txgh-bot",
123
+ "html_url": "https://github.com/txgh-bot",
124
+ "followers_url": "https://api.github.com/users/txgh-bot/followers",
125
+ "following_url": "https://api.github.com/users/txgh-bot/following{/other_user}",
126
+ "gists_url": "https://api.github.com/users/txgh-bot/gists{/gist_id}",
127
+ "starred_url": "https://api.github.com/users/txgh-bot/starred{/owner}{/repo}",
128
+ "subscriptions_url": "https://api.github.com/users/txgh-bot/subscriptions",
129
+ "organizations_url": "https://api.github.com/users/txgh-bot/orgs",
130
+ "repos_url": "https://api.github.com/users/txgh-bot/repos",
131
+ "events_url": "https://api.github.com/users/txgh-bot/events{/privacy}",
132
+ "received_events_url": "https://api.github.com/users/txgh-bot/received_events",
133
+ "type": "User",
134
+ "site_admin": false
135
+ }
136
+ }