Skip to content
This repository was archived by the owner on Sep 30, 2026. It is now read-only.

Add timeout-minutes to jobs that have none (PM_GH_REPO_024) - #21

Open
anish-sujanani wants to merge 1 commit into
mainfrom
pmsec/job-timeouts
Open

anish-sujanani wants to merge 1 commit into
mainfrom
pmsec/job-timeouts

Conversation

@anish-sujanani

Copy link
Copy Markdown
Contributor

Add timeout-minutes to jobs that have none

Addresses PM_GH_REPO_024 — Workflow jobs must declare a timeout.

A job with no timeout-minutes inherits GitHub's default of 360 minutes, so a hung job
holds a runner for six hours before the platform stops it. This bounds 8 jobs;
worst case for this repo drops from 2880 runner-minutes to 45.

Proposed values

Workflow Job Successful runs sampled p50 p90 max timeout-minutes
plugin-checks.yml json-validation 49 0.1m 0.2m 0.3m 5
plugin-checks.yml frontmatter-validation 46 0.1m 0.2m 0.2m 5
plugin-checks.yml markdown-lint 48 0.2m 0.2m 0.3m 5
plugin-checks.yml link-check 49 0.1m 0.2m 0.2m 5
plugin-checks.yml structure-integrity 46 0.1m 0.2m 0.2m 5
plugin-checks.yml version-sync 4 0.1m 0.1m 0.1m 5
pr-labeler.yml label 34 0.1m 0.1m 0.2m 5
release.yml release 1 0.1m 0.1m 0.1m 10

How these were calculated

timeout-minutes = min(350, max(3, ceil(m x slowest SUCCESSFUL run)))
    m = 2.0 under 30m   1.5 for 30-120m   1.3 above 120m
  • Source: GET /repos/{owner}/{repo}/actions/runs/{id}/jobs, per-job started_at to
    completed_at over the 50 most recent completed runs of each workflow. That is the same
    clock timeout-minutes uses: it starts when the job begins executing and excludes queue
    and runner-acquisition time, so it will read lower than the run duration shown in the
    Actions tab.
  • Only successful runs were counted. Cancelled and failed runs measure when someone hit
    cancel or when a job died, not how long the work takes.
  • Floor of 5 rather than 3 for any job that installs dependencies or runs a build or test
    suite. A 3-minute floor killed a legitimate job in CI earlier in this rollout.
  • 350 cap because GitHub-hosted runners hard-stop at 360, so anything above it is decorative.

Verification

  • The parsed YAML is identical before and after with timeout-minutes stripped from both
    trees, so nothing else moved.
  • The diff adds only timeout-minutes: lines and deletes nothing.
  • actionlint reports the same findings before and after.
  • Re-running the tool refuses every job, so the change is idempotent.

Break risk

A timeout can only stop a job that exceeds it. If any value is tighter than you want, say so
and I will raise it — a loose bound still fixes the finding.

Sized from observed per-job durations of successful runs where available, otherwise from declared budgets in the job or from what the steps do. See the batch working notes for per-job reasoning.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant