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
14concurrency:
15 # Allow only one workflow per any non-`main` branch.
16 group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}
17 cancel-in-progress: true
18
19env:
20 CARGO_TERM_COLOR: always
21 CARGO_INCREMENTAL: 0
22 RUST_BACKTRACE: 1
23
24jobs:
25 style:
26 timeout-minutes: 60
27 name: Check formatting and spelling
28 runs-on:
29 - self-hosted
30 - test
31 steps:
32 - name: Checkout repo
33 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
34 with:
35 clean: false
36 fetch-depth: 0
37
38 - name: Remove untracked files
39 run: git clean -df
40
41 - name: Check spelling
42 run: |
43 if ! cargo install --list | grep "typos-cli v$TYPOS_CLI_VERSION" > /dev/null; then
44 echo "Installing typos-cli@$TYPOS_CLI_VERSION..."
45 cargo install "typos-cli@$TYPOS_CLI_VERSION"
46 else
47 echo "typos-cli@$TYPOS_CLI_VERSION is already installed."
48 fi
49 typos
50 env:
51 TYPOS_CLI_VERSION: "1.23.3"
52
53 - name: Run style checks
54 uses: ./.github/actions/check_style
55
56 - name: Check unused dependencies
57 uses: bnjbvr/cargo-machete@main
58
59 - name: Check licenses are present
60 run: script/check-licenses
61
62 - name: Check license generation
63 run: script/generate-licenses /tmp/zed_licenses_output
64
65 - name: Ensure fresh merge
66 shell: bash -euxo pipefail {0}
67 run: |
68 if [ -z "$GITHUB_BASE_REF" ];
69 then
70 echo "BUF_BASE_BRANCH=$(git merge-base origin/main HEAD)" >> $GITHUB_ENV
71 else
72 git checkout -B temp
73 git merge -q origin/$GITHUB_BASE_REF -m "merge main into temp"
74 echo "BUF_BASE_BRANCH=$GITHUB_BASE_REF" >> $GITHUB_ENV
75 fi
76
77 - uses: bufbuild/buf-setup-action@v1
78 with:
79 version: v1.29.0
80 - uses: bufbuild/buf-breaking-action@v1
81 with:
82 input: "crates/proto/proto/"
83 against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/proto/proto/"
84
85 macos_tests:
86 timeout-minutes: 60
87 name: (macOS) Run Clippy and tests
88 runs-on:
89 - self-hosted
90 - test
91 steps:
92 - name: Checkout repo
93 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
94 with:
95 clean: false
96
97 - name: cargo clippy
98 run: ./script/clippy
99
100 - name: Run tests
101 uses: ./.github/actions/run_tests
102
103 - name: Build collab
104 run: cargo build -p collab
105
106 - name: Build other binaries and features
107 run: cargo build --workspace --bins --all-features; cargo check -p gpui --features "macos-blade"
108
109 linux_tests:
110 timeout-minutes: 60
111 name: (Linux) Run Clippy and tests
112 runs-on:
113 - self-hosted
114 - deploy
115 steps:
116 - name: Add Rust to the PATH
117 run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
118
119 - name: Checkout repo
120 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
121 with:
122 clean: false
123
124 - name: cargo clippy
125 run: ./script/clippy
126
127 - name: Run tests
128 uses: ./.github/actions/run_tests
129
130 - name: Build Zed
131 run: cargo build -p zed
132
133 # todo(windows): Actually run the tests
134 windows_tests:
135 timeout-minutes: 60
136 name: (Windows) Run Clippy and tests
137 runs-on: hosted-windows-1
138 steps:
139 - name: Checkout repo
140 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
141 with:
142 clean: false
143
144 - name: Cache dependencies
145 uses: swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2
146 with:
147 save-if: ${{ github.ref == 'refs/heads/main' }}
148
149 - name: cargo clippy
150 # Windows can't run shell scripts, so we need to use `cargo xtask`.
151 run: cargo xtask clippy
152
153 - name: Build Zed
154 run: cargo build -p zed
155
156 bundle-mac:
157 timeout-minutes: 60
158 name: Create a macOS bundle
159 runs-on:
160 - self-hosted
161 - bundle
162 if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
163 needs: [macos_tests]
164 env:
165 MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
166 MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
167 APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
168 APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
169 ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
170 ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
171 DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
172 DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
173 steps:
174 - name: Install Node
175 uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
176 with:
177 node-version: "18"
178
179 - name: Checkout repo
180 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
181 with:
182 # We need to fetch more than one commit so that `script/draft-release-notes`
183 # is able to diff between the current and previous tag.
184 #
185 # 25 was chosen arbitrarily.
186 fetch-depth: 25
187 clean: false
188
189 - name: Limit target directory size
190 run: script/clear-target-dir-if-larger-than 100
191
192 - name: Determine version and release channel
193 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
194 run: |
195 set -eu
196
197 version=$(script/get-crate-version zed)
198 channel=$(cat crates/zed/RELEASE_CHANNEL)
199 echo "Publishing version: ${version} on release channel ${channel}"
200 echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
201
202 expected_tag_name=""
203 case ${channel} in
204 stable)
205 expected_tag_name="v${version}";;
206 preview)
207 expected_tag_name="v${version}-pre";;
208 nightly)
209 expected_tag_name="v${version}-nightly";;
210 *)
211 echo "can't publish a release on channel ${channel}"
212 exit 1;;
213 esac
214 if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
215 echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
216 exit 1
217 fi
218 mkdir -p target/
219 # Ignore any errors that occur while drafting release notes to not fail the build.
220 script/draft-release-notes "$version" "$channel" > target/release-notes.md || true
221
222 - name: Generate license file
223 run: script/generate-licenses
224
225 - name: Create macOS app bundle
226 run: script/bundle-mac
227
228 - name: Rename single-architecture binaries
229 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
230 run: |
231 mv target/aarch64-apple-darwin/release/Zed.dmg target/aarch64-apple-darwin/release/Zed-aarch64.dmg
232 mv target/x86_64-apple-darwin/release/Zed.dmg target/x86_64-apple-darwin/release/Zed-x86_64.dmg
233
234 - name: Upload app bundle (universal) to workflow run if main branch or specific label
235 uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
236 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
237 with:
238 name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.dmg
239 path: target/release/Zed.dmg
240 - name: Upload app bundle (aarch64) to workflow run if main branch or specific label
241 uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
242 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
243 with:
244 name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg
245 path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg
246
247 - name: Upload app bundle (x86_64) to workflow run if main branch or specific label
248 uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
249 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
250 with:
251 name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg
252 path: target/x86_64-apple-darwin/release/Zed-x86_64.dmg
253
254 - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
255 name: Upload app bundle to release
256 if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
257 with:
258 draft: true
259 prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
260 files: |
261 target/zed-remote-server-macos-x86_64.gz
262 target/zed-remote-server-macos-aarch64.gz
263 target/aarch64-apple-darwin/release/Zed-aarch64.dmg
264 target/x86_64-apple-darwin/release/Zed-x86_64.dmg
265 target/release/Zed.dmg
266 body_path: target/release-notes.md
267 env:
268 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
269
270 bundle-linux:
271 timeout-minutes: 60
272 name: Create a Linux bundle
273 runs-on:
274 - self-hosted
275 - deploy
276 if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
277 needs: [linux_tests]
278 env:
279 ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
280 ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
281 steps:
282 - name: Add Rust to the PATH
283 run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
284
285 - name: Checkout repo
286 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
287 with:
288 clean: false
289
290 - name: Limit target directory size
291 run: script/clear-target-dir-if-larger-than 100
292
293 - name: Determine version and release channel
294 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
295 run: |
296 set -eu
297
298 version=$(script/get-crate-version zed)
299 channel=$(cat crates/zed/RELEASE_CHANNEL)
300 echo "Publishing version: ${version} on release channel ${channel}"
301 echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
302
303 expected_tag_name=""
304 case ${channel} in
305 stable)
306 expected_tag_name="v${version}";;
307 preview)
308 expected_tag_name="v${version}-pre";;
309 nightly)
310 expected_tag_name="v${version}-nightly";;
311 *)
312 echo "can't publish a release on channel ${channel}"
313 exit 1;;
314 esac
315 if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
316 echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
317 exit 1
318 fi
319
320 - name: Create Linux .tar.gz bundle
321 run: script/bundle-linux
322
323 - name: Upload Linux bundle to workflow run if main branch or specific label
324 uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
325 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
326 with:
327 name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz
328 path: target/release/zed-*.tar.gz
329
330 - name: Upload app bundle to release
331 uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
332 with:
333 draft: true
334 prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
335 files: |
336 target/zed-remote-server-linux-x86_64.gz
337 target/release/zed-linux-x86_64.tar.gz
338 body: ""
339 env:
340 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
341
342 bundle-linux-aarch64: # this runs on ubuntu22.04
343 timeout-minutes: 60
344 name: Create arm64 Linux bundle
345 runs-on:
346 - hosted-linux-arm-1
347 if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
348 needs: [linux_tests]
349 env:
350 ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
351 ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
352 steps:
353 - name: Checkout repo
354 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
355 with:
356 clean: false
357 - name: "Setup jq"
358 uses: dcarbone/install-jq-action@8867ddb4788346d7c22b72ea2e2ffe4d514c7bcb # v2
359
360 - name: Set up Clang
361 run: |
362 sudo apt-get update
363 sudo apt-get install -y llvm-15 clang-15 build-essential cmake pkg-config libasound2-dev libfontconfig-dev libwayland-dev libxkbcommon-x11-dev libssl-dev libsqlite3-dev libzstd-dev libvulkan1 libgit2-dev
364 echo "/usr/lib/llvm-15/bin" >> $GITHUB_PATH
365
366 - uses: rui314/setup-mold@0bf4f07ef9048ec62a45f9dbf2f098afa49695f0 # v1
367 with:
368 mold-version: 2.32.0
369
370 - name: rustup
371 run: |
372 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
373 echo "$HOME/.cargo/bin" >> $GITHUB_PATH
374
375 - name: Limit target directory size
376 run: script/clear-target-dir-if-larger-than 100
377
378 - name: Determine version and release channel
379 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
380 run: |
381 set -eu
382
383 version=$(script/get-crate-version zed)
384 channel=$(cat crates/zed/RELEASE_CHANNEL)
385 echo "Publishing version: ${version} on release channel ${channel}"
386 echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
387
388 expected_tag_name=""
389 case ${channel} in
390 stable)
391 expected_tag_name="v${version}";;
392 preview)
393 expected_tag_name="v${version}-pre";;
394 nightly)
395 expected_tag_name="v${version}-nightly";;
396 *)
397 echo "can't publish a release on channel ${channel}"
398 exit 1;;
399 esac
400 if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
401 echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
402 exit 1
403 fi
404
405 - name: Create and upload Linux .tar.gz bundle
406 run: script/bundle-linux
407
408 - name: Upload Linux bundle to workflow run if main branch or specific label
409 uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
410 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
411 with:
412 name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz
413 path: target/release/zed-*.tar.gz
414
415 - name: Upload app bundle to release
416 uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
417 if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
418 with:
419 draft: true
420 prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
421 files: |
422 target/zed-remote-server-linux-aarch64.gz
423 target/release/zed-linux-aarch64.tar.gz
424 body: ""
425 env:
426 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}