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
119      - name: Install Linux dependencies
120        run: ./script/linux
121
122      - name: cargo clippy
123        run: ./script/clippy
124
125      - name: Run tests
126        uses: ./.github/actions/run_tests
127
128      - name: Build Zed
129        run: cargo build -p zed
130
131  # todo(windows): Actually run the tests
132  windows_tests:
133    timeout-minutes: 60
134    name: (Windows) Run Clippy and tests
135    runs-on: hosted-windows-1
136    steps:
137      - name: Checkout repo
138        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
139        with:
140          clean: false
141
142      - name: Cache dependencies
143        uses: swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2
144        with:
145          save-if: ${{ github.ref == 'refs/heads/main' }}
146
147      - name: cargo clippy
148        # Windows can't run shell scripts, so we need to use `cargo xtask`.
149        run: cargo xtask clippy
150
151      - name: Build Zed
152        run: cargo build -p zed
153
154  bundle-mac:
155    timeout-minutes: 60
156    name: Create a macOS bundle
157    runs-on:
158      - self-hosted
159      - bundle
160    if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
161    needs: [macos_tests]
162    env:
163      MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
164      MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
165      APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
166      APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
167      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
168      ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
169      DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
170      DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
171    steps:
172      - name: Install Node
173        uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
174        with:
175          node-version: "18"
176
177      - name: Checkout repo
178        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
179        with:
180          # We need to fetch more than one commit so that `script/draft-release-notes`
181          # is able to diff between the current and previous tag.
182          #
183          # 25 was chosen arbitrarily.
184          fetch-depth: 25
185          clean: false
186
187      - name: Limit target directory size
188        run: script/clear-target-dir-if-larger-than 100
189
190      - name: Determine version and release channel
191        if: ${{ startsWith(github.ref, 'refs/tags/v') }}
192        run: |
193          set -eu
194
195          version=$(script/get-crate-version zed)
196          channel=$(cat crates/zed/RELEASE_CHANNEL)
197          echo "Publishing version: ${version} on release channel ${channel}"
198          echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
199
200          expected_tag_name=""
201          case ${channel} in
202            stable)
203              expected_tag_name="v${version}";;
204            preview)
205              expected_tag_name="v${version}-pre";;
206            nightly)
207              expected_tag_name="v${version}-nightly";;
208            *)
209              echo "can't publish a release on channel ${channel}"
210              exit 1;;
211          esac
212          if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
213            echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
214            exit 1
215          fi
216          mkdir -p target/
217          # Ignore any errors that occur while drafting release notes to not fail the build.
218          script/draft-release-notes "$version" "$channel" > target/release-notes.md || true
219
220      - name: Generate license file
221        run: script/generate-licenses
222
223      - name: Create macOS app bundle
224        run: script/bundle-mac
225
226      - name: Rename single-architecture binaries
227        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
228        run: |
229          mv target/aarch64-apple-darwin/release/Zed.dmg target/aarch64-apple-darwin/release/Zed-aarch64.dmg
230          mv target/x86_64-apple-darwin/release/Zed.dmg target/x86_64-apple-darwin/release/Zed-x86_64.dmg
231
232      - name: Upload app bundle (universal) to workflow run if main branch or specific label
233        uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
234        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
235        with:
236          name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.dmg
237          path: target/release/Zed.dmg
238      - name: Upload app bundle (aarch64) to workflow run if main branch or specific label
239        uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
240        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
241        with:
242          name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg
243          path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg
244
245      - name: Upload app bundle (x86_64) to workflow run if main branch or specific label
246        uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
247        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
248        with:
249          name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg
250          path: target/x86_64-apple-darwin/release/Zed-x86_64.dmg
251
252      - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
253        name: Upload app bundle to release
254        if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
255        with:
256          draft: true
257          prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
258          files: |
259            target/zed-remote-server-macos-x86_64.gz
260            target/zed-remote-server-macos-aarch64.gz
261            target/aarch64-apple-darwin/release/Zed-aarch64.dmg
262            target/x86_64-apple-darwin/release/Zed-x86_64.dmg
263            target/release/Zed.dmg
264          body_path: target/release-notes.md
265        env:
266          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
267
268  bundle-linux:
269    timeout-minutes: 60
270    name: Create a Linux bundle
271    runs-on:
272      - buildjet-16vcpu-ubuntu-2204
273    if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
274    needs: [linux_tests]
275    env:
276      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
277      ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
278    steps:
279      - name: Checkout repo
280        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
281        with:
282          clean: false
283
284      - name: Install Linux dependencies
285        run: ./script/linux
286
287      - name: Determine version and release channel
288        if: ${{ startsWith(github.ref, 'refs/tags/v') }}
289        run: |
290          set -eu
291
292          version=$(script/get-crate-version zed)
293          channel=$(cat crates/zed/RELEASE_CHANNEL)
294          echo "Publishing version: ${version} on release channel ${channel}"
295          echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
296
297          expected_tag_name=""
298          case ${channel} in
299            stable)
300              expected_tag_name="v${version}";;
301            preview)
302              expected_tag_name="v${version}-pre";;
303            nightly)
304              expected_tag_name="v${version}-nightly";;
305            *)
306              echo "can't publish a release on channel ${channel}"
307              exit 1;;
308          esac
309          if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
310            echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
311            exit 1
312          fi
313
314      - name: Create Linux .tar.gz bundle
315        run: script/bundle-linux
316
317      - name: Upload Linux bundle to workflow run if main branch or specific label
318        uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
319        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
320        with:
321          name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz
322          path: target/release/zed-*.tar.gz
323
324      - name: Upload app bundle to release
325        uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
326        with:
327          draft: true
328          prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
329          files: |
330            target/zed-remote-server-linux-x86_64.gz
331            target/release/zed-linux-x86_64.tar.gz
332          body: ""
333        env:
334          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
335
336  bundle-linux-aarch64: # this runs on ubuntu22.04
337    timeout-minutes: 60
338    name: Create arm64 Linux bundle
339    runs-on:
340      - buildjet-16vcpu-ubuntu-2204-arm
341    if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
342    needs: [linux_tests]
343    env:
344      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
345      ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
346    steps:
347      - name: Checkout repo
348        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
349        with:
350          clean: false
351
352      - name: Install Linux dependencies
353        run: ./script/linux
354
355      - name: Determine version and release channel
356        if: ${{ startsWith(github.ref, 'refs/tags/v') }}
357        run: |
358          set -eu
359
360          version=$(script/get-crate-version zed)
361          channel=$(cat crates/zed/RELEASE_CHANNEL)
362          echo "Publishing version: ${version} on release channel ${channel}"
363          echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
364
365          expected_tag_name=""
366          case ${channel} in
367            stable)
368              expected_tag_name="v${version}";;
369            preview)
370              expected_tag_name="v${version}-pre";;
371            nightly)
372              expected_tag_name="v${version}-nightly";;
373            *)
374              echo "can't publish a release on channel ${channel}"
375              exit 1;;
376          esac
377          if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
378            echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
379            exit 1
380          fi
381
382      - name: Create and upload Linux .tar.gz bundle
383        run: script/bundle-linux
384
385      - name: Upload Linux bundle to workflow run if main branch or specific label
386        uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4
387        if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
388        with:
389          name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz
390          path: target/release/zed-*.tar.gz
391
392      - name: Upload app bundle to release
393        uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
394        if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
395        with:
396          draft: true
397          prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
398          files: |
399            target/zed-remote-server-linux-aarch64.gz
400            target/release/zed-linux-aarch64.tar.gz
401          body: ""
402        env:
403          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}