Skip to content

ci: run the Python/Django combinations as one ubuntu-slim job - #74

Closed
jab3z wants to merge 3 commits into
mainfrom
task/160214-ci-one-job
Closed

jab3z wants to merge 3 commits into
mainfrom
task/160214-ci-one-job

Conversation

@jab3z

@jab3z jab3z commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Part of #160214 (cut GitHub Actions minutes across the org).

Why

GitHub counts every job rounded up to a whole minute. CI ran a 5-job test matrix plus a build job, each 10-45 s, so every run counted 6 minutes on ubuntu-latest.

Note: ecsctx is a public repo, so these minutes are free. The September usage report shows 890 Actions minutes for ecsctx with a net cost of $0. This PR lowers the minute count and frees runner slots. It saves no money.

What changed

  • One ci job replaces the test matrix and the build job. Each Python/Django combination is its own named step with its own venv, so a red step still names exactly what broke. Every step has if: !cancelled(), so one failing combination does not hide the rest.
  • The Django pin is unchanged: uv sync, then uv pip install Django~=X, then uv run --no-sync pytest. The logs show each step running the Django version it names.
  • The venvs live in runner.temp, not the checkout. Hatchling ignores a venv's own .gitignore, so a venv inside the checkout ends up in the sdist and uv build fails (checked locally).
  • uv build and the dist artifact upload are still there.
  • pull_request now runs only for PRs into main, with types: [opened, synchronize, reopened, ready_for_review]. Draft PRs are skipped. push: main is unchanged.
  • concurrency: ci-<PR number or run_id> with cancel-in-progress: true. A new push to a PR cancels its older run. Each push to main gets its own group, so a queued push is never dropped.
  • Runner: ubuntu-latest, not ubuntu-slim. On slim (1 vCPU) every combination failed the 0.25 s wall-clock bound in test_many_start_tags_nothing_closes_take_linear_time, 2-3 cases each (run). Everything else passed there, and the job took 4m53s.

No required status checks reference the old test (...) / build job names (no repo rulesets, no branch protection, and no org ruleset targets ecsctx).

Trade-offs

  • Stacked PRs. These are PRs whose base is another feature branch: 12 of the last 73 PRs. They no longer get CI until they target main and get a new push. A retarget alone is an edited event, which does not start CI. Before, the workflow ran on every PR on purpose.
  • Slower feedback. The matrix finished in about 40 s. One job takes about 2.5-4 min.

Before / after (minutes counted per run)

Jobs Wall clock Minutes counted
Before: matrix + build, ubuntu-latest 6 ~40 s 6
After: one job, ubuntu-latest 1 2m34s-3m57s 3-4

Runs on this PR:

  • 37586169092:
    • Attempt 2: all five combinations, the build and the artifact upload passed (2m55s).
    • Attempt 1: red only on the flaky timing test.
  • 37586997304 (head): all green (2m34s).

Pre-existing flake

test_many_start_tags_nothing_closes_take_linear_time also fails on main today: 8 of the last 9 CI runs are red on that one test. It asserts each masking call finishes in under 0.25 s, so it fails on slower runner hardware.

  • The matrix spread the five combinations over five machines, so one slow machine turned the run red.
  • One job puts every combination on the same machine, so a run is now all-green or all-red on this test.

jab3z added 3 commits October 7, 2026 10:08
GitHub bills every job rounded up to a whole minute, so the five-job
matrix plus the build job cost six minutes per run for about three
minutes of work. One job runs each combination as its own step, in its
own venv, and keeps running after a failure so every combination
reports. PRs into main only, drafts skipped, superseded PR runs
cancelled.

Refs #160214
On ubuntu-slim's single vCPU the wall-clock bound in the XML masking
linear-time test failed in all five combinations.

Refs #160214
A concurrency group holds one pending run and cancels the older pending
one when a newer run arrives, even with cancel-in-progress false, so a
group shared by every push to a branch could drop a queued push. Pushes
now group by run_id; PR runs still group by PR number and cancel their
superseded run.

Refs #160214
@jab3z jab3z closed this Oct 8, 2026
@jab3z
jab3z deleted the task/160214-ci-one-job branch October 8, 2026 04:58
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