CI: improve distribution of cases to batches (GH offers limited concurrency)

See https://docs.github.com/en/actions/reference/limits#job-concurrency-limits-for-github-hosted-runners
This commit is contained in:
Michael Panchenko committed 2026-06-28 19:04:31 +02:00
1 parent 4b7e02239a
commit ad7f65ef13
2 files changed
+32 -73

No files matched your search

+28 -71
View File
@@ -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"