|
| 1 | +# CI Trigger Specification |
| 2 | + |
| 3 | +This document defines the CI trigger flow in bit-relay: |
| 4 | + |
| 5 | +1. Relay receives `refs/relay/incoming/...` through `git-receive-pack` |
| 6 | +2. Relay dispatches an external webhook event |
| 7 | +3. External CI posts the result back to relay |
| 8 | +4. Clients consume CI results from relay APIs |
| 9 | + |
| 10 | +## 1. Trigger Source |
| 11 | + |
| 12 | +Incoming refs are extracted from `POST /git/<session_id>/git-receive-pack` request bodies. |
| 13 | + |
| 14 | +- Matching pattern: `refs/relay/incoming/[A-Za-z0-9._/-]{1,255}` |
| 15 | +- Duplicate refs in the same request body are deduplicated |
| 16 | +- For each unique incoming ref, relay emits one `incoming_ref` event |
| 17 | + |
| 18 | +## 2. Webhook Dispatch Conditions |
| 19 | + |
| 20 | +Relay dispatches a webhook only when all of the following are true: |
| 21 | + |
| 22 | +- `RELAY_TRIGGER_WEBHOOK_URL` is configured |
| 23 | +- Incoming ref matches one of configured prefixes |
| 24 | +- Request handling reached the incoming-ref event emission path |
| 25 | + |
| 26 | +Configuration: |
| 27 | + |
| 28 | +- `RELAY_TRIGGER_WEBHOOK_URL`: destination URL |
| 29 | +- `RELAY_TRIGGER_WEBHOOK_TOKEN`: optional bearer token |
| 30 | +- `RELAY_TRIGGER_EVENT_TYPE`: default `relay.incoming_ref` |
| 31 | +- `RELAY_TRIGGER_REF_PREFIXES`: CSV list, default `refs/relay/incoming/` |
| 32 | + |
| 33 | +Dispatch result behavior: |
| 34 | + |
| 35 | +- Any 2xx is treated as success |
| 36 | +- Non-2xx or network errors are logged as trigger dispatch failures |
| 37 | + |
| 38 | +## 3. Outbound Webhook Payload |
| 39 | + |
| 40 | +Relay sends `POST <RELAY_TRIGGER_WEBHOOK_URL>` with JSON body: |
| 41 | + |
| 42 | +```json |
| 43 | +{ |
| 44 | + "event_type": "relay.incoming_ref", |
| 45 | + "event_id": "evt-...", |
| 46 | + "occurred_at": 1700000000, |
| 47 | + "room": "main", |
| 48 | + "source": "deno:127.0.0.1:8788", |
| 49 | + "target": "session:<session_id>", |
| 50 | + "ref": "refs/relay/incoming/repo-ci" |
| 51 | +} |
| 52 | +``` |
| 53 | + |
| 54 | +If `RELAY_TRIGGER_WEBHOOK_TOKEN` is set, relay adds: |
| 55 | + |
| 56 | +```text |
| 57 | +Authorization: Bearer <token> |
| 58 | +``` |
| 59 | + |
| 60 | +## 4. CI Callback API |
| 61 | + |
| 62 | +External CI should report results to: |
| 63 | + |
| 64 | +- `POST /api/v1/trigger/callback` |
| 65 | + |
| 66 | +Required fields: |
| 67 | + |
| 68 | +- `ref` (string) |
| 69 | +- `status` (string) |
| 70 | + |
| 71 | +Optional fields: |
| 72 | + |
| 73 | +- `room` |
| 74 | +- `logs_url` |
| 75 | +- `artifact_url` |
| 76 | +- `external_id` |
| 77 | +- `provider` |
| 78 | +- `id` |
| 79 | + |
| 80 | +Room resolution: |
| 81 | + |
| 82 | +- If `room` is provided: use it |
| 83 | +- Else if `ref` starts with `refs/relay/incoming/<room>/...`: use that first `<room>` segment |
| 84 | +- Else: fallback to `main` |
| 85 | + |
| 86 | +Published envelope: |
| 87 | + |
| 88 | +- `topic`: `ci.result` |
| 89 | +- `sender`: `ci:callback` |
| 90 | +- payload includes `ref`, `status`, `logs_url`, `artifact_url`, `external_id`, `provider`, |
| 91 | + `received_at` |
| 92 | + |
| 93 | +## 5. Reading CI Results |
| 94 | + |
| 95 | +Two APIs are available: |
| 96 | + |
| 97 | +- `GET /api/v1/trigger/results?room=<room>&after=<cursor>&limit=<n>` |
| 98 | +- `GET /api/v1/poll?room=<room>&after=<cursor>&limit=<n>` (includes `ci.result` in room timeline) |
| 99 | + |
| 100 | +## 6. Auth and Room Token Rules |
| 101 | + |
| 102 | +- If `BIT_RELAY_AUTH_TOKEN` is configured, `/api/v1/trigger/*` requires Bearer auth |
| 103 | +- If a room token is configured for the room, callback/results access must include `x-room-token` |
| 104 | + header or `room_token` query param |
| 105 | + |
| 106 | +## 7. Verification Commands |
| 107 | + |
| 108 | +Use the existing integration tests: |
| 109 | + |
| 110 | +```bash |
| 111 | +deno test --allow-net --allow-env tests/trigger_incoming_ref_integration_test.ts |
| 112 | +deno test --allow-net --allow-env tests/trigger_callback_test.ts |
| 113 | +``` |
0 commit comments