chore(ci): cut CI wall clock from ~50m to ~14m (#784)

* fix(ci): build the workspace once per e2e job

* perf(ci): cache rust compilations with sccache

* fix(ci): stop sccache idling out mid-compile and cancel superseded runs

* fix(tests): poll for the new root index instead of a fixed sleep

* perf(ci): cache release target builds with sccache
This commit is contained in:
Dmitriy Kovalenko
2026-08-16 07:00:14 -07:00
committed by GitHub
parent 232288c60b
commit cf2130090e
11 changed files with 132 additions and 8 deletions
+21
View File
@@ -23,12 +23,23 @@ env:
CARGO_PROFILE_RELEASE_LTO: thin
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 16
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') }}
jobs:
lua-tests:
name: e2e (${{ matrix.os }})
runs-on: ${{ matrix.os }}
# e2e tests could be flaky on CI so we do not block release creation if they failed
continue-on-error: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
# alpine-musl installs rust via apk and has no sccache, so keep this scoped.
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: sccache
# fff-search alone exceeds the 600s default on windows, and the server
# sees no new requests while it compiles, so it would idle out mid-unit.
SCCACHE_IDLE_TIMEOUT: "0"
strategy:
fail-fast: false
matrix:
@@ -53,10 +64,20 @@ jobs:
cache-key: "v2-lua-e2e"
rustflags: ""
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.11
with:
version: v0.17.0
- name: Build Rust binary
shell: bash
run: make build-e2e
- name: sccache stats
if: always()
shell: bash
run: sccache --show-stats
- name: Verify Windows DLL has no unexpected dependencies
if: matrix.os == 'windows-latest'
shell: pwsh
+4
View File
@@ -12,6 +12,10 @@ on:
- '**.md'
- 'doc/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') }}
jobs:
lua-ls:
name: lua-language-server type check
+4
View File
@@ -12,6 +12,10 @@ on:
- '**.md'
- 'doc/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') }}
jobs:
check:
runs-on: ubuntu-22.04
+14
View File
@@ -17,6 +17,15 @@ env:
MACOSX_DEPLOYMENT_TARGET: "13.0"
CARGO_PROFILE_RELEASE_LTO: thin
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 16
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: sccache
# fff-search alone exceeds the 600s default on windows, and the server sees
# no new requests while it compiles, so it would idle out mid-unit.
SCCACHE_IDLE_TIMEOUT: "0"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') }}
jobs:
test:
@@ -39,6 +48,11 @@ jobs:
cache-on-failure: true
cache-key: "v1-rust-python"
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.11
with:
version: v0.17.0
- name: Setup uv
uses: astral-sh/setup-uv@v5
with:
+31
View File
@@ -17,10 +17,18 @@ on:
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') }}
jobs:
build-nvim:
name: Build Neovim ${{ matrix.target }}
runs-on: ${{ matrix.os }}
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: sccache
SCCACHE_IDLE_TIMEOUT: "0"
permissions:
contents: read
id-token: write
@@ -91,6 +99,11 @@ jobs:
with:
key: nvim-${{ matrix.target }}
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.11
with:
version: v0.17.0
- name: Install Zig
uses: mlugg/setup-zig@v2
with:
@@ -146,6 +159,10 @@ jobs:
build-c:
name: Build C FFI ${{ matrix.target }}
runs-on: ${{ matrix.os }}
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: sccache
SCCACHE_IDLE_TIMEOUT: "0"
permissions:
contents: read
strategy:
@@ -228,6 +245,11 @@ jobs:
with:
key: c-${{ matrix.target }}
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.11
with:
version: v0.17.0
- name: Install Zig
uses: mlugg/setup-zig@v2
with:
@@ -294,6 +316,10 @@ jobs:
build-mcp:
name: Build MCP ${{ matrix.target }}
runs-on: ${{ matrix.os }}
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: sccache
SCCACHE_IDLE_TIMEOUT: "0"
permissions:
contents: read
strategy:
@@ -344,6 +370,11 @@ jobs:
with:
key: mcp-${{ matrix.target }}
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.11
with:
version: v0.17.0
- name: Install Zig
uses: mlugg/setup-zig@v2
with:
+37 -1
View File
@@ -17,6 +17,15 @@ env:
# Ensure consistent macOS deployment target across all compiled objects
# (Rust, cc-compiled C code, and Zig-compiled zlob) to avoid linker warnings
MACOSX_DEPLOYMENT_TARGET: "13"
# RUSTC_WRAPPER is set per job, since cargo fmt runs without sccache.
SCCACHE_GHA_ENABLED: "true"
# fff-search alone exceeds the 600s default on windows, and the server sees
# no new requests while it compiles, so it would idle out mid-unit.
SCCACHE_IDLE_TIMEOUT: "0"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') }}
jobs:
test:
@@ -46,7 +55,14 @@ jobs:
cache-key: "v1-rust"
components: rustfmt, clippy
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.11
with:
version: v0.17.0
- name: Run tests
env:
RUSTC_WRAPPER: sccache
# fff-python requires full python o3 machinery which is very slow
run: cargo test --no-default-features --features zlob --workspace --exclude fff-nvim --exclude fff-python
@@ -66,6 +82,7 @@ jobs:
FFF_STRESS_CASES: "5"
FFF_STRESS_MIN_OPS: "30"
FFF_STRESS_MAX_OPS: "60"
RUSTC_WRAPPER: sccache
steps:
- uses: actions/checkout@v5
@@ -82,6 +99,11 @@ jobs:
cache-key: "v1-rust-stress-${{ matrix.os }}"
components: rustfmt, clippy
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.11
with:
version: v0.17.0
- name: Stress test seeded
shell: bash
run: make test-stress-seeded
@@ -125,7 +147,14 @@ jobs:
cache-on-failure: true
cache-key: "v1-rust-i686"
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.11
with:
version: v0.17.0
- name: Build fff-search for i686
env:
RUSTC_WRAPPER: sccache
run: cargo build -p fff-search --target i686-unknown-linux-gnu
fmt:
@@ -158,6 +187,13 @@ jobs:
with:
toolchain: stable
components: clippy
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.11
with:
version: v0.17.0
- name: Run clippy
env:
RUSTC_WRAPPER: sccache
run: cargo clippy --no-default-features --features zlob -- -D warnings
+4
View File
@@ -12,6 +12,10 @@ on:
env:
CLICOLOR: 1
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') }}
jobs:
spelling:
name: Spell Check with Typos
+4
View File
@@ -20,6 +20,10 @@ on:
env:
CLICOLOR: 1
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') }}
jobs:
stylua:
name: Check lua files using Stylua
+5 -5
View File
@@ -123,7 +123,7 @@ SMOKE_BIN := $(TARGET_DIR)/fff_c_smoke
SMOKE_SRC := crates/fff-c/tests/smoke.c
SMOKE_INCLUDE := crates/fff-c/include
test-c-smoke: build
test-c-smoke: build-e2e
$(CC) $(CFLAGS) -I $(SMOKE_INCLUDE) -L $(TARGET_DIR) \
-Wl,-rpath,@loader_path/../target/release \
-Wl,-rpath,$$(pwd)/$(TARGET_DIR) \
@@ -136,7 +136,7 @@ test-c-api: test-c-smoke
# neovim instance swallows internal crashes and doesn't rise the the error exiting silently
# so check the stdout in case the sigsegv coming out of fff was printed (actual regression).
# Output is streamed live via `tee`; pipefail (set above) propagates nvim's exit.
test-lua: test-setup build
test-lua: test-setup build-e2e
@logfile=$$(mktemp); \
trap 'rm -f "$$logfile"' EXIT; \
nvim --headless -u tests/minimal_init.lua \
@@ -148,7 +148,7 @@ test-lua: test-setup build
exit 1; \
fi
test-lua-snap: test-setup build
test-lua-snap: test-setup build-e2e
@logfile=$$(mktemp); \
trap 'rm -f "$$logfile"' EXIT; \
nvim --headless -u tests/minimal_init.lua \
@@ -164,13 +164,13 @@ test-version: test-setup
nvim --headless -u tests/minimal_init.lua \
-c "PlenaryBustedFile tests/version_spec.lua" 2>&1
prepare-bun: build sync-js-api
prepare-bun: build-e2e sync-js-api
mkdir -p packages/fff-bun/bin
cp target/release/libfff_c.dylib packages/fff-bun/bin/ 2>/dev/null || true; \
cp target/release/libfff_c.so packages/fff-bun/bin/ 2>/dev/null || true; \
cp target/release/fff_c.dll packages/fff-bun/bin/ 2>/dev/null || true
prepare-node: build sync-js-api
prepare-node: build-e2e sync-js-api
mkdir -p packages/fff-node/bin
cp target/release/libfff_c.dylib packages/fff-node/bin/ 2>/dev/null || true; \
cp target/release/libfff_c.so packages/fff-node/bin/ 2>/dev/null || true; \
+1 -1
View File
@@ -11,7 +11,7 @@ workspace = true
[lib]
path = "src/lib.rs"
crate-type = ["rlib", "staticlib", "cdylib"]
crate-type = ["rlib"]
[[bench]]
name = "parse_bench"
+7 -1
View File
@@ -218,7 +218,13 @@ describe('programmatic search APIs', function()
local before = fff.content_search(marker)
assert.are.equal(0, #before.items, 'marker leaked into primary fff tree')
local result = fff.content_search(marker, { cwd = sandbox_root })
-- Poll instead of asserting on the first grep: the index of the new root
-- can lag a mkdir by a few ms on CI, which flaked on linux too.
local result
vim.wait(2000, function()
result = fff.content_search(marker, { cwd = sandbox_root })
return #result.items > 0
end, 50)
assert.is_true(#result.items > 0, 'cwd switch did not surface match from the new root')
end)
end)