diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8fe069c5e060ce5846cfd493f07148b8e4e8d2a5..4e1d5d59c551976c94272b682250e100ed3957ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,16 +2,9 @@ name: CI on: push: - branches: - - main - - "v[0-9]+.[0-9]+.x" tags: - "v*" - pull_request: - branches: - - "**" - concurrency: # Allow only one workflow per any non-`main` branch. group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }} @@ -273,15 +266,12 @@ jobs: uses: ./.github/actions/run_tests - name: Build collab + # we should do this on a linux x86 machinge run: cargo build -p collab - name: Build other binaries and features run: | - cargo build --workspace --bins --all-features - cargo check -p gpui --features "macos-blade" - cargo check -p workspace - cargo build -p remote_server - cargo check -p gpui --examples + cargo build --workspace --bins --examples # Since the macOS runners are stateful, so we need to remove the config file to prevent potential bug. - name: Clean CI config file @@ -731,10 +721,6 @@ jobs: (contains(github.event.pull_request.labels.*.name, 'run-nix') || needs.job_spec.outputs.run_nix == 'true') secrets: inherit - with: - flake-output: debug - # excludes the final package to only cache dependencies - cachix-filter: "-zed-editor-[0-9.]*-nightly" bundle-windows-x64: timeout-minutes: 120 diff --git a/.github/workflows/nix_build.yml b/.github/workflows/nix_build.yml index cc6bac824f8374cd60bb5ce5dcfb19439ecdc22d..4dd45bd3a740a43785e0284f0b86b2cdef50c1c7 100644 --- a/.github/workflows/nix_build.yml +++ b/.github/workflows/nix_build.yml @@ -1,14 +1,31 @@ # Generated from xtask::workflows::nix_build # Rebuild with `cargo xtask workflows`. name: nix_build +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: '1' + CARGO_INCREMENTAL: '0' on: - workflow_call: - inputs: - flake-output: - type: string - default: default - cachix-filter: - type: string + pull_request: + branches: + - '**' + paths: + - nix/** + - flake.* + - Cargo.* + - rust-toolchain.toml + - .cargo/config.toml + push: + branches: + - main + - v[0-9]+.[0-9]+.x + paths: + - nix/** + - flake.* + - Cargo.* + - rust-toolchain.toml + - .cargo/config.toml + workflow_call: {} jobs: build_nix_linux_x86_64: if: github.repository_owner == 'zed-industries' @@ -33,9 +50,9 @@ jobs: name: zed authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} cachixArgs: -v - pushFilter: ${{ inputs.cachix-filter }} + pushFilter: -zed-editor-[0-9.]*-nightly - name: nix_build::build - run: nix build .#${{ inputs.flake-output }} -L --accept-flake-config + run: nix build .#debug -L --accept-flake-config shell: bash -euxo pipefail {0} timeout-minutes: 60 continue-on-error: true @@ -63,9 +80,9 @@ jobs: name: zed authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} cachixArgs: -v - pushFilter: ${{ inputs.cachix-filter }} + pushFilter: -zed-editor-[0-9.]*-nightly - name: nix_build::build - run: nix build .#${{ inputs.flake-output }} -L --accept-flake-config + run: nix build .#debug -L --accept-flake-config shell: bash -euxo pipefail {0} - name: nix_build::limit_store run: |- @@ -75,3 +92,6 @@ jobs: shell: bash -euxo pipefail {0} timeout-minutes: 60 continue-on-error: true +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }} + cancel-in-progress: true diff --git a/.github/workflows/release_nightly.yml b/.github/workflows/release_nightly.yml index c593fea4cdf8538704aa6bab3478c2a3d894af41..80e6534e70e8f7169514fb8cc569f7b11488cd88 100644 --- a/.github/workflows/release_nightly.yml +++ b/.github/workflows/release_nightly.yml @@ -49,6 +49,9 @@ jobs: uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 with: node-version: '20' + - name: steps::clippy + run: ./script/clippy + shell: bash -euxo pipefail {0} - name: steps::cargo_install_nextest run: cargo install cargo-nextest --locked shell: bash -euxo pipefail {0} @@ -81,6 +84,9 @@ jobs: uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 with: node-version: '20' + - name: steps::clippy + run: ./script/clippy.ps1 + shell: pwsh - name: steps::cargo_install_nextest run: cargo install cargo-nextest --locked shell: pwsh diff --git a/.github/workflows/run_action_checks.yml b/.github/workflows/run_action_checks.yml new file mode 100644 index 0000000000000000000000000000000000000000..7301e77733b915008d68ad6cfcea6ad979ad7f78 --- /dev/null +++ b/.github/workflows/run_action_checks.yml @@ -0,0 +1,58 @@ +# Generated from xtask::workflows::run_action_checks +# Rebuild with `cargo xtask workflows`. +name: run_action_checks +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: '1' + CARGO_INCREMENTAL: '0' +on: + pull_request: + branches: + - '**' + paths: + - .github/workflows/** + - .github/actions/** + - .github/actionlint.yml + - script/** + push: + branches: + - main + - v[0-9]+.[0-9]+.x + paths: + - .github/workflows/** + - .github/actions/** + - .github/actionlint.yml + - script/** +jobs: + actionlint: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-2x4-ubuntu-2404 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - id: get_actionlint + name: run_action_checks::download_actionlint + run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) + shell: bash -euxo pipefail {0} + - name: run_action_checks::run_actionlint + run: | + ${{ steps.get_actionlint.outputs.executable }} -color + shell: bash -euxo pipefail {0} + timeout-minutes: 60 + shellcheck: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-2x4-ubuntu-2404 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: run_action_checks::run_shellcheck + run: ./script/shellcheck-scripts error + shell: bash -euxo pipefail {0} + timeout-minutes: 60 +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }} + cancel-in-progress: true diff --git a/.github/workflows/run_bundling.yml b/.github/workflows/run_bundling.yml index 98354d0b7895848196ccd58d0d953d2856cfa8c2..9766c7c14b64007692cfb1c68efead5b23382426 100644 --- a/.github/workflows/run_bundling.yml +++ b/.github/workflows/run_bundling.yml @@ -109,10 +109,10 @@ jobs: uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b with: token: ${{ secrets.SENTRY_AUTH_TOKEN }} - - name: ./script/linux + - name: steps::setup_linux run: ./script/linux shell: bash -euxo pipefail {0} - - name: ./script/install-mold + - name: steps::install_mold run: ./script/install-mold shell: bash -euxo pipefail {0} - name: ./script/bundle-linux @@ -143,9 +143,12 @@ jobs: uses: matbour/setup-sentry-cli@3e938c54b3018bdd019973689ef984e033b0454b with: token: ${{ secrets.SENTRY_AUTH_TOKEN }} - - name: ./script/linux + - name: steps::setup_linux run: ./script/linux shell: bash -euxo pipefail {0} + - name: steps::install_mold + run: ./script/install-mold + shell: bash -euxo pipefail {0} - name: ./script/bundle-linux run: ./script/bundle-linux shell: bash -euxo pipefail {0} diff --git a/.github/workflows/run_docs_checks.yml b/.github/workflows/run_docs_checks.yml new file mode 100644 index 0000000000000000000000000000000000000000..b19afa924382a082f25970e902dc3e560c648b36 --- /dev/null +++ b/.github/workflows/run_docs_checks.yml @@ -0,0 +1,68 @@ +# Generated from xtask::workflows::run_docs_checks +# Rebuild with `cargo xtask workflows`. +name: run_docs_checks +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: '1' + CARGO_INCREMENTAL: '0' +on: + pull_request: + branches: + - '**' + paths: + - docs/** + - crates/docs_preprocessor/** + push: + branches: + - main + - v[0-9]+.[0-9]+.x + paths: + - docs/** + - crates/docs_preprocessor/** +jobs: + check_docs: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-8x16-ubuntu-2204 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_cargo_config + run: | + mkdir -p ./../.cargo + cp ./.cargo/ci-config.toml ./../.cargo/config.toml + shell: bash -euxo pipefail {0} + - name: steps::cache_rust_dependencies + uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 + with: + save-if: ${{ github.ref == 'refs/heads/main' }} + - name: run_docs_checks::lychee_link_check + uses: lycheeverse/lychee-action@82202e5e9c2f4ef1a55a3d02563e1cb6041e5332 + with: + args: --no-progress --exclude '^http' './docs/src/**/*' + fail: true + - name: steps::setup_linux + run: ./script/linux + shell: bash -euxo pipefail {0} + - name: steps::install_mold + run: ./script/install-mold + shell: bash -euxo pipefail {0} + - name: run_docs_checks::install_mdbook + uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 + with: + mdbook-version: 0.4.37 + - name: run_docs_checks::build_docs + run: | + mkdir -p target/deploy + mdbook build ./docs --dest-dir=../target/deploy/docs/ + shell: bash -euxo pipefail {0} + - name: run_docs_checks::lychee_link_check + uses: lycheeverse/lychee-action@82202e5e9c2f4ef1a55a3d02563e1cb6041e5332 + with: + args: --no-progress --exclude '^http' 'target/deploy/docs' + fail: true + timeout-minutes: 60 +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }} + cancel-in-progress: true diff --git a/.github/workflows/run_license_checks.yml b/.github/workflows/run_license_checks.yml new file mode 100644 index 0000000000000000000000000000000000000000..b88116ee32bd6aaf0f976835249ba604b3b1dd6d --- /dev/null +++ b/.github/workflows/run_license_checks.yml @@ -0,0 +1,51 @@ +# Generated from xtask::workflows::run_license_checks +# Rebuild with `cargo xtask workflows`. +name: run_license_checks +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: '1' + CARGO_INCREMENTAL: '0' +on: + pull_request: + branches: + - '**' + paths: + - Cargo.lock + - '**/Cargo.lock' + - script/*licenses + - '**/LICENSE*' + - .github/workflows/run_license_checks.yml + push: + branches: + - main + - v[0-9]+.[0-9]+.x + paths: + - Cargo.lock + - '**/Cargo.lock' + - script/*licenses + - '**/LICENSE*' + - .github/workflows/run_license_checks.yml +jobs: + check_licenses: + runs-on: namespace-profile-2x4-ubuntu-2404 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: ./script/check-licenses + run: ./script/check-licenses + shell: bash -euxo pipefail {0} + build_licenses: + runs-on: namespace-profile-4x8-ubuntu-2204 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: ./script/generate-licenses + run: ./script/generate-licenses + shell: bash -euxo pipefail {0} +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }} + cancel-in-progress: true diff --git a/.github/workflows/run_style_checks.yml b/.github/workflows/run_style_checks.yml new file mode 100644 index 0000000000000000000000000000000000000000..a16a89e4c754dfb16c2379aab4ddb0a1fd79d147 --- /dev/null +++ b/.github/workflows/run_style_checks.yml @@ -0,0 +1,48 @@ +# Generated from xtask::workflows::run_style_checks +# Rebuild with `cargo xtask workflows`. +name: run_style_checks +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: '1' + CARGO_INCREMENTAL: '0' +on: + pull_request: + branches: + - '**' + push: + branches: + - main + - v[0-9]+.[0-9]+.x +jobs: + check_style: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-4x8-ubuntu-2204 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_pnpm + uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 + with: + version: '9' + - name: ./script/prettier + run: ./script/prettier + shell: bash -euxo pipefail {0} + - name: ./script/check-todos + run: ./script/check-todos + shell: bash -euxo pipefail {0} + - name: ./script/check-keymaps + run: ./script/check-keymaps + shell: bash -euxo pipefail {0} + - name: run_style_checks::check_for_typos + uses: crate-ci/typos@80c8a4945eec0f6d464eaf9e65ed98ef085283d1 + with: + config: ./typos.toml + - name: steps::cargo_fmt + run: cargo fmt --all -- --check + shell: bash -euxo pipefail {0} + timeout-minutes: 60 +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }} + cancel-in-progress: true diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml new file mode 100644 index 0000000000000000000000000000000000000000..e0738e939ae29985ddc6714e24fa19d1bad296b5 --- /dev/null +++ b/.github/workflows/run_tests.yml @@ -0,0 +1,265 @@ +# Generated from xtask::workflows::run_tests +# Rebuild with `cargo xtask workflows`. +name: run_tests +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: '1' + CARGO_INCREMENTAL: '0' +on: + pull_request: + branches: + - '**' + paths: + - '!docs/**' + - '!script/update_top_ranking_issues/**' + - '!.github/ISSUE_TEMPLATE/**' + - '!.github/workflows/**' + - .github/workflows/run_tests.yml + push: + branches: + - main + - v[0-9]+.[0-9]+.x + paths: + - '!docs/**' + - '!script/update_top_ranking_issues/**' + - '!.github/ISSUE_TEMPLATE/**' + - '!.github/workflows/**' + - .github/workflows/run_tests.yml +jobs: + run_tests_windows: + if: github.repository_owner == 'zed-industries' + runs-on: self-32vcpu-windows-2022 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_cargo_config + run: | + New-Item -ItemType Directory -Path "./../.cargo" -Force + Copy-Item -Path "./.cargo/ci-config.toml" -Destination "./../.cargo/config.toml" + shell: pwsh + - name: steps::setup_node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '20' + - name: steps::clippy + run: ./script/clippy.ps1 + shell: pwsh + - name: steps::cargo_install_nextest + run: cargo install cargo-nextest --locked + shell: pwsh + - name: steps::clear_target_dir_if_large + run: ./script/clear-target-dir-if-larger-than.ps1 250 + shell: pwsh + - name: steps::cargo_nextest + run: cargo nextest run --workspace --no-fail-fast --failure-output immediate-final + shell: pwsh + - name: steps::cleanup_cargo_config + if: always() + run: | + Remove-Item -Recurse -Path "./../.cargo" -Force -ErrorAction SilentlyContinue + shell: pwsh + timeout-minutes: 60 + run_tests_linux: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-16x32-ubuntu-2204 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_cargo_config + run: | + mkdir -p ./../.cargo + cp ./.cargo/ci-config.toml ./../.cargo/config.toml + shell: bash -euxo pipefail {0} + - name: steps::setup_linux + run: ./script/linux + shell: bash -euxo pipefail {0} + - name: steps::install_mold + run: ./script/install-mold + shell: bash -euxo pipefail {0} + - name: steps::setup_node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '20' + - name: steps::clippy + run: ./script/clippy + shell: bash -euxo pipefail {0} + - name: steps::cargo_install_nextest + run: cargo install cargo-nextest --locked + shell: bash -euxo pipefail {0} + - name: steps::clear_target_dir_if_large + run: ./script/clear-target-dir-if-larger-than 100 + shell: bash -euxo pipefail {0} + - name: steps::cargo_nextest + run: cargo nextest run --workspace --no-fail-fast --failure-output immediate-final + shell: bash -euxo pipefail {0} + - name: steps::cleanup_cargo_config + if: always() + run: | + rm -rf ./../.cargo + shell: bash -euxo pipefail {0} + timeout-minutes: 60 + run_tests_mac: + if: github.repository_owner == 'zed-industries' + runs-on: self-mini-macos + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_cargo_config + run: | + mkdir -p ./../.cargo + cp ./.cargo/ci-config.toml ./../.cargo/config.toml + shell: bash -euxo pipefail {0} + - name: steps::setup_node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '20' + - name: steps::clippy + run: ./script/clippy + shell: bash -euxo pipefail {0} + - name: steps::cargo_install_nextest + run: cargo install cargo-nextest --locked + shell: bash -euxo pipefail {0} + - name: steps::clear_target_dir_if_large + run: ./script/clear-target-dir-if-larger-than 300 + shell: bash -euxo pipefail {0} + - name: steps::cargo_nextest + run: cargo nextest run --workspace --no-fail-fast --failure-output immediate-final + shell: bash -euxo pipefail {0} + - name: steps::cleanup_cargo_config + if: always() + run: | + rm -rf ./../.cargo + shell: bash -euxo pipefail {0} + timeout-minutes: 60 + check_postgres_and_protobuf_migrations: + if: github.repository_owner == 'zed-industries' + runs-on: self-mini-macos + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + fetch-depth: 0 + - name: run_tests::check_postgres_and_protobuf_migrations::remove_untracked_files + run: git clean -df + shell: bash -euxo pipefail {0} + - name: run_tests::check_postgres_and_protobuf_migrations::ensure_fresh_merge + run: | + if [ -z "$GITHUB_BASE_REF" ]; + then + echo "BUF_BASE_BRANCH=$(git merge-base origin/main HEAD)" >> "$GITHUB_ENV" + else + git checkout -B temp + git merge -q "origin/$GITHUB_BASE_REF" -m "merge main into temp" + echo "BUF_BASE_BRANCH=$GITHUB_BASE_REF" >> "$GITHUB_ENV" + fi + shell: bash -euxo pipefail {0} + - name: run_tests::check_postgres_and_protobuf_migrations::bufbuild_setup_action + uses: bufbuild/buf-setup-action@v1 + with: + version: v1.29.0 + - name: run_tests::check_postgres_and_protobuf_migrations::bufbuild_breaking_action + uses: bufbuild/buf-breaking-action@v1 + with: + input: crates/proto/proto/ + against: https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/proto/proto/ + timeout-minutes: 60 + doctests: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-16x32-ubuntu-2204 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::cache_rust_dependencies + uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 + with: + save-if: ${{ github.ref == 'refs/heads/main' }} + - name: steps::setup_linux + run: ./script/linux + shell: bash -euxo pipefail {0} + - name: steps::install_mold + run: ./script/install-mold + shell: bash -euxo pipefail {0} + - name: steps::setup_cargo_config + run: | + mkdir -p ./../.cargo + cp ./.cargo/ci-config.toml ./../.cargo/config.toml + shell: bash -euxo pipefail {0} + - id: run_doctests + name: run_tests::doctests::run_doctests + run: | + cargo test --workspace --doc --no-fail-fast + shell: bash -euxo pipefail {0} + - name: steps::cleanup_cargo_config + if: always() + run: | + rm -rf ./../.cargo + shell: bash -euxo pipefail {0} + timeout-minutes: 60 + check_dependencies: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-2x4-ubuntu-2404 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: run_tests::check_dependencies::install_cargo_machete + uses: clechasseur/rs-cargo@8435b10f6e71c2e3d4d3b7573003a8ce4bfc6386 + with: + command: install + args: cargo-machete@0.7.0 + - name: run_tests::check_dependencies::run_cargo_machete + uses: clechasseur/rs-cargo@8435b10f6e71c2e3d4d3b7573003a8ce4bfc6386 + with: + command: machete + - name: run_tests::check_dependencies::check_cargo_lock + run: cargo update --locked --workspace + shell: bash -euxo pipefail {0} + - name: run_tests::check_dependencies::check_vulnerable_dependencies + if: github.event_name == 'pull_request' + uses: actions/dependency-review-action@67d4f4bd7a9b17a0db54d2a7519187c65e339de8 + with: + license-check: false + timeout-minutes: 60 + check_workspace_binaries: + if: github.repository_owner == 'zed-industries' + runs-on: namespace-profile-8x16-ubuntu-2204 + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - name: steps::setup_cargo_config + run: | + mkdir -p ./../.cargo + cp ./.cargo/ci-config.toml ./../.cargo/config.toml + shell: bash -euxo pipefail {0} + - name: steps::setup_linux + run: ./script/linux + shell: bash -euxo pipefail {0} + - name: steps::install_mold + run: ./script/install-mold + shell: bash -euxo pipefail {0} + - name: cargo build -p collab + run: cargo build -p collab + shell: bash -euxo pipefail {0} + - name: cargo build --workspace --bins --examples + run: cargo build --workspace --bins --examples + shell: bash -euxo pipefail {0} + - name: steps::cleanup_cargo_config + if: always() + run: | + rm -rf ./../.cargo + shell: bash -euxo pipefail {0} + timeout-minutes: 60 +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }} + cancel-in-progress: true diff --git a/.github/workflows/script_checks.yml b/.github/workflows/script_checks.yml deleted file mode 100644 index 5dbfc9cb7fa9a51b9e0aca972d125c2a27677584..0000000000000000000000000000000000000000 --- a/.github/workflows/script_checks.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Script - -on: - pull_request: - paths: - - "script/**" - push: - branches: - - main - -jobs: - shellcheck: - name: "ShellCheck Scripts" - if: github.repository_owner == 'zed-industries' - runs-on: namespace-profile-2x4-ubuntu-2404 - - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - name: Shellcheck ./scripts - run: | - ./script/shellcheck-scripts error diff --git a/docs/src/vim.md b/docs/src/vim.md index f1296c4575ce26a298a2e7bb8d13eba37c239a50..c9a0cd09f2dafb9f07a26ef07b71205f5ddbdf15 100644 --- a/docs/src/vim.md +++ b/docs/src/vim.md @@ -628,7 +628,7 @@ Here's an example of these settings changed: // Allow the cursor to reach the edges of the screen "vertical_scroll_margin": 0, "gutter": { - // Disable line numbers completely: + // Disable line numbers completely "line_numbers": false }, "command_aliases": { diff --git a/script/prettier b/script/prettier new file mode 100755 index 0000000000000000000000000000000000000000..b1d28fb66d70c08a6d03b21be6f168fd0b2da5dc --- /dev/null +++ b/script/prettier @@ -0,0 +1,17 @@ +#!/bin/bash +set -euxo pipefail + +PRETTIER_VERSION=3.5.0 + +pnpm dlx "prettier@${PRETTIER_VERSION}" assets/settings/default.json --check || { + echo "To fix, run from the root of the Zed repo:" + echo " pnpm dlx prettier@${PRETTIER_VERSION} assets/settings/default.json --write" + false +} + +cd docs +pnpm dlx "prettier@${PRETTIER_VERSION}" . --check || { + echo "To fix, run from the root of the Zed repo:" + echo " cd docs && pnpm dlx prettier@${PRETTIER_VERSION} . --write && cd .." + false +} diff --git a/tooling/xtask/src/tasks/workflows.rs b/tooling/xtask/src/tasks/workflows.rs index b86f31cbd26321998d1b1c26d94459d512e7d817..df0dfb772af8304353b802b1fc0a6d5eb257ed30 100644 --- a/tooling/xtask/src/tasks/workflows.rs +++ b/tooling/xtask/src/tasks/workflows.rs @@ -6,8 +6,13 @@ use std::path::Path; mod danger; mod nix_build; mod release_nightly; +mod run_action_checks; mod run_bundling; +mod run_docs_checks; +mod run_license_checks; +mod run_style_checks; +mod run_tests; mod runners; mod steps; mod vars; @@ -23,8 +28,17 @@ pub fn run_workflows(_: GenerateWorkflowArgs) -> Result<()> { ("nix_build.yml", nix_build::nix_build()), ("run_bundling.yml", run_bundling::run_bundling()), ("release_nightly.yml", release_nightly::release_nightly()), - // ("run_tests.yml", run_tests::run_tests()), - // ("release.yml", release::release()), + ("run_tests.yml", run_tests::run_tests()), + ("run_docs_checks.yml", run_docs_checks::run_docs_checks()), + ("run_style_checks.yml", run_style_checks::run_style_checks()), + ( + "run_action_checks.yml", + run_action_checks::run_action_checks(), + ), + ( + "run_license_checks.yml", + run_license_checks::run_license_checks(), + ), // ("release.yml", release::release()), ]; fs::create_dir_all(dir) .with_context(|| format!("Failed to create directory: {}", dir.display()))?; diff --git a/tooling/xtask/src/tasks/workflows/danger.rs b/tooling/xtask/src/tasks/workflows/danger.rs index e4121d8f5c20852f1d7eda446a2742c82ef80fb9..6ae7543a76480b37ca53d96d3f682c06b3d073e8 100644 --- a/tooling/xtask/src/tasks/workflows/danger.rs +++ b/tooling/xtask/src/tasks/workflows/danger.rs @@ -21,7 +21,7 @@ pub fn danger() -> Workflow { .cond(Expression::new( "github.repository_owner == 'zed-industries'", )) - .runs_on(runners::LINUX_CHEAP) + .runs_on(runners::LINUX_SMALL) .add_step(steps::checkout_repo()) .add_step(steps::setup_pnpm()) .add_step( diff --git a/tooling/xtask/src/tasks/workflows/nix_build.rs b/tooling/xtask/src/tasks/workflows/nix_build.rs index 1406f2a1e12518c39d65d208205d6abd3ea38bb4..d76741f59e25f9d5351421ad2cbfae030d1d943d 100644 --- a/tooling/xtask/src/tasks/workflows/nix_build.rs +++ b/tooling/xtask/src/tasks/workflows/nix_build.rs @@ -1,6 +1,7 @@ use crate::tasks::workflows::{ + run_tests::run_tests_in, runners::{Arch, Platform}, - steps::NamedJob, + steps::{FluentBuilder, NamedJob}, }; use super::{runners, steps, steps::named, vars}; @@ -9,46 +10,35 @@ use indoc::indoc; /// Generates the nix.yml workflow pub fn nix_build() -> Workflow { - // todo(ci) instead of having these as optional YAML inputs, - // should we just generate two copies of the job (one for release-nightly - // and one for CI?) - let (input_flake_output, flake_output) = vars::input( - "flake-output", - WorkflowCallInput { - input_type: "string".into(), - default: Some("default".into()), - ..Default::default() - }, - ); - let (input_cachix_filter, cachix_filter) = vars::input( - "cachix-filter", - WorkflowCallInput { - input_type: "string".into(), - ..Default::default() - }, - ); - let linux_x86 = build_nix( Platform::Linux, Arch::X86_64, - &input_flake_output, - Some(&input_cachix_filter), + "debug", + Some("-zed-editor-[0-9.]*-nightly"), &[], ); let mac_arm = build_nix( Platform::Mac, Arch::ARM64, - &input_flake_output, - Some(&input_cachix_filter), + "debug", + Some("-zed-editor-[0-9.]*-nightly"), &[], ); named::workflow() - .on(Event::default().workflow_call( - WorkflowCall::default() - .add_input(flake_output.0, flake_output.1) - .add_input(cachix_filter.0, cachix_filter.1), - )) + .map(|workflow| { + run_tests_in( + &[ + "nix/**", + "flake.*", + "Cargo.*", + "rust-toolchain.toml", + ".cargo/config.toml", + ], + workflow, + ) + }) + .add_event(Event::default().workflow_call(WorkflowCall::default())) .add_job(linux_x86.name, linux_x86.job) .add_job(mac_arm.name, mac_arm.job) } diff --git a/tooling/xtask/src/tasks/workflows/release_nightly.rs b/tooling/xtask/src/tasks/workflows/release_nightly.rs index 4e203f6934d50ec869068d237bcf8fd193678736..7d7de5b289572c49eeccc103979a7518bec82d44 100644 --- a/tooling/xtask/src/tasks/workflows/release_nightly.rs +++ b/tooling/xtask/src/tasks/workflows/release_nightly.rs @@ -1,6 +1,7 @@ use crate::tasks::workflows::{ nix_build::build_nix, run_bundling::bundle_mac, + run_tests::run_platform_tests, runners::{Arch, Platform}, steps::NamedJob, vars::{mac_bundle_envs, windows_bundle_envs}, @@ -32,8 +33,8 @@ pub fn release_nightly() -> Workflow { .collect(); let style = check_style(); - let tests = run_tests(Platform::Mac); - let windows_tests = run_tests(Platform::Windows); + let tests = run_platform_tests(Platform::Mac); + let windows_tests = run_platform_tests(Platform::Windows); let bundle_mac_x86 = bundle_mac_nightly(Arch::X86_64, &[&style, &tests]); let bundle_mac_arm = bundle_mac_nightly(Arch::ARM64, &[&style, &tests]); let linux_x86 = bundle_linux_nightly(Arch::X86_64, &[&style, &tests]); @@ -111,26 +112,6 @@ fn release_job(deps: &[&NamedJob]) -> Job { } } -fn run_tests(platform: Platform) -> NamedJob { - let runner = match platform { - Platform::Windows => runners::WINDOWS_DEFAULT, - Platform::Linux => runners::LINUX_DEFAULT, - Platform::Mac => runners::MAC_DEFAULT, - }; - NamedJob { - name: format!("run_tests_{platform}"), - job: release_job(&[]) - .runs_on(runner) - .add_step(steps::checkout_repo()) - .add_step(steps::setup_cargo_config(platform)) - .add_step(steps::setup_node()) - .add_step(steps::cargo_install_nextest(platform)) - .add_step(steps::clear_target_dir_if_large(platform)) - .add_step(steps::cargo_nextest(platform)) - .add_step(steps::cleanup_cargo_config(platform)), - } -} - fn bundle_mac_nightly(arch: Arch, deps: &[&NamedJob]) -> NamedJob { let platform = Platform::Mac; NamedJob { @@ -150,7 +131,7 @@ fn bundle_mac_nightly(arch: Arch, deps: &[&NamedJob]) -> NamedJob { fn bundle_linux_nightly(arch: Arch, deps: &[&NamedJob]) -> NamedJob { let platform = Platform::Linux; - let mut job = release_job(deps) + let mut job = steps::release_job(deps) .runs_on(arch.linux_bundler()) .add_step(steps::checkout_repo()) .add_step(steps::setup_sentry()) @@ -176,7 +157,7 @@ fn bundle_windows_nightly(arch: Arch, deps: &[&NamedJob]) -> NamedJob { let platform = Platform::Windows; NamedJob { name: format!("bundle_windows_nightly_{arch}"), - job: release_job(deps) + job: steps::release_job(deps) .runs_on(runners::WINDOWS_DEFAULT) .envs(windows_bundle_envs()) .add_step(steps::checkout_repo()) @@ -190,8 +171,8 @@ fn bundle_windows_nightly(arch: Arch, deps: &[&NamedJob]) -> NamedJob { fn update_nightly_tag_job(deps: &[&NamedJob]) -> NamedJob { NamedJob { name: "update_nightly_tag".to_owned(), - job: release_job(deps) - .runs_on(runners::LINUX_CHEAP) + job: steps::release_job(deps) + .runs_on(runners::LINUX_SMALL) .add_step(steps::checkout_repo().add_with(("fetch-depth", 0))) .add_step(update_nightly_tag()) .add_step(create_sentry_release()), diff --git a/tooling/xtask/src/tasks/workflows/run_action_checks.rs b/tooling/xtask/src/tasks/workflows/run_action_checks.rs new file mode 100644 index 0000000000000000000000000000000000000000..b0b7555e3251b1963e1a64d6437aa863f5d1d1e6 --- /dev/null +++ b/tooling/xtask/src/tasks/workflows/run_action_checks.rs @@ -0,0 +1,61 @@ +use gh_workflow::*; + +use crate::tasks::workflows::{ + run_tests::run_tests_in, + runners, + steps::{self, FluentBuilder, NamedJob, named, release_job}, +}; + +pub(crate) fn run_action_checks() -> Workflow { + let action_checks = actionlint(); + let shell_checks = shellcheck(); + + named::workflow() + .map(|workflow| { + run_tests_in( + &[ + ".github/workflows/**", + ".github/actions/**", + ".github/actionlint.yml", + "script/**", + ], + workflow, + ) + }) + .add_job(action_checks.name, action_checks.job) + .add_job(shell_checks.name, shell_checks.job) +} +const ACTION_LINT_STEP_ID: &'static str = "get_actionlint"; + +fn actionlint() -> NamedJob { + named::job( + release_job(&[]) + .runs_on(runners::LINUX_SMALL) + .add_step(steps::checkout_repo()) + .add_step(download_actionlint()) + .add_step(run_actionlint()), + ) +} + +fn shellcheck() -> NamedJob { + named::job( + release_job(&[]) + .runs_on(runners::LINUX_SMALL) + .add_step(steps::checkout_repo()) + .add_step(run_shellcheck()), + ) +} + +fn download_actionlint() -> Step { + named::bash("bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)").id(ACTION_LINT_STEP_ID) +} + +fn run_actionlint() -> Step { + named::bash(indoc::indoc! {r#" + ${{ steps.get_actionlint.outputs.executable }} -color + "#}) +} + +fn run_shellcheck() -> Step { + named::bash("./script/shellcheck-scripts error") +} diff --git a/tooling/xtask/src/tasks/workflows/run_bundling.rs b/tooling/xtask/src/tasks/workflows/run_bundling.rs index ee3d5b2a7558af7b8561952836badcd38d20f01e..2e83678967ca030ec64493ec0d802ba42664496b 100644 --- a/tooling/xtask/src/tasks/workflows/run_bundling.rs +++ b/tooling/xtask/src/tasks/workflows/run_bundling.rs @@ -1,5 +1,5 @@ use crate::tasks::workflows::{ - steps::named, + steps::{FluentBuilder, named}, vars::{mac_bundle_envs, windows_bundle_envs}, }; @@ -76,16 +76,12 @@ fn bundle_linux(arch: runners::Arch) -> Job { vars::GITHUB_SHA, arch.triple() ); - let mut job = bundle_job() + bundle_job() .runs_on(arch.linux_bundler()) .add_step(steps::checkout_repo()) .add_step(steps::setup_sentry()) - .add_step(steps::script("./script/linux")); - // todo(ci) can we do this on arm too? - if arch == runners::Arch::X86_64 { - job = job.add_step(steps::script("./script/install-mold")); - } - job.add_step(steps::script("./script/bundle-linux")) + .map(steps::install_linux_dependencies) + .add_step(steps::script("./script/bundle-linux")) .add_step(steps::upload_artifact( &artifact_name, "target/release/zed-*.tar.gz", diff --git a/tooling/xtask/src/tasks/workflows/run_docs_checks.rs b/tooling/xtask/src/tasks/workflows/run_docs_checks.rs new file mode 100644 index 0000000000000000000000000000000000000000..d76b5df571b35143ea48e4370027b3e9e3d9a788 --- /dev/null +++ b/tooling/xtask/src/tasks/workflows/run_docs_checks.rs @@ -0,0 +1,55 @@ +use crate::tasks::workflows::{ + run_tests::run_tests_in, + runners::{self, Platform}, + steps::{self, FluentBuilder, NamedJob, named, release_job}, +}; +use gh_workflow::*; + +pub(crate) fn run_docs_checks() -> Workflow { + let docs = check_docs(); + named::workflow() + .map(|workflow| run_tests_in(&["docs/**", "crates/docs_preprocessor/**"], workflow)) + .add_job(docs.name, docs.job) +} + +fn check_docs() -> NamedJob { + named::job( + release_job(&[]) + .runs_on(runners::LINUX_LARGE) + .add_step(steps::checkout_repo()) + .add_step(steps::setup_cargo_config(Platform::Linux)) + // todo(ci): un-inline build_docs/action.yml here + .add_step(steps::cache_rust_dependencies()) + .add_step(lychee_link_check("./docs/src/**/*")) // check markdown links + .map(steps::install_linux_dependencies) + .add_step(install_mdbook()) + .add_step(build_docs()) + .add_step(lychee_link_check("target/deploy/docs")), // check links in generated html + ) +} + +fn lychee_link_check(dir: &str) -> Step { + named::uses( + "lycheeverse", + "lychee-action", + "82202e5e9c2f4ef1a55a3d02563e1cb6041e5332", + ) // v2.4.1 + .add_with(("args", format!("--no-progress --exclude '^http' '{dir}'"))) + .add_with(("fail", true)) +} + +fn install_mdbook() -> Step { + named::uses( + "peaceiris", + "actions-mdbook", + "ee69d230fe19748b7abf22df32acaa93833fad08", // v2 + ) + .with(("mdbook-version", "0.4.37")) +} + +fn build_docs() -> Step { + named::bash(indoc::indoc! {r#" + mkdir -p target/deploy + mdbook build ./docs --dest-dir=../target/deploy/docs/ + "#}) +} diff --git a/tooling/xtask/src/tasks/workflows/run_license_checks.rs b/tooling/xtask/src/tasks/workflows/run_license_checks.rs new file mode 100644 index 0000000000000000000000000000000000000000..a91c4ecc2f94d950277360b16a639dfcaf460ddc --- /dev/null +++ b/tooling/xtask/src/tasks/workflows/run_license_checks.rs @@ -0,0 +1,49 @@ +use gh_workflow::{Job, Workflow}; + +use crate::tasks::workflows::{ + run_tests::run_tests_in, + runners::{self, LINUX_MEDIUM}, + steps::{self, FluentBuilder, NamedJob, named}, +}; + +pub fn run_license_checks() -> Workflow { + let check_licenses = check_licenses(); + let build_licenses = build_licenses(); + + named::workflow() + .map(|workflow| { + run_tests_in( + &[ + // no Cargo.toml - the case where Cargo.lock isn't updated + // is checked by the `check_dependencies` job as part of the + // `run_tests` workflow + "Cargo.lock", + "**/Cargo.lock", + "script/*licenses", + "**/LICENSE*", + ".github/workflows/run_license_checks.yml", + ], + workflow, + ) + }) + .add_job(check_licenses.name, check_licenses.job) + .add_job(build_licenses.name, build_licenses.job) +} + +fn check_licenses() -> NamedJob { + named::job( + Job::default() + .runs_on(runners::LINUX_SMALL) + .add_step(steps::checkout_repo()) + .add_step(steps::script("./script/check-licenses")), + ) +} + +fn build_licenses() -> NamedJob { + named::job( + Job::default() + .runs_on(LINUX_MEDIUM) + .add_step(steps::checkout_repo()) + .add_step(steps::script("./script/generate-licenses")), + ) +} diff --git a/tooling/xtask/src/tasks/workflows/run_style_checks.rs b/tooling/xtask/src/tasks/workflows/run_style_checks.rs new file mode 100644 index 0000000000000000000000000000000000000000..f5f9488816120580bf4385bd08d5a542a912ac4a --- /dev/null +++ b/tooling/xtask/src/tasks/workflows/run_style_checks.rs @@ -0,0 +1,37 @@ +use crate::tasks::workflows::{runners, steps::release_job}; + +use super::{ + run_tests::run_tests_in, + steps::{self, FluentBuilder as _, NamedJob, named}, +}; +use gh_workflow::*; + +pub(crate) fn run_style_checks() -> Workflow { + let style = check_style(); + named::workflow() + .map(|workflow| run_tests_in(&[], workflow)) + .add_job(style.name, style.job) +} + +pub(crate) fn check_style() -> NamedJob { + named::job( + release_job(&[]) + .runs_on(runners::LINUX_MEDIUM) + .add_step(steps::checkout_repo()) + .add_step(steps::setup_pnpm()) + .add_step(steps::script("./script/prettier")) + .add_step(steps::script("./script/check-todos")) + .add_step(steps::script("./script/check-keymaps")) + .add_step(check_for_typos()) + .add_step(steps::cargo_fmt()), + ) +} + +fn check_for_typos() -> Step { + named::uses( + "crate-ci", + "typos", + "80c8a4945eec0f6d464eaf9e65ed98ef085283d1", + ) // v1.38.1 + .with(("config", "./typos.toml")) +} diff --git a/tooling/xtask/src/tasks/workflows/run_tests.rs b/tooling/xtask/src/tasks/workflows/run_tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..5c07743ead91f01c6eb24284c0ea31856f77e74e --- /dev/null +++ b/tooling/xtask/src/tasks/workflows/run_tests.rs @@ -0,0 +1,216 @@ +use gh_workflow::{Concurrency, Event, Expression, PullRequest, Push, Run, Step, Use, Workflow}; + +use super::{ + runners::{self, Platform}, + steps::{self, FluentBuilder, NamedJob, named, release_job}, +}; + +fn str_vec(values: &'static [&'static str]) -> Vec { + values.into_iter().map(ToString::to_string).collect() +} + +pub(crate) fn run_tests_in(paths: &'static [&'static str], workflow: Workflow) -> Workflow { + let paths = str_vec(paths); + workflow + .add_event(Event::default() + .push( + Push::default() + .branches( + [ + "main", + "v[0-9]+.[0-9]+.x", // any release branch + ] + .map(String::from), + ) + .paths(paths.clone()) + , + ) + .pull_request( + PullRequest::default().branches( + [ + "**", // all branches + ] + .map(String::from), + ) + .paths(paths), + )) + .concurrency(Concurrency::default() + .group("${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}") + .cancel_in_progress(true) + ) + .add_env(( "CARGO_TERM_COLOR", "always" )) + .add_env(( "RUST_BACKTRACE", 1 )) + .add_env(( "CARGO_INCREMENTAL", 0 )) +} + +pub(crate) fn run_tests() -> Workflow { + let windows_tests = run_platform_tests(Platform::Windows); + let linux_tests = run_platform_tests(Platform::Linux); + let mac_tests = run_platform_tests(Platform::Mac); + let migrations = check_postgres_and_protobuf_migrations(); + let doctests = doctests(); + let check_dependencies = check_dependencies(); + let check_other_binaries = check_workspace_binaries(); + + named::workflow() + .map(|workflow| { + run_tests_in( + &[ + "!docs/**", + "!script/update_top_ranking_issues/**", + "!.github/ISSUE_TEMPLATE/**", + "!.github/workflows/**", + ".github/workflows/run_tests.yml", // re-include this workflow so it re-runs when changed + ], + workflow, + ) + }) + .add_job(windows_tests.name, windows_tests.job) + .add_job(linux_tests.name, linux_tests.job) + .add_job(mac_tests.name, mac_tests.job) + .add_job(migrations.name, migrations.job) + .add_job(doctests.name, doctests.job) + .add_job(check_dependencies.name, check_dependencies.job) + .add_job(check_other_binaries.name, check_other_binaries.job) +} + +fn check_dependencies() -> NamedJob { + fn install_cargo_machete() -> Step { + named::uses( + "clechasseur", + "rs-cargo", + "8435b10f6e71c2e3d4d3b7573003a8ce4bfc6386", // v2 + ) + .add_with(("command", "install")) + .add_with(("args", "cargo-machete@0.7.0")) + } + + fn run_cargo_machete() -> Step { + named::uses( + "clechasseur", + "rs-cargo", + "8435b10f6e71c2e3d4d3b7573003a8ce4bfc6386", // v2 + ) + .add_with(("command", "machete")) + } + + fn check_cargo_lock() -> Step { + named::bash("cargo update --locked --workspace") + } + + fn check_vulnerable_dependencies() -> Step { + named::uses( + "actions", + "dependency-review-action", + "67d4f4bd7a9b17a0db54d2a7519187c65e339de8", // v4 + ) + .if_condition(Expression::new("github.event_name == 'pull_request'")) + .with(("license-check", false)) + } + + named::job( + release_job(&[]) + .runs_on(runners::LINUX_SMALL) + .add_step(steps::checkout_repo()) + .add_step(install_cargo_machete()) + .add_step(run_cargo_machete()) + .add_step(check_cargo_lock()) + .add_step(check_vulnerable_dependencies()), + ) +} + +fn check_workspace_binaries() -> NamedJob { + named::job( + release_job(&[]) + .runs_on(runners::LINUX_LARGE) + .add_step(steps::checkout_repo()) + .add_step(steps::setup_cargo_config(Platform::Linux)) + .map(steps::install_linux_dependencies) + .add_step(steps::script("cargo build -p collab")) + .add_step(steps::script("cargo build --workspace --bins --examples")) + .add_step(steps::cleanup_cargo_config(Platform::Linux)), + ) +} + +pub(crate) fn run_platform_tests(platform: Platform) -> NamedJob { + let runner = match platform { + Platform::Windows => runners::WINDOWS_DEFAULT, + Platform::Linux => runners::LINUX_DEFAULT, + Platform::Mac => runners::MAC_DEFAULT, + }; + NamedJob { + name: format!("run_tests_{platform}"), + job: release_job(&[]) + .runs_on(runner) + .add_step(steps::checkout_repo()) + .add_step(steps::setup_cargo_config(platform)) + .when( + platform == Platform::Linux, + steps::install_linux_dependencies, + ) + .add_step(steps::setup_node()) + .add_step(steps::clippy(platform)) + .add_step(steps::cargo_install_nextest(platform)) + .add_step(steps::clear_target_dir_if_large(platform)) + .add_step(steps::cargo_nextest(platform)) + .add_step(steps::cleanup_cargo_config(platform)), + } +} + +pub(crate) fn check_postgres_and_protobuf_migrations() -> NamedJob { + fn remove_untracked_files() -> Step { + named::bash("git clean -df") + } + + fn ensure_fresh_merge() -> Step { + named::bash(indoc::indoc! {r#" + if [ -z "$GITHUB_BASE_REF" ]; + then + echo "BUF_BASE_BRANCH=$(git merge-base origin/main HEAD)" >> "$GITHUB_ENV" + else + git checkout -B temp + git merge -q "origin/$GITHUB_BASE_REF" -m "merge main into temp" + echo "BUF_BASE_BRANCH=$GITHUB_BASE_REF" >> "$GITHUB_ENV" + fi + "#}) + } + + fn bufbuild_setup_action() -> Step { + named::uses("bufbuild", "buf-setup-action", "v1").add_with(("version", "v1.29.0")) + } + + fn bufbuild_breaking_action() -> Step { + named::uses("bufbuild", "buf-breaking-action", "v1").add_with(("input", "crates/proto/proto/")) + .add_with(("against", "https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/proto/proto/")) + } + + named::job( + release_job(&[]) + .runs_on(runners::MAC_DEFAULT) + .add_step(steps::checkout_repo().with(("fetch-depth", 0))) // fetch full history + .add_step(remove_untracked_files()) + .add_step(ensure_fresh_merge()) + .add_step(bufbuild_setup_action()) + .add_step(bufbuild_breaking_action()), + ) +} + +fn doctests() -> NamedJob { + fn run_doctests() -> Step { + named::bash(indoc::indoc! {r#" + cargo test --workspace --doc --no-fail-fast + "#}) + .id("run_doctests") + } + + named::job( + release_job(&[]) + .runs_on(runners::LINUX_DEFAULT) + .add_step(steps::checkout_repo()) + .add_step(steps::cache_rust_dependencies()) + .map(steps::install_linux_dependencies) + .add_step(steps::setup_cargo_config(Platform::Linux)) + .add_step(run_doctests()) + .add_step(steps::cleanup_cargo_config(Platform::Linux)), + ) +} diff --git a/tooling/xtask/src/tasks/workflows/runners.rs b/tooling/xtask/src/tasks/workflows/runners.rs index 02263ef42bb54dc31c10bfa07a4dde76010fdd85..d001439b175789e709bd733f7660cc3200721d0a 100644 --- a/tooling/xtask/src/tasks/workflows/runners.rs +++ b/tooling/xtask/src/tasks/workflows/runners.rs @@ -1,5 +1,8 @@ -pub const LINUX_CHEAP: Runner = Runner("namespace-profile-2x4-ubuntu-2404"); -pub const LINUX_DEFAULT: Runner = Runner("namespace-profile-16x32-ubuntu-2204"); +pub const LINUX_SMALL: Runner = Runner("namespace-profile-2x4-ubuntu-2404"); +pub const LINUX_DEFAULT: Runner = LINUX_XL; +pub const LINUX_XL: Runner = Runner("namespace-profile-16x32-ubuntu-2204"); +pub const LINUX_LARGE: Runner = Runner("namespace-profile-8x16-ubuntu-2204"); +pub const LINUX_MEDIUM: Runner = Runner("namespace-profile-4x8-ubuntu-2204"); // Using Ubuntu 20.04 for minimal glibc version pub const LINUX_X86_BUNDLER: Runner = Runner("namespace-profile-32x64-ubuntu-2004"); diff --git a/tooling/xtask/src/tasks/workflows/steps.rs b/tooling/xtask/src/tasks/workflows/steps.rs index 235fcd64b1e40c8809c4c237f4bbcdcb37874acd..e03c8e83e1d68684bc1f0e9b023444d2a07ee909 100644 --- a/tooling/xtask/src/tasks/workflows/steps.rs +++ b/tooling/xtask/src/tasks/workflows/steps.rs @@ -105,6 +105,34 @@ pub fn clear_target_dir_if_large(platform: Platform) -> Step { } } +pub(crate) fn clippy(platform: Platform) -> Step { + match platform { + Platform::Windows => named::pwsh("./script/clippy.ps1"), + _ => named::bash("./script/clippy"), + } +} + +pub(crate) fn cache_rust_dependencies() -> Step { + named::uses( + "swatinem", + "rust-cache", + "9d47c6ad4b02e050fd481d890b2ea34778fd09d6", // v2 + ) + .with(("save-if", "${{ github.ref == 'refs/heads/main' }}")) +} + +fn setup_linux() -> Step { + named::bash("./script/linux") +} + +fn install_mold() -> Step { + named::bash("./script/install-mold") +} + +pub(crate) fn install_linux_dependencies(job: Job) -> Job { + job.add_step(setup_linux()).add_step(install_mold()) +} + pub fn script(name: &str) -> Step { if name.ends_with(".ps1") { Step::new(name).run(name).shell(PWSH_SHELL) @@ -118,6 +146,78 @@ pub(crate) struct NamedJob { pub job: Job, } +pub(crate) fn release_job(deps: &[&NamedJob]) -> Job { + let job = Job::default() + .cond(Expression::new( + "github.repository_owner == 'zed-industries'", + )) + .timeout_minutes(60u32); + if deps.len() > 0 { + job.needs(deps.iter().map(|j| j.name.clone()).collect::>()) + } else { + job + } +} + +impl FluentBuilder for Job {} +impl FluentBuilder for Workflow {} + +/// A helper trait for building complex objects with imperative conditionals in a fluent style. +/// Copied from GPUI to avoid adding GPUI as dependency +/// todo(ci) just put this in gh-workflow +#[allow(unused)] +pub(crate) trait FluentBuilder { + /// Imperatively modify self with the given closure. + fn map(self, f: impl FnOnce(Self) -> U) -> U + where + Self: Sized, + { + f(self) + } + + /// Conditionally modify self with the given closure. + fn when(self, condition: bool, then: impl FnOnce(Self) -> Self) -> Self + where + Self: Sized, + { + self.map(|this| if condition { then(this) } else { this }) + } + + /// Conditionally modify self with the given closure. + fn when_else( + self, + condition: bool, + then: impl FnOnce(Self) -> Self, + else_fn: impl FnOnce(Self) -> Self, + ) -> Self + where + Self: Sized, + { + self.map(|this| if condition { then(this) } else { else_fn(this) }) + } + + /// Conditionally unwrap and modify self with the given closure, if the given option is Some. + fn when_some(self, option: Option, then: impl FnOnce(Self, T) -> Self) -> Self + where + Self: Sized, + { + self.map(|this| { + if let Some(value) = option { + then(this, value) + } else { + this + } + }) + } + /// Conditionally unwrap and modify self with the given closure, if the given option is None. + fn when_none(self, option: &Option, then: impl FnOnce(Self) -> Self) -> Self + where + Self: Sized, + { + self.map(|this| if option.is_some() { this } else { then(this) }) + } +} + // (janky) helper to generate steps with a name that corresponds // to the name of the calling function. pub(crate) mod named { diff --git a/tooling/xtask/src/tasks/workflows/vars.rs b/tooling/xtask/src/tasks/workflows/vars.rs index 6220e3960b091dc04798283ff7239a56ffef5eb0..9377b697bb1393ccaaad78e7bc402ec0269b47af 100644 --- a/tooling/xtask/src/tasks/workflows/vars.rs +++ b/tooling/xtask/src/tasks/workflows/vars.rs @@ -1,4 +1,4 @@ -use gh_workflow::{Env, WorkflowCallInput}; +use gh_workflow::Env; macro_rules! secret { ($secret_name:ident) => { @@ -12,10 +12,6 @@ macro_rules! var { }; } -pub fn input(name: &str, input: WorkflowCallInput) -> (String, (&str, WorkflowCallInput)) { - return (format!("${{{{ inputs.{name} }}}}"), (name, input)); -} - secret!(APPLE_NOTARIZATION_ISSUER_ID); secret!(APPLE_NOTARIZATION_KEY); secret!(APPLE_NOTARIZATION_KEY_ID);