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
 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 }}