Files
neovim/.github/workflows/ci.yml
dundargoc f1c5887377 ci: add GCC Release testing (#22274)
ci: add GCC release testing

We currently have no release testing, so it's good to check for any
unwanted behavior on release builds as well. Prefer GCC over clang, as
GCC release builds seem to create more warnings on release compared to
debug.
2023-02-16 00:15:09 +01:00

467 lines
16 KiB
YAML

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: 15
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: 15
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: 15
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