Actions runner smoke runbook
This runbook drives one queued Actions job with curl. It is for S41c
operator validation before the real shithubd-runner binary lands.
Prereqs:
- Database migrations are current through
0053_runner_jwt_used.sql. SHITHUB_TOTP_KEYorauth.totp_key_b64is set on the web process.- Object storage is configured if testing artifact upload.
- A repo has a workflow under
.shithub/workflows/*.ymlwithruns-on: ubuntu-latest, and a push/dispatch has enqueued a run.
Register a runner:
shithubd admin runner register \
--name runner-1 \
--labels self-hosted,linux,ubuntu-latest \
--capacity 1
Save the printed token:
export RUNNER_TOKEN='<printed-token>'
export BASE='https://shithub.example'
Claim a job:
curl -fsS "$BASE/api/v1/runners/heartbeat" \
-H "Authorization: Bearer $RUNNER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"labels":["self-hosted","linux","ubuntu-latest"],"capacity":1}' \
| tee /tmp/shithub-claim.json
Extract the job token and id:
export JOB_ID="$(jq -r '.job.id' /tmp/shithub-claim.json)"
export JOB_TOKEN="$(jq -r '.token' /tmp/shithub-claim.json)"
Append a log chunk:
curl -fsS "$BASE/api/v1/jobs/$JOB_ID/logs" \
-H "Authorization: Bearer $JOB_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"seq\":0,\"chunk\":\"$(printf 'hello from curl\n' | base64)\"}" \
| tee /tmp/shithub-log.json
export JOB_TOKEN="$(jq -r '.next_token' /tmp/shithub-log.json)"
Complete the job:
curl -fsS "$BASE/api/v1/jobs/$JOB_ID/status" \
-H "Authorization: Bearer $JOB_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status":"completed","conclusion":"success"}'
Replay check: reusing the log token after the log call must fail with
401 because its jti is already present in runner_jwt_used.
curl -i "$BASE/api/v1/jobs/$JOB_ID/status" \
-H "Authorization: Bearer $(jq -r '.next_token' /tmp/shithub-log.json)" \
-H "Content-Type: application/json" \
-d '{"status":"running"}'
Expected results:
workflow_jobs.status = completedand conclusionsuccess.- The parent
workflow_runsrow rolls up to completed/success when all jobs are terminal. - The PR Checks tab shows the matching check run as success.
/metricsincludes runner registration, heartbeat, and JWT counters.
View source
| 1 | # Actions runner smoke runbook |
| 2 | |
| 3 | This runbook drives one queued Actions job with curl. It is for S41c |
| 4 | operator validation before the real `shithubd-runner` binary lands. |
| 5 | |
| 6 | Prereqs: |
| 7 | |
| 8 | - Database migrations are current through `0053_runner_jwt_used.sql`. |
| 9 | - `SHITHUB_TOTP_KEY` or `auth.totp_key_b64` is set on the web process. |
| 10 | - Object storage is configured if testing artifact upload. |
| 11 | - A repo has a workflow under `.shithub/workflows/*.yml` with |
| 12 | `runs-on: ubuntu-latest`, and a push/dispatch has enqueued a run. |
| 13 | |
| 14 | Register a runner: |
| 15 | |
| 16 | ```sh |
| 17 | shithubd admin runner register \ |
| 18 | --name runner-1 \ |
| 19 | --labels self-hosted,linux,ubuntu-latest \ |
| 20 | --capacity 1 |
| 21 | ``` |
| 22 | |
| 23 | Save the printed token: |
| 24 | |
| 25 | ```sh |
| 26 | export RUNNER_TOKEN='<printed-token>' |
| 27 | export BASE='https://shithub.example' |
| 28 | ``` |
| 29 | |
| 30 | Claim a job: |
| 31 | |
| 32 | ```sh |
| 33 | curl -fsS "$BASE/api/v1/runners/heartbeat" \ |
| 34 | -H "Authorization: Bearer $RUNNER_TOKEN" \ |
| 35 | -H "Content-Type: application/json" \ |
| 36 | -d '{"labels":["self-hosted","linux","ubuntu-latest"],"capacity":1}' \ |
| 37 | | tee /tmp/shithub-claim.json |
| 38 | ``` |
| 39 | |
| 40 | Extract the job token and id: |
| 41 | |
| 42 | ```sh |
| 43 | export JOB_ID="$(jq -r '.job.id' /tmp/shithub-claim.json)" |
| 44 | export JOB_TOKEN="$(jq -r '.token' /tmp/shithub-claim.json)" |
| 45 | ``` |
| 46 | |
| 47 | Append a log chunk: |
| 48 | |
| 49 | ```sh |
| 50 | curl -fsS "$BASE/api/v1/jobs/$JOB_ID/logs" \ |
| 51 | -H "Authorization: Bearer $JOB_TOKEN" \ |
| 52 | -H "Content-Type: application/json" \ |
| 53 | -d "{\"seq\":0,\"chunk\":\"$(printf 'hello from curl\n' | base64)\"}" \ |
| 54 | | tee /tmp/shithub-log.json |
| 55 | |
| 56 | export JOB_TOKEN="$(jq -r '.next_token' /tmp/shithub-log.json)" |
| 57 | ``` |
| 58 | |
| 59 | Complete the job: |
| 60 | |
| 61 | ```sh |
| 62 | curl -fsS "$BASE/api/v1/jobs/$JOB_ID/status" \ |
| 63 | -H "Authorization: Bearer $JOB_TOKEN" \ |
| 64 | -H "Content-Type: application/json" \ |
| 65 | -d '{"status":"completed","conclusion":"success"}' |
| 66 | ``` |
| 67 | |
| 68 | Replay check: reusing the log token after the log call must fail with |
| 69 | 401 because its `jti` is already present in `runner_jwt_used`. |
| 70 | |
| 71 | ```sh |
| 72 | curl -i "$BASE/api/v1/jobs/$JOB_ID/status" \ |
| 73 | -H "Authorization: Bearer $(jq -r '.next_token' /tmp/shithub-log.json)" \ |
| 74 | -H "Content-Type: application/json" \ |
| 75 | -d '{"status":"running"}' |
| 76 | ``` |
| 77 | |
| 78 | Expected results: |
| 79 | |
| 80 | - `workflow_jobs.status = completed` and conclusion `success`. |
| 81 | - The parent `workflow_runs` row rolls up to completed/success when all |
| 82 | jobs are terminal. |
| 83 | - The PR Checks tab shows the matching check run as success. |
| 84 | - `/metrics` includes runner registration, heartbeat, and JWT counters. |