Repository navigation
Automatically isolate breeze testing for each git worktree in a totally isolated project. - #73836
Conversation
A number of brreze commands supported `--project-name` to be able to run multiple breeze commands in parallel (very useful when you are using git worktrees), but there were two big gaps to this feature: - the Postgres volume was "global", so all breeze projects used the same volume - the `testing` commands didn't have this flag. Adding this means can now run `breeze testing core-tests --project-name $my_worktree --backend postgres` safely on multiple worktrees without collision
shahar1
left a comment
There was a problem hiding this comment.
LGTM, note the failing test (might be a transient error)
There was a problem hiding this comment.
I think this will eat your disk very quickly and will use a lot of memory and resources if you do it this way. Because you will forget to run breeze down for all the worktrees.
You won't even know you have to do it. Breeze will not automatically shut down the databases and volumes it creates to save.time when bootstrapping.
The solution to it is to detect if you are i.in worktrees and register a git hook on wprktree deletion to perform complete cleeanup.
Also 'breeze down should detect multiple worktree breeze composes running and volumes being treated and add a suite of options and commands to deal with it - possibly even warn the users when they have multiple breeze composes and volumes created
|
@potiuk Isn't that my (as in the user's) choice? Many people don't use work trees, and you only pay this potential cost if you specify Note: this is "allow", not "automatically make worktrees isolated". I don't see anything related to worktree deletion in https://git-scm.com/docs/githooks. The CLI does nothing automatic to detect the current worktree. I could have three projects on the same main checkout, and that's by design. |
|
I'm looking at making |
The use of workflows is that they are often created and deleted on demand - Breeze has been designed to handle just "several - but static set of projects" simply. We do it in Magpie, but indeed those hooks were Claude hooks. I think the easiest way is:
|
|
We could also run a reaper process for each worktree or one per all, but we do not need to delete the project immediately, it's enough that it is deleted automatically when the worktree is gone. And when the worktree is gone, there is no way running project will have any use. |
|
This will be way better - to automatically have a separate breeze project per each worktree, there is no particular need to specify If you want I can quickly implement this @ashb |
|
It's alright, I've got it @potiuk (i've got a chunk of it already written locally) Also I think we can record the worktree as a label on the docker resources, so don't need to track things via files. |
Andrushika
left a comment
There was a problem hiding this comment.
Left two comments, thanks.
potiuk
left a comment
There was a problem hiding this comment.
OK. Fine how it is - since you indeed describe a manual process, and cleanup change might be useful, but I will also add a new option (configured with a new setup, enabled by default) to get separate project per worktree automatically. I think it's totally worth it - and your PR gave me this idea.
Project isolation leaves named database volumes behind after test containers are removed. Cleanup needs a Breeze ownership marker independent of Compose project names so those unused volumes remain discoverable across worktrees. An absolute checkout path lets cleanup identify containers whose linked worktree has been deleted, including running database services. Empty paths preserve primary-checkout containers, and shared caches and networks have no worktree owner. Filesystem errors must not be treated as evidence of deletion. This path check assumes the Docker resources belong to the local machine. Volume pruning follows container cleanup so it can reclaim newly unreferenced storage while Docker preserves volumes still attached to containers. Existing volumes retain their creation-time labels, so the legacy default-project filter remains necessary; older custom-project volumes need manual cleanup.
When a worktree is detected, the last component of the dirname is taken as the suffix of the project name. And to prevent bloating of DB from deleted worktrees, any "docker"-touching command will clean up dead resources from any deleted worktrees.
breeze testing for each git worktree in a totally isolated project.
potiuk
left a comment
There was a problem hiding this comment.
Thanks for taking this further. Using labels for ownership (org.apache.airflow.breeze / .worktree) is a nicer basis than a separate registry, and it means resources are marked for cleanup as soon as they're created.
Since my earlier approval, the PR has changed from the manual --project-name flow to automatic per-worktree naming plus an opportunistic sweep. I've left four inline comments on the new part. Two I'd like addressed before merge because they can hurt users:
- the
check=Truecalls in the sweep, which can fail unrelated commands - staleness decided by local path existence, which can remove resources that belong to another host
The other two are silent behaviour changes: the Postgres volume rename, and the scope of breeze down. The PR description also still describes only the manual flag, so it's worth updating it to cover the automatic naming and the new breeze down semantics.
Several improvements go beyond the original scope, and I'm happy to do them in a follow-up PR rather than grow this one:
-
Automatic resource release when a worktree is deleted. A small detached watcher, started on the first compose up in a worktree, brings the project down soon after the directory disappears. Today CPU and memory are only freed on the next Docker-touching breeze command.
-
A
breeze setup configswitch for per-worktree isolation, on by default. -
A short path hash in the project name. Same-named worktrees in different locations or clones currently share a project.
-
Scoping the remaining fixed names:
- the
breeze-docs,breeze-db,breeze-prek,breeze-constraints*andbreeze-providers*projects - the airflow-ctl, task-sdk and quick-start conftest projects, which are currently neither scoped nor labelled
- the fixed
container_names and the kerberos network
- the
-
Per-worktree kind cluster names and the pycache volume, and cleaning up both.
-
A warning from
breeze down(or a listing) when other worktrees' projects and volumes are still around. -
An ADR (
dev/breeze/doc/adr/0019-…) describing the whole per-worktree isolation effort:- why worktrees need isolation
- label-based ownership, rather than a registry or name matching
- the naming scheme
- what is deliberately kept shared (CI/PROD images, the mypy cache, host ports)
- the cleanup triggers (opportunistic sweep, watcher, explicit
breeze down/cleanup) and their safety rules (host scoping, best-effort sweep) - the opt-out switch
Today that reasoning lives only in commit messages and review threads.
Drafted-by: Claude Code (Opus 5.5); reviewed by @potiuk before posting
680fd57 to
298c46a
Compare
Backport failed to create: v3-3-test. View the failure log Run detailsNote: As of Merging PRs targeted for Airflow 3.X In matter of doubt please ask in #release-management Slack channel.
You can attempt to backport this manually by running: cherry_picker 0768924 v3-3-testThis should apply the commit to the v3-3-test branch and leave the commit in conflict state marking After you have resolved the conflicts, you can continue the backport process by running: cherry_picker --continueIf you don't have cherry-picker installed, see the installation guide. |
A number of brreze commands supported
--project-nameto be able to runmultiple breeze commands in parallel (very useful when you are using git
worktrees), but there were two big gaps to this feature:
testingcommands didn't have this flag.Adding this means can now run
breeze testing core-tests --project-name $my_worktree --backend postgressafely on multiple worktrees without collisionWas generative AI tooling used to co-author this PR?
{pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.