name: e2e Tests on: push: branches: [main] paths-ignore: - '**.md' - 'doc/**' pull_request: branches: [main] paths-ignore: - '**.md' - 'doc/**' env: CARGO_TERM_COLOR: always MACOSX_DEPLOYMENT_TARGET: "13" # Force Node 24 for all JS-based actions to avoid the libuv # process_title assertion crash on Windows (known Node 20 bug). FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true 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' }} strategy: fail-fast: false matrix: include: - os: ubuntu-latest - os: macos-latest - os: windows-latest target: x86_64-pc-windows-msvc steps: - uses: actions/checkout@v5 - uses: oven-sh/setup-bun@v2 - uses: actions/setup-node@v6 - name: Install Zig uses: mlugg/setup-zig@v2 with: version: 0.16.0 - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1.15.4 with: cache: true cache-on-failure: false cache-key: "v2-lua-e2e" rustflags: "" target: ${{ matrix.target || '' }} - name: Build Rust binary (Windows) if: matrix.target run: cargo build --release --target ${{ matrix.target }} -p fff-nvim --no-default-features --features zlob - name: Copy binary to target/release (Windows) if: matrix.target shell: bash run: | cp target/${{ matrix.target }}/release/fff_nvim.dll target/release/fff_nvim.dll - name: Verify Windows DLL has no unexpected dependencies if: matrix.target shell: pwsh run: | # Find dumpbin via vswhere (always available on GitHub Actions Windows runners) $vsPath = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath $dumpbin = Get-ChildItem "$vsPath" -Recurse -Filter "dumpbin.exe" | Select-Object -First 1 if (-not $dumpbin) { Write-Error "dumpbin.exe not found"; exit 1 } $deps = & $dumpbin.FullName /DEPENDENTS target\release\fff_nvim.dll | Out-String Write-Host $deps # zlob must be statically linked - fail if zlob.dll appears as a dependency if ($deps -match 'zlob\.dll') { Write-Error "fff_nvim.dll has unexpected dynamic dependency on zlob.dll - zlob should be statically linked" exit 1 } - name: Build Rust binary if: ${{ !matrix.target }} run: cargo build --release -p fff-nvim --no-default-features --features zlob - name: Install Neovim uses: rhysd/action-setup-vim@v1 with: neovim: true version: v0.10.4 - name: Clone plenary.nvim shell: bash run: git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ../plenary.nvim - name: Run Lua tests shell: bash run: make test-lua - name: Dump fff trace log on failure if: failure() shell: bash run: | # init_tracing writes session files named fff-test++.log found=0 for f in fff-test*.log; do [ -f "$f" ] || continue found=1 echo "=== $f ===" cat "$f" done if [ "$found" = 0 ]; then echo "(no log file produced)" fi - name: Run version resolution tests shell: bash run: make test-version - name: Run non windows tests shell: bash if: ${{ matrix.os != 'windows-latest' }} run: | make test-bun make test-c-api - name: Verify bun --compile shell: bash run: make test-bun-compile - name: Install Node.js if: ${{ matrix.os != 'ubuntu-latest' }} uses: actions/setup-node@v6 with: node-version: "25" - name: Install node dependencies shell: bash run: cd packages/fff-node && npm install - name: Run node tests shell: bash run: make test-node # Regression for https://github.com/dmtrKovalenko/fff/issues/480: build & # run @ff-labs/fff-node end-to-end on real Alpine Linux (musl). Forces # findBinary() through the npm-package resolver so detectLinuxLibc() # actually runs. alpine-musl: name: e2e (alpine-musl) runs-on: ubuntu-latest container: node:22-alpine continue-on-error: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }} defaults: run: shell: sh steps: - name: Install build deps run: apk add --no-cache git rust cargo musl-dev - uses: actions/checkout@v5 # libgit2 refuses repos owned by a different user; checkout in a # container can land at a uid mismatch, so opt every dir in. - name: Mark workspace safe for git run: git config --global --add safe.directory '*' - name: Sanity check libc is musl run: | if ! ldd --version 2>&1 | grep -qi musl; then echo "FAIL: container is not running musl libc" exit 1 fi - uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: alpine-musl-cargo-${{ hashFiles('**/Cargo.lock') }} restore-keys: | alpine-musl-cargo- - name: Build libfff_c (musl) run: cargo build --release -p fff-c - name: Install workspace npm deps run: npm install --no-package-lock # Upstream @yuuang/ffi-rs-linux-x64-musl ships with libc:"glibc" in # its package.json (a publishing bug in ffi-rs), so npm filters it # out. Force-install it so the FFI runtime is present on Alpine. - name: Install ffi-rs musl runtime run: | FFI_RS_VERSION=$(node -p "require('ffi-rs/package.json').version") npm install --no-package-lock --no-save --force \ "@yuuang/ffi-rs-linux-x64-musl@${FFI_RS_VERSION}" # Stage the freshly built libfff_c.so as the platform npm package # so findBinary() resolves through the @ff-labs/fff-bin-* path — # this is what exercises detectLinuxLibc(). - name: Stage musl bin package run: | PKG_DIR=node_modules/@ff-labs/fff-bin-linux-x64-musl mkdir -p "$PKG_DIR" cp target/release/libfff_c.so "$PKG_DIR/libfff_c.so" cat >"$PKG_DIR/package.json" <<'JSON' { "name": "@ff-labs/fff-bin-linux-x64-musl", "version": "0.0.0" } JSON - name: Build fff-node working-directory: packages/fff-node run: npm run build - name: Run fff-node e2e suite working-directory: packages/fff-node run: node test/e2e.mjs