name: test on: push: branches: - 'master' - 'release-[0-9]+.[0-9]+' pull_request: branches: - 'master' - 'release-[0-9]+.[0-9]+' workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: ASAN_OPTIONS: detect_leaks=1:check_initialization_order=1:log_path=${{ github.workspace }}/build/log/asan:intercept_tls_get_addr=0 BIN_DIR: ${{ github.workspace }}/bin BUILD_DIR: ${{ github.workspace }}/build INSTALL_PREFIX: ${{ github.workspace }}/nvim-install LOG_DIR: ${{ github.workspace }}/build/log NVIM_LOG_FILE: ${{ github.workspace }}/build/.nvimlog TSAN_OPTIONS: log_path=${{ github.workspace }}/build/log/tsan VALGRIND_LOG: ${{ github.workspace }}/build/log/valgrind-%p.log # TEST_FILE: test/functional/core/startup_spec.lua # TEST_FILTER: foo jobs: lint: runs-on: ubuntu-24.04 timeout-minutes: 10 env: CC: clang steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup - name: Install stylua run: | wget --directory-prefix="$BIN_DIR" https://github.com/JohnnyMorganz/StyLua/releases/latest/download/stylua-linux-x86_64.zip (cd "$BIN_DIR"; unzip stylua*.zip) - name: Build third-party deps run: | cmake -S cmake.deps -B .deps -G Ninja cmake --build .deps - run: cmake -B build -G Ninja -D CI_LINT=ON - if: "!cancelled()" name: Determine if run should be aborted id: abort_job run: echo "status=${{ job.status }}" >> $GITHUB_OUTPUT - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: stylua run: cmake --build build --target lintlua-stylua - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: luacheck run: cmake --build build --target lintlua-luacheck - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: lintsh run: cmake --build build --target lintsh - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: clint.py run: cmake --build build --target lintc-clint - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: clang-tidy run: cmake --build build --target lintc-clang-tidy - if: success() || failure() && steps.abort_job.outputs.status == 'success' name: uncrustify run: cmake --build build --target lintc-uncrustify clang-analyzer: runs-on: ubuntu-24.04 timeout-minutes: 20 env: CC: clang steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup - name: Build third-party deps run: | cmake -S cmake.deps --preset ci cmake --build .deps cmake --preset ci - run: cmake --build build --target clang-analyzer posix: name: ${{ matrix.build.os }} ${{ matrix.build.flavor }} ${{ matrix.build.cc }} ${{ matrix.test }} strategy: fail-fast: false matrix: # The `os` field is not needed to differentiate between the different # matrix builds. It is needed to not change the required checks (which # uses jobs names) each time we bump the runner version. It may be # possible to remove if we e.g. start using `-latest` runner versions # or if github introduces a wildcard for required checks in the future. build: [ { runner: ubuntu-24.04, os: ubuntu, flavor: asan, cc: clang, flags: -D ENABLE_ASAN_UBSAN=ON }, { runner: ubuntu-24.04, os: ubuntu, flavor: tsan, cc: clang, flags: -D ENABLE_TSAN=ON }, { runner: ubuntu-24.04, os: ubuntu, cc: gcc }, { runner: macos-12, os: macos, flavor: 12, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER }, { runner: macos-15, os: macos, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER }, { runner: ubuntu-24.04, os: ubuntu, flavor: puc-lua, cc: gcc, deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON, flags: -D PREFER_LUA=ON }, ] test: [unittest, functionaltest, oldtest] exclude: - test: unittest build: { flavor: tsan } - test: unittest build: { flavor: puc-lua } - test: oldtest build: { flavor: tsan } runs-on: ${{ matrix.build.runner }} timeout-minutes: 45 env: CC: ${{ matrix.build.cc }} steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup with: install_flags: "--test" - name: Create log dir run: mkdir -p "$LOG_DIR" - if: ${{ matrix.test != 'unittest' }} name: Set up interpreter packages run: | echo "Install neovim RubyGem." gem install --no-document --bindir "$BIN_DIR" --user-install --pre neovim echo "Install neovim npm package" npm install -g neovim npm link neovim sudo cpanm -n Neovim::Ext || cat "$HOME/.cpanm/build.log" perl -W -e 'use Neovim::Ext; print $Neovim::Ext::VERSION' - name: Build third-party deps run: | cmake -S cmake.deps --preset ci -D CMAKE_BUILD_TYPE=Debug ${{ matrix.build.deps_flags }} cmake --build .deps - name: Build run: | cmake --preset ci -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.build.flags }} cmake --build build - name: ${{ matrix.test }} timeout-minutes: 20 run: make ${{ matrix.test }} - name: Install run: | cmake --install build "$INSTALL_PREFIX/bin/nvim" --version if ! "$INSTALL_PREFIX/bin/nvim" -u NONE -e -c ':help' -c ':qall'; then echo "Running ':help' in the installed nvim failed." echo "Maybe the helptags have not been generated properly." echo 'Failed running :help' exit 1 fi # Check that all runtime files were installed for file in $(git -C runtime ls-files '*.vim' '*.ps' '*.dict' '*.py' '*.tutor' '*.awk' '*.sh' '*.bat'); do if ! test -e "$INSTALL_PREFIX/share/nvim/runtime/$file"; then printf "It appears that %s is not installed." "$file" exit 1 fi done # Check that generated syntax file has function names, #5060. genvimsynf=syntax/vim/generated.vim gpat='syn keyword vimFuncName .*eval' if ! grep -q "$gpat" "$INSTALL_PREFIX/share/nvim/runtime/$genvimsynf"; then echo "It appears that $genvimsynf does not contain $gpat." exit 1 fi - if: '!cancelled()' name: Show logs run: cat $(find "$LOG_DIR" -type f) windows: uses: ./.github/workflows/test_windows.yml # This job tests the following things: # - Check if Release, MinSizeRel and RelWithDebInfo compiles correctly. # - Test the above build types with the GCC compiler specifically. # Empirically the difference in warning levels between GCC and other # compilers is particularly big. # - Test if the build works with multi-config generators. We mostly use # single-config generators so it's nice to have a small sanity check for # multi-config. build-types: runs-on: ubuntu-24.04 timeout-minutes: 10 env: CC: gcc steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup - name: Build third-party deps run: | cmake -S cmake.deps -B .deps -G "Ninja Multi-Config" cmake --build .deps - name: Configure run: cmake --preset ci -G "Ninja Multi-Config" - name: Release run: cmake --build build --config Release - name: RelWithDebInfo run: cmake --build build --config RelWithDebInfo - name: MinSizeRel run: cmake --build build --config MinSizeRel with-external-deps: runs-on: ubuntu-24.04 timeout-minutes: 10 env: CC: gcc steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup - name: Install dependencies run: | sudo add-apt-repository ppa:neovim-ppa/stable sudo apt-get install -y \ libluajit-5.1-dev \ libunibilium-dev \ libuv1-dev \ lua-filesystem \ lua-lpeg \ luajit \ lua-luv-dev # libtree-sitter-dev \ # Remove comments from packages once we start using these external # dependencies. - name: Build third-party deps run: | cmake -S cmake.deps --preset external_deps cmake --build .deps - name: Build run: | cmake --preset ci cmake --build build