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 DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
171 DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
172 steps:
173 - name: Install Node
174 uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
175 with:
176 node-version: "18"
177
178 - name: Checkout repo
179 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
180 with:
181 # We need to fetch more than one commit so that `script/draft-release-notes`
182 # is able to diff between the current and previous tag.
183 #
184 # 25 was chosen arbitrarily.
185 fetch-depth: 25
186 clean: false
187
188 - name: Limit target directory size
189 run: script/clear-target-dir-if-larger-than 100
190
191 - name: Determine version and release channel
192 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
193 run: |
194 set -eu
195
196 version=$(script/get-crate-version zed)
197 channel=$(cat crates/zed/RELEASE_CHANNEL)
198 echo "Publishing version: ${version} on release channel ${channel}"
199 echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
200
201 expected_tag_name=""
202 case ${channel} in
203 stable)
204 expected_tag_name="v${version}";;
205 preview)
206 expected_tag_name="v${version}-pre";;
207 nightly)
208 expected_tag_name="v${version}-nightly";;
209 *)
210 echo "can't publish a release on channel ${channel}"
211 exit 1;;
212 esac
213 if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
214 echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
215 exit 1
216 fi
217 mkdir -p target/
218 # Ignore any errors that occur while drafting release notes to not fail the build.
219 script/draft-release-notes "$version" "$channel" > target/release-notes.md || true
220
221 - name: Generate license file
222 run: script/generate-licenses
223
224 - name: Create macOS app bundle
225 run: script/bundle-mac
226
227 - name: Rename single-architecture binaries
228 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
229 run: |
230 mv target/aarch64-apple-darwin/release/Zed.dmg target/aarch64-apple-darwin/release/Zed-aarch64.dmg
231 mv target/x86_64-apple-darwin/release/Zed.dmg target/x86_64-apple-darwin/release/Zed-x86_64.dmg
232
233 - name: Upload app bundle (universal) to workflow run if main branch or specific label
234 uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4
235 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
236 with:
237 name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.dmg
238 path: target/release/Zed.dmg
239 - name: Upload app bundle (aarch64) to workflow run if main branch or specific label
240 uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4
241 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
242 with:
243 name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg
244 path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg
245
246 - name: Upload app bundle (x86_64) to workflow run if main branch or specific label
247 uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4
248 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
249 with:
250 name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg
251 path: target/x86_64-apple-darwin/release/Zed-x86_64.dmg
252
253 - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
254 name: Upload app bundle to release
255 if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
256 with:
257 draft: true
258 prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
259 files: |
260 target/zed-remote-server-macos-x86_64.gz
261 target/zed-remote-server-macos-aarch64.gz
262 target/aarch64-apple-darwin/release/Zed-aarch64.dmg
263 target/x86_64-apple-darwin/release/Zed-x86_64.dmg
264 target/release/Zed.dmg
265 body_path: target/release-notes.md
266 env:
267 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
268
269 bundle-linux:
270 timeout-minutes: 60
271 name: Create a Linux bundle
272 runs-on:
273 - self-hosted
274 - deploy
275 if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
276 needs: [linux_tests]
277 env:
278 ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
279 steps:
280 - name: Add Rust to the PATH
281 run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
282
283 - name: Checkout repo
284 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
285 with:
286 clean: false
287
288 - name: Limit target directory size
289 run: script/clear-target-dir-if-larger-than 100
290
291 - name: Determine version and release channel
292 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
293 run: |
294 set -eu
295
296 version=$(script/get-crate-version zed)
297 channel=$(cat crates/zed/RELEASE_CHANNEL)
298 echo "Publishing version: ${version} on release channel ${channel}"
299 echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
300
301 expected_tag_name=""
302 case ${channel} in
303 stable)
304 expected_tag_name="v${version}";;
305 preview)
306 expected_tag_name="v${version}-pre";;
307 nightly)
308 expected_tag_name="v${version}-nightly";;
309 *)
310 echo "can't publish a release on channel ${channel}"
311 exit 1;;
312 esac
313 if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
314 echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
315 exit 1
316 fi
317
318 - name: Create Linux .tar.gz bundle
319 run: script/bundle-linux
320
321 - name: Upload Linux bundle to workflow run if main branch or specific label
322 uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4
323 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
324 with:
325 name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz
326 path: target/release/zed-*.tar.gz
327
328 - name: Upload app bundle to release
329 uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
330 with:
331 draft: true
332 prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
333 files: |
334 target/zed-remote-server-linux-x86_64.gz
335 target/release/zed-linux-x86_64.tar.gz
336 body: ""
337 env:
338 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
339
340 bundle-linux-aarch64:
341 timeout-minutes: 60
342 name: Create arm64 Linux bundle
343 runs-on:
344 - hosted-linux-arm-1
345 if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
346 needs: [linux_tests]
347 env:
348 ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
349 steps:
350 - name: Checkout repo
351 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
352 with:
353 clean: false
354 - name: "Setup jq"
355 uses: dcarbone/install-jq-action@8867ddb4788346d7c22b72ea2e2ffe4d514c7bcb # v2
356
357 - name: Set up Clang
358 run: |
359 sudo apt-get update
360 sudo apt-get install -y llvm-10 clang-10 build-essential cmake pkg-config libasound2-dev libfontconfig-dev libwayland-dev libxkbcommon-x11-dev libssl-dev libsqlite3-dev libzstd-dev libvulkan1 libgit2-dev
361 echo "/usr/lib/llvm-10/bin" >> $GITHUB_PATH
362
363 - uses: rui314/setup-mold@2e332a0b602c2fc65d2d3995941b1b29a5f554a0 # v1
364 with:
365 mold-version: 2.32.0
366
367 - name: rustup
368 run: |
369 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
370 echo "$HOME/.cargo/bin" >> $GITHUB_PATH
371
372 - name: Limit target directory size
373 run: script/clear-target-dir-if-larger-than 100
374
375 - name: Determine version and release channel
376 if: ${{ startsWith(github.ref, 'refs/tags/v') }}
377 run: |
378 set -eu
379
380 version=$(script/get-crate-version zed)
381 channel=$(cat crates/zed/RELEASE_CHANNEL)
382 echo "Publishing version: ${version} on release channel ${channel}"
383 echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
384
385 expected_tag_name=""
386 case ${channel} in
387 stable)
388 expected_tag_name="v${version}";;
389 preview)
390 expected_tag_name="v${version}-pre";;
391 nightly)
392 expected_tag_name="v${version}-nightly";;
393 *)
394 echo "can't publish a release on channel ${channel}"
395 exit 1;;
396 esac
397 if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
398 echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
399 exit 1
400 fi
401
402 - name: Create and upload Linux .tar.gz bundle
403 run: script/bundle-linux
404
405 - name: Upload Linux bundle to workflow run if main branch or specific label
406 uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4
407 if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
408 with:
409 name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz
410 path: target/release/zed-*.tar.gz
411
412 - name: Upload app bundle to release
413 uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
414 if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
415 with:
416 draft: true
417 prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
418 files: |
419 target/zed-remote-server-linux-aarch64.gz
420 target/release/zed-linux-aarch64.tar.gz
421 body: ""
422 env:
423 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}