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: script/check-spelling
 43
 44      - name: Run style checks
 45        uses: ./.github/actions/check_style
 46
 47      - name: Check unused dependencies
 48        uses: bnjbvr/cargo-machete@main
 49
 50      - name: Check licenses are present
 51        run: script/check-licenses
 52
 53      - name: Check license generation
 54        run: script/generate-licenses /tmp/zed_licenses_output
 55
 56      - name: Ensure fresh merge
 57        shell: bash -euxo pipefail {0}
 58        run: |
 59          if [ -z "$GITHUB_BASE_REF" ];
 60          then
 61            echo "BUF_BASE_BRANCH=$(git merge-base origin/main HEAD)" >> $GITHUB_ENV
 62          else
 63            git checkout -B temp
 64            git merge -q origin/$GITHUB_BASE_REF -m "merge main into temp"
 65            echo "BUF_BASE_BRANCH=$GITHUB_BASE_REF" >> $GITHUB_ENV
 66          fi
 67
 68      - uses: bufbuild/buf-setup-action@v1
 69        with:
 70          version: v1.29.0
 71      - uses: bufbuild/buf-breaking-action@v1
 72        with:
 73          input: "crates/proto/proto/"
 74          against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/proto/proto/"
 75
 76  macos_tests:
 77    timeout-minutes: 60
 78    name: (macOS) Run Clippy and tests
 79    runs-on:
 80      - self-hosted
 81      - test
 82    steps:
 83      - name: Checkout repo
 84        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
 85        with:
 86          clean: false
 87
 88      - name: cargo clippy
 89        run: ./script/clippy
 90
 91      - name: Run tests
 92        uses: ./.github/actions/run_tests
 93
 94      - name: Build collab
 95        run: cargo build -p collab
 96
 97      - name: Build other binaries and features
 98        run: cargo build --workspace --bins --all-features; cargo check -p gpui --features "macos-blade"
 99
100  linux_tests:
101    timeout-minutes: 60
102    name: (Linux) Run Clippy and tests
103    runs-on:
104      - buildjet-16vcpu-ubuntu-2204
105    steps:
106      - name: Add Rust to the PATH
107        run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
108
109      - name: Checkout repo
110        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
111        with:
112          clean: false
113
114      - name: Cache dependencies
115        uses: swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2
116        with:
117          save-if: ${{ github.ref == 'refs/heads/main' }}
118          cache-provider: "buildjet"
119
120      - name: Install Linux dependencies
121        run: ./script/linux
122
123      - name: cargo clippy
124        run: ./script/clippy
125
126      - name: Run tests
127        uses: ./.github/actions/run_tests
128
129      - name: Build Zed
130        run: cargo build -p zed
131
132  # todo(windows): Actually run the tests
133  windows_tests:
134    timeout-minutes: 60
135    name: (Windows) Run Clippy and tests
136    runs-on: hosted-windows-1
137    steps:
138      - name: Checkout repo
139        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
140        with:
141          clean: false
142
143      - name: Cache dependencies
144        uses: swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2
145        with:
146          save-if: ${{ github.ref == 'refs/heads/main' }}
147          cache-provider: "github"
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      - buildjet-16vcpu-ubuntu-2204
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      ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
280    steps:
281      - name: Checkout repo
282        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
283        with:
284          clean: false
285
286      - name: Install Linux dependencies
287        run: ./script/linux
288
289      - name: Determine version and release channel
290        if: ${{ startsWith(github.ref, 'refs/tags/v') }}
291        run: |
292          set -eu
293
294          version=$(script/get-crate-version zed)
295          channel=$(cat crates/zed/RELEASE_CHANNEL)
296          echo "Publishing version: ${version} on release channel ${channel}"
297          echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
298
299          expected_tag_name=""
300          case ${channel} in
301            stable)
302              expected_tag_name="v${version}";;
303            preview)
304              expected_tag_name="v${version}-pre";;
305            nightly)
306              expected_tag_name="v${version}-nightly";;
307            *)
308              echo "can't publish a release on channel ${channel}"
309              exit 1;;
310          esac
311          if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
312            echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
313            exit 1
314          fi
315
316      - name: Create Linux .tar.gz bundle
317        run: script/bundle-linux
318
319      - name: Upload Linux bundle to workflow run if main branch or specific label
320        uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
321        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
322        with:
323          name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz
324          path: target/release/zed-*.tar.gz
325
326      - name: Upload app bundle to release
327        uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
328        with:
329          draft: true
330          prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
331          files: |
332            target/zed-remote-server-linux-x86_64.gz
333            target/release/zed-linux-x86_64.tar.gz
334          body: ""
335        env:
336          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
337
338  bundle-linux-aarch64: # this runs on ubuntu22.04
339    timeout-minutes: 60
340    name: Create arm64 Linux bundle
341    runs-on:
342      - buildjet-16vcpu-ubuntu-2204-arm
343    if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
344    needs: [linux_tests]
345    env:
346      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
347      ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
348    steps:
349      - name: Checkout repo
350        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
351        with:
352          clean: false
353
354      - name: Install Linux dependencies
355        run: ./script/linux
356
357      - name: Determine version and release channel
358        if: ${{ startsWith(github.ref, 'refs/tags/v') }}
359        run: |
360          set -eu
361
362          version=$(script/get-crate-version zed)
363          channel=$(cat crates/zed/RELEASE_CHANNEL)
364          echo "Publishing version: ${version} on release channel ${channel}"
365          echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
366
367          expected_tag_name=""
368          case ${channel} in
369            stable)
370              expected_tag_name="v${version}";;
371            preview)
372              expected_tag_name="v${version}-pre";;
373            nightly)
374              expected_tag_name="v${version}-nightly";;
375            *)
376              echo "can't publish a release on channel ${channel}"
377              exit 1;;
378          esac
379          if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
380            echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
381            exit 1
382          fi
383
384      - name: Create and upload 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@50769540e7f4bd5e21e526ee35c689e35e0d6874 # 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 }}-aarch64-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        if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
397        with:
398          draft: true
399          prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
400          files: |
401            target/zed-remote-server-linux-aarch64.gz
402            target/release/zed-linux-aarch64.tar.gz
403          body: ""
404        env:
405          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}