@slates-integrations/github 0.2.0-rc.9 → 0.2.3
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 +96 -70
- package/package.json +4 -3
package/docs/SPEC.md
CHANGED
|
@@ -359,73 +359,99 @@ In addition to the REST API, GitHub provides a GraphQL API (v4) that allows more
|
|
|
359
359
|
|
|
360
360
|
## Events
|
|
361
361
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
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
|
@@ -8,16 +8,17 @@
|
|
|
8
8
|
"typecheck": "tsc --noEmit"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
+
"@lowerdeck/error": "^1.1.0",
|
|
11
12
|
"@types/node": "^20",
|
|
12
|
-
"slates": "1.0.0-rc.
|
|
13
|
+
"slates": "1.0.0-rc.24",
|
|
13
14
|
"zod": "^4.2"
|
|
14
15
|
},
|
|
15
16
|
"devDependencies": {
|
|
16
|
-
"@slates/test": "1.0.0-rc.
|
|
17
|
+
"@slates/test": "1.0.0-rc.22",
|
|
17
18
|
"typescript": "^5",
|
|
18
19
|
"vitest": "^3.1.2"
|
|
19
20
|
},
|
|
20
|
-
"version": "0.2.
|
|
21
|
+
"version": "0.2.3",
|
|
21
22
|
"files": [
|
|
22
23
|
"dist/**",
|
|
23
24
|
"docs/**",
|