Skip to content

ci: timeouts and cancel-in-progress for superseded runs - #216

Merged
AminDhouib merged 1 commit into
canaryfrom
ci/track7/hygiene
Sep 16, 2026
Merged

AminDhouib merged 1 commit into
canaryfrom
ci/track7/hygiene

Conversation

@AminDhouib

Copy link
Copy Markdown
Member

Timeouts. Each job below had no timeout-minutes, so it inherited the
GitHub default of 360 minutes. On a fixed-size self-hosted pool that is what
a hung step really costs: one wedged run holds a slot for six hours and every
queued run waits behind it.

The value is 3 x the job's observed p90 over 72 h, rounded up to the nearest
5; where history showed no usable sample the job takes its class default
instead. Class and source are given per job.

.github/workflows/create-pr.yml
create-pr 15 min class=deploy/notify class default (no observed runs)

.github/workflows/deploy.yml
build-and-push-cloud-image 45 min class=docker-image class default (no observed runs)
build-and-push-schedule-image 45 min class=docker-image class default (no observed runs)
build-and-push-server-image 45 min class=docker-image class default (no observed runs)

.github/workflows/dokploy.yml
combine-manifests 45 min class=docker-image class default (p90=0.2m, sample too small for the 3x rule)
docker-amd 45 min class=docker-image class default (p90=7.2m, sample too small for the 3x rule)
docker-arm 45 min class=docker-image class default (p90=6.9m, sample too small for the 3x rule)

.github/workflows/format.yml
format 15 min class=lint class default (no observed runs)

.github/workflows/monitoring.yml
combine-manifests 45 min class=docker-image class default (no observed runs)
docker-amd 45 min class=docker-image class default (no observed runs)
docker-arm 45 min class=docker-image class default (no observed runs)

.github/workflows/pull-request.yml
pr-check 25 min class=deploy/notify 3 x p90 6.8m rounded up

.github/workflows/sync-openapi-docs.yml
generate-and-commit 15 min class=deploy/notify class default (no observed runs)

.github/workflows/upgrade-integration-test.yml
build-matrix 15 min class=deploy/notify class default (no observed runs)
upgrade-test 15 min class=deploy/notify class default (no observed runs)

Concurrency. A superseded run is one whose commit a newer push to the same
ref has already replaced; nothing reads its result, but it still holds a
runner slot until it finishes.

.github/workflows/format.yml
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

The group keys on workflow and ref, so runs supersede only within one ref;
a branch never cancels another branch. The default branch (canary) cancels
superseded runs too, because these are CI-only workflows: no deploy step, no
publish step and no environment:, so no downstream state depends on a run
that a newer commit has already replaced. The newest commit on the ref still
gets a full CI result recorded against it.

Part of the CI pool right-sizing programme; edits derived from 72 h of run history.

Timeouts. Each job below had no timeout-minutes, so it inherited the
GitHub default of 360 minutes. On a fixed-size self-hosted pool that is what
a hung step really costs: one wedged run holds a slot for six hours and every
queued run waits behind it.

The value is 3 x the job's observed p90 over 72 h, rounded up to the nearest
5; where history showed no usable sample the job takes its class default
instead. Class and source are given per job.

  .github/workflows/create-pr.yml
    create-pr                       15 min   class=deploy/notify class default (no observed runs)

  .github/workflows/deploy.yml
    build-and-push-cloud-image      45 min   class=docker-image class default (no observed runs)
    build-and-push-schedule-image   45 min   class=docker-image class default (no observed runs)
    build-and-push-server-image     45 min   class=docker-image class default (no observed runs)

  .github/workflows/dokploy.yml
    combine-manifests               45 min   class=docker-image class default (p90=0.2m, sample too small for the 3x rule)
    docker-amd                      45 min   class=docker-image class default (p90=7.2m, sample too small for the 3x rule)
    docker-arm                      45 min   class=docker-image class default (p90=6.9m, sample too small for the 3x rule)

  .github/workflows/format.yml
    format                          15 min   class=lint         class default (no observed runs)

  .github/workflows/monitoring.yml
    combine-manifests               45 min   class=docker-image class default (no observed runs)
    docker-amd                      45 min   class=docker-image class default (no observed runs)
    docker-arm                      45 min   class=docker-image class default (no observed runs)

  .github/workflows/pull-request.yml
    pr-check                        25 min   class=deploy/notify 3 x p90 6.8m rounded up

  .github/workflows/sync-openapi-docs.yml
    generate-and-commit             15 min   class=deploy/notify class default (no observed runs)

  .github/workflows/upgrade-integration-test.yml
    build-matrix                    15 min   class=deploy/notify class default (no observed runs)
    upgrade-test                    15 min   class=deploy/notify class default (no observed runs)

Concurrency. A superseded run is one whose commit a newer push to the same
ref has already replaced; nothing reads its result, but it still holds a
runner slot until it finishes.

  .github/workflows/format.yml
    group: ${{ github.workflow }}-${{ github.ref }}
    cancel-in-progress: true

The group keys on workflow and ref, so runs supersede only within one ref;
a branch never cancels another branch. The default branch (canary) cancels
superseded runs too, because these are CI-only workflows: no deploy step, no
publish step and no environment:, so no downstream state depends on a run
that a newer commit has already replaced. The newest commit on the ref still
gets a full CI result recorded against it.
@AminDhouib
AminDhouib merged commit 6ddfcc5 into canary Sep 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant