hmm
db274ab · gmorell · 2026-05-22 16:37
Files changed
modified
lib/git_gud_web/controllers/runner_controller.ex
+17
−2
@@ -215,14 +215,29 @@ defmodule GitGudWeb.RunnerController do
| 215 | 215 | # ── update_task ────────────────────────────────────────────────────── |
| 216 | 216 | |
| 217 | 217 | def update_task(conn, _params) do |
| 218 | − with {:ok, %UpdateTaskRequest{state: state}} <- | |
| 218 | + with {:ok, %UpdateTaskRequest{state: state} = req} <- | |
| 219 | 219 | decode_request(conn, UpdateTaskRequest), |
| 220 | 220 | %RunnerSchema{} = _runner <- authenticate(conn) do |
| 221 | 221 | job_id = (state && state.id) || 0 |
| 222 | 222 | |
| 223 | + require Logger | |
| 224 | + | |
| 225 | + Logger.info( | |
| 226 | + "update_task incoming state.id=#{inspect(job_id)} " <> | |
| 227 | + "state.result=#{inspect(state && state.result)} " <> | |
| 228 | + "outputs=#{inspect(req.outputs |> Map.keys() |> Enum.take(5))}" | |
| 229 | + ) | |
| 230 | + | |
| 223 | 231 | case GitGud.Repo.get(GitGud.Workflows.WorkflowJob, job_id) do |
| 224 | 232 | nil -> |
| 225 | − error(conn, :not_found, "no such job") | |
| 233 | + # Ack-and-ignore. Forgejo-runner retries indefinitely on a | |
| 234 | + # 404, which clobbers logs even when the work is fundamentally | |
| 235 | + # complete (job long since reaped, db rolled back, etc.). | |
| 236 | + # We log the miss for forensics but echo back what the runner | |
| 237 | + # told us so it can stop pestering and free the worker slot. | |
| 238 | + Logger.warning("update_task lookup miss — acking anyway for state.id=#{inspect(job_id)}") | |
| 239 | + | |
| 240 | + respond(conn, %UpdateTaskResponse{state: state, sent_outputs: []}) | |
| 226 | 241 | |
| 227 | 242 | job -> |
| 228 | 243 | mapped = map_result(state && state.result) |
modified
priv/proto/runner/v1/messages.proto
+20
−4
@@ -12,6 +12,7 @@ syntax = "proto3";
| 12 | 12 | package runner.v1; |
| 13 | 13 | |
| 14 | 14 | import "google/protobuf/timestamp.proto"; |
| 15 | +import "google/protobuf/struct.proto"; | |
| 15 | 16 | |
| 16 | 17 | // ── Ping ───────────────────────────────────────────────────────────── |
| 17 | 18 |
@@ -70,16 +71,31 @@ enum Result {
| 70 | 71 | RESULT_SKIPPED = 4; |
| 71 | 72 | } |
| 72 | 73 | |
| 74 | +// Per-need state — the runner needs the parent-job result to drive | |
| 75 | +// `needs.<id>.result` and the parent's outputs map. | |
| 76 | +message TaskNeed { | |
| 77 | + Result result = 1; | |
| 78 | + map<string, string> outputs = 2; | |
| 79 | +} | |
| 80 | + | |
| 73 | 81 | message Task { |
| 74 | 82 | int64 id = 1; |
| 75 | 83 | // gzip-compressed YAML of the job definition the runner should execute. |
| 76 | 84 | bytes workflow_payload = 2; |
| 77 | − // Context the runner injects into `${{ github.* }}` and friends. | |
| 78 | − map<string, string> context = 3; | |
| 85 | + // Context the runner injects into `${{ github.* }}` etc. Forgejo's | |
| 86 | + // proto switched this from `map<string,string>` to a Struct so values | |
| 87 | + // can carry richer types (nested objects, numbers, bools). String | |
| 88 | + // values are still the common case for us. | |
| 89 | + google.protobuf.Struct context = 3; | |
| 79 | 90 | // Repo / org secrets the job can read via `${{ secrets.* }}`. |
| 80 | 91 | map<string, string> secrets = 4; |
| 81 | − repeated string needs = 5; | |
| 82 | − map<string, string> vars = 6; | |
| 92 | + // 5 = `machine` (deprecated upstream, leave unset). | |
| 93 | + string machine = 5; | |
| 94 | + // `needs.<job_id>` lookups. Each prior job's result + its declared | |
| 95 | + // outputs are available; this map is keyed by the upstream job's id. | |
| 96 | + map<string, TaskNeed> needs = 6; | |
| 97 | + // Repo / org variables (non-secret); `${{ vars.* }}`. | |
| 98 | + map<string, string> vars = 7; | |
| 83 | 99 | } |
| 84 | 100 | |
| 85 | 101 | message FetchTaskRequest { |
Parents: 91bcbd0