repomatic.github.runs module¶

Read and cancel GitHub Actions workflow runs.

Every call to the runs API goes through this module: the listings ci_status and job_timings read, and the cancellation sweep behind the cancel-runs command. The repository is resolved by the gh CLI from GH_REPO or the checkout.

repomatic.github.runs.RUN_LISTING_WINDOW = datetime.timedelta(days=90)¶

How far back every runs listing here reaches, through its created filter.

Warning

GitHub’s runs listings can answer with a stale snapshot: a page weeks or months old, presented as the newest runs, on a branch that ran every hour. gh run list reads the same endpoints and carries the same risk. A listing that sends a created filter has not been seen to do it, so every listing here sends one.

Ninety days holds the few runs any caller needs on an active branch. A workflow idle for longer reads as having no run.

repomatic.github.runs.RUNS_PAGE_SIZE = 100¶

Runs per page of a listing, the most the REST API serves.

repomatic.github.runs.LIVE_RUN_STATUSES = ('in_progress', 'queued')¶

Run statuses cancel_superseded_runs() sweeps: the ones still to finish.

repomatic.github.runs.ANSI_ESCAPE_RE = re.compile('\\x1b\\[[0-9;?]*[ -/]*[@-~]')¶

A terminal control sequence, as a CI log colours its lines with.

repomatic.github.runs.runs_created_since()[source]¶

The created filter a runs listing sends: runs from the last window.

See RUN_LISTING_WINDOW for why every listing carries one.

Return type:

str

repomatic.github.runs.workflow_runs(workflow, branch, *, status='', limit=1, strict=False)[source]¶

The newest runs of workflow on branch, newest first.

Reads the workflow’s runs endpoint with a runs_created_since() filter, never gh run list: see RUN_LISTING_WINDOW. Pages are read one at a time, so a listing stops at limit instead of walking the window.

Parameters:
  • workflow (str) – Workflow filename, like tests.yaml.

  • branch (str) – Branch whose runs to list.

  • status (str) – A run status or conclusion to keep, like success. Empty keeps every run.

  • limit (int) – How many runs to return at most.

  • strict (bool) – Raise the error of a gh call that could not run or did not answer JSON, instead of returning the runs read so far.

Return type:

list[dict[str, Any]]

Returns:

Run payloads as the REST API returns them.

repomatic.github.runs.commit_runs(sha)[source]¶

Every run GitHub created for commit sha, newest first.

One page of the largest size covers every run a single commit carries.

Parameters:

sha (str) – Full commit SHA.

Return type:

list[dict[str, Any]]

Returns:

Run payloads as the REST API returns them.

Raises:
repomatic.github.runs.read_run(run_id, fields, *, soft=False)[source]¶

Read one run by ID, with the gh run view --json fields named.

Parameters:
  • run_id (int | str) – The run’s numeric ID.

  • fields (Sequence[str]) – The JSON fields to request, like jobs or headSha.

  • soft (bool) – Return None when the call fails, as gh_json() does.

Return type:

dict[str, Any] | None

Returns:

The run payload, or None when the answer is not a JSON object.

Raises:
  • GhCommandError – When the gh call fails and soft is not set.

  • GhOutputError – When the answer is not JSON and soft is not set.

repomatic.github.runs.job_log(job_id)[source]¶

The log of one job, control sequences stripped.

Readable the moment the job settles, while the rest of its run still goes: the run-scoped gh run view --log-failed answers nothing until the whole run is terminal. gh refuses to print a body holding terminal escape sequences, which a CI log always does, unless told to, and the colour codes are then stripped so a reader greps plain text.

Parameters:

job_id (int | str) – The job’s numeric ID, databaseId in a run’s job listing.

Return type:

str

Returns:

The log, one line per step line, timestamps kept.

Raises:

GhCommandError – When the gh call fails.

repomatic.github.runs.live_runs(branch)[source]¶

The in-progress and queued runs of branch, every page of them.

A live run is recent by definition, so the listing window drops none.

Parameters:

branch (str) – Head branch whose runs to list.

Return type:

list[dict[str, Any]]

Returns:

Run payloads, the in-progress ones first.

Raises:
repomatic.github.runs.cancel_superseded_runs(branch, current_run_id)[source]¶

Cancel the in-progress and queued workflow runs of branch.

Backs the cancel-runs command, fired when a pull request closes: GitHub’s concurrency mechanism only cancels a run when a new run enters the same group, and closing a PR fires no such run, so the branch’s live runs would otherwise burn CI minutes to completion.

Every listed run is cancelled except two: current_run_id (the cancelling run itself), and any run whose head commit carries one of the RELEASE_PUSH_PREFIXES. A run that fails to cancel (already finished, insufficient token scope) is logged and skipped so one straggler never aborts the sweep.

Caution

The release guard is what makes this safe to point at a default branch. The concurrency groups of release.yaml and tests.yaml already spare a release run from automatic supersession, but a sweep like this one enters no concurrency group, so nothing else would stop it from killing the matrix that publishes a release. Cancelling a release run mid-flight costs the version its binaries permanently, since publishing locks the asset list (see the publish-release job of _release-engine.yaml).

Parameters:
  • branch (str) – Head branch whose runs to cancel.

  • current_run_id (str) – Run ID to spare (the caller’s own run).

Return type:

int

Returns:

Number of runs cancelled.