@slates-integrations/github 0.2.0-rc.7 → 0.2.2
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.
- package/README.md +81 -0
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/docs/SPEC.md +315 -73
- package/package.json +7 -3
package/docs/SPEC.md
CHANGED
|
@@ -1,11 +1,227 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
# Slates Specification for GitHub
|
|
1
|
+
# GitHub Integration Specification
|
|
4
2
|
|
|
5
3
|
## Overview
|
|
6
4
|
|
|
7
5
|
GitHub is a cloud-based platform for version control and collaboration using Git. It provides hosting for software repositories along with features for issue tracking, code review, project management, CI/CD (GitHub Actions), and package hosting. GitHub offers both REST and GraphQL APIs for programmatic access to its platform resources.
|
|
8
6
|
|
|
7
|
+
## Notable Tool Contracts
|
|
8
|
+
|
|
9
|
+
- `create_repository` creates a repository in the authenticated user's account unless
|
|
10
|
+
`organization` is provided. `private` defaults to `true`; pass `false` explicitly to
|
|
11
|
+
create a public repository. `autoInit` initializes the repository with a README.
|
|
12
|
+
- `merge_pull_request` accepts the optional snake-case fields `commit_title`,
|
|
13
|
+
`commit_message`, and `merge_method`. Supported merge methods are `merge`, `squash`,
|
|
14
|
+
and `rebase`.
|
|
15
|
+
- `list_issues` uses GraphQL cursor pagination. Pass `pageInfo.endCursor` from one
|
|
16
|
+
response as `after` to fetch the next page. `state` accepts `OPEN` or `CLOSED` and
|
|
17
|
+
returns both states when omitted. Labels are supplied as an array. Custom issue
|
|
18
|
+
fields can be filtered with `field_filters` entries containing `field_name` and
|
|
19
|
+
`value`.
|
|
20
|
+
- `issue_read` consolidates issue detail, comment, hierarchy, and label reads. Its
|
|
21
|
+
`get` method includes best-effort parent/child relationship signals and custom issue
|
|
22
|
+
field values.
|
|
23
|
+
- `pull_request_read` consolidates pull request detail, diff, status, file, commit,
|
|
24
|
+
review-thread, review, conversation-comment, and check-run reads.
|
|
25
|
+
- `list_pull_requests` is for repository filters such as state and branches. To filter
|
|
26
|
+
pull requests by author, use `search` with type `issues` and GitHub search qualifiers
|
|
27
|
+
such as `is:pr author:<login>`.
|
|
28
|
+
- `star_repository` deliberately consolidates both star and unstar operations through
|
|
29
|
+
its required `action` field.
|
|
30
|
+
- `search` covers organizations through GitHub's user-search endpoint: use type
|
|
31
|
+
`users` with the `type:org` qualifier.
|
|
32
|
+
- `create_branch` creates a branch from `from_branch`, or from the repository's
|
|
33
|
+
default branch when the source is omitted.
|
|
34
|
+
- `push_files` writes multiple plain-text files atomically in one commit through the
|
|
35
|
+
Git tree, commit, and ref APIs. If the requested branch is absent, it is created
|
|
36
|
+
from the default branch.
|
|
37
|
+
- `get_repository_tree` reads a tree at an optional SHA, branch, or tag, supports
|
|
38
|
+
recursive traversal, and can filter returned entries by a path prefix.
|
|
39
|
+
- `update_pull_request_branch` starts GitHub's base-branch update for a pull request;
|
|
40
|
+
`expectedHeadSha` provides optimistic concurrency protection.
|
|
41
|
+
- `sub_issue_write` supports `add`, `remove`, and `reprioritize`. `sub_issue_id` is
|
|
42
|
+
the issue database ID rather than the issue number, and reprioritization requires
|
|
43
|
+
exactly one of `after_id` or `before_id`.
|
|
44
|
+
- `get_global_security_advisory` and `list_global_security_advisories` expose the
|
|
45
|
+
public GitHub Advisory Database with GHSA, CVE, ecosystem, severity, CWE,
|
|
46
|
+
withdrawn-state, affected-package, and date filters.
|
|
47
|
+
|
|
48
|
+
## Added Tool Coverage
|
|
49
|
+
|
|
50
|
+
The tools below expose focused GitHub capabilities with stable identifiers and
|
|
51
|
+
structured results. A classic OAuth token must include the listed scope. For
|
|
52
|
+
fine-grained tokens and GitHub Apps, grant the equivalent repository,
|
|
53
|
+
organization, notification, security, or Projects permission.
|
|
54
|
+
|
|
55
|
+
### Security and code quality
|
|
56
|
+
|
|
57
|
+
| Tool | OAuth scope | User outcome |
|
|
58
|
+
| --- | --- | --- |
|
|
59
|
+
| `get_code_scanning_alert` | `security_events` | Read one code scanning alert by repository and alert number, including rule, severity, location, state, and dismissal details. |
|
|
60
|
+
| `list_code_scanning_alerts` | `security_events` | Triage repository alerts by state, Git ref, severity, scanning tool, and page. The state defaults to `open`. |
|
|
61
|
+
| `get_dependabot_alert` | `security_events` | Read one Dependabot alert by repository and alert number, including dependency, advisory, severity, and remediation details. |
|
|
62
|
+
| `list_dependabot_alerts` | `security_events` | List Dependabot alerts by state or severity and continue with the returned cursor. The state defaults to `open`. |
|
|
63
|
+
| `get_secret_scanning_alert` | `security_events` | Read one secret scanning alert by repository and alert number, including secret type, location, state, and resolution. |
|
|
64
|
+
| `list_secret_scanning_alerts` | `security_events` | List secret scanning alerts by state, resolution, secret type, and page. |
|
|
65
|
+
| `list_repository_security_advisories` | `security_events` | List one repository's private security advisories by state, sort field, and direction. |
|
|
66
|
+
| `list_org_repository_security_advisories` | `security_events` | List repository security advisories across an organization by state, sort field, and direction. |
|
|
67
|
+
| `get_code_quality_finding` | `repo` or `public_repo` | Read one code quality finding by repository and finding number, including diagnostic and remediation details when available. |
|
|
68
|
+
|
|
69
|
+
### Notifications
|
|
70
|
+
|
|
71
|
+
| Tool | OAuth scope | User outcome |
|
|
72
|
+
| --- | --- | --- |
|
|
73
|
+
| `list_notifications` | `notifications` | List the authenticated user's notification inbox, optionally including read items, limiting to participating threads, filtering by RFC3339 timestamps, or limiting to one repository. `owner` and `repo` must be supplied together. |
|
|
74
|
+
| `get_notification_details` | `notifications` | Read one notification thread by `notificationID`; use `list_notifications` first when the ID is unknown. |
|
|
75
|
+
| `manage_notification_subscription` | `notifications` | Watch, ignore, or delete a notification-thread subscription by `notificationID`. |
|
|
76
|
+
| `manage_repository_notification_subscription` | `notifications` | Watch, ignore, or delete notification subscription settings for a repository. |
|
|
77
|
+
| `mark_all_notifications_read` | `notifications` | Mark notifications read through `lastReadAt`, defaulting to the current time. Supplying `owner` and `repo` together limits the operation to that repository. |
|
|
78
|
+
| `dismiss_notification` | `notifications` | Mark a thread `read` or `done`; `done` removes it from the notification inbox. |
|
|
79
|
+
|
|
80
|
+
### Discussions
|
|
81
|
+
|
|
82
|
+
| Tool | OAuth scope | User outcome |
|
|
83
|
+
| --- | --- | --- |
|
|
84
|
+
| `list_discussion_categories` | `repo` or `public_repo` | List category node IDs and names for a repository. Omitting `repo` reads organization-level categories from the owner's `.github` repository. |
|
|
85
|
+
| `list_discussions` | `repo` or `public_repo` | List discussions with cursor pagination, category filtering, optional page-local title/body filtering, and paired ordering controls. `orderBy` and `direction` must be supplied together. |
|
|
86
|
+
| `get_discussion` | `repo` or `public_repo` | Read a discussion by repository-local number with its body, category, answer state, author, timestamps, and permalink. |
|
|
87
|
+
| `get_discussion_comments` | `repo` or `public_repo` | Read a cursor-paginated page of top-level comments. `includeReplies: true` also returns up to 100 replies per top-level comment. |
|
|
88
|
+
| `discussion_comment_write` | `repo` or `public_repo` | Add, reply to, update, or delete discussion comments and mark or unmark accepted answers. See the conditional fields below. |
|
|
89
|
+
|
|
90
|
+
`discussion_comment_write` uses these conditional fields:
|
|
91
|
+
|
|
92
|
+
- `add` requires `owner`, `repo`, `discussionNumber`, and `body`.
|
|
93
|
+
- `reply` also requires the parent `commentNodeID`. Discussions support one
|
|
94
|
+
level of nested replies.
|
|
95
|
+
- `update` requires `commentNodeID` and `body`.
|
|
96
|
+
- `delete`, `mark_answer`, and `unmark_answer` require `commentNodeID`.
|
|
97
|
+
|
|
98
|
+
### GitHub Projects
|
|
99
|
+
|
|
100
|
+
| Tool | OAuth scope | User outcome |
|
|
101
|
+
| --- | --- | --- |
|
|
102
|
+
| `projects_list` | `read:project` | List user or organization projects, or list fields, items, and status updates for a project. Methods other than `list_projects` require `project_number`. Item reads accept either `fields` IDs or `field_names`, never both. |
|
|
103
|
+
| `projects_get` | `read:project` | Get a project, field, item, or status update. Project, field, and item reads require `owner` and `project_number`; field and item reads also require their corresponding ID. A status-update read requires only `status_update_id`. |
|
|
104
|
+
| `projects_write` | `project` | Create a project, add/update/delete items, publish status updates, or create an iteration field. Each method validates its own owner, project, item, field, and date inputs before changing data. |
|
|
105
|
+
|
|
106
|
+
For `projects_write`, `create_project` requires `owner_type` and `title`.
|
|
107
|
+
`add_project_item` requires `project_number`, `item_type`, `item_owner`,
|
|
108
|
+
`item_repo`, and the matching issue or pull request number.
|
|
109
|
+
`update_project_item` requires `project_number`, `updated_field`, and exactly
|
|
110
|
+
one item locator: `item_id` or `item_owner` + `item_repo` + `issue_number`.
|
|
111
|
+
`delete_project_item` requires `project_number` and `item_id`.
|
|
112
|
+
`create_iteration_field` requires `project_number`, `field_name`,
|
|
113
|
+
`start_date`, and a positive `iteration_duration`.
|
|
114
|
+
|
|
115
|
+
### Repository and account reads
|
|
116
|
+
|
|
117
|
+
| Tool | OAuth scope | User outcome |
|
|
118
|
+
| --- | --- | --- |
|
|
119
|
+
| `fork_repository` | `repo` or `public_repo` | Fork a repository to the authenticated account or the optional `organization`, returning created-fork metadata or an `in_progress` status for asynchronous forks. |
|
|
120
|
+
| `list_starred_repositories` | `repo` or `public_repo` | List repositories starred by `username`, or by the authenticated user when it is omitted, with sort direction and page controls. |
|
|
121
|
+
|
|
122
|
+
## Expanded Consolidated Contracts
|
|
123
|
+
|
|
124
|
+
All tools in this section require `repo` or `public_repo`.
|
|
125
|
+
|
|
126
|
+
### `manage_workflow`
|
|
127
|
+
|
|
128
|
+
`manage_workflow` covers GitHub Actions listing, inspection, downloads, job-log
|
|
129
|
+
troubleshooting, and run operations while retaining the existing `action`
|
|
130
|
+
values `list_workflows`, `list_runs`, `get_run`, `trigger`, `cancel`, `rerun`,
|
|
131
|
+
and `list_jobs`.
|
|
132
|
+
|
|
133
|
+
- Listing methods are `list_workflows`, `list_workflow_runs`,
|
|
134
|
+
`list_workflow_jobs`, and `list_workflow_run_artifacts`.
|
|
135
|
+
`list_workflow_runs` optionally accepts a workflow ID or filename as
|
|
136
|
+
`resource_id` plus `workflow_runs_filter`. Job and artifact listing require
|
|
137
|
+
the workflow run ID as `resource_id`. Job listing accepts
|
|
138
|
+
`workflow_jobs_filter.filter` as `latest` or `all`.
|
|
139
|
+
- Read methods are `get_workflow`, `get_workflow_run`, `get_workflow_job`,
|
|
140
|
+
`get_workflow_run_usage`, `get_workflow_run_logs_url`, and
|
|
141
|
+
`download_workflow_run_artifact`. Each requires `resource_id`; only
|
|
142
|
+
`get_workflow` accepts a workflow filename instead of a numeric ID.
|
|
143
|
+
- Run methods are `run_workflow`, `rerun_workflow_run`, `rerun_failed_jobs`,
|
|
144
|
+
`cancel_workflow_run`, and `delete_workflow_run_logs`. `run_workflow`
|
|
145
|
+
requires `workflow_id` and `ref`; all other run methods require `run_id`.
|
|
146
|
+
- For one job's logs, omit `method` and provide `job_id`. For all failed jobs
|
|
147
|
+
in a run, provide `run_id` with `failed_only: true`. `tail_lines` defaults
|
|
148
|
+
to 500. With `return_content: false`, the result contains authenticated
|
|
149
|
+
download endpoints. With `return_content: true`, each requested log is a
|
|
150
|
+
downloadable text file and the structured result contains only file name,
|
|
151
|
+
MIME type, byte count, line counts, truncation state, and job IDs.
|
|
152
|
+
- Downloaded workflow artifacts are returned as ZIP files. The structured
|
|
153
|
+
result contains artifact ID, file name, MIME type, and byte count rather
|
|
154
|
+
than embedding the archive bytes.
|
|
155
|
+
|
|
156
|
+
### `comment_on_issue`
|
|
157
|
+
|
|
158
|
+
`comment_on_issue` accepts `issue_number` or the existing `issueNumber` alias
|
|
159
|
+
and can create a comment, add a reaction, or do both in one call.
|
|
160
|
+
|
|
161
|
+
- At least one of `body` or `reaction` is required.
|
|
162
|
+
- Omitting `comment_id` targets the issue or pull request itself.
|
|
163
|
+
- Providing `comment_id` targets that issue comment, requires `reaction`, and
|
|
164
|
+
cannot be combined with `body`. The comment is verified to belong to the
|
|
165
|
+
requested issue before the reaction is added.
|
|
166
|
+
- Review-comment reactions belong in `review_pull_request`, not this tool.
|
|
167
|
+
|
|
168
|
+
### `manage_issue`
|
|
169
|
+
|
|
170
|
+
`manage_issue` supports explicit `create` and `update` methods. Existing calls
|
|
171
|
+
may omit `method`; providing either issue-number field selects update behavior.
|
|
172
|
+
|
|
173
|
+
- `create` requires `title`; `update` requires `issue_number` or
|
|
174
|
+
`issueNumber`.
|
|
175
|
+
- `type` uses an issue type returned by `list_issue_types`.
|
|
176
|
+
- Every `issue_fields` entry requires `field_name` and exactly one of
|
|
177
|
+
`value`, `field_option_name`, or `delete: true`.
|
|
178
|
+
- Closing as a duplicate requires `state: "closed"`,
|
|
179
|
+
`state_reason: "duplicate"`, and `duplicate_of`. `duplicate_of` is not
|
|
180
|
+
accepted for other state reasons.
|
|
181
|
+
- `stateReason` remains an accepted existing alias. If both state-reason
|
|
182
|
+
fields are supplied, their values must agree.
|
|
183
|
+
|
|
184
|
+
### `manage_labels`
|
|
185
|
+
|
|
186
|
+
`manage_labels` creates, updates, renames, deletes, and continues to list
|
|
187
|
+
repository labels through the existing `action: "list"` operation.
|
|
188
|
+
|
|
189
|
+
- Supply either `method` or `action`. If both are present, they must agree.
|
|
190
|
+
- Create, update, and delete require `name`; create also requires `color`.
|
|
191
|
+
- Update requires at least one of `new_name`, `color`, or `description`.
|
|
192
|
+
|
|
193
|
+
### `manage_pull_request`
|
|
194
|
+
|
|
195
|
+
Omitting `pullNumber` creates a pull request and requires `title`, `head`, and
|
|
196
|
+
`base`. Providing `pullNumber` updates a pull request and requires at least one
|
|
197
|
+
change among title, body, state, base, draft state, maintainer-edit permission,
|
|
198
|
+
or reviewers.
|
|
199
|
+
|
|
200
|
+
`reviewers` accepts GitHub usernames and `ORG/team-slug` team identifiers.
|
|
201
|
+
`draft: true` converts an existing pull request to draft; `draft: false` marks
|
|
202
|
+
it ready for review. `maintainer_can_modify` is the preferred field, while
|
|
203
|
+
`maintainerCanModify` remains accepted; if both are supplied, they must agree.
|
|
204
|
+
|
|
205
|
+
### `review_pull_request`
|
|
206
|
+
|
|
207
|
+
Supply either `method` or the existing `action`, never both.
|
|
208
|
+
|
|
209
|
+
- Existing actions submit `APPROVE`, `REQUEST_CHANGES`, or `COMMENT` reviews,
|
|
210
|
+
or request user/team reviewers.
|
|
211
|
+
- `create` requires `pullNumber`; omitting `event` creates a pending review.
|
|
212
|
+
Providing `event` submits it immediately.
|
|
213
|
+
- `submit_pending` requires `pullNumber` and `event`; `delete_pending`
|
|
214
|
+
requires `pullNumber`.
|
|
215
|
+
- `resolve_thread` and `unresolve_thread` require the GraphQL `threadId`
|
|
216
|
+
returned by `pull_request_read` with `method: "get_review_comments"`.
|
|
217
|
+
- `add_comment_to_pending_review` requires `pullNumber`, `path`, `body`, and
|
|
218
|
+
`subjectType`. A `FILE` comment omits all line fields. A `LINE` comment
|
|
219
|
+
requires positive `line` and `side`; a range additionally requires
|
|
220
|
+
`startLine` and `startSide`, with matching sides and `startLine < line`.
|
|
221
|
+
- `add_reply_to_pull_request_comment` requires a numeric `commentId` and at
|
|
222
|
+
least one of `body` or `reaction`. A text reply also requires `pullNumber`;
|
|
223
|
+
a reaction-only call can use the comment ID alone.
|
|
224
|
+
|
|
9
225
|
## Authentication
|
|
10
226
|
|
|
11
227
|
GitHub supports several authentication methods for API access:
|
|
@@ -143,73 +359,99 @@ In addition to the REST API, GitHub provides a GraphQL API (v4) that allows more
|
|
|
143
359
|
|
|
144
360
|
## Events
|
|
145
361
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
362
|
+
The integration implements one automatically managed repository event source with
|
|
363
|
+
23 separate event triggers. Its setup, event catalog, permission requirements,
|
|
364
|
+
and output examples are documented in [Repository events](../README.md#repository-events).
|
|
365
|
+
|
|
366
|
+
### Configuration and lifecycle
|
|
367
|
+
|
|
368
|
+
Connection configuration is empty. Callback enablement starts automatic discovery,
|
|
369
|
+
including for portal-created instances. Discovery uses `GET /user/repos` with 100
|
|
370
|
+
repositories per page ordered by full name. Because the runtime starts every
|
|
371
|
+
15-minute rediscovery with a null page token and keeps no state between cycles,
|
|
372
|
+
conditional requests cannot reduce cost; discovery is bounded instead. The page
|
|
373
|
+
token is `{ page, probes }` and is validated: at most 10 pages (1,000 repositories)
|
|
374
|
+
are scanned per cycle, and at most 50 non-admin repositories per cycle are probed
|
|
375
|
+
with `GET /repos/{owner}/{repo}/hooks` for webhook access (custom roles). Admin
|
|
376
|
+
repositories (`permissions.admin`) are eligible without a probe; archived repositories
|
|
377
|
+
are skipped; non-admin repositories beyond the probe budget are skipped. Reaching
|
|
378
|
+
either limit logs a warning (`github_webhook_probe_limit`, `github_webhook_page_limit`).
|
|
379
|
+
Worst case per connection per cycle is 60 requests. Discovery deduplicates repository
|
|
380
|
+
IDs per page and preserves the next page token even when no repositories on a page
|
|
381
|
+
qualify. The runtime deduplicates stable targets across pages and connections.
|
|
382
|
+
Resource-level 403/404 responses are skipped; rate limits are recognised from GitHub's
|
|
383
|
+
`x-ratelimit-remaining`/`retry-after` headers (429, or 403 with those headers) and
|
|
384
|
+
propagate together with authentication errors and other service failures. Read access
|
|
385
|
+
does not prove fine-grained token write access; creation reports missing write
|
|
386
|
+
permissions. No manual target-selection or webhook configuration is exposed.
|
|
387
|
+
|
|
388
|
+
A target is identified by its normalized GitHub instance URL and immutable repository
|
|
389
|
+
ID. Registration resolves its current name and checks identity before creating an
|
|
390
|
+
active JSON hook with a random secret, TLS verification, and the exact event catalog.
|
|
391
|
+
Connections in the same tenant share the target. Cleanup uses the saved hook ID and
|
|
392
|
+
checks repository identity before deletion. A DELETE 404 is accepted only after an
|
|
393
|
+
authorized paginated hooks list confirms absence. Repository lookup 404 remains
|
|
394
|
+
retryable because it can indicate lost access to a private repository.
|
|
395
|
+
|
|
396
|
+
The companion hub changes rescan active automatic subscriptions every 15 minutes,
|
|
397
|
+
continue empty discovery pages, initialize cleanup with connection auth/config, and
|
|
398
|
+
keep provider cleanup failures retryable. Shared hooks remain until the last callback
|
|
399
|
+
is removed. No provider-specific behavior is added to the hub. Deploy those runtime
|
|
400
|
+
changes alongside this integration for lifecycle behavior; SDK tests alone do not
|
|
401
|
+
prove deployed runtime cleanup or delivery.
|
|
402
|
+
|
|
403
|
+
### Event contract
|
|
404
|
+
|
|
405
|
+
Every trigger exposes `{ deliveryId, event, action, payload }`. The event name
|
|
406
|
+
matches GitHub's header, action is a string or `null`, and payload is the complete
|
|
407
|
+
GitHub JSON object. Typed resource schemas preserve additional fields, including
|
|
408
|
+
nested fields. Mapping uses the delivery snapshot without authenticated lookups.
|
|
409
|
+
The callback ID is the delivery ID; its type is `event.action` or `event` when
|
|
410
|
+
there is no action. A merge is `pull_request.closed` with
|
|
411
|
+
`payload.pull_request.merged === true`, not a separate action.
|
|
412
|
+
|
|
413
|
+
Incoming requests require POST, a valid SHA-256 signature over the original
|
|
414
|
+
body, a GUID delivery ID, a matching `X-GitHub-Hook-ID`, installation-target
|
|
415
|
+
headers naming the saved repository, and a payload `repository.id` equal to the
|
|
416
|
+
saved repository. Malformed or unauthenticated requests are rejected. Every rejected
|
|
417
|
+
or ignored delivery is logged with a reason code (`github_webhook_*`) and the event,
|
|
418
|
+
delivery, and hook headers; payloads and secrets are never logged. Valid pings and
|
|
419
|
+
unsupported event families are acknowledged without callbacks. Repeated deliveries
|
|
420
|
+
use the same idempotency key; GitHub does not supply a signed delivery timestamp.
|
|
421
|
+
|
|
422
|
+
Repository hooks support only `created`/`completed` check runs and `completed`
|
|
423
|
+
check suites. Repository creation across an organization cannot be observed by a
|
|
424
|
+
hook attached to an existing repository. Discussions and Dependabot depend on
|
|
425
|
+
repository feature availability. Unsupported events on older Enterprise versions
|
|
426
|
+
cause registration errors; coverage is never silently reduced.
|
|
427
|
+
|
|
428
|
+
### Verification
|
|
429
|
+
|
|
430
|
+
SDK contract tests live in the enterprise repository next to the live suite
|
|
431
|
+
(`tests/integrations/github/triggers*.test.ts`, run with `bun run triggers:test -- github`),
|
|
432
|
+
not in this package. They exercise all event families, payload preservation, request
|
|
433
|
+
verification, target discovery (including the page and probe limits), registration,
|
|
434
|
+
and cleanup. A second suite sweeps all 169 GitHub-recorded payload examples for the
|
|
435
|
+
23 implemented families, vendored verbatim from `octokit/webhooks` at a pinned commit
|
|
436
|
+
(`tests/integrations/github/__fixtures__/octokit-webhooks`), through verification, selection, and mapping
|
|
437
|
+
with deep equality. That repository is unmaintained and its successor
|
|
438
|
+
(`octokit/openapi-webhooks`) publishes GitHub's OpenAPI schemas rather than example
|
|
439
|
+
deliveries, so the examples are real but dated (last updated 2024-10); they prove the
|
|
440
|
+
schemas accept recorded shapes. A third suite covers the current contract: it checks
|
|
441
|
+
every event schema against a pinned structural skeleton of GitHub's OpenAPI webhook
|
|
442
|
+
description (`tests/integrations/github/__fixtures__/github-openapi-webhooks`, generated by
|
|
443
|
+
`scripts/github-webhook-schema-skeleton.ts` at the repo root) for all 114 operations
|
|
444
|
+
GitHub's description marks as deliverable to repository hooks (a per-event flag, so it
|
|
445
|
+
includes the app-only check actions the trigger descriptions exclude; checking them can
|
|
446
|
+
only make the schemas looser), asserting the schemas are never stricter than GitHub:
|
|
447
|
+
every field required here is required by GitHub, every null GitHub may send is
|
|
448
|
+
accepted, and every JSON type or enum value GitHub may send parses. Local negative
|
|
449
|
+
tests are needed because GitHub cannot
|
|
450
|
+
send intentionally forged signatures or invalid repository identities. Private live
|
|
451
|
+
coverage creates, reads back, and deletes a real hook on a disposable repository.
|
|
452
|
+
This lifecycle check uses a non-resolving receiver URL and does not claim to verify
|
|
453
|
+
end-to-end callback delivery.
|
|
454
|
+
|
|
455
|
+
Provider references: [repository webhook API](https://docs.github.com/en/rest/repos/webhooks),
|
|
456
|
+
[event payloads](https://docs.github.com/en/webhooks/webhook-events-and-payloads),
|
|
457
|
+
and [signature verification](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries).
|
package/package.json
CHANGED
|
@@ -4,17 +4,21 @@
|
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
|
|
7
|
+
"test": "vitest run --config vitest.config.ts --passWithNoTests",
|
|
7
8
|
"typecheck": "tsc --noEmit"
|
|
8
9
|
},
|
|
9
10
|
"dependencies": {
|
|
11
|
+
"@lowerdeck/error": "^1.1.0",
|
|
10
12
|
"@types/node": "^20",
|
|
11
|
-
"slates": "1.0.0-rc.
|
|
13
|
+
"slates": "1.0.0-rc.23",
|
|
12
14
|
"zod": "^4.2"
|
|
13
15
|
},
|
|
14
16
|
"devDependencies": {
|
|
15
|
-
"
|
|
17
|
+
"@slates/test": "1.0.0-rc.21",
|
|
18
|
+
"typescript": "^5",
|
|
19
|
+
"vitest": "^3.1.2"
|
|
16
20
|
},
|
|
17
|
-
"version": "0.2.
|
|
21
|
+
"version": "0.2.2",
|
|
18
22
|
"files": [
|
|
19
23
|
"dist/**",
|
|
20
24
|
"docs/**",
|