@@ -126,6 +126,10 @@ Completed jobs require a valid check conclusion. The handler updates |
| 126 | 126 | `workflow_jobs`, rolls up `workflow_runs`, and best-effort updates the |
| 127 | 127 | matching `check_runs` row created by the trigger pipeline. |
| 128 | 128 | |
| 129 | +When a runner reports `status:"cancelled"`, any still-open steps in the |
| 130 | +job are marked cancelled too. This keeps a killed job from leaving queued |
| 131 | +step rows that the UI would otherwise treat as live. |
| 132 | + |
| 129 | 133 | S41d PR2 runner execution supports containerized `run:` steps with |
| 130 | 134 | per-step log streaming and server-side log finalization. `uses:` aliases |
| 131 | 135 | such as `actions/checkout@v4` and artifact upload/download remain |
@@ -143,6 +147,24 @@ Auth: job JWT. Body: |
| 143 | 147 | Creates a `workflow_artifacts` row and returns a pre-signed S3 PUT URL. |
| 144 | 148 | The object key is `actions/runs/<run_id>/artifacts/<name>`. |
| 145 | 149 | |
| 150 | +`POST /api/v1/jobs/{id}/cancel` |
| 151 | + |
| 152 | +Auth: PAT with `repo:write`, and the actor must have write permission on |
| 153 | +the repository that owns the job's workflow run. Browser UI forms use |
| 154 | +CSRF-protected repo routes that call the same lifecycle orchestrator. |
| 155 | + |
| 156 | +Queued jobs are made terminal immediately: |
| 157 | + |
| 158 | +- `workflow_jobs.status = cancelled` |
| 159 | +- `workflow_jobs.conclusion = cancelled` |
| 160 | +- `workflow_jobs.cancel_requested = true` |
| 161 | +- open steps for that job are marked cancelled |
| 162 | + |
| 163 | +Running jobs keep `status = running` and get |
| 164 | +`cancel_requested = true`. The runner sees this through |
| 165 | +`cancel-check`, kills the active container, then reports terminal |
| 166 | +`cancelled`. |
| 167 | + |
| 146 | 168 | `POST /api/v1/jobs/{id}/cancel-check` |
| 147 | 169 | |
| 148 | 170 | Auth: job JWT. Returns: |
@@ -151,12 +173,16 @@ Auth: job JWT. Returns: |
| 151 | 173 | {"cancelled":false,"next_token":"..."} |
| 152 | 174 | ``` |
| 153 | 175 | |
| 154 | | -The boolean mirrors `workflow_jobs.cancel_requested`; the actual cancel |
| 155 | | -request UI lands later in S41g. |
| 176 | +The boolean mirrors `workflow_jobs.cancel_requested`. `shithubd-runner` |
| 177 | +polls this endpoint during job execution, serializing it through the |
| 178 | +same single-use JWT chain as logs and status updates. On `cancelled: |
| 179 | +true`, the Docker engine runs `docker kill <active-container>` and the |
| 180 | +runner posts terminal job status `cancelled`. |
| 156 | 181 | |
| 157 | 182 | ## Metrics |
| 158 | 183 | |
| 159 | 184 | - `shithub_actions_runner_registrations_total` |
| 160 | 185 | - `shithub_actions_runner_heartbeats_total{result="claimed|no_job"}` |
| 161 | 186 | - `shithub_actions_runner_jwt_total{result="issued|rejected|replay"}` |
| 187 | +- `shithub_actions_jobs_cancelled_total{reason="user|concurrency|timeout"}` |
| 162 | 188 | - `shithub_actions_log_scrub_replacements_total{location="server"}` |