ci.yml

  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@11bd71901bbe5b1630ceea73d27597364c9af683 # 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 FIX​ME 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 }}