fj run list cannot filter by status/branch/event/workflow, forcing scripts to grep JSON #128

Open
opened 2026-06-11 00:51:51 +00:00 by stephen · 1 comment
Owner

What

fj run list takes only --limit. It cannot filter by status, branch,
event, or workflow, so any "find the run I care about" query in a script
has to fetch a page and post-process the JSON by hand. gh run list supports
--status, --branch, --workflow, --event, --user, which is how CI
locates "the latest failed run on main" or "the most recent run of ci.yml".

Evidence

list_runs sends only page + limit and nothing else
(src/api/workflow_run.rs:57):

pub async fn list_runs(client, owner, name, limit) -> Result<Vec<WorkflowRun>> {
    let path = format!("{}/actions/runs", crate::api::repo_path(owner, name));
    let q = vec![
        ("page".into(), "1".to_string()),
        ("limit".into(), limit.clamp(1, 50).to_string()),
    ];
    let list: RunList = client.json(Method::GET, &path, &q, None::<&()>).await?;
    Ok(list.workflow_runs)
}

The CLI ListArgs exposes only -L/--limit and --json
(src/cli/workflow_run.rs:37-47). The WorkflowRun struct already carries
every field needed to filter (status, conclusion, head_branch,
workflow_id, created_at) at src/api/workflow_run.rs:15-46, so the data is
in hand; only the selection is missing.

Why it matters for CI/automation buyers

The everyday automation query is "did the last run on this branch pass, and what
was its number?":

RUN=$(fj run list --branch "$BRANCH" --workflow ci.yml --status failure \
       -L 1 --json | jq '.[0].run_number')
fj run view "$RUN" --log-failed

Without filters the script must over-fetch (-L 50) and reimplement the
matching in jq for every call site, and the 50-row clamp means a busy repo can
push the run you want off the page entirely.

Proposed shape

  • Add --status <queued|in_progress|success|failure|cancelled|...>,
    --branch <name>, --event <name>, and --workflow <file> to
    fj run list.
  • Apply them client-side over the fetched rows so behavior is identical across
    the Forgejo schema variants the struct already tolerates (newer builds also
    accept some of these as server-side query params on actions/runs; use them
    as an optimization where present, but don't depend on them for correctness).
  • Filters compose with --json and -L.

Scope

Filtering over already-modeled fields; no new endpoint required. Independent of
the truncation/pagination work (rasterstate/fj#107 / #111), which addressed
how many rows, not which rows.

## What `fj run list` takes only `--limit`. It cannot filter by **status**, **branch**, **event**, or **workflow**, so any "find the run I care about" query in a script has to fetch a page and post-process the JSON by hand. `gh run list` supports `--status`, `--branch`, `--workflow`, `--event`, `--user`, which is how CI locates "the latest failed run on `main`" or "the most recent run of `ci.yml`". ## Evidence `list_runs` sends only `page` + `limit` and nothing else (`src/api/workflow_run.rs:57`): ```rust pub async fn list_runs(client, owner, name, limit) -> Result<Vec<WorkflowRun>> { let path = format!("{}/actions/runs", crate::api::repo_path(owner, name)); let q = vec![ ("page".into(), "1".to_string()), ("limit".into(), limit.clamp(1, 50).to_string()), ]; let list: RunList = client.json(Method::GET, &path, &q, None::<&()>).await?; Ok(list.workflow_runs) } ``` The CLI `ListArgs` exposes only `-L/--limit` and `--json` (`src/cli/workflow_run.rs:37-47`). The `WorkflowRun` struct already carries every field needed to filter (`status`, `conclusion`, `head_branch`, `workflow_id`, `created_at`) at `src/api/workflow_run.rs:15-46`, so the data is in hand; only the selection is missing. ## Why it matters for CI/automation buyers The everyday automation query is "did the last run on this branch pass, and what was its number?": ```sh RUN=$(fj run list --branch "$BRANCH" --workflow ci.yml --status failure \ -L 1 --json | jq '.[0].run_number') fj run view "$RUN" --log-failed ``` Without filters the script must over-fetch (`-L 50`) and reimplement the matching in `jq` for every call site, and the 50-row clamp means a busy repo can push the run you want off the page entirely. ## Proposed shape - Add `--status <queued|in_progress|success|failure|cancelled|...>`, `--branch <name>`, `--event <name>`, and `--workflow <file>` to `fj run list`. - Apply them client-side over the fetched rows so behavior is identical across the Forgejo schema variants the struct already tolerates (newer builds also accept some of these as server-side query params on `actions/runs`; use them as an optimization where present, but don't depend on them for correctness). - Filters compose with `--json` and `-L`. ## Scope Filtering over already-modeled fields; no new endpoint required. Independent of the truncation/pagination work (rasterstate/fj#107 / #111), which addressed *how many* rows, not *which* rows.
Author
Owner

Converted to backlog item rasterstate/fj#138 (p2, size M).

Converted to backlog item rasterstate/fj#138 (p2, size M).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rasterstate/fj#128
No description provided.