diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index b06c99cc..b54c6f77 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -24,36 +24,22 @@ jobs: # group) add a case branch below + the batch name to the matrix list. env: MARKERS_JVM: "java or csharp or fsharp or kotlin or scala or groovy or clojure or bsl" - MARKERS_NATIVE: "cpp or rust or go or zig or pascal" - MARKERS_SWIFT: "swift" # split out: swiftly toolchain install is the slowest setup, isolate + cache it - MARKERS_WEB: "typescript or svelte or vue or angular or html or scss or json or solidity or elm" - MARKERS_PYTHON: "python" - MARKERS_SCRIPTING: "ruby or php or lua or luau or bash or powershell or elixir or erlang or dart or haxe" - MARKERS_OTHER_LANGS: "terraform or rego or ansible or yaml or toml or markdown or latex or crystal or cue or fortran or ada or matlab or systemverilog or hlsl or msl or al" - # Slow / heavy toolchains, each isolated in its own batch (OS gating via the matrix excludes). - MARKERS_HASKELL: "haskell" - MARKERS_OCAML: "ocaml" - MARKERS_NIX: "nix" - MARKERS_LEAN: "lean4" - MARKERS_NICHE: "julia or r or perl" # lighter niche toolchains grouped together + MARKERS_NATIVE: "cpp or rust or go or zig or pascal or swift" # swift is macOS-only (skips elsewhere via the guard) + # other-langs: grab-bag + scripting languages + haskell (haskell skips on Windows via the guard) + MARKERS_OTHER_LANGS: "ruby or php or lua or luau or bash or powershell or elixir or erlang or dart or haxe or haskell or terraform or rego or ansible or yaml or toml or markdown or latex or crystal or cue or fortran or ada or matlab or systemverilog or hlsl or msl or al" + # niche: slow, mostly-cached toolchains. ocaml + haskell are the two slowest -- kept in separate + # batches (ocaml here, haskell in other-langs). nix + perl skip on Windows via the guard. + MARKERS_NICHE: "julia or r or perl or lean4 or nix or ocaml" strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ["3.11"] - # Test execution is split into parallel batches by pytest marker. Each batch installs ONLY - # the toolchains its languages need -- steps below are gated with `if: matrix.batch == ...`. - # Node/Python/uv stay in every batch (cheap, and needed for the venv + auto-installed LSes). - # "catch-all" carries the unmarked core-framework tests in test/serena and needs no language - # toolchains. haskell/ocaml/nix/lean are slow toolchains isolated in their own batches. - batch: [jvm, native, swift, web, python, scripting, other-langs, haskell, ocaml, nix, lean, niche, catch-all] - exclude: - # swift is macOS-only (swiftly toolchain + cache; its Linux path has never actually run) - - { os: ubuntu-latest, batch: swift } - - { os: windows-latest, batch: swift } - # haskell / nix have no native Windows support (matches the original `runner.os != 'Windows'`) - - { os: windows-latest, batch: haskell } - - { os: windows-latest, batch: nix } + # 5 batches, each installs ONLY the toolchains its languages need (steps gated by matrix.batch). + # Node/Python/uv stay in every batch (cheap, needed for the venv + auto-installed LSes). + # OS-specific languages skip via the central guards (swift -> macOS only; haskell/nix/perl -> + # not Windows), so no matrix excludes are needed. catch-all = web + python + the core framework. + batch: [jvm, native, other-langs, niche, catch-all] steps: - uses: actions/checkout@v4 - name: Free disk space @@ -196,7 +182,7 @@ jobs: # We can try again when version 3 of the action is released, where they will also use swiftly # Until then, we use custom code to install swift. Sourcekit-lsp is installed automatically with swift - name: Cache Swift toolchain (swiftly) - if: runner.os == 'macOS' && matrix.batch == 'swift' + if: runner.os == 'macOS' && matrix.batch == 'native' id: cache-swiftly uses: actions/cache@v3 with: @@ -207,7 +193,7 @@ jobs: ~/Library/Developer/Toolchains key: swiftly-${{ runner.os }}-6.1.2-v2 - name: Install Swift with swiftly (macOS) - if: runner.os == 'macOS' && matrix.batch == 'swift' + if: runner.os == 'macOS' && matrix.batch == 'native' run: | set -e # Install swiftly itself only if its binary isn't already present (e.g. restored from cache). @@ -233,34 +219,13 @@ jobs: fi echo "sourcekit-lsp: $SK" dirname "$SK" >> "$GITHUB_PATH" - - name: Install Swift with swiftly (Ubuntu) - if: runner.os == 'Linux' && matrix.batch == 'swift' - run: | - echo "=== Installing swiftly on Ubuntu ===" - # Install dependencies BEFORE Swift to avoid exit code 1 - sudo apt-get update - sudo apt-get -y install libcurl4-openssl-dev - curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz && \ - tar zxf swiftly-$(uname -m).tar.gz && \ - ./swiftly init --quiet-shell-followup && \ - . "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh" && \ - hash -r - swiftly install --use 6.1.2 - swiftly use 6.1.2 - echo "=== Adding Swift toolchain to PATH ===" - echo "$HOME/.local/share/swiftly/bin" >> $GITHUB_PATH - echo "Swiftly installed successfully!" - # Verify sourcekit-lsp is working before proceeding - echo "=== Verifying sourcekit-lsp installation ===" - which sourcekit-lsp || echo "Warning: sourcekit-lsp not found in PATH" - sourcekit-lsp --help || echo "Warning: sourcekit-lsp not responding" - name: Install Ruby - if: matrix.batch == 'scripting' + if: matrix.batch == 'other-langs' uses: ruby/setup-ruby@v1 with: ruby-version: '3.4' - name: Install Ruby language server - if: matrix.batch == 'scripting' + if: matrix.batch == 'other-langs' shell: bash run: gem install ruby-lsp - name: Install Zig @@ -327,7 +292,7 @@ jobs: echo "WARNING: verible-verilog-ls not found in PATH" fi - name: Install Lua Language Server - if: matrix.batch == 'scripting' + if: matrix.batch == 'other-langs' shell: bash run: | LUA_LS_VERSION="3.15.0" @@ -377,14 +342,14 @@ jobs: shell: bash run: uv run pip install ansible-core ansible-lint - name: Install Haxe - if: matrix.batch == 'scripting' + if: matrix.batch == 'other-langs' # The Haxe LS binary (server.js) is auto-downloaded and runs on Node.js, # but it delegates to the Haxe compiler for code analysis at runtime. uses: krdlab/setup-haxe@v2 with: haxe-version: 4.3.7 - name: Install Elm - if: matrix.batch == 'web' + if: matrix.batch == 'catch-all' shell: bash run: npm install -g elm@0.19.1-6 - name: Install Regal (Rego Language Server) @@ -519,14 +484,14 @@ jobs: fi # --- Slow / heavy language toolchains, each isolated in its own batch (OS gating via matrix excludes) --- - name: Setup Haskell toolchain - if: matrix.batch == 'haskell' + if: matrix.batch == 'other-langs' && runner.os != 'Windows' uses: haskell/ghcup-setup@v1 with: ghc: '9.12.2' cabal: '3.10.3.0' hls: '2.11.0.0' - name: Verify Haskell tools - if: matrix.batch == 'haskell' + if: matrix.batch == 'other-langs' && runner.os != 'Windows' shell: bash run: | which ghc && ghc --version @@ -537,7 +502,7 @@ jobs: echo "WARNING: haskell-language-server-wrapper not found (may be incompatible with GHC 9.12.2)" fi - name: Pre-build Haskell test project for HLS - if: matrix.batch == 'haskell' + if: matrix.batch == 'other-langs' && runner.os != 'Windows' shell: bash run: | cd test/resources/repos/haskell/test_repo @@ -545,7 +510,7 @@ jobs: cabal build --only-dependencies cabal build - name: Install OCaml and opam - if: matrix.batch == 'ocaml' + if: matrix.batch == 'niche' uses: ocaml/setup-ocaml@v3 with: ocaml-compiler: ${{ runner.os == 'Windows' && '4.14' || '5.3.x' }} @@ -554,7 +519,7 @@ jobs: ${{ runner.os == 'Windows' && 'opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset' || '' }} default: https://github.com/ocaml/opam-repository.git - name: Install OCaml packages - if: matrix.batch == 'ocaml' + if: matrix.batch == 'niche' shell: bash run: | if [ "$RUNNER_OS" = "Windows" ]; then @@ -563,12 +528,12 @@ jobs: opam install -y dune 'ocaml-lsp-server>=1.23.0' fi - name: Install Nix - if: matrix.batch == 'nix' + if: matrix.batch == 'niche' && runner.os != 'Windows' uses: cachix/install-nix-action@v30 with: nix_path: nixpkgs=channel:nixos-unstable - name: Install nixd (Nix Language Server) - if: matrix.batch == 'nix' + if: matrix.batch == 'niche' && runner.os != 'Windows' shell: bash run: | nix profile install github:nix-community/nixd @@ -577,7 +542,7 @@ jobs: fi echo "$HOME/.nix-profile/bin" >> $GITHUB_PATH - name: Build Lean 4 test project - if: matrix.batch == 'lean' + if: matrix.batch == 'niche' uses: leanprover/lean-action@v1 with: lake-package-directory: test/resources/repos/lean4/test_repo @@ -622,7 +587,7 @@ jobs: echo "PERL_MM_OPT=INSTALL_BASE=$HOME/perl5" >> $GITHUB_ENV echo "$HOME/perl5/bin" >> $GITHUB_PATH - name: Install npm deps for Angular test repo - if: matrix.batch == 'web' + if: matrix.batch == 'catch-all' shell: bash run: | if [ -d test/resources/repos/angular/test_repo ]; then @@ -649,17 +614,9 @@ jobs: case "${{ matrix.batch }}" in jvm) expr="$MARKERS_JVM" ;; native) expr="$MARKERS_NATIVE" ;; - swift) expr="$MARKERS_SWIFT" ;; - web) expr="$MARKERS_WEB" ;; - python) expr="$MARKERS_PYTHON" ;; - scripting) expr="$MARKERS_SCRIPTING" ;; other-langs) expr="$MARKERS_OTHER_LANGS" ;; - haskell) expr="$MARKERS_HASKELL" ;; - ocaml) expr="$MARKERS_OCAML" ;; - nix) expr="$MARKERS_NIX" ;; - lean) expr="$MARKERS_LEAN" ;; niche) expr="$MARKERS_NICHE" ;; - catch-all) expr="not ($MARKERS_JVM or $MARKERS_NATIVE or $MARKERS_SWIFT or $MARKERS_WEB or $MARKERS_PYTHON or $MARKERS_SCRIPTING or $MARKERS_OTHER_LANGS or $MARKERS_HASKELL or $MARKERS_OCAML or $MARKERS_NIX or $MARKERS_LEAN or $MARKERS_NICHE)" ;; + catch-all) expr="not ($MARKERS_JVM or $MARKERS_NATIVE or $MARKERS_OTHER_LANGS or $MARKERS_NICHE)" ;; *) echo "Unknown batch: ${{ matrix.batch }}" >&2; exit 1 ;; esac echo "Marker expression: $expr" diff --git a/test/conftest.py b/test/conftest.py index 34487aa7..a8cf3394 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -243,6 +243,7 @@ Flag indicating whether the tests are running in the GitHub CI environment. """ is_windows = platform.system() == "Windows" +is_macos = platform.system() == "Darwin" _LANGUAGE_PYTEST_MARKERS: dict[Language, list[MarkDecorator | Mark]] = { @@ -400,8 +401,9 @@ def _determine_disabled_languages() -> list[Language]: # === 3. Disabled wherever the precondition is missing (including on CI) === # 3a. Platform precondition: these language servers have no native Windows support. if is_windows: - result.append(Language.ANSIBLE) - result.append(Language.SWIFT) + result.append(Language.ANSIBLE) # ansible-language-server has no native Windows support + if not is_macos: + result.append(Language.SWIFT) # swiftly toolchain is only set up on the macOS native batch # 3b. Toolchain / language-server availability (the LS/compiler must be on PATH or installed). if _sh.which("clangd") is None: result.append(Language.CPP)