airbyte-source-github 1.5.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airbyte_source_github-1.5.7.dist-info/METADATA +144 -0
- airbyte_source_github-1.5.7.dist-info/RECORD +88 -0
- airbyte_source_github-1.5.7.dist-info/WHEEL +5 -0
- airbyte_source_github-1.5.7.dist-info/entry_points.txt +2 -0
- airbyte_source_github-1.5.7.dist-info/top_level.txt +3 -0
- integration_tests/__init__.py +0 -0
- integration_tests/abnormal_state.json +237 -0
- integration_tests/acceptance.py +16 -0
- integration_tests/configured_catalog.json +435 -0
- integration_tests/configured_catalog_full_refresh_test.json +415 -0
- integration_tests/invalid_config.json +5 -0
- integration_tests/sample_config.json +5 -0
- integration_tests/sample_state.json +137 -0
- source_github/__init__.py +27 -0
- source_github/config_migrations.py +106 -0
- source_github/constants.py +9 -0
- source_github/github_schema.py +41034 -0
- source_github/graphql.py +327 -0
- source_github/run.py +17 -0
- source_github/schemas/assignees.json +63 -0
- source_github/schemas/branches.json +48 -0
- source_github/schemas/collaborators.json +80 -0
- source_github/schemas/comments.json +104 -0
- source_github/schemas/commit_comment_reactions.json +4 -0
- source_github/schemas/commit_comments.json +53 -0
- source_github/schemas/commits.json +126 -0
- source_github/schemas/contributor_activity.json +109 -0
- source_github/schemas/deployments.json +77 -0
- source_github/schemas/events.json +63 -0
- source_github/schemas/issue_comment_reactions.json +4 -0
- source_github/schemas/issue_events.json +335 -0
- source_github/schemas/issue_labels.json +30 -0
- source_github/schemas/issue_milestones.json +61 -0
- source_github/schemas/issue_reactions.json +28 -0
- source_github/schemas/issue_timeline_events.json +1056 -0
- source_github/schemas/issues.json +281 -0
- source_github/schemas/organizations.json +197 -0
- source_github/schemas/project_cards.json +50 -0
- source_github/schemas/project_columns.json +38 -0
- source_github/schemas/projects.json +50 -0
- source_github/schemas/projects_v2.json +80 -0
- source_github/schemas/pull_request_comment_reactions.json +28 -0
- source_github/schemas/pull_request_commits.json +122 -0
- source_github/schemas/pull_request_stats.json +84 -0
- source_github/schemas/pull_requests.json +363 -0
- source_github/schemas/releases.json +126 -0
- source_github/schemas/repositories.json +313 -0
- source_github/schemas/review_comments.json +118 -0
- source_github/schemas/reviews.json +69 -0
- source_github/schemas/shared/events/comment.json +188 -0
- source_github/schemas/shared/events/commented.json +118 -0
- source_github/schemas/shared/events/committed.json +56 -0
- source_github/schemas/shared/events/cross_referenced.json +784 -0
- source_github/schemas/shared/events/reviewed.json +139 -0
- source_github/schemas/shared/reaction.json +27 -0
- source_github/schemas/shared/reactions.json +35 -0
- source_github/schemas/shared/user.json +59 -0
- source_github/schemas/shared/user_graphql.json +26 -0
- source_github/schemas/stargazers.json +19 -0
- source_github/schemas/tags.json +32 -0
- source_github/schemas/team_members.json +66 -0
- source_github/schemas/team_memberships.json +24 -0
- source_github/schemas/teams.json +50 -0
- source_github/schemas/users.json +63 -0
- source_github/schemas/workflow_jobs.json +109 -0
- source_github/schemas/workflow_runs.json +449 -0
- source_github/schemas/workflows.json +41 -0
- source_github/source.py +339 -0
- source_github/spec.json +179 -0
- source_github/streams.py +1678 -0
- source_github/utils.py +152 -0
- unit_tests/__init__.py +3 -0
- unit_tests/conftest.py +29 -0
- unit_tests/projects_v2_pull_requests_query.json +3 -0
- unit_tests/pull_request_stats_query.json +3 -0
- unit_tests/responses/contributor_activity_response.json +33 -0
- unit_tests/responses/graphql_reviews_responses.json +405 -0
- unit_tests/responses/issue_timeline_events.json +166 -0
- unit_tests/responses/issue_timeline_events_response.json +170 -0
- unit_tests/responses/projects_v2_response.json +45 -0
- unit_tests/responses/pull_request_comment_reactions.json +744 -0
- unit_tests/responses/pull_request_stats_response.json +317 -0
- unit_tests/test_migrations/test_config.json +8 -0
- unit_tests/test_migrations/test_new_config.json +8 -0
- unit_tests/test_multiple_token_authenticator.py +160 -0
- unit_tests/test_source.py +326 -0
- unit_tests/test_stream.py +1471 -0
- unit_tests/utils.py +78 -0
source_github/graphql.py
ADDED
@@ -0,0 +1,327 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
+
#
|
4
|
+
|
5
|
+
import heapq
|
6
|
+
import itertools
|
7
|
+
from typing import Optional
|
8
|
+
|
9
|
+
import sgqlc.operation
|
10
|
+
from sgqlc.operation import Selector
|
11
|
+
|
12
|
+
from . import github_schema
|
13
|
+
|
14
|
+
_schema = github_schema
|
15
|
+
_schema_root = _schema.github_schema
|
16
|
+
|
17
|
+
|
18
|
+
def select_user_fields(user):
|
19
|
+
user.__fields__(
|
20
|
+
id="node_id",
|
21
|
+
database_id="id",
|
22
|
+
login=True,
|
23
|
+
avatar_url="avatar_url",
|
24
|
+
url="html_url",
|
25
|
+
is_site_admin="site_admin",
|
26
|
+
)
|
27
|
+
|
28
|
+
|
29
|
+
def get_query_pull_requests(owner, name, first, after, direction):
|
30
|
+
kwargs = {"first": first, "order_by": {"field": "UPDATED_AT", "direction": direction}}
|
31
|
+
if after:
|
32
|
+
kwargs["after"] = after
|
33
|
+
|
34
|
+
op = sgqlc.operation.Operation(_schema_root.query_type)
|
35
|
+
repository = op.repository(owner=owner, name=name)
|
36
|
+
repository.name()
|
37
|
+
repository.owner.login()
|
38
|
+
pull_requests = repository.pull_requests(**kwargs)
|
39
|
+
pull_requests.nodes.__fields__(
|
40
|
+
id="node_id",
|
41
|
+
database_id="id",
|
42
|
+
number=True,
|
43
|
+
updated_at="updated_at",
|
44
|
+
changed_files="changed_files",
|
45
|
+
deletions=True,
|
46
|
+
additions=True,
|
47
|
+
merged=True,
|
48
|
+
mergeable=True,
|
49
|
+
can_be_rebased="can_be_rebased",
|
50
|
+
maintainer_can_modify="maintainer_can_modify",
|
51
|
+
merge_state_status="merge_state_status",
|
52
|
+
)
|
53
|
+
pull_requests.nodes.comments.__fields__(total_count=True)
|
54
|
+
pull_requests.nodes.commits.__fields__(total_count=True)
|
55
|
+
reviews = pull_requests.nodes.reviews(first=100, __alias__="review_comments")
|
56
|
+
reviews.total_count()
|
57
|
+
reviews.nodes.comments.__fields__(total_count=True)
|
58
|
+
user = pull_requests.nodes.merged_by(__alias__="merged_by").__as__(_schema_root.User)
|
59
|
+
select_user_fields(user)
|
60
|
+
pull_requests.page_info.__fields__(has_next_page=True, end_cursor=True)
|
61
|
+
return str(op)
|
62
|
+
|
63
|
+
|
64
|
+
def get_query_projectsV2(owner, name, first, after, direction):
|
65
|
+
kwargs = {"first": first, "order_by": {"field": "UPDATED_AT", "direction": direction}}
|
66
|
+
if after:
|
67
|
+
kwargs["after"] = after
|
68
|
+
|
69
|
+
op = sgqlc.operation.Operation(_schema_root.query_type)
|
70
|
+
repository = op.repository(owner=owner, name=name)
|
71
|
+
repository.name()
|
72
|
+
repository.owner.login()
|
73
|
+
projects_v2 = repository.projects_v2(**kwargs)
|
74
|
+
projects_v2.nodes.__fields__(
|
75
|
+
closed=True,
|
76
|
+
created_at="created_at",
|
77
|
+
closed_at="closed_at",
|
78
|
+
updated_at="updated_at",
|
79
|
+
creator="creator",
|
80
|
+
id="node_id",
|
81
|
+
database_id="id",
|
82
|
+
number=True,
|
83
|
+
public=True,
|
84
|
+
readme="readme",
|
85
|
+
short_description="short_description",
|
86
|
+
template=True,
|
87
|
+
title="title",
|
88
|
+
url="url",
|
89
|
+
viewer_can_close=True,
|
90
|
+
viewer_can_reopen=True,
|
91
|
+
viewer_can_update=True,
|
92
|
+
)
|
93
|
+
projects_v2.nodes.owner.__fields__(id="id")
|
94
|
+
projects_v2.page_info.__fields__(has_next_page=True, end_cursor=True)
|
95
|
+
return str(op)
|
96
|
+
|
97
|
+
|
98
|
+
def get_query_reviews(owner, name, first, after, number=None):
|
99
|
+
op = sgqlc.operation.Operation(_schema_root.query_type)
|
100
|
+
repository = op.repository(owner=owner, name=name)
|
101
|
+
repository.name()
|
102
|
+
repository.owner.login()
|
103
|
+
if number:
|
104
|
+
pull_request = repository.pull_request(number=number)
|
105
|
+
else:
|
106
|
+
kwargs = {"first": first, "order_by": {"field": "UPDATED_AT", "direction": "ASC"}}
|
107
|
+
if after:
|
108
|
+
kwargs["after"] = after
|
109
|
+
pull_requests = repository.pull_requests(**kwargs)
|
110
|
+
pull_requests.page_info.__fields__(has_next_page=True, end_cursor=True)
|
111
|
+
pull_request = pull_requests.nodes
|
112
|
+
|
113
|
+
pull_request.__fields__(number=True, url=True)
|
114
|
+
kwargs = {"first": first}
|
115
|
+
if number and after:
|
116
|
+
kwargs["after"] = after
|
117
|
+
reviews = pull_request.reviews(**kwargs)
|
118
|
+
reviews.page_info.__fields__(has_next_page=True, end_cursor=True)
|
119
|
+
reviews.nodes.__fields__(
|
120
|
+
id="node_id",
|
121
|
+
database_id="id",
|
122
|
+
body=True,
|
123
|
+
state=True,
|
124
|
+
url="html_url",
|
125
|
+
author_association="author_association",
|
126
|
+
submitted_at="submitted_at",
|
127
|
+
created_at="created_at",
|
128
|
+
updated_at="updated_at",
|
129
|
+
)
|
130
|
+
reviews.nodes.commit.oid()
|
131
|
+
user = reviews.nodes.author(__alias__="user").__as__(_schema_root.User)
|
132
|
+
select_user_fields(user)
|
133
|
+
return str(op)
|
134
|
+
|
135
|
+
|
136
|
+
def get_query_issue_reactions(owner, name, first, after, number=None):
|
137
|
+
op = sgqlc.operation.Operation(_schema_root.query_type)
|
138
|
+
repository = op.repository(owner=owner, name=name)
|
139
|
+
repository.name()
|
140
|
+
repository.owner.login()
|
141
|
+
if number:
|
142
|
+
issue = repository.issue(number=number)
|
143
|
+
else:
|
144
|
+
kwargs = {"first": first}
|
145
|
+
if after:
|
146
|
+
kwargs["after"] = after
|
147
|
+
issues = repository.issues(**kwargs)
|
148
|
+
issues.page_info.__fields__(has_next_page=True, end_cursor=True)
|
149
|
+
issue = issues.nodes
|
150
|
+
|
151
|
+
issue.__fields__(number=True)
|
152
|
+
kwargs = {"first": first}
|
153
|
+
if number and after:
|
154
|
+
kwargs["after"] = after
|
155
|
+
reactions = issue.reactions(**kwargs)
|
156
|
+
reactions.page_info.__fields__(has_next_page=True, end_cursor=True)
|
157
|
+
reactions.nodes.__fields__(
|
158
|
+
id="node_id",
|
159
|
+
database_id="id",
|
160
|
+
content=True,
|
161
|
+
created_at="created_at",
|
162
|
+
)
|
163
|
+
select_user_fields(reactions.nodes.user())
|
164
|
+
return str(op)
|
165
|
+
|
166
|
+
|
167
|
+
class QueryReactions:
|
168
|
+
|
169
|
+
# AVERAGE_REVIEWS - optimal number of reviews to fetch inside every pull request.
|
170
|
+
# If we try to fetch too many (up to 100) we will spend too many scores of query cost.
|
171
|
+
# https://docs.github.com/en/graphql/overview/resource-limitations#calculating-a-rate-limit-score-before-running-the-call
|
172
|
+
# If we query too low we would need to make additional sub-queries to fetch the rest of the reviews inside specific pull request.
|
173
|
+
AVERAGE_REVIEWS = 5
|
174
|
+
AVERAGE_COMMENTS = 2
|
175
|
+
AVERAGE_REACTIONS = 2
|
176
|
+
|
177
|
+
def get_query_root_repository(self, owner: str, name: str, first: int, after: Optional[str] = None):
|
178
|
+
"""
|
179
|
+
Get GraphQL query which allows fetching reactions starting from the repository:
|
180
|
+
query {
|
181
|
+
repository {
|
182
|
+
pull_requests(first: page_size) {
|
183
|
+
reviews(first: AVERAGE_REVIEWS) {
|
184
|
+
comments(first: AVERAGE_COMMENTS) {
|
185
|
+
reactions(first: AVERAGE_REACTIONS) {
|
186
|
+
}
|
187
|
+
}
|
188
|
+
}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
"""
|
193
|
+
op = self._get_operation()
|
194
|
+
repository = op.repository(owner=owner, name=name)
|
195
|
+
repository.name()
|
196
|
+
repository.owner.login()
|
197
|
+
|
198
|
+
kwargs = {"first": first}
|
199
|
+
if after:
|
200
|
+
kwargs["after"] = after
|
201
|
+
pull_requests = repository.pull_requests(**kwargs)
|
202
|
+
pull_requests.page_info.__fields__(has_next_page=True, end_cursor=True)
|
203
|
+
pull_requests.total_count()
|
204
|
+
pull_requests.nodes.id(__alias__="node_id")
|
205
|
+
|
206
|
+
reviews = self._select_reviews(pull_requests.nodes, first=self.AVERAGE_REVIEWS)
|
207
|
+
comments = self._select_comments(reviews.nodes, first=self.AVERAGE_COMMENTS)
|
208
|
+
self._select_reactions(comments.nodes, first=self.AVERAGE_REACTIONS)
|
209
|
+
return str(op)
|
210
|
+
|
211
|
+
def get_query_root_pull_request(self, node_id: str, first: int, after: str):
|
212
|
+
"""
|
213
|
+
Get GraphQL query which allows fetching reactions starting from the pull_request:
|
214
|
+
query {
|
215
|
+
pull_request {
|
216
|
+
reviews(first: AVERAGE_REVIEWS) {
|
217
|
+
comments(first: AVERAGE_COMMENTS) {
|
218
|
+
reactions(first: AVERAGE_REACTIONS) {
|
219
|
+
}
|
220
|
+
}
|
221
|
+
}
|
222
|
+
}
|
223
|
+
}
|
224
|
+
"""
|
225
|
+
op = self._get_operation()
|
226
|
+
pull_request = op.node(id=node_id).__as__(_schema_root.PullRequest)
|
227
|
+
pull_request.id(__alias__="node_id")
|
228
|
+
pull_request.repository.name()
|
229
|
+
pull_request.repository.owner.login()
|
230
|
+
|
231
|
+
reviews = self._select_reviews(pull_request, first, after)
|
232
|
+
comments = self._select_comments(reviews.nodes, first=self.AVERAGE_COMMENTS)
|
233
|
+
self._select_reactions(comments.nodes, first=self.AVERAGE_REACTIONS)
|
234
|
+
return str(op)
|
235
|
+
|
236
|
+
def get_query_root_review(self, node_id: str, first: int, after: str):
|
237
|
+
"""
|
238
|
+
Get GraphQL query which allows fetching reactions starting from the review:
|
239
|
+
query {
|
240
|
+
review {
|
241
|
+
comments(first: AVERAGE_COMMENTS) {
|
242
|
+
reactions(first: AVERAGE_REACTIONS) {
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
"""
|
248
|
+
op = self._get_operation()
|
249
|
+
review = op.node(id=node_id).__as__(_schema_root.PullRequestReview)
|
250
|
+
review.id(__alias__="node_id")
|
251
|
+
review.repository.name()
|
252
|
+
review.repository.owner.login()
|
253
|
+
|
254
|
+
comments = self._select_comments(review, first, after)
|
255
|
+
self._select_reactions(comments.nodes, first=self.AVERAGE_REACTIONS)
|
256
|
+
return str(op)
|
257
|
+
|
258
|
+
def get_query_root_comment(self, node_id: str, first: int, after: str):
|
259
|
+
"""
|
260
|
+
Get GraphQL query which allows fetching reactions starting from the comment:
|
261
|
+
query {
|
262
|
+
comment {
|
263
|
+
reactions(first: AVERAGE_REACTIONS) {
|
264
|
+
}
|
265
|
+
}
|
266
|
+
}
|
267
|
+
"""
|
268
|
+
op = self._get_operation()
|
269
|
+
comment = op.node(id=node_id).__as__(_schema_root.PullRequestReviewComment)
|
270
|
+
comment.id(__alias__="node_id")
|
271
|
+
comment.database_id(__alias__="id")
|
272
|
+
comment.repository.name()
|
273
|
+
comment.repository.owner.login()
|
274
|
+
self._select_reactions(comment, first, after)
|
275
|
+
return str(op)
|
276
|
+
|
277
|
+
def _select_reactions(self, comment: Selector, first: int, after: Optional[str] = None):
|
278
|
+
kwargs = {"first": first}
|
279
|
+
if after:
|
280
|
+
kwargs["after"] = after
|
281
|
+
reactions = comment.reactions(**kwargs)
|
282
|
+
reactions.page_info.__fields__(has_next_page=True, end_cursor=True)
|
283
|
+
reactions.total_count()
|
284
|
+
reactions.nodes.__fields__(id="node_id", database_id="id", content=True, created_at="created_at")
|
285
|
+
select_user_fields(reactions.nodes.user())
|
286
|
+
return reactions
|
287
|
+
|
288
|
+
def _select_comments(self, review: Selector, first: int, after: Optional[str] = None):
|
289
|
+
kwargs = {"first": first}
|
290
|
+
if after:
|
291
|
+
kwargs["after"] = after
|
292
|
+
comments = review.comments(**kwargs)
|
293
|
+
comments.page_info.__fields__(has_next_page=True, end_cursor=True)
|
294
|
+
comments.total_count()
|
295
|
+
comments.nodes.id(__alias__="node_id")
|
296
|
+
comments.nodes.database_id(__alias__="id")
|
297
|
+
return comments
|
298
|
+
|
299
|
+
def _select_reviews(self, pull_request: Selector, first: int, after: Optional[str] = None):
|
300
|
+
kwargs = {"first": first}
|
301
|
+
if after:
|
302
|
+
kwargs["after"] = after
|
303
|
+
reviews = pull_request.reviews(**kwargs)
|
304
|
+
reviews.page_info.__fields__(has_next_page=True, end_cursor=True)
|
305
|
+
reviews.total_count()
|
306
|
+
reviews.nodes.id(__alias__="node_id")
|
307
|
+
reviews.nodes.database_id(__alias__="id")
|
308
|
+
return reviews
|
309
|
+
|
310
|
+
def _get_operation(self):
|
311
|
+
return sgqlc.operation.Operation(_schema_root.query_type)
|
312
|
+
|
313
|
+
|
314
|
+
class CursorStorage:
|
315
|
+
def __init__(self, typenames):
|
316
|
+
self.typename_to_prio = {o: prio for prio, o in enumerate(reversed(typenames))}
|
317
|
+
self.count = itertools.count()
|
318
|
+
self.storage = []
|
319
|
+
|
320
|
+
def add_cursor(self, typename, cursor, total_count, parent_id=None):
|
321
|
+
priority = self.typename_to_prio[typename]
|
322
|
+
heapq.heappush(self.storage, (priority, next(self.count), (typename, cursor, total_count, parent_id)))
|
323
|
+
|
324
|
+
def get_cursor(self):
|
325
|
+
if self.storage:
|
326
|
+
_, _, c = heapq.heappop(self.storage)
|
327
|
+
return {"typename": c[0], "cursor": c[1], "total_count": c[2], "parent_id": c[3]}
|
source_github/run.py
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
+
#
|
4
|
+
|
5
|
+
|
6
|
+
import sys
|
7
|
+
|
8
|
+
from airbyte_cdk.entrypoint import launch
|
9
|
+
from source_github import SourceGithub
|
10
|
+
from source_github.config_migrations import MigrateBranch, MigrateRepository
|
11
|
+
|
12
|
+
|
13
|
+
def run():
|
14
|
+
source = SourceGithub()
|
15
|
+
MigrateRepository.migrate(sys.argv[1:], source)
|
16
|
+
MigrateBranch.migrate(sys.argv[1:], source)
|
17
|
+
launch(source, sys.argv[1:])
|
@@ -0,0 +1,63 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "https://json-schema.org/draft-07/schema#",
|
3
|
+
"type": "object",
|
4
|
+
"properties": {
|
5
|
+
"repository": {
|
6
|
+
"type": "string"
|
7
|
+
},
|
8
|
+
"login": {
|
9
|
+
"type": ["null", "string"]
|
10
|
+
},
|
11
|
+
"id": {
|
12
|
+
"type": ["null", "integer"]
|
13
|
+
},
|
14
|
+
"node_id": {
|
15
|
+
"type": ["null", "string"]
|
16
|
+
},
|
17
|
+
"avatar_url": {
|
18
|
+
"type": ["null", "string"]
|
19
|
+
},
|
20
|
+
"gravatar_id": {
|
21
|
+
"type": ["null", "string"]
|
22
|
+
},
|
23
|
+
"url": {
|
24
|
+
"type": ["null", "string"]
|
25
|
+
},
|
26
|
+
"html_url": {
|
27
|
+
"type": ["null", "string"]
|
28
|
+
},
|
29
|
+
"followers_url": {
|
30
|
+
"type": ["null", "string"]
|
31
|
+
},
|
32
|
+
"following_url": {
|
33
|
+
"type": ["null", "string"]
|
34
|
+
},
|
35
|
+
"gists_url": {
|
36
|
+
"type": ["null", "string"]
|
37
|
+
},
|
38
|
+
"starred_url": {
|
39
|
+
"type": ["null", "string"]
|
40
|
+
},
|
41
|
+
"subscriptions_url": {
|
42
|
+
"type": ["null", "string"]
|
43
|
+
},
|
44
|
+
"organizations_url": {
|
45
|
+
"type": ["null", "string"]
|
46
|
+
},
|
47
|
+
"repos_url": {
|
48
|
+
"type": ["null", "string"]
|
49
|
+
},
|
50
|
+
"events_url": {
|
51
|
+
"type": ["null", "string"]
|
52
|
+
},
|
53
|
+
"received_events_url": {
|
54
|
+
"type": ["null", "string"]
|
55
|
+
},
|
56
|
+
"type": {
|
57
|
+
"type": ["null", "string"]
|
58
|
+
},
|
59
|
+
"site_admin": {
|
60
|
+
"type": ["null", "boolean"]
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "https://json-schema.org/draft-07/schema#",
|
3
|
+
"type": "object",
|
4
|
+
"properties": {
|
5
|
+
"repository": {
|
6
|
+
"type": "string"
|
7
|
+
},
|
8
|
+
"name": {
|
9
|
+
"type": ["null", "string"]
|
10
|
+
},
|
11
|
+
"commit": {
|
12
|
+
"type": ["null", "object"],
|
13
|
+
"properties": {
|
14
|
+
"sha": {
|
15
|
+
"type": ["null", "string"]
|
16
|
+
},
|
17
|
+
"url": {
|
18
|
+
"type": ["null", "string"]
|
19
|
+
}
|
20
|
+
}
|
21
|
+
},
|
22
|
+
"protected": {
|
23
|
+
"type": ["null", "boolean"]
|
24
|
+
},
|
25
|
+
"protection": {
|
26
|
+
"type": ["null", "object"],
|
27
|
+
"properties": {
|
28
|
+
"required_status_checks": {
|
29
|
+
"type": ["null", "object"],
|
30
|
+
"properties": {
|
31
|
+
"enforcement_level": {
|
32
|
+
"type": ["null", "string"]
|
33
|
+
},
|
34
|
+
"contexts": {
|
35
|
+
"type": ["null", "array"],
|
36
|
+
"items": {
|
37
|
+
"type": ["null", "string"]
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
},
|
44
|
+
"protection_url": {
|
45
|
+
"type": ["null", "string"]
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
@@ -0,0 +1,80 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "https://json-schema.org/draft-07/schema#",
|
3
|
+
"type": "object",
|
4
|
+
"properties": {
|
5
|
+
"repository": {
|
6
|
+
"type": "string"
|
7
|
+
},
|
8
|
+
"login": {
|
9
|
+
"type": ["null", "string"]
|
10
|
+
},
|
11
|
+
"id": {
|
12
|
+
"type": ["null", "integer"]
|
13
|
+
},
|
14
|
+
"node_id": {
|
15
|
+
"type": ["null", "string"]
|
16
|
+
},
|
17
|
+
"avatar_url": {
|
18
|
+
"type": ["null", "string"]
|
19
|
+
},
|
20
|
+
"gravatar_id": {
|
21
|
+
"type": ["null", "string"]
|
22
|
+
},
|
23
|
+
"url": {
|
24
|
+
"type": ["null", "string"]
|
25
|
+
},
|
26
|
+
"html_url": {
|
27
|
+
"type": ["null", "string"]
|
28
|
+
},
|
29
|
+
"followers_url": {
|
30
|
+
"type": ["null", "string"]
|
31
|
+
},
|
32
|
+
"following_url": {
|
33
|
+
"type": ["null", "string"]
|
34
|
+
},
|
35
|
+
"gists_url": {
|
36
|
+
"type": ["null", "string"]
|
37
|
+
},
|
38
|
+
"starred_url": {
|
39
|
+
"type": ["null", "string"]
|
40
|
+
},
|
41
|
+
"subscriptions_url": {
|
42
|
+
"type": ["null", "string"]
|
43
|
+
},
|
44
|
+
"organizations_url": {
|
45
|
+
"type": ["null", "string"]
|
46
|
+
},
|
47
|
+
"repos_url": {
|
48
|
+
"type": ["null", "string"]
|
49
|
+
},
|
50
|
+
"events_url": {
|
51
|
+
"type": ["null", "string"]
|
52
|
+
},
|
53
|
+
"received_events_url": {
|
54
|
+
"type": ["null", "string"]
|
55
|
+
},
|
56
|
+
"type": {
|
57
|
+
"type": ["null", "string"]
|
58
|
+
},
|
59
|
+
"site_admin": {
|
60
|
+
"type": ["null", "boolean"]
|
61
|
+
},
|
62
|
+
"role_name": {
|
63
|
+
"type": ["null", "string"]
|
64
|
+
},
|
65
|
+
"permissions": {
|
66
|
+
"type": ["null", "object"],
|
67
|
+
"properties": {
|
68
|
+
"pull": {
|
69
|
+
"type": ["null", "boolean"]
|
70
|
+
},
|
71
|
+
"push": {
|
72
|
+
"type": ["null", "boolean"]
|
73
|
+
},
|
74
|
+
"admin": {
|
75
|
+
"type": ["null", "boolean"]
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
@@ -0,0 +1,104 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "https://json-schema.org/draft-07/schema#",
|
3
|
+
"type": "object",
|
4
|
+
"properties": {
|
5
|
+
"repository": {
|
6
|
+
"type": "string"
|
7
|
+
},
|
8
|
+
"id": {
|
9
|
+
"type": ["null", "integer"]
|
10
|
+
},
|
11
|
+
"node_id": {
|
12
|
+
"type": ["null", "string"]
|
13
|
+
},
|
14
|
+
"user": {
|
15
|
+
"$ref": "user.json"
|
16
|
+
},
|
17
|
+
"url": {
|
18
|
+
"type": ["null", "string"]
|
19
|
+
},
|
20
|
+
"html_url": {
|
21
|
+
"type": ["null", "string"]
|
22
|
+
},
|
23
|
+
"body": {
|
24
|
+
"type": ["null", "string"]
|
25
|
+
},
|
26
|
+
"user_id": {
|
27
|
+
"type": ["null", "integer"]
|
28
|
+
},
|
29
|
+
"created_at": {
|
30
|
+
"type": "string",
|
31
|
+
"format": "date-time"
|
32
|
+
},
|
33
|
+
"updated_at": {
|
34
|
+
"type": "string",
|
35
|
+
"format": "date-time"
|
36
|
+
},
|
37
|
+
"issue_url": {
|
38
|
+
"type": ["null", "string"]
|
39
|
+
},
|
40
|
+
"author_association": {
|
41
|
+
"type": ["null", "string"]
|
42
|
+
},
|
43
|
+
"reactions": {
|
44
|
+
"$ref": "reactions.json"
|
45
|
+
},
|
46
|
+
"performed_via_github_app": {
|
47
|
+
"type": ["null", "object"],
|
48
|
+
"properties": {
|
49
|
+
"id": {
|
50
|
+
"type": ["null", "integer"]
|
51
|
+
},
|
52
|
+
"slug": {
|
53
|
+
"type": ["null", "string"]
|
54
|
+
},
|
55
|
+
"node_id": {
|
56
|
+
"type": ["null", "string"]
|
57
|
+
},
|
58
|
+
"owner": {
|
59
|
+
"$ref": "user.json"
|
60
|
+
},
|
61
|
+
"name": {
|
62
|
+
"type": ["null", "string"]
|
63
|
+
},
|
64
|
+
"description": {
|
65
|
+
"type": ["null", "string"]
|
66
|
+
},
|
67
|
+
"external_url": {
|
68
|
+
"type": ["null", "string"]
|
69
|
+
},
|
70
|
+
"html_url": {
|
71
|
+
"type": ["null", "string"]
|
72
|
+
},
|
73
|
+
"created_at": {
|
74
|
+
"type": "string",
|
75
|
+
"format": "date-time"
|
76
|
+
},
|
77
|
+
"updated_at": {
|
78
|
+
"type": "string",
|
79
|
+
"format": "date-time"
|
80
|
+
},
|
81
|
+
"permissions": {
|
82
|
+
"type": "object",
|
83
|
+
"properties": {
|
84
|
+
"issues": {
|
85
|
+
"type": ["null", "string"]
|
86
|
+
},
|
87
|
+
"metadata": {
|
88
|
+
"type": ["null", "string"]
|
89
|
+
},
|
90
|
+
"pull_requests": {
|
91
|
+
"type": ["null", "string"]
|
92
|
+
}
|
93
|
+
}
|
94
|
+
},
|
95
|
+
"events": {
|
96
|
+
"type": "array",
|
97
|
+
"items": {
|
98
|
+
"type": ["null", "string"]
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "https://json-schema.org/draft-07/schema#",
|
3
|
+
"type": "object",
|
4
|
+
"properties": {
|
5
|
+
"repository": {
|
6
|
+
"type": "string"
|
7
|
+
},
|
8
|
+
"html_url": {
|
9
|
+
"type": ["null", "string"]
|
10
|
+
},
|
11
|
+
"url": {
|
12
|
+
"type": ["null", "string"]
|
13
|
+
},
|
14
|
+
"id": {
|
15
|
+
"type": ["null", "integer"]
|
16
|
+
},
|
17
|
+
"node_id": {
|
18
|
+
"type": ["null", "string"]
|
19
|
+
},
|
20
|
+
"body": {
|
21
|
+
"type": ["null", "string"]
|
22
|
+
},
|
23
|
+
"path": {
|
24
|
+
"type": ["null", "string"]
|
25
|
+
},
|
26
|
+
"position": {
|
27
|
+
"type": ["null", "integer"]
|
28
|
+
},
|
29
|
+
"line": {
|
30
|
+
"type": ["null", "integer"]
|
31
|
+
},
|
32
|
+
"commit_id": {
|
33
|
+
"type": ["null", "string"]
|
34
|
+
},
|
35
|
+
"user": {
|
36
|
+
"$ref": "user.json"
|
37
|
+
},
|
38
|
+
"created_at": {
|
39
|
+
"type": "string",
|
40
|
+
"format": "date-time"
|
41
|
+
},
|
42
|
+
"updated_at": {
|
43
|
+
"type": "string",
|
44
|
+
"format": "date-time"
|
45
|
+
},
|
46
|
+
"author_association": {
|
47
|
+
"type": ["null", "string"]
|
48
|
+
},
|
49
|
+
"reactions": {
|
50
|
+
"$ref": "reactions.json"
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|