Cancel superseded CI runs and skip image builds PRs cannot affect - #855
Conversation
Modern agent-driven development ("vibe-coding") produces many PRs, and
CI minutes scale with them: in zoya, a production project running this
template's CI shape, GitHub Actions alone began costing ~$100/month.
The two biggest line items were superseded runs of the same PR
completing pointlessly, and every PR building all three Docker images
even when nothing image-affecting changed.
Port both cost guards from zoya:
- A concurrency group per workflow and ref, in both the template repo's
own CI and the CI generated projects inherit, cancelling in-progress
runs only for pull requests — a push to master is never cancelled.
- In the generated project's workflow, the lint job asks the GitHub API
for the PR's changed files and reports whether any of them can affect
the image build (Dockerfile, uv.lock, pyproject.toml, .dockerignore).
build-docker-image now also needs lint (execution order is unchanged,
test already needs it) and skips on PRs that touch none of those
files; pushes to master always build.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Если ни у кого нет возражений, я смёрджу |
nvo87
left a comment
There was a problem hiding this comment.
да, круто. Мы до этого у себя билд образа делали опциональным. И при авто-мердже, в пулл-реквестах он не отрабатывал. А тут еще круче.
@f213 при наличии постоянной разработки за эти деньги можно уже арендовать нормальный раннер. Вероятно там деньги будут уходить на канал для скачки образов, но, возможно будет все еще дешевле. Стоит ли попробовать прописать свой раннер из хецнера? Алсо интересно, поможет ли это при падении гитхабовой инфраструктуры. |
|
Сейчас принято пользоваться готовыми сторонними раннерами as a service. Я выбрал https://www.blacksmith.sh, получается в два раза быстрее при почти нулевой конфигурации. Бесплатный порог там довольно большой — через месяц-два будет понятно, насколько это дешевле раннеров, арендованных у гитхаба (думаю, намного). |
Motivation
Modern agent-driven development ("vibe-coding") produces many PRs, and CI minutes scale with them: in zoya, a production project running this template's CI shape, GitHub Actions alone began costing ~$100/month. The two biggest line items were superseded runs of the same PR completing pointlessly, and every PR building all three Docker images even when nothing image-affecting changed. This PR ports both cost guards from zoya's CI.
Concurrency guard (both workflows)
Both the template repo's own
.github/workflows/ci.ymland the workflow generated projects inherit get a top-level concurrency group keyed on workflow and ref:Pushing a new revision to a PR cancels the now-obsolete run of the previous one.
cancel-in-progressis conditional on the event, so a push to master is never cancelled — every master run completes.Conditional image build (generated project's workflow)
The
lintjob gains a step, run only on pull requests, that lists the PR's changed files via the GitHub API and checks them against the set that can affect the image build:Dockerfile,uv.lock,pyproject.toml,.dockerignore. The verdict is exposed as a job output, andbuild-docker-imagenow skips when a PR touches none of those files:Adding
linttoneedsis required to read the output; execution order is unchanged sincetestalready needslint. Pushes to master always build all three images — the condition only ever skips PR runs.The generated workflow lives under
_copy_without_renderincookiecutter.json, so the added${{ }}expressions pass through cookiecutter untouched.🤖 Generated with Claude Code