ci.yml

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