Repository navigation
Description
What
In entrypoint.sh, the reclaim_orphaned_name() function extracts the runner id and status via two independent jq invocations over the same /actions/runners listing. Replace them with a single jq pass that emits both fields from the same matched entry.
Why
The two separate jq runs are a latent cross-entry inconsistency: if the listing ever contains two entries with the same name (the API has been known to lag), id and status could be read from different entries. That would let the function delete a runner whose status was read from a different (offline) entry than the id it deletes — i.e. delete a live runner, which is exactly the outcome the no---replace stance is meant to prevent. Extracting both fields in one pass makes the id/status pair atomic with respect to the matched entry.
How
Replace the two jq calls with a single invocation that emits both fields, then split the result:
read -r id status < <(
jq -r --arg n "$RUNNER_NAME" \
'.runners[]? | select(.name==$n) | "\(.id) \(.status)"' <<<"${listing}"
)Then keep the existing guards ([[ -n "${id}" ]] || return 0, status == "offline" check) unchanged. Note the head -n1 on the current output is a no-op given the select; it can be dropped as part of this change.
This is a mechanical refactor of the extraction only — do not change the delete logic, the api_method DELETE call, or the surrounding control flow.
Files Affected
entrypoint.sh
Constraints
- Must not change behaviour for the single-match case:
offline→ delete,online→ refuse to start. - Must not introduce a new dependency or change the
jqinvocation's argument handling (--argstays, to preserve the injection safety noted in the review). - Out of scope: the
command -v jqguard, the swallowed stderr on the listing call,Retry-Afterhandling, the unconditionalrm -f .runnerfix, and test coverage — these are separate follow-ups from the same review.
LLM tier
Haiku — mechanical single-file refactor of two jq calls into one, with no design judgment required.
Success looks like
reclaim_orphaned_name()performs exactly onejqinvocation over the listing.idandstatusare read from the same matched entry.- The
offline→ delete andonline→ refuse branches behave identically to before for a single-match listing. - No other lines in
entrypoint.shchange.
Failure looks like
- The two
jqcalls remain, or are merged in a way that still allowsidandstatusto come from different entries. - The delete/refuse control flow is altered, or the
--arginterpolation is replaced with string interpolation into the filter. - New dependencies, guards, or unrelated cleanups are bundled in.
Follow-up from AI review of PR #154.
Activity