opsenDocs
Findings

Actions minutes

.md

Superseded pull request runs, duplicate runs, failing default branches, schedules on dormant repositories, and jobs that hang.

Actions findings are measured from job timings over the last 30 days, priced per runner type, and only for minutes that should not have been spent.

Superseded pull request runs

actions.superseded

Every push to an open pull request starts a new run. Without a concurrency group, the run for the previous commit keeps going, and bills, until it finishes.

A run is counted when another run of the same workflow, on the same branch, for a different commit, started before it finished. Only its minutes after the newer run started are priced: those are the minutes cancel-in-progress would have saved.

Example
12:00  run A starts  (commit 1)
12:05  run B starts  (commit 2)   ← A is superseded here
12:15  run A ends                  counted: 10 minutes of A

Workflows that already cancel superseded runs, at the top level or in every job, are never counted.

A workflow that deploys, publishes, applies infrastructure or runs a migration (a job with a deployment environment, or steps such as terraform apply, kubectl apply, npm publish, docker push or manage.py migrate) gets no fix pull request. Cancelling it halfway could leave that change half done, so the row says Check first and the concurrency group is left to someone who knows which jobs are safe to cancel.

Action: Open fix PR adds a concurrency group.

Duplicate push and pull request runs

actions.duplicate_runs

A workflow with on: [push, pull_request] and no branch filter runs twice for every commit to a pull request branch: once for the push, once for the pull request. A push run is counted when the same commit also ran the same workflow for a pull request, on a branch other than the default branch. Every minute of the push run is counted; with many of them, up to 30 per workflow are priced and the rest at their average.

Action: limit push to the default branch. Pull requests are still checked, and so is every merge:

Fix
on:
  push:
    branches: [main]
  pull_request:

opsen does not open this pull request itself: which branches a workflow runs on is a team's decision.

Failing default branches

actions.failing

A workflow whose runs on the default branch, or on a schedule, fail 40% or more of the time over at least 10 runs. Failures on pull requests are never counted: catching them is what CI is for. Runs that hung are counted under jobs that hang, not here.

The minutes of up to 15 failed runs are read and priced, and the remaining failed runs at their average, so the figure is an estimate and says so.

Action: fix the failing job, or quarantine the flaky test. The next audit records what stopped being spent.

Schedules on dormant repositories

actions.dormant_schedules

Scheduled (on: schedule) runs in repositories with no push in 90 days. Every minute of those runs is counted.

Action: Disable calls PUT /repos/{org}/{repo}/actions/workflows/{id}/disable. Enable workflow in the repository's Actions tab turns it back on.

A repository that exists only to run cron jobs is never pushed to, so a quiet repository does not mean a useless schedule. A scheduled workflow that looks like it does real work (a backup, a certificate renewal, a sync, a cleanup, a security scan, a report, or anything that deploys or publishes) is flagged, and Disable needs a tick confirming it is safe to stop.

Jobs that hang

actions.hung

GitHub stops a job after six hours unless timeout-minutes says otherwise. A failed or cancelled run longer than 340 minutes is treated as hung.

Only the minutes beyond a cap are counted. The cap is twice the 90th-percentile duration of the same workflow's successful runs, and at least 30 minutes. With fewer than five successful runs to learn from, the cap is 60 minutes for the estimate, and opsen opens no pull request: the job may be meant to run that long, so the row says Check first and someone who knows the job sets the timeout.

Action: Open fix PR sets timeout-minutes on each job that lacks one, at the cap rounded up to five minutes.

Runner rates

Standard runner $/minute
Linux $0.006
Windows $0.010
macOS $0.062

Larger, ARM, GPU and macOS rates are in Prices.