From fc8c77a69f01eb1eac0a1b4373ae1bb7f81d1629 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sat, 18 Feb 2023 10:47:22 +0100 Subject: ci: split ci.yml into a test workflow and a build test workflow (#22302) Having a workflow that only builds neovim without running all of the tests is a cheap way to test the build still works without burning too much CI time. --- .github/actions/cache/action.yml | 2 +- .github/workflows/build.yml | 118 +++++++++ .github/workflows/ci.yml | 466 ---------------------------------- .github/workflows/test.yml | 370 +++++++++++++++++++++++++++ .github/workflows/universal_macos.yml | 32 --- CMakeLists.txt | 2 +- CONTRIBUTING.md | 2 +- MAINTAIN.md | 13 +- README.md | 2 +- 9 files changed, 499 insertions(+), 508 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/test.yml delete mode 100644 .github/workflows/universal_macos.yml diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml index 819380f351..da36c71a1d 100644 --- a/.github/actions/cache/action.yml +++ b/.github/actions/cache/action.yml @@ -18,5 +18,5 @@ runs: with: path: ${{ env.DEPS_BUILD_DIR }} key: ${{ env.CACHE_KEY }}-${{ hashFiles('cmake**', 'ci/**', - '.github/workflows/ci.yml', 'CMakeLists.txt', + '.github/workflows/test.yml', 'CMakeLists.txt', 'runtime/CMakeLists.txt', 'src/nvim/**/CMakeLists.txt') }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..43e91d9ed4 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,118 @@ +name: build +on: + pull_request: + branches: + - 'master' + - 'release-[0-9]+.[0-9]+' + paths: + - '**.cmake' + - '**/CMakeLists.txt' + - '**/CMakePresets.json' + - 'cmake.*/**' + - '.github/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref }} + cancel-in-progress: true + + +env: + BIN_DIR: ${{ github.workspace }}/bin + INSTALL_PREFIX: ${{ github.workspace }}/nvim-install + +jobs: + macos-universal: + runs-on: macos-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + run: ./.github/scripts/install_deps.sh + + - run: printf 'NVIM_BUILD_TYPE=Release\n' >> $GITHUB_ENV + + - name: Build universal binary + run: ./.github/scripts/build_universal_macos.sh + + old-cmake: + name: Test oldest supported cmake + runs-on: ubuntu-22.04 + timeout-minutes: 15 + env: + CMAKE_URL: 'https://cmake.org/files/v3.10/cmake-3.10.0-Linux-x86_64.sh' + CMAKE_VERSION: '3.10.0' + steps: + - uses: actions/checkout@v3 + + - name: Set up environment + run: echo "$BIN_DIR" >> $GITHUB_PATH + + - name: Install dependencies + run: ./.github/scripts/install_deps.sh + + - name: Install minimum required version of cmake + run: | + curl --retry 5 --silent --show-error --fail -o /tmp/cmake-installer.sh "$CMAKE_URL" + mkdir -p "$BIN_DIR" /opt/cmake-custom + chmod a+x /tmp/cmake-installer.sh + /tmp/cmake-installer.sh --prefix=/opt/cmake-custom --skip-license + ln -sfn /opt/cmake-custom/bin/cmake "$BIN_DIR/cmake" + cmake_version="$(cmake --version | head -1)" + echo "$cmake_version" | grep -qF "cmake version $CMAKE_VERSION" || { + echo "Unexpected CMake version: $cmake_version" + exit 1 + } + + - name: Build dependencies + run: make deps + + - name: Build + run: make CMAKE_FLAGS="-D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX" + + - name: Install + run: make install + + with-external-deps: + runs-on: ubuntu-22.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + run: | + sudo add-apt-repository ppa:neovim-ppa/stable + ./.github/scripts/install_deps.sh + sudo apt-get install -y \ + libluajit-5.1-dev \ + libmsgpack-dev \ + libtermkey-dev \ + libtree-sitter-dev \ + libunibilium-dev \ + libuv1-dev \ + lua-busted \ + lua-filesystem \ + lua-inspect \ + lua-lpeg \ + lua-nvim \ + luajit + # libvterm-dev \ + # lua-luv-dev + + # Remove comments from packages once we start using these external + # dependencies. + + - name: Build third-party deps + run: | + # Ideally all dependencies should external for this job, but some + # dependencies don't have the required version available. We use the + # bundled versions for these with the hopes of being able to remove them + # later on. + cmake -S cmake.deps -B .deps -G Ninja -D USE_BUNDLED=OFF -D USE_BUNDLED_LUV=ON -D USE_BUNDLED_LIBVTERM=ON + cmake --build .deps + + - name: Build + run: | + cmake -B build -G Ninja + cmake --build build + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 455c712948..0000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,466 +0,0 @@ -name: CI -on: - push: - branches: - - 'master' - - 'release-[0-9]+.[0-9]+' - pull_request: - branches: - - 'master' - - 'release-[0-9]+.[0-9]+' - paths-ignore: - - 'contrib/**' - -concurrency: - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} - cancel-in-progress: true - -env: - ASAN_OPTIONS: detect_leaks=1:check_initialization_order=1:handle_abort=1:handle_sigill=1:log_path=${{ github.workspace }}/build/log/asan:intercept_tls_get_addr=0 - BIN_DIR: ${{ github.workspace }}/bin - BUILD_DIR: ${{ github.workspace }}/build - DEPS_BUILD_DIR: ${{ github.workspace }}/nvim-deps - 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 - UBSAN_OPTIONS: "print_stacktrace=1 log_path=${{ github.workspace }}/build/log/ubsan" - VALGRIND_LOG: ${{ github.workspace }}/build/log/valgrind-%p.log - # TEST_FILE: test/functional/core/startup_spec.lua - # TEST_FILTER: foo - -jobs: - lint: - if: (github.event_name == 'pull_request' && github.base_ref == 'master') || (github.event_name == 'push' && github.ref == 'refs/heads/master') - runs-on: ubuntu-22.04 - timeout-minutes: 10 - env: - CACHE_UNCRUSTIFY: ${{ github.workspace }}/.cache/uncrustify - UNCRUSTIFY_VERSION: uncrustify-0.75.0 - steps: - - uses: actions/checkout@v3 - - - name: Install dependencies - run: ./.github/scripts/install_deps.sh lua-check - - - name: Cache uncrustify - id: cache-uncrustify - uses: actions/cache@v3 - with: - path: ${{ env.CACHE_UNCRUSTIFY }} - key: ${{ env.UNCRUSTIFY_VERSION }} - - - name: Clone uncrustify - if: steps.cache-uncrustify.outputs.cache-hit != 'true' - uses: actions/checkout@v3 - with: - repository: uncrustify/uncrustify - ref: ${{ env.UNCRUSTIFY_VERSION }} - path: uncrustify - - - name: Install uncrustify - if: steps.cache-uncrustify.outputs.cache-hit != 'true' - run: | - source_dir=uncrustify - build_dir=uncrustify/build - cmake -S $source_dir -B $build_dir -G Ninja -D CMAKE_BUILD_TYPE=Release - cmake --build $build_dir - mkdir -p .cache - cp $build_dir/uncrustify ${{ env.CACHE_UNCRUSTIFY }} - - - uses: ./.github/actions/cache - - - name: Build third-party deps - run: | - cmake -S cmake.deps -B $DEPS_BUILD_DIR -G Ninja - cmake --build $DEPS_BUILD_DIR - - - 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: lintstylua - uses: JohnnyMorganz/stylua-action@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - version: latest - args: --check runtime/ - - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: luacheck - run: | - cmake -B build -G Ninja - 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: uncrustify - run: | - ${{ env.CACHE_UNCRUSTIFY }} -c ./src/uncrustify.cfg -q --replace --no-backup $(find ./src/nvim -name "*.[ch]") - - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: suggester / uncrustify - uses: reviewdog/action-suggester@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - tool_name: uncrustify - cleanup: false - - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: check uncrustify - run: git diff --color --exit-code - - lintc: - # This job tests two things: it lints the code but also builds neovim using - # system dependencies instead of bundled dependencies. This is to make sure - # we are able to build neovim without pigeonholing ourselves into specifics - # of the bundled dependencies. - - if: (github.event_name == 'pull_request' && github.base_ref == 'master') || (github.event_name == 'push' && github.ref == 'refs/heads/master') - runs-on: ubuntu-22.04 - timeout-minutes: 10 - steps: - - uses: actions/checkout@v3 - - - name: Install dependencies - run: | - sudo add-apt-repository ppa:neovim-ppa/stable - ./.github/scripts/install_deps.sh - sudo apt-get install -y \ - libluajit-5.1-dev \ - libmsgpack-dev \ - libtermkey-dev \ - libtree-sitter-dev \ - libunibilium-dev \ - libuv1-dev \ - lua-busted \ - lua-filesystem \ - lua-inspect \ - lua-lpeg \ - lua-nvim \ - luajit - # libvterm-dev \ - # lua-luv-dev - - # Remove comments from packages once we start using these external - # dependencies. - - - uses: ./.github/actions/cache - - - name: Build third-party deps - run: | - # Ideally all dependencies should external for this job, but some - # dependencies don't have the required version available. We use the - # bundled versions for these with the hopes of being able to remove them - # later on. - cmake -S cmake.deps -B $DEPS_BUILD_DIR -G Ninja -D USE_BUNDLED=OFF -D USE_BUNDLED_LUV=ON -D USE_BUNDLED_LIBVTERM=ON - cmake --build $DEPS_BUILD_DIR - - - name: Build - run: | - cmake -B build -G Ninja - cmake --build build - - - 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: clint.py - run: cmake --build build --target lintc-clint - - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - run: cmake --build build --target clang-tidy - - posix: - name: ${{ matrix.runner }} ${{ matrix.flavor }} (cc=${{ matrix.cc }}) - strategy: - fail-fast: false - matrix: - include: - - flavor: asan - cc: clang - runner: ubuntu-22.04 - flags: -D CLANG_ASAN_UBSAN=ON - - flavor: tsan - cc: clang - runner: ubuntu-22.04 - flags: -D CLANG_TSAN=ON - - flavor: uchar - cc: gcc - runner: ubuntu-22.04 - flags: -D UNSIGNED_CHAR=ON - - flavor: release - cc: gcc - runner: ubuntu-22.04 - flags: -D CMAKE_BUILD_TYPE=Release - - cc: clang - runner: macos-12 - - # functionaltest-lua is our dumping ground for non-mainline configurations. - # 1. Check that the tests pass with PUC Lua instead of LuaJIT. - # 2. No treesitter parsers installed. - - flavor: functionaltest-lua - cc: gcc - runner: ubuntu-22.04 - deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON - flags: -D PREFER_LUA=ON - runs-on: ${{ matrix.runner }} - timeout-minutes: 45 - env: - CC: ${{ matrix.cc }} - steps: - - uses: actions/checkout@v3 - - - name: Set up environment - run: | - ulimit -c unlimited - echo "$BIN_DIR" >> $GITHUB_PATH - - - name: Create log dir - run: mkdir -p "$LOG_DIR" - - - name: Install dependencies - run: ./.github/scripts/install_deps.sh cpanminus - - - name: Setup interpreter packages - run: | - # Use default CC to avoid compilation problems when installing Python modules. - echo "Install neovim module for Python." - CC=cc python3 -m pip -q install --user --upgrade pynvim - - 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 - - if [[ $RUNNER_OS != macOS ]]; then - sudo cpanm -n Neovim::Ext || cat "$HOME/.cpanm/build.log" - perl -W -e 'use Neovim::Ext; print $Neovim::Ext::VERSION' - fi - - - run: echo "DEPS_BUILD_DIR=$HOME/nvim-deps" >> $GITHUB_ENV - - - uses: ./.github/actions/cache - - - name: Build third-party deps - run: | - cmake -S cmake.deps -B $DEPS_BUILD_DIR -G Ninja ${{ matrix.deps_flags }} - cmake --build $DEPS_BUILD_DIR - - - name: Build - run: | - cmake -B build -G Ninja -D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.flags }} - cmake --build build - - - if: "!cancelled()" - name: Determine if run should be aborted - id: abort_job - run: echo "status=${{ job.status }}" >> $GITHUB_OUTPUT - - - if: matrix.flavor != 'tsan' && matrix.flavor != 'release' && matrix.flavor != 'functionaltest-lua' && (success() || failure() && steps.abort_job.outputs.status == 'success') - name: Unittest - timeout-minutes: 5 - run: cmake --build build --target unittest - - - if: matrix.flavor != 'functionaltest-lua' && (success() || failure() && steps.abort_job.outputs.status == 'success') - name: Functionaltest - timeout-minutes: 20 - run: cmake --build build --target functionaltest - - - if: matrix.flavor == 'functionaltest-lua' && (success() || failure() && steps.abort_job.outputs.status == 'success') - name: Functionaltest with PUC Lua - timeout-minutes: 20 - run: cmake --build build --target functionaltest-lua - - - if: matrix.flavor != 'tsan' && (success() || failure() && steps.abort_job.outputs.status == 'success') - name: Oldtest - run: make oldtest - - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Install - run: cmake --install build - - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Installtests - run: | - "$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'); do - if ! test -e "$INSTALL_PREFIX/share/nvim/runtime/$file"; then - printf "%s%s" 'It appears that %s is not installed.' "$file" - exit 1 - fi - done - - # Check that some runtime files are installed and are executables - for file in $(git -C runtime ls-files '*.awk' '*.sh' '*.bat'); do - if ! test -x "$INSTALL_PREFIX/share/nvim/runtime/$file"; then - printf "%s%s" 'It appears that %s is not installed or is not executable.' "$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: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Show logs - run: cat $(find "$LOG_DIR" -type f) - - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Show core dumps - run: | - # TODO(dundargoc): app should be luajit for unittests - app="build/bin/nvim" - if test "$RUNNER_OS" = macOS; then - cores="$(find /cores/ -type f -print)" - else - cores="$(find ./ -type f \( -name 'core.*' -o -name core -o -name nvim.core \) -print)" - fi - - if test -z "$cores"; then - exit 0 - fi - for core in $cores; do - if test "$RUNNER_OS" = macOS; then - lldb -Q -o "bt all" -f "$app" -c "$core" - else - gdb -n -batch -ex 'thread apply all bt full' "$app" -c "$core" - fi - done - echo 'Core dumps found' - exit 1 - - old_cmake: - name: Test oldest supported cmake - runs-on: ubuntu-22.04 - timeout-minutes: 15 - env: - CMAKE_URL: 'https://cmake.org/files/v3.10/cmake-3.10.0-Linux-x86_64.sh' - CMAKE_VERSION: '3.10.0' - steps: - - uses: actions/checkout@v3 - - - name: Set up environment - run: echo "$BIN_DIR" >> $GITHUB_PATH - - - name: Install dependencies - run: ./.github/scripts/install_deps.sh - - - name: Install minimum required version of cmake - run: | - curl --retry 5 --silent --show-error --fail -o /tmp/cmake-installer.sh "$CMAKE_URL" - mkdir -p "$BIN_DIR" /opt/cmake-custom - chmod a+x /tmp/cmake-installer.sh - /tmp/cmake-installer.sh --prefix=/opt/cmake-custom --skip-license - ln -sfn /opt/cmake-custom/bin/cmake "$BIN_DIR/cmake" - cmake_version="$(cmake --version | head -1)" - echo "$cmake_version" | grep -qF "cmake version $CMAKE_VERSION" || { - echo "Unexpected CMake version: $cmake_version" - exit 1 - } - - - uses: ./.github/actions/cache - - - name: Build dependencies - run: make deps - - - name: Build - run: make CMAKE_FLAGS="-D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX" - - - name: Install - run: make install - - windows: - runs-on: windows-2019 - timeout-minutes: 45 - name: windows - steps: - - uses: actions/checkout@v3 - - - uses: ./.github/actions/cache - - - name: Set env - run: | - $installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath - if ($installationPath -and (Test-Path "$installationPath\Common7\Tools\vsdevcmd.bat")) { - & "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | ForEach-Object { - $name, $value = $_ -split '=', 2 - "$name=$value" >> $env:GITHUB_ENV - } - } - - - name: Build deps - run: | - cmake -S cmake.deps -B $env:DEPS_BUILD_DIR -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo' - cmake --build $env:DEPS_BUILD_DIR - - - name: Build - run: | - cmake -B build -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo' -D CI_BUILD=ON - cmake --build build - - - name: Install test deps - run: | - $PSNativeCommandArgumentPassing = 'Legacy' - - & build\bin\nvim.exe "--version" - - # Ensure that the "win32" feature is set. - & build\bin\nvim -u NONE --headless -c 'exe !has(\"win32\").\"cq\"' - - python -m pip install pynvim - # Sanity check - python -c "import pynvim; print(str(pynvim))" - - gem.cmd install --pre neovim - Get-Command -CommandType Application neovim-ruby-host.bat - - node --version - npm.cmd --version - - npm.cmd install -g neovim - Get-Command -CommandType Application neovim-node-host.cmd - npm.cmd link neovim - - - if: "!cancelled()" - name: Determine if run should be aborted - id: abort_job - run: | - "status=${{ job.status }}" >> $env:GITHUB_OUTPUT - - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Run functionaltest - timeout-minutes: 20 - run: cmake --build build --target functionaltest - - - if: success() || failure() && steps.abort_job.outputs.status == 'success' - name: Run oldtest - run: | - # Add MSYS to path, required for e.g. `find` used in test scripts. - # But would break functionaltest, where its `more` would be used then. - $OldPath = $env:PATH - $env:PATH = "C:\msys64\usr\bin;$env:PATH" - & "C:\msys64\mingw64\bin\mingw32-make.exe" -C $(Convert-Path src\nvim\testdir) VERBOSE=1 - $env:PATH = $OldPath diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000000..bfe6a22390 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,370 @@ +name: test +on: + push: + branches: + - 'master' + - 'release-[0-9]+.[0-9]+' + pull_request: + branches: + - 'master' + - 'release-[0-9]+.[0-9]+' + paths-ignore: + - 'contrib/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +env: + ASAN_OPTIONS: detect_leaks=1:check_initialization_order=1:handle_abort=1:handle_sigill=1:log_path=${{ github.workspace }}/build/log/asan:intercept_tls_get_addr=0 + BIN_DIR: ${{ github.workspace }}/bin + BUILD_DIR: ${{ github.workspace }}/build + DEPS_BUILD_DIR: ${{ github.workspace }}/nvim-deps + 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 + UBSAN_OPTIONS: "print_stacktrace=1 log_path=${{ github.workspace }}/build/log/ubsan" + VALGRIND_LOG: ${{ github.workspace }}/build/log/valgrind-%p.log + # TEST_FILE: test/functional/core/startup_spec.lua + # TEST_FILTER: foo + +jobs: + lint: + if: (github.event_name == 'pull_request' && github.base_ref == 'master') || (github.event_name == 'push' && github.ref == 'refs/heads/master') + runs-on: ubuntu-22.04 + timeout-minutes: 10 + env: + CACHE_UNCRUSTIFY: ${{ github.workspace }}/.cache/uncrustify + UNCRUSTIFY_VERSION: uncrustify-0.75.0 + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + run: ./.github/scripts/install_deps.sh lua-check + + - name: Cache uncrustify + id: cache-uncrustify + uses: actions/cache@v3 + with: + path: ${{ env.CACHE_UNCRUSTIFY }} + key: ${{ env.UNCRUSTIFY_VERSION }} + + - name: Clone uncrustify + if: steps.cache-uncrustify.outputs.cache-hit != 'true' + uses: actions/checkout@v3 + with: + repository: uncrustify/uncrustify + ref: ${{ env.UNCRUSTIFY_VERSION }} + path: uncrustify + + - name: Install uncrustify + if: steps.cache-uncrustify.outputs.cache-hit != 'true' + run: | + source_dir=uncrustify + build_dir=uncrustify/build + cmake -S $source_dir -B $build_dir -G Ninja -D CMAKE_BUILD_TYPE=Release + cmake --build $build_dir + mkdir -p .cache + cp $build_dir/uncrustify ${{ env.CACHE_UNCRUSTIFY }} + + - uses: ./.github/actions/cache + + - name: Build third-party deps + run: | + cmake -S cmake.deps -B $DEPS_BUILD_DIR -G Ninja + cmake --build $DEPS_BUILD_DIR + + - 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: lintstylua + uses: JohnnyMorganz/stylua-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + version: latest + args: --check runtime/ + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: luacheck + run: | + cmake -B build -G Ninja + 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' + run: cmake --build build --target clang-tidy + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: uncrustify + run: | + ${{ env.CACHE_UNCRUSTIFY }} -c ./src/uncrustify.cfg -q --replace --no-backup $(find ./src/nvim -name "*.[ch]") + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: suggester / uncrustify + uses: reviewdog/action-suggester@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + tool_name: uncrustify + cleanup: false + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: check uncrustify + run: git diff --color --exit-code + + posix: + name: ${{ matrix.runner }} ${{ matrix.flavor }} (cc=${{ matrix.cc }}) + strategy: + fail-fast: false + matrix: + include: + - flavor: asan + cc: clang + runner: ubuntu-22.04 + flags: -D CLANG_ASAN_UBSAN=ON + - flavor: tsan + cc: clang + runner: ubuntu-22.04 + flags: -D CLANG_TSAN=ON + - flavor: uchar + cc: gcc + runner: ubuntu-22.04 + flags: -D UNSIGNED_CHAR=ON + - flavor: release + cc: gcc + runner: ubuntu-22.04 + flags: -D CMAKE_BUILD_TYPE=Release + - cc: clang + runner: macos-12 + + # functionaltest-lua is our dumping ground for non-mainline configurations. + # 1. Check that the tests pass with PUC Lua instead of LuaJIT. + # 2. No treesitter parsers installed. + - flavor: functionaltest-lua + cc: gcc + runner: ubuntu-22.04 + deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON + flags: -D PREFER_LUA=ON + runs-on: ${{ matrix.runner }} + timeout-minutes: 45 + env: + CC: ${{ matrix.cc }} + steps: + - uses: actions/checkout@v3 + + - name: Set up environment + run: | + ulimit -c unlimited + echo "$BIN_DIR" >> $GITHUB_PATH + + - name: Create log dir + run: mkdir -p "$LOG_DIR" + + - name: Install dependencies + run: ./.github/scripts/install_deps.sh cpanminus + + - name: Setup interpreter packages + run: | + # Use default CC to avoid compilation problems when installing Python modules. + echo "Install neovim module for Python." + CC=cc python3 -m pip -q install --user --upgrade pynvim + + 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 + + if [[ $RUNNER_OS != macOS ]]; then + sudo cpanm -n Neovim::Ext || cat "$HOME/.cpanm/build.log" + perl -W -e 'use Neovim::Ext; print $Neovim::Ext::VERSION' + fi + + - run: echo "DEPS_BUILD_DIR=$HOME/nvim-deps" >> $GITHUB_ENV + + - uses: ./.github/actions/cache + + - name: Build third-party deps + run: | + cmake -S cmake.deps -B $DEPS_BUILD_DIR -G Ninja ${{ matrix.deps_flags }} + cmake --build $DEPS_BUILD_DIR + + - name: Build + run: | + cmake -B build -G Ninja -D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.flags }} + cmake --build build + + - if: "!cancelled()" + name: Determine if run should be aborted + id: abort_job + run: echo "status=${{ job.status }}" >> $GITHUB_OUTPUT + + - if: matrix.flavor != 'tsan' && matrix.flavor != 'release' && matrix.flavor != 'functionaltest-lua' && (success() || failure() && steps.abort_job.outputs.status == 'success') + name: Unittest + timeout-minutes: 5 + run: cmake --build build --target unittest + + - if: matrix.flavor != 'functionaltest-lua' && (success() || failure() && steps.abort_job.outputs.status == 'success') + name: Functionaltest + timeout-minutes: 20 + run: cmake --build build --target functionaltest + + - if: matrix.flavor == 'functionaltest-lua' && (success() || failure() && steps.abort_job.outputs.status == 'success') + name: Functionaltest with PUC Lua + timeout-minutes: 20 + run: cmake --build build --target functionaltest-lua + + - if: matrix.flavor != 'tsan' && (success() || failure() && steps.abort_job.outputs.status == 'success') + name: Oldtest + run: make oldtest + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: Install + run: cmake --install build + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: Installtests + run: | + "$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'); do + if ! test -e "$INSTALL_PREFIX/share/nvim/runtime/$file"; then + printf "%s%s" 'It appears that %s is not installed.' "$file" + exit 1 + fi + done + + # Check that some runtime files are installed and are executables + for file in $(git -C runtime ls-files '*.awk' '*.sh' '*.bat'); do + if ! test -x "$INSTALL_PREFIX/share/nvim/runtime/$file"; then + printf "%s%s" 'It appears that %s is not installed or is not executable.' "$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: success() || failure() && steps.abort_job.outputs.status == 'success' + name: Show logs + run: cat $(find "$LOG_DIR" -type f) + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: Show core dumps + run: | + # TODO(dundargoc): app should be luajit for unittests + app="build/bin/nvim" + if test "$RUNNER_OS" = macOS; then + cores="$(find /cores/ -type f -print)" + else + cores="$(find ./ -type f \( -name 'core.*' -o -name core -o -name nvim.core \) -print)" + fi + + if test -z "$cores"; then + exit 0 + fi + for core in $cores; do + if test "$RUNNER_OS" = macOS; then + lldb -Q -o "bt all" -f "$app" -c "$core" + else + gdb -n -batch -ex 'thread apply all bt full' "$app" -c "$core" + fi + done + echo 'Core dumps found' + exit 1 + + windows: + runs-on: windows-2019 + timeout-minutes: 45 + name: windows + steps: + - uses: actions/checkout@v3 + + - uses: ./.github/actions/cache + + - name: Set env + run: | + $installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath + if ($installationPath -and (Test-Path "$installationPath\Common7\Tools\vsdevcmd.bat")) { + & "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | ForEach-Object { + $name, $value = $_ -split '=', 2 + "$name=$value" >> $env:GITHUB_ENV + } + } + + - name: Build deps + run: | + cmake -S cmake.deps -B $env:DEPS_BUILD_DIR -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo' + cmake --build $env:DEPS_BUILD_DIR + + - name: Build + run: | + cmake -B build -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo' -D CI_BUILD=ON + cmake --build build + + - name: Install test deps + run: | + $PSNativeCommandArgumentPassing = 'Legacy' + + & build\bin\nvim.exe "--version" + + # Ensure that the "win32" feature is set. + & build\bin\nvim -u NONE --headless -c 'exe !has(\"win32\").\"cq\"' + + python -m pip install pynvim + # Sanity check + python -c "import pynvim; print(str(pynvim))" + + gem.cmd install --pre neovim + Get-Command -CommandType Application neovim-ruby-host.bat + + node --version + npm.cmd --version + + npm.cmd install -g neovim + Get-Command -CommandType Application neovim-node-host.cmd + npm.cmd link neovim + + - if: "!cancelled()" + name: Determine if run should be aborted + id: abort_job + run: | + "status=${{ job.status }}" >> $env:GITHUB_OUTPUT + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: Run functionaltest + timeout-minutes: 20 + run: cmake --build build --target functionaltest + + - if: success() || failure() && steps.abort_job.outputs.status == 'success' + name: Run oldtest + run: | + # Add MSYS to path, required for e.g. `find` used in test scripts. + # But would break functionaltest, where its `more` would be used then. + $OldPath = $env:PATH + $env:PATH = "C:\msys64\usr\bin;$env:PATH" + & "C:\msys64\mingw64\bin\mingw32-make.exe" -C $(Convert-Path src\nvim\testdir) VERBOSE=1 + $env:PATH = $OldPath diff --git a/.github/workflows/universal_macos.yml b/.github/workflows/universal_macos.yml deleted file mode 100644 index 765cea63c1..0000000000 --- a/.github/workflows/universal_macos.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: macos-universal -on: - pull_request: - branches: - - 'master' - - 'release-[0-9]+.[0-9]+' - paths: - - '**.cmake' - - '**/CMakeLists.txt' - - '**/CMakePresets.json' - - 'cmake.*/**' - - '.github/scripts/build_universal_macos.sh' - - '.github/workflow/universal_macos.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref }} - cancel-in-progress: true - -jobs: - macos-universal: - runs-on: macos-latest - timeout-minutes: 20 - steps: - - uses: actions/checkout@v3 - - - name: Install dependencies - run: ./.github/scripts/install_deps.sh - - - run: printf 'NVIM_BUILD_TYPE=Release\n' >> $GITHUB_ENV - - - name: Build universal binary - run: ./.github/scripts/build_universal_macos.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index d12b71a651..a608e42dab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # best practices (3.0+): https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1 # pitfalls: https://izzys.casa/2019/02/everything-you-never-wanted-to-know-about-cmake/ -# Version should match the tested CMAKE_URL in .github/workflows/ci.yml. +# Version should match the tested CMAKE_URL in .github/workflows/build.yml. cmake_minimum_required(VERSION 3.10) # Can be removed once minimum version is at least 3.15 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe2cdb8a36..ca13e1b956 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -130,7 +130,7 @@ Each pull request must pass the automated builds on [Cirrus CI] and [GitHub Acti [style](#style). (See [#3174][3174] for background.) - CI for FreeBSD runs on [Cirrus CI]. - To see CI results faster in your PR, you can temporarily set `TEST_FILE` in - [ci.yml](https://github.com/neovim/neovim/blob/e35b9020b16985eee26e942f9a3f6b045bc3809b/.github/workflows/ci.yml#L205). + [test.yml](https://github.com/neovim/neovim/blob/e35b9020b16985eee26e942f9a3f6b045bc3809b/.github/workflows/test.yml#L29). ### Clang scan-build diff --git a/MAINTAIN.md b/MAINTAIN.md index 1b3176f4ff..629327a67a 100644 --- a/MAINTAIN.md +++ b/MAINTAIN.md @@ -117,12 +117,13 @@ our CI strategy be. The following guidelines have worked well for us so far: prefer `-latest` tags so we don't need to manually bump the versions. An example of a special-purpose workflow is `labeler.yml`. -* For our testing jobs, which is currently only `ci.yml`, prefer to use the - latest stable (i.e. non-beta) version explicitly. Avoid using the `-latest` - tags here as it makes it difficult to determine from an unrelated PR if a - failure is due to the PR itself or due to GitHub bumping the `-latest` tag - without our knowledge. There's also a high risk that automatic bumping the CI - versions will fail due to manual work being required from experience. +* For our testing jobs, which are in `test.yml` and `build.yml`, prefer to use + the latest stable (i.e. non-beta) version explicitly. Avoid using the + `-latest` tags here as it makes it difficult to determine from an unrelated + PR if a failure is due to the PR itself or due to GitHub bumping the + `-latest` tag without our knowledge. There's also a high risk that automatic + bumping the CI versions will fail due to manual work being required from + experience. * For our release job, which is `release.yml`, prefer to use the oldest stable (i.e. non-deprecated) versions available. The reason is that we're trying to diff --git a/README.md b/README.md index 3f2e158900..0ccb097ee1 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Chat -[![GitHub CI](https://github.com/neovim/neovim/actions/workflows/ci.yml/badge.svg?event=push&branch=master)](https://github.com/neovim/neovim/actions?query=workflow%3ACI+branch%3Amaster+event%3Apush) +[![GitHub CI](https://github.com/neovim/neovim/actions/workflows/build.yml/badge.svg?event=push&branch=master)](https://github.com/neovim/neovim/actions?query=workflow%3ACI+branch%3Amaster+event%3Apush) [![Coverity Scan analysis](https://scan.coverity.com/projects/2227/badge.svg)](https://scan.coverity.com/projects/2227) [![Clang analysis](https://neovim.io/doc/reports/clang/badge.svg)](https://neovim.io/doc/reports/clang) [![PVS-Studio analysis](https://neovim.io/doc/reports/pvs/badge.svg)](https://neovim.io/doc/reports/pvs/PVS-studio.html.d) -- cgit