fix(ci): Deploy detects changed images from the pushed diff, not head_commit.modified #1126

Closed
kert wants to merge 0 commits from fix/deploy-detect-changes-by-diff into main
Owner

Problem

Every image job in deploy.yml was gated on contains(github.event.head_commit.modified, …). That list describes only the tip commit of a push, and Gitea leaves it empty for merge commits. So every PR landed with a merge commit skipped all six image builds. The llm image for #1120 (merge dff1919) was skipped and had to be built and deployed by hand.

Fix

dev/scripts/backends/gitea.py::_gen_deploy now emits a changes job that:

  • fetches the push's previous tip (github.event.before) into the shallow checkout with git fetch --depth=1 origin <sha> (verified against this Gitea: a raw-SHA shallow fetch is accepted), and
  • diffs it against the new tip with git diff --name-only, so the whole pushed range counts: a merge commit's branch, or all commits of a direct multi-commit push;
  • matches the changed paths against each image's path_filter from stack.toml (globs translated to bash case patterns) and publishes one boolean output per image.

Each image job needs: [changes] and gates on needs.changes.outputs.<image> == 'true'. An image without path filters follows every push. If the previous tip is unknown or unfetchable (first push, history rewrite), every image builds rather than none. The report job also waits on changes, so a detector failure files an issue like any other job failure.

The 11 GB repo rules out fetch-depth: 0; fetching the single previous tip at depth 1 keeps the job as cheap as the current checkout.

Tests

tests/dev/test_gen_config_deploy.py: generated shape (outputs, needs, if, case globs, no filter → always), plus the detector script executed for real in a scratch repository: merge-commit push rebuilds the images the branch touched, a multi-commit direct push covers the whole range, unknown/zero/unfetchable before builds everything.

gen_config.py --check clean; tests/dev + tests/test_notebook_layout.py 68 passed.

Verification plan

The push of this PR's merge commit to main is itself the first live run of the detector: the changes job log lists the diffed files and every image output should be false (only dev/, .gitea/ and tests/ change here).

## Problem Every image job in `deploy.yml` was gated on `contains(github.event.head_commit.modified, …)`. That list describes only the tip commit of a push, and Gitea leaves it empty for merge commits. So every PR landed with a merge commit skipped all six image builds. The `llm` image for #1120 (merge dff1919) was skipped and had to be built and deployed by hand. ## Fix `dev/scripts/backends/gitea.py::_gen_deploy` now emits a `changes` job that: - fetches the push's previous tip (`github.event.before`) into the shallow checkout with `git fetch --depth=1 origin <sha>` (verified against this Gitea: a raw-SHA shallow fetch is accepted), and - diffs it against the new tip with `git diff --name-only`, so the whole pushed range counts: a merge commit's branch, or all commits of a direct multi-commit push; - matches the changed paths against each image's `path_filter` from `stack.toml` (globs translated to bash `case` patterns) and publishes one boolean output per image. Each image job `needs: [changes]` and gates on `needs.changes.outputs.<image> == 'true'`. An image without path filters follows every push. If the previous tip is unknown or unfetchable (first push, history rewrite), every image builds rather than none. The `report` job also waits on `changes`, so a detector failure files an issue like any other job failure. The 11 GB repo rules out `fetch-depth: 0`; fetching the single previous tip at depth 1 keeps the job as cheap as the current checkout. ## Tests `tests/dev/test_gen_config_deploy.py`: generated shape (outputs, `needs`, `if`, `case` globs, no filter → always), plus the detector script executed for real in a scratch repository: merge-commit push rebuilds the images the branch touched, a multi-commit direct push covers the whole range, unknown/zero/unfetchable `before` builds everything. `gen_config.py --check` clean; `tests/dev` + `tests/test_notebook_layout.py` 68 passed. ## Verification plan The push of this PR's merge commit to main is itself the first live run of the detector: the `changes` job log lists the diffed files and every image output should be `false` (only `dev/`, `.gitea/` and `tests/` change here).
kert added 1 commit 2026-10-24 22:23:57 +00:00
fix(ci): Deploy detects changed images from the pushed diff, not head_commit.modified
Some checks failed
CI / lint (pull_request) Successful in 34s
CI / notebooks-smoke (pull_request) Successful in 1m29s
CI / test (pull_request) Failing after 2m8s
CI / lint (push) Successful in 34s
CI / test (push) Failing after 2m13s
CI / notebooks-smoke (push) Successful in 1m41s
b4087a1110
The per-image jobs in deploy.yml were gated on
contains(github.event.head_commit.modified, …). That list only describes
the tip commit of a push and Gitea leaves it empty for merge commits, so
every PR landed with a merge commit skipped all six image builds; the
llm image for #1120 had to be built and deployed by hand.

A new 'changes' job fetches the push's previous tip (github.event.before)
into the shallow checkout and diffs it against the new tip, so the whole
pushed range counts: a merge commit's branch, or all commits of a direct
multi-commit push. Each image job now needs that job and gates on its
boolean output; an image without path filters follows every push. When
the previous tip is unknown or unfetchable (first push, history rewrite)
every image builds rather than none.

Tests cover the generated shape and run the detector script in a scratch
repository for the merge-commit, multi-commit and unknown-tip cases.
Author
Owner

Merged to main as merge commit d98a47e (local merge + push: the API merge is blocked by the CI/test and Infra CI/mc checks that have been red on main since 2026-09-25). The push of d98a47e is the first live run of the changes job.

Merged to main as merge commit d98a47e (local merge + push: the API merge is blocked by the CI/test and Infra CI/mc checks that have been red on main since 2026-09-25). The push of d98a47e is the first live run of the `changes` job.
kert closed this pull request 2026-10-24 22:24:31 +00:00
Some checks are pending
CI / lint (pull_request) Successful in 34s
CI / notebooks-smoke (pull_request) Successful in 1m29s
CI / test (pull_request) Failing after 2m8s
CI / lint (push) Successful in 34s
CI / test (push) Failing after 2m13s
CI / notebooks-smoke (push) Successful in 1m41s
ci/woodpecker/push/ci
Required
ci/woodpecker/pr/ci
Required
ci/woodpecker/push/infra-ci
Required
ci/woodpecker/pr/infra-ci
Required

Pull request closed

Sign in to join this conversation.