markdown · 1299 bytes Raw Blame History

Actions runbook

Live log tail

Step log pages open an SSE stream at:

/{owner}/{repo}/actions/runs/{run}/jobs/{job}/steps/{step}/log/stream

The stream sends event: chunk records with the chunk sequence as the SSE id. Browsers reconnect with Last-Event-ID; the handler also accepts ?after=<seq> for the first connection from a rendered log page. A terminal step sends event: done and closes the stream.

Log chunks are never sent through Postgres NOTIFY. Runner log writes append to workflow_step_log_chunks, then NOTIFY step_log_<step_id> with only the sequence number. Step completion notifies done.

Rate limit

Live tails use internal/ratelimit scope actions:logtail with five concurrent streams per viewer. Authenticated viewers key by user id; anonymous public-repo viewers key by client IP. The limiter uses a short lease TTL so a dropped connection cannot hold a slot permanently.

Caddy

The production Caddy template has a dedicated Actions log-stream route with:

flush_interval -1

The same route is excluded from gzip compression. If logs arrive only after several kilobytes accumulate, verify the deployed /etc/caddy/Caddyfile contains that route and reload Caddy:

sudo caddy reload --config /etc/caddy/Caddyfile
View source
1 # Actions runbook
2
3 ## Live log tail
4
5 Step log pages open an SSE stream at:
6
7 ```text
8 /{owner}/{repo}/actions/runs/{run}/jobs/{job}/steps/{step}/log/stream
9 ```
10
11 The stream sends `event: chunk` records with the chunk sequence as the SSE
12 `id`. Browsers reconnect with `Last-Event-ID`; the handler also accepts
13 `?after=<seq>` for the first connection from a rendered log page. A terminal
14 step sends `event: done` and closes the stream.
15
16 Log chunks are never sent through Postgres `NOTIFY`. Runner log writes append
17 to `workflow_step_log_chunks`, then `NOTIFY step_log_<step_id>` with only the
18 sequence number. Step completion notifies `done`.
19
20 ## Rate limit
21
22 Live tails use `internal/ratelimit` scope `actions:logtail` with five
23 concurrent streams per viewer. Authenticated viewers key by user id; anonymous
24 public-repo viewers key by client IP. The limiter uses a short lease TTL so a
25 dropped connection cannot hold a slot permanently.
26
27 ## Caddy
28
29 The production Caddy template has a dedicated Actions log-stream route with:
30
31 ```caddy
32 flush_interval -1
33 ```
34
35 The same route is excluded from gzip compression. If logs arrive only after
36 several kilobytes accumulate, verify the deployed `/etc/caddy/Caddyfile`
37 contains that route and reload Caddy:
38
39 ```sh
40 sudo caddy reload --config /etc/caddy/Caddyfile
41 ```