Skip to content

Commit 79b9bfb

Browse files
authored
Merge pull request #58 from helixml/feature/002029-merge-latest-zed
Merge upstream Zed (8bdd78e..1399540, 261 commits) into Helix fork
2 parents e60a1b2 + 454cdee commit 79b9bfb

919 files changed

Lines changed: 120787 additions & 45246 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/gpui-test/SKILL.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
name: gpui-test
3+
description: >-
4+
Use when writing, debugging, or reproducing GPUI tests in Zed, including
5+
gpui::test arguments, TestAppContext parameters, scheduler seeds,
6+
ITERATIONS/SEED reproduction, parking failures, and pending task traces.
7+
---
8+
9+
# GPUI Test Debugging
10+
11+
Use this skill when the user asks about `#[gpui::test]`, GPUI test seeds or iterations, deterministic scheduler failures, parking/pending task failures, or how to reproduce a flaky GPUI test.
12+
13+
## What `#[gpui::test]` does
14+
15+
`#[gpui::test]` expands to a normal Rust `#[test]`, so it runs under standard Rust test runners such as `cargo test` and `cargo nextest`.
16+
17+
It wraps the body in GPUI's deterministic test dispatcher/scheduler and can run the same test multiple times with different seeds. The seed controls scheduler task interleavings and any `StdRng` argument injected into the test.
18+
19+
The macro supports both synchronous and asynchronous tests.
20+
21+
### Supported function arguments
22+
23+
The macro recognizes arguments by type name:
24+
25+
| Test kind | Supported arguments |
26+
| --- | --- |
27+
| Sync and async | `&TestAppContext`, `&mut TestAppContext`, `StdRng` |
28+
| Async only | `BackgroundExecutor` |
29+
| Sync only | `&App`, `&mut App` |
30+
31+
`StdRng` is seeded from the current GPUI test seed, and `BackgroundExecutor` is backed by the same deterministic test dispatcher.
32+
33+
### Attribute arguments
34+
35+
Use these forms on `#[gpui::test(arguments)]`:
36+
37+
- No arguments: runs once with seed `0`, unless `SEED` is set.
38+
- `seed = N`: adds a single explicit seed.
39+
- `seeds(...)`: adds multiple explicit seeds.
40+
- `iterations = N`: runs sequential seeds starting at `0` by default.
41+
- `retries = N`: retries a failing run up to `N` times before surfacing the failure.
42+
- `on_failure = "path::to::function"`: calls the function after final failure, before resuming the panic.
43+
- `iterations` can be combined with explicit `seed` / `seeds`; explicit seeds are appended to the `0..iterations` range.
44+
- If the `SEED` environment variable is set, it takes precedence over explicit seeds.
45+
- With `SEED=N` and `ITERATIONS=M` or `iterations = M`, the harness runs seeds `N..N+M`.
46+
47+
## Environment variables
48+
49+
### GPUI test macro / scheduler execution
50+
51+
- `SEED=<u64>` — chooses the scheduler seed. Use this to reproduce a failure printed as `failing seed: N`. It also seeds injected `StdRng` arguments. For `#[gpui::property_test]`, it controls the scheduler seed and GPUI applies it to the proptest config for deterministic case generation.
52+
- `ITERATIONS=<usize>` — overrides the `iterations = ...` value at runtime. Use to sweep many seeds without editing the test.
53+
- `PENDING_TRACES=1` or `PENDING_TRACES=true` — captures and prints pending task traces when the test scheduler panics with `Parking forbidden`. Use this when `run_until_parked()` or teardown reports pending work.
54+
- `GPUI_RUN_UNTIL_PARKED_LOG=1` — logs when `allow_parking()` is enabled. Use to find tests that explicitly permit parking/pending work.
55+
- `DEBUG_SCHEDULER=1` — prints scheduler clock/timer debugging from `scheduler::TestScheduler`.
56+
57+
### Lower-level scheduler tests
58+
59+
- `SCHEDULER_NONINTERACTIVE=1` — suppresses interactive seed progress output in `scheduler::TestScheduler::many`. This does not affect the `#[gpui::test]` harness path.
60+
61+
### General Rust test debugging vars often useful with GPUI tests
62+
63+
- `RUST_BACKTRACE=1` or `RUST_BACKTRACE=full` — show panic backtraces.
64+
- `RUST_LOG=<filter>` — enable logs when the test initializes logging.
65+
- `ZED_HEADLESS=1` — forces GPUI platform guessing toward headless mode; useful for tests that otherwise interact with platform/window setup.
66+
67+
Prefer env vars over editing the test when narrowing a reproduction.
68+
69+
## Reproducing a specific GPUI test
70+
71+
1. Identify the crate/package and test name.
72+
73+
2. Run the narrowest test filter first, skip to 3. if a failing seed is known.
74+
75+
```sh
76+
cargo -q test -p <crate-name> <test_name> -- --nocapture
77+
```
78+
79+
3. If the failure mentions a seed, rerun exactly that seed.
80+
81+
```sh
82+
SEED=<seed> cargo -q test -p <crate-name> <test_name> -- --nocapture
83+
```
84+
85+
4. If the failure is flaky and no seed is known, sweep seeds.
86+
87+
```sh
88+
ITERATIONS=100 cargo -q test -p <crate-name> <test_name> -- --nocapture
89+
```
90+
91+
When the harness prints `failing seed: <seed>`, switch to `SEED=<seed>` for all future debugging.
92+
93+
5. If the failure is `Parking forbidden`, rerun with pending traces.
94+
95+
```sh
96+
PENDING_TRACES=1 cargo -q test -p <crate-name> <test_name> -- --nocapture
97+
```
98+
99+
If a failing seed was printed or is already known, include it too:
100+
101+
```sh
102+
SEED=<seed> PENDING_TRACES=1 cargo -q test -p <crate-name> <test_name> -- --nocapture
103+
```
104+
105+
Inspect the pending traces for a task that was spawned but not awaited, detached, completed, or intentionally allowed to park.
106+
107+
6. If timing or timer advancement is involved, prefer GPUI scheduler timers in tests:
108+
109+
```rust
110+
cx.background_executor().timer(duration).await;
111+
```
112+
113+
Avoid `smol::Timer::after(...)` in GPUI tests that rely on `run_until_parked()`, because GPUI's scheduler may not track it.
114+
115+
7. Minimize the reproduction.
116+
- Keep the failing `SEED` fixed.
117+
- Reduce `ITERATIONS` to `1` or remove it once a seed is known.
118+
- Remove unrelated setup only after confirming the same seed still fails.
119+
- Preserve scheduler-sensitive awaits/yields; removing them can mask the bug.
120+
- If randomness is test-controlled via `StdRng`, log or assert the generated scenario after fixing the scheduler seed.
121+
122+
8. Validate the fix.
123+
- Run the fixed seed.
124+
- Run a modest seed sweep, e.g. `ITERATIONS=20`, if the failure was scheduler-sensitive.
125+
- Run the relevant crate's test filter or broader suite if the touched code has shared behavior.
126+
127+
## Common diagnosis patterns
128+
129+
### Seed-dependent assertion failure
130+
131+
Likely caused by a scheduler interleaving or by `StdRng`-driven test data. Fix `SEED`, reproduce, and inspect which task or generated scenario differs.
132+
133+
### `Parking forbidden`
134+
135+
Usually means a foreground/background task is still pending when the scheduler expected the test to make progress or finish. Look for:
136+
137+
- A task that should be awaited but was dropped.
138+
- A task that should be detached with error logging.
139+
- A timer or receiver that is waiting forever.
140+
- A missing `cx.run_until_parked()` after triggering async work in a test.
141+
- A missing `cx.advance_clock(...)` to wait for debounced work in a test.
142+
- Use of non-GPUI timers or executors that the test scheduler cannot drive.
143+
144+
Rerun with `PENDING_TRACES=1` before changing code.
145+
146+
### Non-determinism / wrong thread
147+
148+
The scheduler can report activity from an unexpected thread. Look for work escaping GPUI's foreground/background executors, direct thread spawns, or external async runtimes not controlled by the test dispatcher.
149+
150+
### Tests pass alone but fail in sweeps
151+
152+
Use the failing seed from sweep output. Avoid assuming test order unless the runner is explicitly serial. Check globals, leaked entities/tasks, and state not reset by test initialization.
153+
154+
## Writing GPUI tests
155+
156+
- Prefer `#[gpui::test]` for tests that need `TestAppContext`, deterministic executors, fake time, or scheduler interleaving coverage.
157+
- Add `iterations = N` when the test is intentionally checking interleavings.
158+
- Use `StdRng` as a test argument when randomized test data should follow the same seed as the scheduler.
159+
- Use `cx.background_executor().timer(duration).await` for delays/timeouts in GPUI tests.
160+
- Do not add or increase `retries` while fixing a test unless the user explicitly asks or the test already documents why probabilistic tolerance is intentional. Retries can mask the failure instead of fixing it.
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
---
2+
name: zed-cherry-pick
3+
description: Cherry-pick one or more merged PRs and/or commits into Zed's `preview` or `stable` release branch. Use this whenever the user mentions cherry-picking to preview/stable, a failed cherry-pick run, or wants to manually port fix(es) into a release branch.
4+
---
5+
6+
# Zed Cherry-Pick
7+
8+
Zed ships from two long-lived release branches that live on `origin`:
9+
10+
- `preview` channel → branch like `v1.4.x`
11+
- `stable` channel → branch like `v1.3.x`
12+
13+
The version numbers change with each release. **Never hardcode them — always discover the current mapping** (see [Finding the target branch](#finding-the-target-branch)).
14+
15+
A merged PR on `main` gets ported to a release branch by `script/cherry-pick`, normally driven by the `cherry_pick` GitHub Actions workflow. When that workflow fails (almost always a merge conflict), use this skill to finish the job locally and open the cherry-pick PR by hand.
16+
17+
## When to use
18+
19+
Use this when the user asks to cherry-pick one or more commits and/or Pull Requests (by number or URL) to `preview` or `stable`.
20+
Optionally, the user may specify whether to resolve merge conflicts; if unspecified, attempt the cherry-pick, and then if there are merge conflicts in practice, stop and inform the user that there are merge conflicts and offer to resolve them. (Users may prefer to resolve the merge conflicts themselves before continuing.)
21+
22+
## The script you're emulating
23+
24+
The canonical procedure lives in `script/cherry-pick` and the `cherry_pick` GitHub Actions workflow. Read the script first if anything looks off — your local steps must produce the same branch name, PR title, and PR body it would.
25+
26+
Signature: `script/cherry-pick <branch-name> <commit-sha> <channel>`
27+
28+
- `<branch-name>` is the release branch (e.g. `v1.4.x`), **not** the channel name.
29+
- `<channel>` is `preview` or `stable`, used only for display text in the PR title/body.
30+
31+
It creates a local branch named `cherry-pick-<branch-name>-<short-sha>` (the short SHA is the first 8 chars of the commit), force-pushes it to `origin`, and opens a PR.
32+
33+
## Finding the target branch
34+
35+
The channel→branch mapping changes every release. Find the current one by inspecting the most recent `cherry_pick` workflow runs:
36+
37+
```
38+
gh run list --workflow=cherry_pick.yml --limit 30 --json displayTitle,databaseId
39+
# pick a recent run for the channel you want, then:
40+
gh run view <id> --log 2>&1 | grep -E "BRANCH:|CHANNEL:"
41+
```
42+
43+
A successful run prints both `BRANCH:` and `CHANNEL:` env vars; that's your mapping.
44+
45+
## Procedure
46+
47+
### 1. Gather context
48+
49+
You need three things: the **merge commit SHA**, the **target branch**, and the **channel name**.
50+
51+
If the user requested multiple PRs and/or commits, gather the metadata for all of them first and cherry-pick them in the order they landed on `main`, oldest to newest. For PRs, order by `mergedAt`; for raw commits, use their order on `main` when available, otherwise commit date. This tends to reduce avoidable conflicts because later changes may depend on earlier ones, but it does not guarantee a conflict-free cherry-pick when the release branch has diverged.
52+
53+
```
54+
gh pr view <PR_NUMBER> --json title,number,mergeCommit,mergedAt,url
55+
```
56+
57+
If the user said the workflow failed, fetch its log to see exactly which command failed and which file conflicted:
58+
59+
```
60+
gh run list --workflow=cherry_pick.yml --limit 10 --json databaseId,displayTitle,status,conclusion
61+
gh run view <failed_run_id> --log-failed
62+
```
63+
64+
The failed-run log also confirms the `BRANCH` and `COMMIT` the workflow used — handy if there's any ambiguity.
65+
66+
### 2. Reproduce the script's setup locally
67+
68+
The repository may be a worktree (check `.git` — if it's a file, you're in a worktree pointing at a shared gitdir). That's fine; just operate normally.
69+
70+
```
71+
git --no-pager fetch origin <branch-name> <commit-sha>
72+
git checkout --force origin/<branch-name> -B cherry-pick-<branch-name>-<short-sha>
73+
git cherry-pick <commit-sha>
74+
```
75+
76+
The branch name **must** match `cherry-pick-<branch-name>-<short-sha>` exactly (script convention; reviewers and tooling expect it).
77+
78+
### 3. Check for missing prerequisite cherry-picks
79+
80+
If the cherry-pick conflicts, do not immediately resolve the conflicts manually.
81+
82+
First determine whether the conflict is likely caused by other PRs or commits that are already on `main` but missing from the release branch. If so, point out those candidate prerequisite PRs/commits to the user, including PR links, and offer to either resolve the conflicts manually or let the user run the GitHub cherry-pick workflow for those commits first.
83+
84+
If the user wants to run the workflow for the missing prerequisites, stop here. This often keeps cherry-picks clean and eligible for automatic approval.
85+
86+
Only resolve conflicts manually if:
87+
- no likely missing prerequisites are found, or
88+
- the user chooses manual conflict resolution instead of cherry-picking the prerequisites first.
89+
90+
### 4. Resolve the conflicts manually
91+
92+
Do this only after checking for missing prerequisite cherry-picks.
93+
94+
- Inspect every conflicted file with `grep -n '<<<<<<<\\|>>>>>>>\\|=======' <path>` to find the markers.
95+
- Conflicts are usually `diff3` style with three sections: HEAD (release branch), `||||||| parent of <sha>` (merge base on `main`), and the incoming change.
96+
- Read the **original commit** (`git --no-pager show <commit-sha> -- <path>`) to understand the author's intent, then pick the resolution that produces the equivalent end state on the release branch.
97+
- Don't grab unrelated changes from `main` that happen to surround the conflict — keep the cherry-pick minimal.
98+
99+
### 5. Validate
100+
101+
Always build and (if reasonable) test the affected crate(s) before continuing the cherry-pick.
102+
103+
```
104+
cargo check -p <affected_crate>
105+
cargo test -p <affected_crate>
106+
```
107+
108+
If validation fails, fix the resolution — do **not** continue with a broken build. If you can't reach a clean state, abort with `git cherry-pick --abort` and report back to the user.
109+
110+
### 6. Finish the cherry-pick
111+
112+
`git cherry-pick --continue` opens an editor by default. Prevent that:
113+
114+
```
115+
git add <resolved_files>
116+
GIT_EDITOR=true git cherry-pick --continue
117+
```
118+
119+
This preserves the original commit message verbatim, which is what the script does.
120+
121+
### 7. Push and open the PR
122+
123+
```
124+
git push origin -f cherry-pick-<branch-name>-<short-sha>
125+
```
126+
127+
Then create the PR with the **exact** title and body format `script/cherry-pick` uses, so it's indistinguishable from an automated one.
128+
129+
**Title:**
130+
131+
```
132+
<original commit subject> (cherry-pick to <channel>)
133+
```
134+
135+
The original commit subject already ends in ` (#<original_pr_number>)`; keep it.
136+
137+
**Body** (when the original commit title ends in `(#<N>)`, which is the normal case):
138+
139+
```
140+
Cherry-pick of #<original_pr_number> to <channel>
141+
142+
----
143+
<original commit body, verbatim>
144+
```
145+
146+
Create it with `gh pr create`, writing the body to a temp file to keep formatting intact:
147+
148+
```
149+
git --no-pager log -1 --pretty=format:"%b" > /tmp/cp-body-tail.md
150+
printf 'Cherry-pick of #%s to %s\n\n----\n' <PR_NUMBER> <channel> | cat - /tmp/cp-body-tail.md > /tmp/cp-body.md
151+
gh pr create --base <branch-name> --head cherry-pick-<branch-name>-<short-sha> \\
152+
--title "<commit subject> (cherry-pick to <channel>)" \\
153+
--body-file /tmp/cp-body.md
154+
```
155+
156+
Do **not** add a `Release Notes:` section — the original commit body already has one (or already says `N/A`), and you don't want it duplicated.
157+
158+
## Final report to the user
159+
160+
Tell the user:
161+
- The new PR URL.
162+
- A one-line summary of the conflict and how you resolved it.
163+
- What validation you ran (commands + result).
164+
- That their local branch is now `cherry-pick-<branch-name>-<short-sha>`, in case they want you to switch back.
165+
166+
## Gotchas
167+
168+
- **`--no-pager` and `GIT_EDITOR=true`**: required for non-interactive git in this environment. Forgetting `GIT_EDITOR=true` on `cherry-pick --continue` hangs the terminal.
169+
- **Worktree index lock**: if a previous git command was interrupted, you may see `index.lock` errors. The lock lives at `<gitdir>/index.lock` where `<gitdir>` is what `cat .git` points to (for a worktree). Remove it only if you're sure no git process is running.
170+
- **Don't expand the cherry-pick's scope**: when resolving conflicts, never pull in unrelated changes from `main` just because they sit next to the conflict region. The PR should be the smallest diff that reproduces the original commit's intent on the release branch.
171+
- **Channel branches are not called `preview`/`stable`**: don't try to `git fetch origin preview`. Look up the actual `vX.Y.x` branch name first.
172+
173+
## When Finished
174+
175+
After everything is finished, the last thing to do is to provide a link to the opened pull request(s) for the cherry-pick(s).

.github/CODEOWNERS.hold

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
/crates/open_ai/ @zed-industries/ai-team
5656
/crates/open_router/ @zed-industries/ai-team
5757
/crates/prompt_store/ @zed-industries/ai-team
58-
/crates/rules_library/ @zed-industries/ai-team
5958
# SUGGESTED: Review needed - based on Richard Feldman (2 commits)
6059
/crates/shell_command_parser/ @zed-industries/ai-team
6160
/crates/vercel/ @zed-industries/ai-team
@@ -181,7 +180,6 @@
181180
/crates/fs_benchmarks/ @zed-industries/infrastructure-team
182181
/crates/http_client/ @zed-industries/infrastructure-team
183182
/crates/http_client_tls/ @zed-industries/infrastructure-team
184-
/crates/nc/ @zed-industries/infrastructure-team
185183
/crates/net/ @zed-industries/infrastructure-team
186184
/crates/paths/ @zed-industries/infrastructure-team
187185
/crates/release_channel/ @zed-industries/infrastructure-team

.github/workflows/after_release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ jobs:
4444
uses: zed-industries/zed/.github/workflows/deploy_docs.yml@main
4545
secrets:
4646
DOCS_AMPLITUDE_API_KEY: ${{ secrets.DOCS_AMPLITUDE_API_KEY }}
47+
DOCS_CONSENT_IO_INSTANCE: ${{ secrets.DOCS_CONSENT_IO_INSTANCE }}
4748
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
4849
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
4950
with:

.github/workflows/autofix_pr.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ jobs:
7474
git diff > autofix.patch
7575
echo "has_changes=true" >> "$GITHUB_OUTPUT"
7676
fi
77-
- name: upload artifact autofix-patch
78-
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4
77+
- name: autofix_pr::upload_patch_artifact
78+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
7979
with:
8080
name: autofix-patch
8181
path: autofix.patch
@@ -112,7 +112,7 @@ jobs:
112112
PR_NUMBER: ${{ inputs.pr_number }}
113113
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
114114
- name: autofix_pr::download_patch_artifact
115-
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
115+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
116116
with:
117117
name: autofix-patch
118118
- name: autofix_pr::commit_changes::apply_patch
@@ -122,10 +122,10 @@ jobs:
122122
git commit -am "Autofix"
123123
git push
124124
env:
125-
GIT_COMMITTER_NAME: Zed Zippy
126-
GIT_COMMITTER_EMAIL: 234243425+zed-zippy[bot]@users.noreply.github.com
127-
GIT_AUTHOR_NAME: Zed Zippy
125+
GIT_AUTHOR_NAME: zed-zippy[bot]
128126
GIT_AUTHOR_EMAIL: 234243425+zed-zippy[bot]@users.noreply.github.com
127+
GIT_COMMITTER_NAME: zed-zippy[bot]
128+
GIT_COMMITTER_EMAIL: 234243425+zed-zippy[bot]@users.noreply.github.com
129129
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
130130
concurrency:
131131
group: ${{ github.workflow }}-${{ inputs.pr_number }}

0 commit comments

Comments
 (0)