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        name: Check formatting and spelling
 27        runs-on:
 28            - self-hosted
 29            - test
 30        steps:
 31            - name: Checkout repo
 32              uses: actions/checkout@v4
 33              with:
 34                  clean: false
 35                  submodules: "recursive"
 36                  fetch-depth: 0
 37
 38            - name: Remove untracked files
 39              run: git clean -df
 40
 41            - name: Set up default .cargo/config.toml
 42              run: cp ./.cargo/ci-config.toml ~/.cargo/config.toml
 43
 44            - name: Check spelling
 45              run: |
 46                  if ! which typos > /dev/null; then
 47                    cargo install typos-cli
 48                  fi
 49                  typos
 50
 51            - name: Run style checks
 52              uses: ./.github/actions/check_style
 53
 54            - name: Ensure fresh merge
 55              shell: bash -euxo pipefail {0}
 56              run: |
 57                  if [ -z "$GITHUB_BASE_REF" ];
 58                  then
 59                    echo "BUF_BASE_BRANCH=$(git merge-base origin/main HEAD)" >> $GITHUB_ENV
 60                  else
 61                    git checkout -B temp
 62                    git merge -q origin/$GITHUB_BASE_REF -m "merge main into temp"
 63                    echo "BUF_BASE_BRANCH=$GITHUB_BASE_REF" >> $GITHUB_ENV
 64                  fi
 65
 66            - uses: bufbuild/buf-setup-action@v1
 67            - uses: bufbuild/buf-breaking-action@v1
 68              with:
 69                  input: "crates/rpc/proto/"
 70                  against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/rpc/proto/"
 71
 72    macos_tests:
 73        name: (macOS) Run Clippy and tests
 74        runs-on:
 75            - self-hosted
 76            - test
 77        steps:
 78            - name: Checkout repo
 79              uses: actions/checkout@v4
 80              with:
 81                  clean: false
 82                  submodules: "recursive"
 83
 84            - name: cargo clippy
 85              shell: bash -euxo pipefail {0}
 86              run: script/clippy
 87
 88            - name: Run tests
 89              uses: ./.github/actions/run_tests
 90
 91            - name: Build collab
 92              run: cargo build -p collab
 93
 94            - name: Build other binaries
 95              run: cargo build --workspace --bins --all-features
 96
 97    # todo!(linux): Actually run the tests
 98    linux_tests:
 99        name: (Linux) Run Clippy and tests
100        runs-on: ubuntu-latest
101        steps:
102            - name: Checkout repo
103              uses: actions/checkout@v4
104              with:
105                  clean: false
106                  submodules: "recursive"
107
108            - name: Restore from cache
109              uses: actions/cache@v4
110              with:
111                  path: |
112                      ~/.cargo/bin/
113                      ~/.cargo/registry/index/
114                      ~/.cargo/registry/cache/
115                      ~/.cargo/git/db/
116                      target/
117                  key: ${{ runner.os }}-cargo-${{ hashFiles('**/rust-toolchain.toml') }}-${{ hashFiles('**/Cargo.lock') }}
118                  restore-keys: ${{ runner.os }}-cargo-${{ hashFiles('**/rust-toolchain.toml') }}-
119
120            - name: configure linux
121              shell: bash -euxo pipefail {0}
122              run: script/linux
123
124            - name: cargo clippy
125              shell: bash -euxo pipefail {0}
126              run: script/clippy
127
128            - name: Build Zed
129              run: cargo build -p zed
130    bundle:
131        name: Bundle macOS app
132        runs-on:
133            - self-hosted
134            - bundle
135        if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-build-dmg') }}
136        needs: [macos_tests]
137        env:
138            MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
139            MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
140            APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
141            APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
142            ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
143            DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
144            DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
145        steps:
146            - name: Install Node
147              uses: actions/setup-node@v4
148              with:
149                  node-version: "18"
150
151            - name: Checkout repo
152              uses: actions/checkout@v4
153              with:
154                  clean: false
155                  submodules: "recursive"
156
157            - name: Limit target directory size
158              run: script/clear-target-dir-if-larger-than 100
159
160            - name: Determine version and release channel
161              if: ${{ startsWith(github.ref, 'refs/tags/v') }}
162              run: |
163                  set -eu
164
165                  version=$(script/get-crate-version zed)
166                  channel=$(cat crates/zed/RELEASE_CHANNEL)
167                  echo "Publishing version: ${version} on release channel ${channel}"
168                  echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
169
170                  expected_tag_name=""
171                  case ${channel} in
172                    stable)
173                      expected_tag_name="v${version}";;
174                    preview)
175                      expected_tag_name="v${version}-pre";;
176                    nightly)
177                      expected_tag_name="v${version}-nightly";;
178                    *)
179                      echo "can't publish a release on channel ${channel}"
180                      exit 1;;
181                  esac
182                  if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
183                    echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
184                    exit 1
185                  fi
186
187            - name: Generate license file
188              run: script/generate-licenses
189
190            - name: Create app bundle
191              run: script/bundle
192
193            - name: Upload app bundle to workflow run if main branch or specific label
194              uses: actions/upload-artifact@v3
195              if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-build-dmg') }}
196              with:
197                  name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.dmg
198                  path: target/release/Zed.dmg
199
200            - uses: softprops/action-gh-release@v1
201              name: Upload app bundle to release
202              if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
203              with:
204                  draft: true
205                  prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
206                  files: target/release/Zed.dmg
207                  body: ""
208              env:
209                  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}