view .github/workflows/ci.yml @ 33408:dcfbfe57141c v9.0.1962

patch 9.0.1962: No support for writing extended attributes Commit: https://github.com/vim/vim/commit/e085dfda5d8dde064b0332464040959479696d1c Author: Christian Brabandt <cb@256bit.org> Date: Sat Sep 30 12:49:18 2023 +0200 patch 9.0.1962: No support for writing extended attributes Problem: No support for writing extended attributes Solution: Add extended attribute support for linux It's been a long standing issue, that if you write a file with extended attributes and backupcopy is set to no, the file will loose the extended attributes. So this patch adds support for retrieving the extended attributes and copying it to the new file. It currently only works on linux, mainly because I don't know the different APIs for other systems (BSD, MacOSX and Solaris). On linux, this should be supported since Kernel 2.4 or something, so this should be pretty safe to use now. Enable the extended attribute support with normal builds. I also added it explicitly to the :version output as well as make it able to check using `:echo has("xattr")`, to have users easily check that this is available. In contrast to the similar support for SELINUX and SMACK support (which also internally uses extended attributes), I have made this a FEAT_XATTR define, instead of the similar HAVE_XATTR. Add a test and change CI to include relevant packages so that CI can test that extended attributes are correctly written. closes: #306 closes: #13203 Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Sat, 30 Sep 2023 13:00:06 +0200
parents 14b9adfe6822
children e6c291944e18
line wrap: on
line source

name: GitHub CI

on:
  push:
    branches: ['**']
  pull_request:

# Cancels all previous workflow runs for pull requests that have not completed.
concurrency:
  # The concurrency group contains the workflow name and the branch name for
  # pull requests or the commit hash for any other events.
  group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
  cancel-in-progress: true

permissions:
  contents: read # to fetch code (actions/checkout)

jobs:
  linux:
    runs-on: ubuntu-22.04

    env:
      CC: ${{ matrix.compiler }}
      GCC_VER: 13
      CLANG_VER: 17
      TEST: test
      SRCDIR: ./src
      LEAK_CFLAGS: -DEXITFREE
      LOG_DIR: ${{ github.workspace }}/logs
      TERM: xterm
      DISPLAY: ':99'
      DEBIAN_FRONTEND: noninteractive

    strategy:
      fail-fast: false
      matrix:
        features: [tiny, normal, huge]
        compiler: [clang, gcc]
        extra: [[]]
        # Only use non-native architecture when features != huge.
        # features=huge tries to install python3-dev, which fails to install
        # for the non-native architecture.
        architecture: [native]
        include:
          - features: tiny
            compiler: clang
            extra: [nogui]
          - features: tiny
            compiler: gcc
            extra: [nogui]
          - features: normal
            shadow: ./src/shadow
            compiler: gcc
            architecture: i386
          - features: huge
            coverage: true
          - features: huge
            compiler: clang
            interface: dynamic
            python3: stable-abi
          - features: huge
            compiler: gcc
            coverage: true
            interface: dynamic
            extra: [uchar, testgui]
          - features: huge
            compiler: clang
            # Lua5.1 is the most widely used version (since it's what LuaJIT is
            # compatible with), so ensure it works
            lua_ver: '5.1'
            extra: [asan]
          - features: huge
            compiler: gcc
            coverage: true
            extra: [unittests]
          - features: normal
            compiler: gcc
            extra: [vimtags]

    steps:
      - name: Checkout repository from github
        uses: actions/checkout@v4

      - run: sudo dpkg --add-architecture i386
        if: matrix.architecture == 'i386'

      - name: Install packages
        run: |
          PKGS=( \
            gettext \
            libgtk2.0-dev:${{ matrix.architecture }} \
            desktop-file-utils \
            libtool-bin \
            libncurses-dev:${{ matrix.architecture }} \
            libxt-dev:${{ matrix.architecture }} \
          )
          if ${{ matrix.features == 'huge' }}; then
            LUA_VER=${{ matrix.lua_ver || '5.4' }}
            PKGS+=( \
              autoconf \
              gdb \
              lcov \
              libcanberra-dev \
              libperl-dev \
              python2-dev \
              python3-dev \
              liblua${LUA_VER}-dev \
              lua${LUA_VER} \
              ruby-dev \
              tcl-dev \
              cscope \
              libsodium-dev \
              attr \
              libattr1-dev
            )
          fi
          sudo apt-get update && sudo apt-get install -y "${PKGS[@]}"

      - name: Install gcc-${{ env.GCC_VER }}
        if:  matrix.compiler == 'gcc'
        run: |
          sudo apt-get install -y gcc-${{ env.GCC_VER }}:${{ matrix.architecture }}
          sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${{ env.GCC_VER }} 100
          sudo update-alternatives --set gcc /usr/bin/gcc-${{ env.GCC_VER }}

      - name: Install clang-${{ env.CLANG_VER }}
        if: matrix.compiler == 'clang'
        run: |
          wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
          . /etc/lsb-release
          sudo add-apt-repository -y "deb http://apt.llvm.org/${DISTRIB_CODENAME}/ llvm-toolchain-${DISTRIB_CODENAME}-${{ env.CLANG_VER }} main"
          sudo apt-get install -y clang-${{ env.CLANG_VER }} llvm-${{ env.CLANG_VER }}
          sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${{ env.CLANG_VER }} 100
          sudo update-alternatives --set clang /usr/bin/clang-${{ env.CLANG_VER }}
          sudo update-alternatives --install /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-${{ env.CLANG_VER }} 100
          sudo update-alternatives --install /usr/bin/asan_symbolize asan_symbolize /usr/bin/asan_symbolize-${{ env.CLANG_VER }} 100

      - name: Set up environment
        run: |
          mkdir -p "${LOG_DIR}"
          mkdir -p "${HOME}/bin"
          echo "${HOME}/bin" >> $GITHUB_PATH
          (
          echo "LINUX_VERSION=$(uname -r)"
          echo "NPROC=$(getconf _NPROCESSORS_ONLN)"
          echo "TMPDIR=${{ runner.temp }}"

          case "${{ matrix.features }}" in
          tiny)
            echo "TEST=testtiny"
            if ${{ contains(matrix.extra, 'nogui') }}; then
              echo "CONFOPT=--disable-gui"
            fi
            ;;
          normal)
            ;;
          huge)
            echo "TEST=scripttests test_libvterm"
            INTERFACE=${{ matrix.interface || 'yes' }}
            if ${{ matrix.python3 == 'stable-abi' }}; then
              PYTHON3_CONFOPT="--with-python3-stable-abi=3.8"
            fi
            echo "CONFOPT=--enable-perlinterp=${INTERFACE} --enable-pythoninterp=${INTERFACE} --enable-python3interp=${INTERFACE} --enable-rubyinterp=${INTERFACE} --enable-luainterp=${INTERFACE} --enable-tclinterp=${INTERFACE} ${PYTHON3_CONFOPT}"
            ;;
          esac

          if ${{ matrix.coverage == true }}; then
            CFLAGS="${CFLAGS} --coverage -DUSE_GCOV_FLUSH"
            echo "LDFLAGS=--coverage"
          fi
          if ${{ contains(matrix.extra, 'uchar') }}; then
            CFLAGS="${CFLAGS} -funsigned-char"
          fi
          if ${{ contains(matrix.extra, 'testgui') }}; then
            echo "TEST=-C src testgui"
          fi
          if ${{ contains(matrix.extra, 'unittests') }}; then
            echo "TEST=unittests"
          fi
          if ${{ contains(matrix.extra, 'asan') }}; then
            echo "SANITIZER_CFLAGS=-g -O1 -DABORT_ON_INTERNAL_ERROR -DEXITFREE -fsanitize-recover=all -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer"
            echo "ASAN_OPTIONS=print_stacktrace=1 log_path=${LOG_DIR}/asan"
            echo "UBSAN_OPTIONS=print_stacktrace=1 log_path=${LOG_DIR}/ubsan"
            echo "LSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/src/testdir/lsan-suppress.txt"
          fi
          if ${{ contains(matrix.extra, 'vimtags') }}; then
            echo "TEST=-C runtime/doc vimtags VIMEXE=../../${SRCDIR}/vim"
          fi
          echo "CFLAGS=${CFLAGS}"
          ) >> $GITHUB_ENV

      - name: Set up system
        run: |
          if [[ ${CC} = clang ]]; then
            # Use llvm-cov instead of gcov when compiler is clang.
            ln -fs /usr/bin/llvm-cov ${HOME}/bin/gcov
          fi
          sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0
          sudo usermod -a -G audio "${USER}"
          sudo bash ci/setup-xvfb.sh

      - name: Set up snd-dummy
        if: (!(contains(matrix.extra, 'unittests') || contains(matrix.extra, 'vimtags')))
        env:
          DEST_DIR: ${{ env.TMPDIR }}/linux-modules-extra-${{ env.LINUX_VERSION }}
        uses: tecolicom/actions-use-apt-tools@main
        with:
          tools: linux-modules-extra-${{ env.LINUX_VERSION }}
          path: "${DEST_DIR}"

      - name: modprobe snd-dummy
        if: (!(contains(matrix.extra, 'unittests') || contains(matrix.extra, 'vimtags')))
        run: |
          sudo depmod --verbose
          sudo modprobe --verbose snd-dummy || true

      - name: Check autoconf
        if: contains(matrix.extra, 'unittests')
        run: |
          make -C src autoconf

      - name: Set up shadow dir
        if: matrix.shadow
        run: |
          make -C src shadow
          echo "SRCDIR=${{ matrix.shadow }}" >> $GITHUB_ENV
          echo "SHADOWOPT=-C ${{ matrix.shadow }}" >> $GITHUB_ENV

      - name: Configure
        run: |
          ./configure --with-features=${{ matrix.features }} ${CONFOPT} --enable-fail-if-missing
          # Append various warning flags to CFLAGS.
          sed -i -f ci/config.mk.sed ${SRCDIR}/auto/config.mk
          sed -i -f ci/config.mk.${CC}.sed ${SRCDIR}/auto/config.mk
          if [[ ${CC} = clang ]]; then
            # Suppress some warnings produced by clang 12 and later.
            sed -i -f ci/config.mk.clang-12.sed ${SRCDIR}/auto/config.mk
          fi

      - name: Build
        if: (!contains(matrix.extra, 'unittests'))
        run: |
          make ${SHADOWOPT} -j${NPROC}

      - name: Check version
        if: (!contains(matrix.extra, 'unittests'))
        run: |
          "${SRCDIR}"/vim --version
          "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit
          "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit

      - name: Test
        timeout-minutes: 25
        run: |
          do_test() { sg audio "sg $(id -gn) '$*'"; }
          do_test make ${SHADOWOPT} ${TEST}

      - name: Vim tags
        if: contains(matrix.extra, 'vimtags')
        run: |
          # This will exit with an error code if the generated vim tags differs from source.
          git diff --exit-code -- runtime/doc/tags

      - name: Generate gcov files
        if: matrix.coverage
        run: |
          cd "${SRCDIR}"
          find . -type f -name '*.gcno' -exec gcov -pb {} + || true

      - name: Codecov
        timeout-minutes: 20
        if: matrix.coverage
        uses: codecov/codecov-action@v3
        with:
          flags: linux,${{ matrix.features }}-${{ matrix.compiler }}-${{ matrix.extra }}

      - name: ASan logs
        if: contains(matrix.extra, 'asan') && !cancelled()
        run: |
          for f in $(grep -lR '#[[:digit:]]* *0x[[:xdigit:]]*' "${LOG_DIR}"); do
            asan_symbolize -l "$f"
            false # in order to fail a job
          done

  macos:
    runs-on: macos-latest

    env:
      CC: clang
      TEST: test
      SRCDIR: ./src
      LEAK_CFLAGS: -DEXITFREE
      TERM: xterm

    strategy:
      fail-fast: false
      matrix:
        features: [tiny, normal, huge]

    steps:
      - name: Checkout repository from github
        uses: actions/checkout@v4

      - name: Install packages
        if: matrix.features == 'huge'
        run: |
          brew install lua
          echo "LUA_PREFIX=/usr/local" >> $GITHUB_ENV

      - name: Set up environment
        run: |
          (
          echo "NPROC=$(getconf _NPROCESSORS_ONLN)"
          case "${{ matrix.features }}" in
          tiny)
            echo "TEST=testtiny"
            echo "CONFOPT=--disable-gui"
            ;;
          normal)
            ;;
          huge)
            echo "CONFOPT=--enable-perlinterp --enable-python3interp --enable-rubyinterp --enable-luainterp --enable-tclinterp"
            ;;
          esac
          ) >> $GITHUB_ENV

      - name: Configure
        run: |
          ./configure --with-features=${{ matrix.features }} ${CONFOPT} --enable-fail-if-missing
          # Append various warning flags to CFLAGS.
          # BSD sed needs backup extension specified.
          sed -i.bak -f ci/config.mk.sed ${SRCDIR}/auto/config.mk
          # On macOS, the entity of gcc is clang.
          sed -i.bak -f ci/config.mk.clang.sed ${SRCDIR}/auto/config.mk
          # Suppress some warnings produced by clang 12 and later.
          if clang --version | grep -qs 'Apple clang version \(1[3-9]\|[2-9]\)\.'; then
            sed -i.bak -f ci/config.mk.clang-12.sed ${SRCDIR}/auto/config.mk
          fi

      - name: Build
        env:
          LC_ALL: C
        run: |
          make -j${NPROC}

      - name: Check version
        run: |
          "${SRCDIR}"/vim --version
          "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit
          "${SRCDIR}"/vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit

      - name: Test
        timeout-minutes: 20
        run: |
          make ${TEST}

  windows:
    runs-on: windows-2022

    env:
      # Interfaces
      # Lua
      LUA_VER: 54
      LUA_VER_DOT: '5.4'
      LUA_RELEASE: 5.4.2
      LUA32_URL: https://downloads.sourceforge.net/luabinaries/lua-%LUA_RELEASE%_Win32_dllw6_lib.zip
      LUA64_URL: https://downloads.sourceforge.net/luabinaries/lua-%LUA_RELEASE%_Win64_dllw6_lib.zip
      LUA_DIR: D:\Lua
      # do not want \L to end up in pathdef.c and compiler complaining about unknown escape sequences \l
      LUA_DIR_SLASH: D:/Lua
      # Python 2
      PYTHON_VER: 27
      PYTHON_VER_DOT: '2.7'
      PYTHON_DIR: 'C:\Python27'
      # Python 3
      PYTHON3_VER: 311
      PYTHON3_VER_DOT: '3.11'
      # Other dependencies
      # winpty
      WINPTY_URL: https://github.com/rprichard/winpty/releases/download/0.4.3/winpty-0.4.3-msvc2015.zip
      # libsodium
      SODIUM_VER: '1.0.18'
      SODIUM_MSVC_URL: https://download.libsodium.org/libsodium/releases/libsodium-%SODIUM_VER%-stable-msvc.zip
      SODIUM_MSVC_VER: v143
      SODIUM_MINGW_URL: https://download.libsodium.org/libsodium/releases/libsodium-%SODIUM_VER%-stable-mingw.tar.gz
      SODIUM_MINGW_VER: 23
      # Escape sequences
      COL_RED: "\x1b[31m"
      COL_GREEN: "\x1b[32m"
      COL_YELLOW: "\x1b[33m"
      COL_RESET: "\x1b[m"

    strategy:
      fail-fast: false
      matrix:
        include:
          - { features: HUGE,   toolchain: msvc,  VIMDLL: no,  GUI: no,  arch: x64, python3: stable }
          - { features: HUGE,   toolchain: mingw, VIMDLL: yes, GUI: yes, arch: x86, python3: stable, coverage: yes }
          - { features: HUGE,   toolchain: msvc,  VIMDLL: no,  GUI: yes, arch: x86 }
          - { features: HUGE,   toolchain: mingw, VIMDLL: yes, GUI: no,  arch: x64, coverage: yes }
          - { features: NORMAL, toolchain: msvc,  VIMDLL: yes, GUI: no,  arch: x86 }
          - { features: NORMAL, toolchain: mingw, VIMDLL: no,  GUI: yes, arch: x64 }
          - { features: TINY,   toolchain: msvc,  VIMDLL: yes, GUI: yes, arch: x64 }
          - { features: TINY,   toolchain: mingw, VIMDLL: no,  GUI: no,  arch: x86 }

    steps:
      - name: Initialize
        id: init
        shell: bash
        run: |
          # Show Windows version
          cmd /c ver

          git config --global core.autocrlf input

          if ${{ matrix.arch == 'x64' }}; then
            cygreg=registry
            pyreg=
            echo "VCARCH=amd64" >> $GITHUB_ENV
            echo "WARCH=x64" >> $GITHUB_ENV
            echo "BITS=64" >> $GITHUB_ENV
            echo "MSYSTEM=MINGW64" >> $GITHUB_ENV
          else
            cygreg=registry32
            pyreg=-32
            echo "VCARCH=x86" >> $GITHUB_ENV
            echo "WARCH=ia32" >> $GITHUB_ENV
            echo "BITS=32" >> $GITHUB_ENV
            echo "MSYSTEM=MINGW32" >> $GITHUB_ENV
          fi

          echo "VCVARSALL=$(vswhere -products \* -latest -property installationPath)\\VC\\Auxiliary\\Build\\vcvarsall.bat" >> $GITHUB_ENV
          if ${{ matrix.features != 'TINY' }}; then
            if ${{ matrix.arch == 'x86' }}; then
              choco install python2 --no-progress --forcex86
            else
              choco install python2 --no-progress
            fi
          fi
          python3_dir=$(cat "/proc/$cygreg/HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${PYTHON3_VER_DOT}$pyreg/InstallPath/@")
          echo "PYTHON3_DIR=$python3_dir" >> $GITHUB_ENV

          if ${{ matrix.toolchain == 'msvc' }}; then
            SODIUM_DIR=D:\\libsodium
            echo "SODIUM_LIB=${SODIUM_DIR}\\${{ matrix.arch == 'x64' && 'x64' || 'Win32' }}\\Release\\${SODIUM_MSVC_VER}\\dynamic" >> $GITHUB_ENV
          else
            SODIUM_DIR=D:\\libsodium-win${{ matrix.arch == 'x64' && '64' || '32' }}
            echo "SODIUM_LIB=${SODIUM_DIR}\\bin" >> $GITHUB_ENV
          fi
          echo "SODIUM_DIR=${SODIUM_DIR}" >> $GITHUB_ENV

      - uses: msys2/setup-msys2@v2
        if: matrix.toolchain == 'mingw'
        with:
          update: true
          install: tar
          pacboy: >-
            make:p gcc:p
          msystem: ${{ env.MSYSTEM }}
          release: false

      - name: Checkout repository from github
        uses: actions/checkout@v4

      - name: Create a list of download URLs
        shell: cmd
        run: |
          type NUL > urls.txt
          echo %LUA_RELEASE%>> urls.txt
          echo %WINPTY_URL%>> urls.txt
          echo %SODIUM_VER%>> urls.txt

      - name: Cache downloaded files
        uses: actions/cache@v3
        with:
          path: downloads
          key: ${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('urls.txt') }}

      - name: Download dependencies
        shell: cmd
        run: |
          path C:\Program Files\7-Zip;%path%
          if not exist downloads mkdir downloads

          echo %COL_GREEN%Download Lua%COL_RESET%
          call :downloadfile %LUA${{ env.BITS }}_URL% downloads\lua.zip
          7z x downloads\lua.zip -o%LUA_DIR% > nul || exit 1

          echo %COL_GREEN%Download winpty%COL_RESET%
          call :downloadfile %WINPTY_URL% downloads\winpty.zip
          7z x -y downloads\winpty.zip -oD:\winpty > nul || exit 1
          copy /Y D:\winpty\%WARCH%\bin\winpty.dll        src\winpty%BITS%.dll
          copy /Y D:\winpty\%WARCH%\bin\winpty-agent.exe  src\

          echo %COL_GREEN%Download libsodium%COL_RESET%
          if "${{ matrix.toolchain }}"=="msvc" (
            call :downloadfile %SODIUM_MSVC_URL% downloads\libsodium.zip
            7z x -y downloads\libsodium.zip -oD:\ > nul || exit 1
          ) else (
            call :downloadfile %SODIUM_MINGW_URL% downloads\libsodium.tar.gz
            7z x -y downloads\libsodium.tar.gz -so | 7z x -si -ttar -oD:\ > nul || exit 1
            mklink %SODIUM_LIB%\libsodium.dll %SODIUM_LIB%\libsodium-%SODIUM_MINGW_VER%.dll
          )

          goto :eof

          :downloadfile
          :: call :downloadfile <URL> <localfile>
          if not exist %2 (
            curl -f -L %1 -o %2
          )
          if ERRORLEVEL 1 (
            rem Retry once.
            curl -f -L %1 -o %2 || exit 1
          )
          goto :eof

      - name: Build (MSVC)
        if: matrix.toolchain == 'msvc'
        shell: cmd
        run: |
          call "%VCVARSALL%" %VCARCH%
          cd src
          if "${{ matrix.VIMDLL }}"=="yes" (
            set GUI=yes
          ) else (
            set GUI=${{ matrix.GUI }}
          )
          if "${{ matrix.python3 }}"=="stable" (
            set PYTHON3_STABLE=yes
          ) else (
            set PYTHON3_STABLE=no
          )
          if "${{ matrix.features }}"=="HUGE" (
            nmake -nologo -f Make_mvc.mak ^
              FEATURES=${{ matrix.features }} ^
              GUI=%GUI% IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} ^
              DYNAMIC_LUA=yes LUA=%LUA_DIR% ^
              DYNAMIC_PYTHON=yes PYTHON=%PYTHON_DIR% ^
              DYNAMIC_PYTHON3=yes PYTHON3=%PYTHON3_DIR% ^
              DYNAMIC_PYTHON3_STABLE_ABI=%PYTHON3_STABLE% ^
              DYNAMIC_SODIUM=yes SODIUM=%SODIUM_DIR%
          ) else (
            nmake -nologo -f Make_mvc.mak ^
              FEATURES=${{ matrix.features }} ^
              GUI=%GUI% IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }}
          )

      - name: Build (MinGW)
        if: matrix.toolchain == 'mingw'
        shell: msys2 {0}
        run: |
          cd src
          if [ "${{ matrix.VIMDLL }}" = "yes" ]; then
            GUI=yes
          else
            GUI=${{ matrix.GUI }}
          fi
          if [ "${{ matrix.python3 }}" = "stable" ]; then
            PYTHON3_STABLE=yes
          else
            PYTHON3_STABLE=no
          fi
          if [ "${{ matrix.features }}" = "HUGE" ]; then
            mingw32-make -f Make_ming.mak -j2 \
              FEATURES=${{ matrix.features }} \
              GUI=$GUI IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} \
              DYNAMIC_LUA=yes LUA=${LUA_DIR_SLASH} \
              DYNAMIC_PYTHON=yes PYTHON=${PYTHON_DIR} \
              DYNAMIC_PYTHON3=yes PYTHON3=${PYTHON3_DIR} \
              DYNAMIC_PYTHON3_STABLE_ABI=${PYTHON3_STABLE} \
              DYNAMIC_SODIUM=yes SODIUM=${SODIUM_DIR} \
              STATIC_STDCPLUS=yes COVERAGE=${{ matrix.coverage }}
          else
            mingw32-make -f Make_ming.mak -j2 \
              FEATURES=${{ matrix.features }} \
              GUI=$GUI IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} \
              STATIC_STDCPLUS=yes
          fi

      - name: Check version
        shell: cmd
        run: |
          PATH %LUA_DIR%;C:\msys64\%MSYSTEM%\bin;%PATH%;%PYTHON3_DIR%
          if "${{ matrix.GUI }}"=="yes" (
            start /wait src\gvim -u NONE -i NONE -c "redir > version.txt | ver | q" || exit 1
            type version.txt
            echo.
            start /wait src\gvim -u NONE -i NONE -c "redir! > version.txt | so ci\if_ver-1.vim | q"
            start /wait src\gvim -u NONE -i NONE -c "redir >> version.txt | so ci\if_ver-2.vim | q"
            type version.txt
            del version.txt
          ) else (
            src\vim --version || exit 1
            src\vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit
            src\vim -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit
          )

      #- name: Prepare Artifact
      #  shell: cmd
      #  run: |
      #    mkdir artifacts
      #    copy src\*vim.exe artifacts
      #    copy src\vim*.dll artifacts
      #
      #- name: Upload Artifact
      #  uses: actions/upload-artifact@v1
      #  with:
      #    name: vim${{ matrix.bits }}-${{ matrix.toolchain }}
      #    path: ./artifacts

      - name: Test and show the result of testing gVim
        if: matrix.GUI == 'yes' || matrix.VIMDLL == 'yes'
        shell: cmd
        timeout-minutes: 15
        run: |
          PATH %LUA_DIR%;C:\msys64\%MSYSTEM%\bin;%PATH%;%PYTHON3_DIR%;%SODIUM_LIB%
          call "%VCVARSALL%" %VCARCH%

          echo %COL_GREEN%Test gVim:%COL_RESET%
          cd src\testdir
          if "${{ matrix.GUI }}"=="yes" (
            nmake -nologo -f Make_mvc.mak VIMPROG=..\gvim || exit 1
          ) else (
            @rem Run only tiny tests.
            nmake -nologo -f Make_mvc.mak tiny VIMPROG=..\gvim  || exit 1
          )

      - name: Test and show the result of testing Vim
        if: matrix.GUI == 'no' || matrix.VIMDLL == 'yes'
        shell: cmd
        timeout-minutes: 15
        run: |
          PATH %LUA_DIR%;C:\msys64\%MSYSTEM%\bin;%PATH%;%PYTHON3_DIR%;%SODIUM_LIB%
          call "%VCVARSALL%" %VCARCH%

          echo %COL_GREEN%Test Vim:%COL_RESET%
          cd src\testdir
          nmake -nologo -f Make_mvc.mak clean
          if "${{ matrix.GUI }}"=="no" (
            nmake -nologo -f Make_mvc.mak VIMPROG=..\vim || exit 1
          ) else (
            @rem Run only tiny tests.
            nmake -nologo -f Make_mvc.mak tiny VIMPROG=..\vim  || exit 1
          )

      - name: Generate gcov files
        if: matrix.coverage
        shell: msys2 {0}
        run: |
          cd src
          find . -type f -name '*.gcno' -exec gcov -pb {} + || true

      - name: Codecov
        timeout-minutes: 20
        if: matrix.coverage
        uses: codecov/codecov-action@v3
        with:
          directory: src
          flags: windows,${{ matrix.toolchain }}-${{ matrix.arch }}-${{ matrix.features }}