ci.yml

  1name: CI
  2
  3on:
  4  push:
  5    branches:
  6      - main
  7      - "v[0-9]+.[0-9]+.x"
  8    tags:
  9      - "v*"
 10
 11  pull_request:
 12    branches:
 13      - "**"
 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
 25jobs:
 26  migration_checks:
 27    name: Check Postgres and Protobuf migrations, mergability
 28    if: github.repository_owner == 'zed-industries'
 29    timeout-minutes: 60
 30    runs-on:
 31      - self-hosted
 32      - test
 33    steps:
 34      - name: Checkout repo
 35        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
 36        with:
 37          clean: false
 38          fetch-depth: 0 # fetch full history
 39
 40      - name: Remove untracked files
 41        run: git clean -df
 42
 43      - name: Find modified migrations
 44        shell: bash -euxo pipefail {0}
 45        run: |
 46          export SQUAWK_GITHUB_TOKEN=${{ github.token }}
 47          . ./script/squawk
 48
 49      - name: Ensure fresh merge
 50        shell: bash -euxo pipefail {0}
 51        run: |
 52          if [ -z "$GITHUB_BASE_REF" ];
 53          then
 54            echo "BUF_BASE_BRANCH=$(git merge-base origin/main HEAD)" >> $GITHUB_ENV
 55          else
 56            git checkout -B temp
 57            git merge -q origin/$GITHUB_BASE_REF -m "merge main into temp"
 58            echo "BUF_BASE_BRANCH=$GITHUB_BASE_REF" >> $GITHUB_ENV
 59          fi
 60
 61      - uses: bufbuild/buf-setup-action@v1
 62        with:
 63          version: v1.29.0
 64      - uses: bufbuild/buf-breaking-action@v1
 65        with:
 66          input: "crates/proto/proto/"
 67          against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/proto/proto/"
 68
 69  style:
 70    timeout-minutes: 60
 71    name: Check formatting and spelling
 72    if: github.repository_owner == 'zed-industries'
 73    runs-on:
 74      - buildjet-8vcpu-ubuntu-2204
 75    steps:
 76      - name: Checkout repo
 77        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
 78
 79      # To support writing comments that they will certainly be revisited.
 80      - name: Check for todo! and FIXME comments
 81        run: script/check-todos
 82
 83      - name: Run style checks
 84        uses: ./.github/actions/check_style
 85
 86      - name: Check for typos
 87        uses: crate-ci/typos@8e6a4285bcbde632c5d79900a7779746e8b7ea3f # v1.24.6
 88        with:
 89          config: ./typos.toml
 90
 91  macos_tests:
 92    timeout-minutes: 60
 93    name: (macOS) Run Clippy and tests
 94    if: github.repository_owner == 'zed-industries'
 95    runs-on:
 96      - self-hosted
 97      - test
 98    steps:
 99      - name: Checkout repo
100        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
101        with:
102          clean: false
103
104      - name: Configure CI
105        run: |
106          mkdir -p ./../.cargo
107          cp ./.cargo/ci-config.toml ./../.cargo/config.toml
108
109      - name: cargo clippy
110        run: ./script/clippy
111
112      - name: Install cargo-machete
113        uses: clechasseur/rs-cargo@8435b10f6e71c2e3d4d3b7573003a8ce4bfc6386 # v2
114        with:
115          command: install
116          args: cargo-machete@0.7.0
117
118      - name: Check unused dependencies
119        uses: clechasseur/rs-cargo@8435b10f6e71c2e3d4d3b7573003a8ce4bfc6386 # v2
120        with:
121          command: machete
122
123      - name: Check licenses
124        run: |
125          script/check-licenses
126          script/generate-licenses /tmp/zed_licenses_output
127
128      - name: Check for new vulnerable dependencies
129        if: github.event_name == 'pull_request'
130        uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4
131        with:
132          license-check: false
133
134      - name: Run tests
135        uses: ./.github/actions/run_tests
136
137      - name: Build collab
138        run: cargo build -p collab
139
140      - name: Build other binaries and features
141        run: |
142          cargo build --workspace --bins --all-features
143          cargo check -p gpui --features "macos-blade"
144          cargo check -p workspace
145          cargo build -p remote_server
146          cargo check -p gpui --examples
147          script/check-rust-livekit-macos
148
149      # Since the macOS runners are stateful, so we need to remove the config file to prevent potential bug.
150      - name: Clean CI config file
151        if: always()
152        run: rm -rf ./../.cargo
153
154  linux_tests:
155    timeout-minutes: 60
156    name: (Linux) Run Clippy and tests
157    if: github.repository_owner == 'zed-industries'
158    runs-on:
159      - buildjet-16vcpu-ubuntu-2204
160    steps:
161      - name: Add Rust to the PATH
162        run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
163
164      - name: Checkout repo
165        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
166        with:
167          clean: false
168
169      - name: Cache dependencies
170        uses: swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
171        with:
172          save-if: ${{ github.ref == 'refs/heads/main' }}
173          cache-provider: "buildjet"
174
175      - name: Install Linux dependencies
176        run: ./script/linux
177
178      - name: Configure CI
179        run: |
180          mkdir -p ./../.cargo
181          cp ./.cargo/ci-config.toml ./../.cargo/config.toml
182
183      - name: cargo clippy
184        run: ./script/clippy
185
186      - name: Run tests
187        uses: ./.github/actions/run_tests
188
189      - name: Build other binaries and features
190        run: |
191          cargo build -p zed
192          cargo check -p workspace
193          cargo check -p gpui --examples
194
195      # Even the Linux runner is not stateful, in theory there is no need to do this cleanup.
196      # But, to avoid potential issues in the future if we choose to use a stateful Linux runner and forget to add code
197      # to clean up the config file, I’ve included the cleanup code here as a precaution.
198      # While it’s not strictly necessary at this moment, I believe it’s better to err on the side of caution.
199      - name: Clean CI config file
200        if: always()
201        run: rm -rf ./../.cargo
202
203  build_remote_server:
204    timeout-minutes: 60
205    name: (Linux) Build Remote Server
206    if: github.repository_owner == 'zed-industries'
207    runs-on:
208      - buildjet-16vcpu-ubuntu-2204
209    steps:
210      - name: Add Rust to the PATH
211        run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
212
213      - name: Checkout repo
214        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
215        with:
216          clean: false
217
218      - name: Cache dependencies
219        uses: swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
220        with:
221          save-if: ${{ github.ref == 'refs/heads/main' }}
222          cache-provider: "buildjet"
223
224      - name: Install Clang & Mold
225        run: ./script/remote-server && ./script/install-mold 2.34.0
226
227      - name: Configure CI
228        run: |
229          mkdir -p ./../.cargo
230          cp ./.cargo/ci-config.toml ./../.cargo/config.toml
231
232      - name: Build Remote Server
233        run: cargo build -p remote_server
234
235      - name: Clean CI config file
236        if: always()
237        run: rm -rf ./../.cargo
238
239  windows_clippy:
240    timeout-minutes: 60
241    name: (Windows) Run Clippy
242    if: github.repository_owner == 'zed-industries'
243    runs-on: hosted-windows-2
244    steps:
245      # Temporarily Collect some metadata about the hardware behind our runners.
246      - name: GHA Runner Info
247        run: |
248          Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute?api-version=2023-07-01" |
249            ConvertTo-Json -Depth 10 |
250            jq "{ vm_size: .vmSize, location: .location, os_disk_gb: (.storageProfile.osDisk.diskSizeGB | tonumber), rs_disk_gb: (.storageProfile.resourceDisk.size | tonumber / 1024) }"
251          @{
252              Cores = (Get-CimInstance Win32_Processor).NumberOfCores
253              vCPUs = (Get-CimInstance Win32_Processor).NumberOfLogicalProcessors
254              RamGb = [math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 2)
255              cpuid = (Get-CimInstance Win32_Processor).Name.Trim()
256          } | ConvertTo-Json
257      # more info here:- https://github.com/rust-lang/cargo/issues/13020
258      - name: Enable longer pathnames for git
259        run: git config --system core.longpaths true
260
261      - name: Checkout repo
262        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
263        with:
264          clean: false
265
266      - name: Create Dev Drive using ReFS
267        run: ./script/setup-dev-driver.ps1
268
269      # actions/checkout does not let us clone into anywhere outside ${{ github.workspace }}, so we have to copy the clone...
270      - name: Copy Git Repo to Dev Drive
271        run: |
272          Copy-Item -Path "${{ github.workspace }}" -Destination "${{ env.ZED_WORKSPACE }}" -Recurse
273
274      - name: Cache dependencies
275        uses: swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
276        with:
277          save-if: ${{ github.ref == 'refs/heads/main' }}
278          workspaces: ${{ env.ZED_WORKSPACE }}
279          cache-provider: "github"
280
281      - name: Configure CI
282        run: |
283          mkdir -p ${{ env.CARGO_HOME }} -ErrorAction Ignore
284          cp ./.cargo/ci-config.toml ${{ env.CARGO_HOME }}/config.toml
285
286      - name: cargo clippy
287        working-directory: ${{ env.ZED_WORKSPACE }}
288        run: ./script/clippy.ps1
289
290      - name: Check dev drive space
291        working-directory: ${{ env.ZED_WORKSPACE }}
292        # `setup-dev-driver.ps1` creates a 100GB drive, with CI taking up ~45GB of the drive.
293        run: ./script/exit-ci-if-dev-drive-is-full.ps1 95
294
295      # Since the Windows runners are stateful, so we need to remove the config file to prevent potential bug.
296      - name: Clean CI config file
297        if: always()
298        run: Remove-Item -Path "${{ env.CARGO_HOME }}/config.toml"  -Force
299
300  # Windows CI takes twice as long as our other platforms and fast github hosted runners are expensive.
301  # But we still want to do CI, so let's only run tests on main and come back to this when we're
302  # ready to self host our Windows CI (e.g. during the push for full Windows support)
303  windows_tests:
304    timeout-minutes: 60
305    name: (Windows) Run Tests
306    if: ${{ github.repository_owner == 'zed-industries' && (github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'windows')) }}
307    runs-on: hosted-windows-2
308    steps:
309      # Temporarily Collect some metadata about the hardware behind our runners.
310      - name: GHA Runner Info
311        run: |
312          Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute?api-version=2023-07-01" |
313            ConvertTo-Json -Depth 10 |
314            jq "{ vm_size: .vmSize, location: .location, os_disk_gb: (.storageProfile.osDisk.diskSizeGB | tonumber), rs_disk_gb: (.storageProfile.resourceDisk.size | tonumber / 1024) }"
315          @{
316              Cores = (Get-CimInstance Win32_Processor).NumberOfCores
317              vCPUs = (Get-CimInstance Win32_Processor).NumberOfLogicalProcessors
318              RamGb = [math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 2)
319              cpuid = (Get-CimInstance Win32_Processor).Name.Trim()
320          } | ConvertTo-Json
321      # more info here:- https://github.com/rust-lang/cargo/issues/13020
322      - name: Enable longer pathnames for git
323        run: git config --system core.longpaths true
324
325      - name: Checkout repo
326        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
327        with:
328          clean: false
329
330      - name: Create Dev Drive using ReFS
331        run: ./script/setup-dev-driver.ps1
332
333      # actions/checkout does not let us clone into anywhere outside ${{ github.workspace }}, so we have to copy the clone...
334      - name: Copy Git Repo to Dev Drive
335        run: |
336          Copy-Item -Path "${{ github.workspace }}" -Destination "${{ env.ZED_WORKSPACE }}" -Recurse
337
338      - name: Cache dependencies
339        uses: swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
340        with:
341          save-if: ${{ github.ref == 'refs/heads/main' }}
342          workspaces: ${{ env.ZED_WORKSPACE }}
343          cache-provider: "github"
344
345      - name: Configure CI
346        run: |
347          mkdir -p ${{ env.CARGO_HOME }} -ErrorAction Ignore
348          cp ./.cargo/ci-config.toml ${{ env.CARGO_HOME }}/config.toml
349
350      - name: Run tests
351        uses: ./.github/actions/run_tests_windows
352        with:
353          working-directory: ${{ env.ZED_WORKSPACE }}
354
355      - name: Build Zed
356        working-directory: ${{ env.ZED_WORKSPACE }}
357        run: cargo build
358
359      - name: Check dev drive space
360        working-directory: ${{ env.ZED_WORKSPACE }}
361        # `setup-dev-driver.ps1` creates a 100GB drive, with CI taking up ~45GB of the drive.
362        run: ./script/exit-ci-if-dev-drive-is-full.ps1 95
363
364      # Since the Windows runners are stateful, so we need to remove the config file to prevent potential bug.
365      - name: Clean CI config file
366        if: always()
367        run: Remove-Item -Path "${{ env.CARGO_HOME }}/config.toml"  -Force
368
369  bundle-mac:
370    timeout-minutes: 120
371    name: Create a macOS bundle
372    runs-on:
373      - self-hosted
374      - bundle
375    if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
376    needs: [macos_tests]
377    env:
378      MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
379      MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
380      APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
381      APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
382      APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
383      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
384      ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
385      DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
386      DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
387    steps:
388      - name: Install Node
389        uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
390        with:
391          node-version: "18"
392
393      - name: Checkout repo
394        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
395        with:
396          # We need to fetch more than one commit so that `script/draft-release-notes`
397          # is able to diff between the current and previous tag.
398          #
399          # 25 was chosen arbitrarily.
400          fetch-depth: 25
401          clean: false
402          ref: ${{ github.ref }}
403
404      - name: Limit target directory size
405        run: script/clear-target-dir-if-larger-than 100
406
407      - name: Determine version and release channel
408        if: ${{ startsWith(github.ref, 'refs/tags/v') }}
409        run: |
410          # This exports RELEASE_CHANNEL into env (GITHUB_ENV)
411          script/determine-release-channel
412
413      - name: Draft release notes
414        if: ${{ startsWith(github.ref, 'refs/tags/v') }}
415        run: |
416          mkdir -p target/
417          # Ignore any errors that occur while drafting release notes to not fail the build.
418          script/draft-release-notes "$RELEASE_VERSION" "$RELEASE_CHANNEL" > target/release-notes.md || true
419          script/create-draft-release target/release-notes.md
420        env:
421          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
422
423      - name: Create macOS app bundle
424        run: script/bundle-mac
425
426      - name: Rename binaries
427        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
428        run: |
429          mv target/aarch64-apple-darwin/release/Zed.dmg target/aarch64-apple-darwin/release/Zed-aarch64.dmg
430          mv target/x86_64-apple-darwin/release/Zed.dmg target/x86_64-apple-darwin/release/Zed-x86_64.dmg
431
432      - name: Upload app bundle (aarch64) to workflow run if main branch or specific label
433        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4
434        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
435        with:
436          name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg
437          path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg
438
439      - name: Upload app bundle (x86_64) to workflow run if main branch or specific label
440        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4
441        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
442        with:
443          name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg
444          path: target/x86_64-apple-darwin/release/Zed-x86_64.dmg
445
446      - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
447        name: Upload app bundle to release
448        if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
449        with:
450          draft: true
451          prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
452          files: |
453            target/zed-remote-server-macos-x86_64.gz
454            target/zed-remote-server-macos-aarch64.gz
455            target/aarch64-apple-darwin/release/Zed-aarch64.dmg
456            target/x86_64-apple-darwin/release/Zed-x86_64.dmg
457        env:
458          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
459
460  bundle-linux-x86_x64:
461    timeout-minutes: 60
462    name: Linux x86_x64 release bundle
463    runs-on:
464      - buildjet-16vcpu-ubuntu-2004
465    if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
466    needs: [linux_tests]
467    env:
468      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
469      ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
470      DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
471      DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
472    steps:
473      - name: Checkout repo
474        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
475        with:
476          clean: false
477
478      - name: Install Linux dependencies
479        run: ./script/linux && ./script/install-mold 2.34.0
480
481      - name: Determine version and release channel
482        if: ${{ startsWith(github.ref, 'refs/tags/v') }}
483        run: |
484          # This exports RELEASE_CHANNEL into env (GITHUB_ENV)
485          script/determine-release-channel
486
487      - name: Create Linux .tar.gz bundle
488        run: script/bundle-linux
489
490      - name: Upload Linux bundle to workflow run if main branch or specific label
491        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4
492        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
493        with:
494          name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz
495          path: target/release/zed-*.tar.gz
496
497      - name: Upload app bundle to release
498        uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
499        with:
500          draft: true
501          prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
502          files: |
503            target/zed-remote-server-linux-x86_64.gz
504            target/release/zed-linux-x86_64.tar.gz
505        env:
506          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
507
508  bundle-linux-aarch64: # this runs on ubuntu22.04
509    timeout-minutes: 60
510    name: Linux arm64 release bundle
511    runs-on:
512      - buildjet-16vcpu-ubuntu-2204-arm
513    if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
514    needs: [linux_tests]
515    env:
516      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
517      ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
518      DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
519      DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
520    steps:
521      - name: Checkout repo
522        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
523        with:
524          clean: false
525
526      - name: Install Linux dependencies
527        run: ./script/linux
528
529      - name: Determine version and release channel
530        if: ${{ startsWith(github.ref, 'refs/tags/v') }}
531        run: |
532          # This exports RELEASE_CHANNEL into env (GITHUB_ENV)
533          script/determine-release-channel
534
535      - name: Create and upload Linux .tar.gz bundle
536        run: script/bundle-linux
537
538      - name: Upload Linux bundle to workflow run if main branch or specific label
539        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4
540        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
541        with:
542          name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz
543          path: target/release/zed-*.tar.gz
544
545      - name: Upload app bundle to release
546        uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
547        with:
548          draft: true
549          prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
550          files: |
551            target/zed-remote-server-linux-aarch64.gz
552            target/release/zed-linux-aarch64.tar.gz
553        env:
554          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
555
556  auto-release-preview:
557    name: Auto release preview
558    if: ${{ startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '-pre') && !endsWith(github.ref, '.0-pre') }}
559    needs: [bundle-mac, bundle-linux-x86_x64, bundle-linux-aarch64]
560    runs-on:
561      - self-hosted
562      - bundle
563    steps:
564      - name: gh release
565        run: gh release edit $GITHUB_REF_NAME --draft=true
566        env:
567          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}