1name: CI
2
3on:
4 push:
5 branches:
6 - main
7 - "v[0-9]+.[0-9]+.x"
8 tags:
9 - "v*"
10 pull_request:
11 branches:
12 - "**"
13 merge_group:
14
15concurrency:
16 # Allow only one workflow per any non-`main` branch.
17 group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}
18 cancel-in-progress: true
19
20env:
21 CARGO_TERM_COLOR: always
22 CARGO_INCREMENTAL: 0
23 RUST_BACKTRACE: 1
24 RUSTFLAGS: "-D warnings"
25
26jobs:
27 check_docs_only:
28 runs-on: ubuntu-latest
29 outputs:
30 docs_only: ${{ steps.check_changes.outputs.docs_only }}
31 steps:
32 - uses: actions/checkout@v4
33 with:
34 fetch-depth: 0
35 - name: Check for non-docs changes
36 id: check_changes
37 run: |
38 if git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep -qvE '^docs/'; then
39 echo "docs_only=false" >> $GITHUB_OUTPUT
40 else
41 echo "docs_only=true" >> $GITHUB_OUTPUT
42 fi
43
44 migration_checks:
45 name: Check Postgres and Protobuf migrations, mergability
46 if: github.repository_owner == 'zed-industries'
47 timeout-minutes: 60
48 runs-on:
49 - self-hosted
50 - test
51 steps:
52 - name: Checkout repo
53 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
54 with:
55 clean: false
56 fetch-depth: 0 # fetch full history
57
58 - name: Remove untracked files
59 run: git clean -df
60
61 - name: Find modified migrations
62 shell: bash -euxo pipefail {0}
63 run: |
64 export SQUAWK_GITHUB_TOKEN=${{ github.token }}
65 . ./script/squawk
66
67 - name: Ensure fresh merge
68 shell: bash -euxo pipefail {0}
69 run: |
70 if [ -z "$GITHUB_BASE_REF" ];
71 then
72 echo "BUF_BASE_BRANCH=$(git merge-base origin/main HEAD)" >> $GITHUB_ENV
73 else
74 git checkout -B temp
75 git merge -q origin/$GITHUB_BASE_REF -m "merge main into temp"
76 echo "BUF_BASE_BRANCH=$GITHUB_BASE_REF" >> $GITHUB_ENV
77 fi
78
79 - uses: bufbuild/buf-setup-action@v1
80 with:
81 version: v1.29.0
82 - uses: bufbuild/buf-breaking-action@v1
83 with:
84 input: "crates/proto/proto/"
85 against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/proto/proto/"
86
87 style:
88 timeout-minutes: 60
89 name: Check formatting and spelling
90 if: github.repository_owner == 'zed-industries'
91 runs-on:
92 - buildjet-8vcpu-ubuntu-2204
93 steps:
94 - name: Checkout repo
95 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
96
97 # To support writing comments that they will certainly be revisited.
98 - name: Check for todo! and FIXME comments
99 run: script/check-todos
100
101 - name: Run style checks
102 uses: ./.github/actions/check_style
103
104 - name: Check for typos
105 uses: crate-ci/typos@8e6a4285bcbde632c5d79900a7779746e8b7ea3f # v1.24.6
106 with:
107 config: ./typos.toml
108
109 macos_tests:
110 timeout-minutes: 60
111 name: (macOS) Run Clippy and tests
112 if: github.repository_owner == 'zed-industries'
113 runs-on:
114 - self-hosted
115 - test
116 needs: check_docs_only
117 steps:
118 - name: Checkout repo
119 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
120 with:
121 clean: false
122
123 - name: cargo clippy
124 if: needs.check_docs_only.outputs.docs_only == 'false'
125 run: ./script/clippy
126
127 - name: Check unused dependencies
128 if: needs.check_docs_only.outputs.docs_only == 'false'
129 uses: bnjbvr/cargo-machete@main
130
131 - name: Check licenses
132 if: needs.check_docs_only.outputs.docs_only == 'false'
133 run: |
134 script/check-licenses
135 script/generate-licenses /tmp/zed_licenses_output
136
137 - name: Check for new vulnerable dependencies
138 if: github.event_name == 'pull_request' && needs.check_docs_only.outputs.docs_only == 'false'
139 uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4
140 with:
141 license-check: false
142
143 - name: Run tests
144 if: needs.check_docs_only.outputs.docs_only == 'false'
145 uses: ./.github/actions/run_tests
146
147 - name: Build collab
148 if: needs.check_docs_only.outputs.docs_only == 'false'
149 run: cargo build -p collab
150
151 - name: Build other binaries and features
152 if: needs.check_docs_only.outputs.docs_only == 'false'
153 run: |
154 cargo build --workspace --bins --all-features
155 cargo check -p gpui --features "macos-blade"
156 cargo check -p workspace
157 cargo build -p remote_server
158 script/check-rust-livekit-macos
159
160 linux_tests:
161 timeout-minutes: 60
162 name: (Linux) Run Clippy and tests
163 if: github.repository_owner == 'zed-industries'
164 runs-on:
165 - buildjet-16vcpu-ubuntu-2204
166 needs: check_docs_only
167 steps:
168 - name: Add Rust to the PATH
169 run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
170
171 - name: Checkout repo
172 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
173 with:
174 clean: false
175
176 - name: Cache dependencies
177 if: needs.check_docs_only.outputs.docs_only == 'false'
178 uses: swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2
179 with:
180 save-if: ${{ github.ref == 'refs/heads/main' }}
181 cache-provider: "buildjet"
182
183 - name: Install Linux dependencies
184 if: needs.check_docs_only.outputs.docs_only == 'false'
185 run: ./script/linux
186
187 - name: cargo clippy
188 if: needs.check_docs_only.outputs.docs_only == 'false'
189 run: ./script/clippy
190
191 - name: Run tests
192 if: needs.check_docs_only.outputs.docs_only == 'false'
193 uses: ./.github/actions/run_tests
194
195 - name: Build other binaries and features
196 if: needs.check_docs_only.outputs.docs_only == 'false'
197 run: |
198 cargo build -p zed
199 cargo check -p workspace
200
201 build_remote_server:
202 timeout-minutes: 60
203 name: (Linux) Build Remote Server
204 if: github.repository_owner == 'zed-industries'
205 runs-on:
206 - buildjet-16vcpu-ubuntu-2204
207 needs: check_docs_only
208 steps:
209 - name: Add Rust to the PATH
210 run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
211
212 - name: Checkout repo
213 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
214 with:
215 clean: false
216
217 - name: Cache dependencies
218 if: needs.check_docs_only.outputs.docs_only == 'false'
219 uses: swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2
220 with:
221 save-if: ${{ github.ref == 'refs/heads/main' }}
222 cache-provider: "buildjet"
223
224 - name: Install Clang & Mold
225 if: needs.check_docs_only.outputs.docs_only == 'false'
226 run: ./script/remote-server && ./script/install-mold 2.34.0
227
228 - name: Build Remote Server
229 if: needs.check_docs_only.outputs.docs_only == 'false'
230 run: cargo build -p remote_server
231
232 # todo(windows): Actually run the tests
233 windows_tests:
234 timeout-minutes: 60
235 name: (Windows) Run Clippy and tests
236 if: github.repository_owner == 'zed-industries'
237 runs-on: hosted-windows-1
238 needs: check_docs_only
239 steps:
240 # more info here:- https://github.com/rust-lang/cargo/issues/13020
241 - name: Enable longer pathnames for git
242 run: git config --system core.longpaths true
243 - name: Checkout repo
244 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
245 with:
246 clean: false
247
248 - name: Cache dependencies
249 if: needs.check_docs_only.outputs.docs_only == 'false'
250 uses: swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2
251 with:
252 save-if: ${{ github.ref == 'refs/heads/main' }}
253 cache-provider: "github"
254
255 - name: cargo clippy
256 if: needs.check_docs_only.outputs.docs_only == 'false'
257 # Windows can't run shell scripts, so we need to use `cargo xtask`.
258 run: cargo xtask clippy
259
260 - name: Build Zed
261 if: needs.check_docs_only.outputs.docs_only == 'false'
262 run: cargo build
263
264 bundle-mac:
265 timeout-minutes: 60
266 name: Create a macOS bundle
267 runs-on:
268 - self-hosted
269 - bundle
270 if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
271 needs: [macos_tests]
272 env:
273 MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
274 MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
275 APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
276 APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
277 ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
278 ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
279 DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
280 DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
281 steps:
282 - name: Install Node
283 uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
284 with:
285 node-version: "18"
286
287 - name: Checkout repo
288 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
289 with:
290 # We need to fetch more than one commit so that `script/draft-release-notes`
291 # is able to diff between the current and previous tag.
292 #
293 # 25 was chosen arbitrarily.
294 fetch-depth: 25
295 clean: false
296 ref: ${{ github.ref }}
297
298 - name: Limit target directory size
299 run: script/clear-target-dir-if-larger-than 100
300
301 - name: Determine version and release channel
302 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
303 run: |
304 # This exports RELEASE_CHANNEL into env (GITHUB_ENV)
305 script/determine-release-channel
306
307 - name: Draft release notes
308 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
309 run: |
310 mkdir -p target/
311 # Ignore any errors that occur while drafting release notes to not fail the build.
312 script/draft-release-notes "$RELEASE_VERSION" "$RELEASE_CHANNEL" > target/release-notes.md || true
313 script/create-draft-release target/release-notes.md
314 env:
315 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
316
317 - name: Generate license file
318 run: script/generate-licenses
319
320 - name: Create macOS app bundle
321 run: script/bundle-mac
322
323 - name: Rename binaries
324 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
325 run: |
326 mv target/aarch64-apple-darwin/release/Zed.dmg target/aarch64-apple-darwin/release/Zed-aarch64.dmg
327 mv target/x86_64-apple-darwin/release/Zed.dmg target/x86_64-apple-darwin/release/Zed-x86_64.dmg
328
329 - name: Upload app bundle (aarch64) to workflow run if main branch or specific label
330 uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4
331 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
332 with:
333 name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg
334 path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg
335
336 - name: Upload app bundle (x86_64) to workflow run if main branch or specific label
337 uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4
338 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
339 with:
340 name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg
341 path: target/x86_64-apple-darwin/release/Zed-x86_64.dmg
342
343 - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
344 name: Upload app bundle to release
345 if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
346 with:
347 draft: true
348 prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
349 files: |
350 target/zed-remote-server-macos-x86_64.gz
351 target/zed-remote-server-macos-aarch64.gz
352 target/aarch64-apple-darwin/release/Zed-aarch64.dmg
353 target/x86_64-apple-darwin/release/Zed-x86_64.dmg
354 env:
355 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
356
357 bundle-linux:
358 timeout-minutes: 60
359 name: Create a Linux bundle
360 runs-on:
361 - buildjet-16vcpu-ubuntu-2004
362 if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
363 needs: [linux_tests]
364 env:
365 ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
366 ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
367 DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
368 DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
369 steps:
370 - name: Checkout repo
371 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
372 with:
373 clean: false
374
375 - name: Install Linux dependencies
376 run: ./script/linux && ./script/install-mold 2.34.0
377
378 - name: Determine version and release channel
379 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
380 run: |
381 # This exports RELEASE_CHANNEL into env (GITHUB_ENV)
382 script/determine-release-channel
383
384 - name: Create Linux .tar.gz bundle
385 run: script/bundle-linux
386
387 - name: Upload Linux bundle to workflow run if main branch or specific label
388 uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4
389 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
390 with:
391 name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz
392 path: target/release/zed-*.tar.gz
393
394 - name: Upload app bundle to release
395 uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
396 with:
397 draft: true
398 prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
399 files: |
400 target/zed-remote-server-linux-x86_64.gz
401 target/release/zed-linux-x86_64.tar.gz
402 env:
403 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
404
405 bundle-linux-aarch64: # this runs on ubuntu22.04
406 timeout-minutes: 60
407 name: Create arm64 Linux bundle
408 runs-on:
409 - buildjet-16vcpu-ubuntu-2204-arm
410 if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
411 needs: [linux_tests]
412 env:
413 ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
414 ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
415 DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
416 DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
417 steps:
418 - name: Checkout repo
419 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
420 with:
421 clean: false
422
423 - name: Install Linux dependencies
424 run: ./script/linux
425
426 - name: Determine version and release channel
427 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
428 run: |
429 # This exports RELEASE_CHANNEL into env (GITHUB_ENV)
430 script/determine-release-channel
431
432 - name: Create and upload Linux .tar.gz bundle
433 run: script/bundle-linux
434
435 - name: Upload Linux bundle to workflow run if main branch or specific label
436 uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4
437 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
438 with:
439 name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz
440 path: target/release/zed-*.tar.gz
441
442 - name: Upload app bundle to release
443 uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
444 with:
445 draft: true
446 prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
447 files: |
448 target/zed-remote-server-linux-aarch64.gz
449 target/release/zed-linux-aarch64.tar.gz
450 env:
451 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
452
453 auto-release-preview:
454 name: Auto release preview
455 if: ${{ startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '-pre') && !endsWith(github.ref, '.0-pre') }}
456 needs: [bundle-mac, bundle-linux, bundle-linux-aarch64]
457 runs-on:
458 - self-hosted
459 - bundle
460 steps:
461 - name: gh release
462 run: gh release edit $GITHUB_REF_NAME --draft=false
463 env:
464 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}