Skip to content

Merge remote-tracking branch 'vim/master' #756

Merge remote-tracking branch 'vim/master'

Merge remote-tracking branch 'vim/master' #756

Workflow file for this run

name: MacVim GitHub CI
on:
push:
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
env:
MACOSX_DEPLOYMENT_TARGET: '10.13'
MACOSX_DEPLOYMENT_TARGET_LEGACY: '10.9'
MACVIM_ARCHS: "x86_64 arm64" # Universal app for Intel/Apple Silicon
MACVIM_ARCHS_LEGACY: "x86_64" # Legacy builds only need to build x86-64 because Apple Silicon can't run on these old OSes
CC: clang
MAKE_BUILD_ARGS: LINK_AS_NEEDED=yes # In macOS we never over-specify link dependencies and we already check against external deps in smoketest. With LTO, linking takes a while, so we want to avoid using link.sh.
VERSIONER_PERL_VERSION: '5.30' # macOS default Perl installation uses this to determine which one to use
vi_cv_path_python: /Library/Frameworks/Python.framework/Versions/2.7/bin/python
vi_cv_path_python3: "%s/bin/python3"
vi_cv_path_plain_lua: "%s/bin/lua"
vi_cv_path_ruby: "%s/opt/ruby/bin/ruby"
vi_cv_dll_name_perl: /System/Library/Perl/%s/darwin-thread-multi-2level/CORE/libperl.dylib
vi_cv_dll_name_python: /Library/Frameworks/Python.framework/Versions/2.7/Python
vi_cv_dll_name_python3: /usr/local/Frameworks/Python.framework/Versions/Current/Python
vi_cv_dll_name_python3_arm64: /opt/homebrew/Frameworks/Python.framework/Versions/Current/Python
vi_cv_dll_name_ruby: /usr/local/opt/ruby/lib/libruby.dylib
vi_cv_dll_name_ruby_arm64: /opt/homebrew/opt/ruby/lib/libruby.dylib
vi_cv_dll_name_lua: /usr/local/lib/liblua.dylib
vi_cv_dll_name_lua_arm64: /opt/homebrew/lib/liblua.dylib
MACVIM_APP: src/MacVim/build/Release/MacVim.app
VIM_BIN: src/MacVim/build/Release/MacVim.app/Contents/MacOS/Vim
MACVIM_BIN: src/MacVim/build/Release/MacVim.app/Contents/MacOS/MacVim
TERM: xterm
BASH_SILENCE_DEPRECATION_WARNING: 1
jobs:
# Builds and test MacVim
build-and-test:
# Test on macOS 11.x / 12.x, and also older versions of Xcode for compatibility testing.
strategy:
fail-fast: false
matrix:
include:
# Oldest version of Xcode supported on GitHub Action to test source code backwards compatibility
# This version of Xcode can run on macOS 11 where as 13.3 has to run on macOS 12.
- os: macos-12
xcode: '13.2.1'
extra: [vimtags, check-xcodeproj-compat]
# Older version of Xcode, and used to publish legacy builds (for macOS 10.9 - 10.12)
- os: macos-12
xcode: '14.0' # last version of Xcode that uses the macOS 12 SDK, which still supports deploying to macOS 10.9
publish: true
legacy: true
publish_postfix: '_10.9'
- os: macos-13
xcode: '15.2'
optimized: true
# Most up to date OS and Xcode. Used to publish release for the main build.
# This runner uses Apple Silicon.
- os: macos-14
xcode: '15.2'
publish: true
optimized: true
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up legacy build
if: matrix.legacy
run: |
# Set the correct build env vars to target the correct architectures and min OS targets.
echo "MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET_LEGACY" >> $GITHUB_ENV
echo "MACVIM_ARCHS=$MACVIM_ARCHS_LEGACY" >> $GITHUB_ENV
# Use Sparkle 1 because Sparkle 2 requires newer OS version than our legacy build.
# Later, we pass the --enable-sparkle_1 flag to configure to set the corresponding ifdef.
ln -fhs Sparkle_1.framework src/MacVim/Sparkle.framework
# Sparkle shows a dialog asking if the user wants to check for updates on 2nd launch of
# MacVim. On Sparkle 1 this is annoyingly a modal dialog box and interferes with tests.
# Just disable it by pre-setting to not check for updates.
defaults write org.vim.MacVim SUEnableAutomaticChecks 0
- name: Set up Xcode
if: matrix.xcode != ''
run: |
sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
xcode-select -p
xcodebuild -version
# Set up, install, and cache gettext library for localization.
#
- name: Set up gettext
if: matrix.publish
uses: ./.github/actions/universal-package
with:
formula: gettext
contents: lib/libintl.a,lib/libintl.dylib
# Set up, install, and cache libsodium library for encryption.
- name: Set up libsodium
if: matrix.publish
uses: ./.github/actions/universal-package
with:
formula: libsodium
contents: lib/libsodium.a,lib/libsodium.dylib
# Set up remaining packages and tools
- name: Install packages
run: |
brew install --quiet libtool
- name: Install packages for testing
run: |
# Apple diff is broken. Use GNU diff instead. See http://github.com/vim/vim/issues/14056.
brew install --quiet diffutils
- name: Grant microphone access for macos-14
if: matrix.os == 'macos-14'
run: |
# Temporary fix to fix microphone permission issues for macos-14 when playing sound.
sqlite3 $HOME/Library/Application\ Support/com.apple.TCC/TCC.db "INSERT OR IGNORE INTO access VALUES ('kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159,NULL,NULL,'UNUSED',1687786159);"
- name: Install scripting runtimes
if: matrix.publish
run: |
# We no longer need to install/update Python 3, as it's guaranteed to
# be installed on runners. Since we use stable ABI, the exact version
# on CI does not matter.
brew install --quiet ruby
brew install --quiet lua
if [[ -d $(brew --prefix)/Cellar/perl ]]; then
# We just use system perl to reduce dependencies
brew unlink perl
fi
echo "vi_cv_path_python3=$(printf $vi_cv_path_python3 $(brew --prefix))" >> $GITHUB_ENV
echo "vi_cv_path_plain_lua=$(printf $vi_cv_path_plain_lua $(brew --prefix))" >> $GITHUB_ENV
echo "vi_cv_path_ruby=$(printf $vi_cv_path_ruby $(brew --prefix))" >> $GITHUB_ENV
# With Perl, we need to manually specify the version number because the dylib path depends on it.
echo "vi_cv_dll_name_perl=$(printf $vi_cv_dll_name_perl $VERSIONER_PERL_VERSION)" >> $GITHUB_ENV
# New runner images (macos-13) no longer have Python2 installed. We
# need to install Python2 manually. Installing from the official
# installer is the easiest way as Homebrew no longer ships python@2
# and this way does not invole manual building from source. We
# mostly only need the headers to build a dynamic build anyway.
#
# This will be removed in the future as Python2 has been completely
# unsupported for years.
curl https://www.python.org/ftp/python/2.7.18/python-2.7.18-macosx10.9.pkg -o ~/Downloads/python-2.7.18-macosx10.9.pkg
sudo installer -pkg ~/Downloads/python-2.7.18-macosx10.9.pkg -target /
# All set up steps are done. Build and test MacVim below.
- name: Configure
run: |
set -o verbose
CONFOPT=(
--with-local-dir=$(brew --prefix)
--with-features=huge
--enable-netbeans
--with-tlib=ncurses
--enable-cscope
--enable-gui=macvim
--with-compiledby="GitHub Actions"
)
if ${{ matrix.publish == true }}; then
CONFOPT+=(
--enable-perlinterp=dynamic
--enable-pythoninterp=dynamic
--enable-python3interp=dynamic
--with-python3-stable-abi=3.9 # macOS and Xcode currently ships 3.9, so we don't want go higher than that.
--enable-rubyinterp=dynamic
--enable-luainterp=dynamic
--with-lua-prefix=$(brew --prefix)
--with-macarchs="$MACVIM_ARCHS"
)
else
CONFOPT+=(
--disable-sparkle # Disable Sparkle for testing that this flag builds and works
)
fi
if ${{ matrix.legacy == true }}; then
CONFOPT+=(
--enable-sparkle_1
)
fi
echo "CONFOPT: ${CONFOPT[@]}"
./configure "${CONFOPT[@]}" --enable-fail-if-missing
sed -i.bak -f ci/config.mk.sed -f ci/config.mk.clang.sed -f ci/config.mk.xcode.sed src/auto/config.mk
if clang --version | grep -qs '^Apple clang version \(1[3-9]\|[2-9]\d\)\.'; then
sed -i.bak -f ci/config.mk.clang-12.sed src/auto/config.mk
fi
if ${{ matrix.optimized == true }}; then
# Additional optimizations like link-time optimizations that are a bit slower to build.
sed -i.bak -f ci/config.mk.optimized.sed src/auto/config.mk
fi
- name: Modify configure result
if: matrix.publish
run: |
# Ruby is keg-only in Homebrew, so need to manually link in the path so Vim will know where to look for the binaries.
perl -p -i -e "s#(?<=-DDYNAMIC_RUBY_DLL=\\\\\").*?(?=\\\\\")#${vi_cv_dll_name_ruby}#" src/auto/config.mk
grep -q -- "-DDYNAMIC_PERL_DLL=\\\\\"${vi_cv_dll_name_perl}\\\\\"" src/auto/config.mk
grep -q -- "-DDYNAMIC_PYTHON_DLL=\\\\\"${vi_cv_dll_name_python}\\\\\"" src/auto/config.mk
grep -q -- "-DDYNAMIC_PYTHON3_DLL=\\\\\"${vi_cv_dll_name_python3}\\\\\"" src/auto/config.mk
grep -q -- "-DDYNAMIC_RUBY_DLL=\\\\\"${vi_cv_dll_name_ruby}\\\\\"" src/auto/config.mk
# Also search for the arm64 overrides for the default library locations, which are different from x86_64
# because Homebrew puts them at a different place.
grep -q -- "-DDYNAMIC_PYTHON3_DLL_ARM64=\\\\\"${vi_cv_dll_name_python3_arm64}\\\\\"" src/auto/config.mk
grep -q -- "-DDYNAMIC_RUBY_DLL_ARM64=\\\\\"${vi_cv_dll_name_ruby_arm64}\\\\\"" src/auto/config.mk
grep -q -- "-DDYNAMIC_LUA_DLL_ARM64=\\\\\"${vi_cv_dll_name_lua_arm64}\\\\\"" src/auto/config.mk
- name: Show configure output
run: |
cat src/auto/config.mk
cat src/auto/config.h
- name: Build
env:
LC_ALL: C
run: |
NPROC=$(getconf _NPROCESSORS_ONLN)
echo "Building MacVim with ${NPROC} cores"
set -o verbose
make ${MAKE_BUILD_ARGS} -j${NPROC}
- name: Check version
run: |
${VIM_BIN} --version
${VIM_BIN} -u NONE -i NONE --not-a-term -esNX -V1 -c 'echo "\nprof_nsec:" .. has("prof_nsec") .. "\n"' -c quit
${VIM_BIN} -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-1.vim -c quit
${VIM_BIN} -u NONE -i NONE --not-a-term -esNX -V1 -S ci/if_ver-2.vim -c quit
- name: Smoketest
run: |
set -o verbose
# Make sure there isn't any dynamic linkage to third-party dependencies in the built binary, as we should only use
# static linkage to avoid dependency hell. Test that all those dylib's are in /usr/lib which is bundled with macOS and not third-party.
if otool -L ${VIM_BIN} | grep '\.dylib\s' | grep -v '^\s*/usr/lib/'; then
echo 'Found external dynamic linkage!'; false
fi
# Make sure that --disable-sparkle flag will properly exclude all references to Sparkle symbols. This is
# necessary because we still use weak linking to Sparkle when that flag is set and so references to Sparkle
# wouldn't fail the build (we just remove Sparkle.framework from the built app after the fact).
if ${{ matrix.publish == false }}; then
# Currently we pass --disable-sparkle flag when publish==false
if objdump -t ${MACVIM_BIN} | grep "_SPU\|_SUUpdate"; then
echo 'Found references to Sparkle even when using --disable-sparkle'; false
fi
fi
# Make sure man pages were bundled
man -M `pwd`/${MACVIM_APP}/Contents/man -w mvim
# Make sure xxd was bundled
echo "AB" | ${MACVIM_APP}/Contents/bin/xxd | grep "4142"
- name: Smoketest (publish)
if: matrix.publish
run: |
set -o verbose
macvim_excmd() {
${VIM_BIN} -u NONE -i NONE -g -f -X -V1 -es "$@" -c 'echo ""' -c 'qall!' 2>&1
}
# Smoketest scripting languages
macvim_excmd -c 'lua print("Test")' | grep Test
macvim_excmd -c 'perl VIM::Msg("Test")' | grep Test
macvim_excmd -c 'py3 print("Test")' | grep Test
macvim_excmd -c 'ruby puts("Test")' | grep Test
if [[ "$(uname -m)" == "x86_64" ]]; then
macvim_excmd -c 'py print "x86 Test"' | grep Test
else
# Python2 doesn't work in Apple Silicon, test under Rosetta
(VIM_BIN="arch -x86_64 ${VIM_BIN}"; macvim_excmd -c 'py print "rosetta Test"' | grep Test)
fi
# Check that localized messages work by printing ':version' and checking against localized word
macvim_excmd -c 'lang es_ES' -c 'version' | grep Enlazado
# Check that libsodium is working
macvim_excmd -c 'set cryptmethod=xchacha20v2'
# Make sure we are building universal x86_64 / arm64 builds and didn't accidentally create a thin app.
check_arch() {
local archs=($(lipo -archs "$1"))
if [[ ${archs[@]} != "$MACVIM_ARCHS" ]]; then
echo "Wrong arch(s) in $1: ${archs[@]}"; false
else
lipo -info "$1"
fi
}
check_arch "${VIM_BIN}"
check_arch "${MACVIM_BIN}"
- name: Check Vim help tags
if: contains(matrix.extra, 'vimtags')
run: |
# Confirm that we can build the help tags, and they match what's in source.
make -C runtime/doc vimtags VIMEXE=../../${VIM_BIN}
git diff --exit-code -- runtime/doc/tags
- name: Check Xcode project compatibility version
if: contains(matrix.extra, 'check-xcodeproj-compat')
run: |
# Confirm that the compatibility version of xcodeproj is correct and not outdated.
rm -rf src/MacVim/MacVim_xcode8.xcodeproj
make -C src macvim-xcodeproj-compat
if ! git diff --exit-code -- src/MacVim/MacVim_xcode8.xcodeproj; then
echo 'MacVim_xcode8.xcodeproj is outdated. Run "make -C src macvim-xcodeproj-compat" to re-generate it.'; false
fi
- name: Test MacVim
timeout-minutes: 10
run: |
make ${MAKE_BUILD_ARGS} -C src macvim-tests
- name: Build Vim test binaries
run: |
# Build the unit test binaries first. With link-time-optimization they take some time to link. Running them
# separately de-couples them from the timeout in tests, and allow us to build in parallel jobs (since tests
# can't run in parallel).
NPROC=$(getconf _NPROCESSORS_ONLN)
set -o verbose
make ${MAKE_BUILD_ARGS} -j${NPROC} -C src unittesttargets
- name: Test Vim
timeout-minutes: 20
run: make ${MAKE_BUILD_ARGS} test
- name: Test Vim (GUI)
timeout-minutes: 20
run: |
make ${MAKE_BUILD_ARGS} -C src/testdir clean
make ${MAKE_BUILD_ARGS} -C src testgui
# Creates a DMG package of MacVim. Note that this doesn't create a GitHub release for us, because we would prefer to
# do it manually, for two reasons: 1) signing / notarization are currently done out of CI, 2) we want to manually
# format our release notes and add pictures to make them look nice.
- name: Build MacVim dmg image
if: startsWith(github.ref, 'refs/tags/') && matrix.publish
run: |
# Use the --skip-jenkins flag to skip the prettify osascript calls which could fail due to permission issues in
# CI environment.
if ${{ matrix.legacy == true }}; then
make -C src macvim-dmg-legacy CREATEDMG_FLAGS=--skip-jenkins
else
make -C src macvim-dmg CREATEDMG_FLAGS=--skip-jenkins
fi
if ${{ matrix.publish_postfix != '' }}; then
mv src/MacVim/build/Release/MacVim.dmg src/MacVim/build/Release/MacVim${{ matrix.publish_postfix }}.dmg
fi
- name: Upload MacVim image
if: startsWith(github.ref, 'refs/tags/') && matrix.publish
uses: actions/upload-artifact@v4
with:
name: MacVim${{ matrix.publish_postfix }}.dmg
path: src/MacVim/build/Release/MacVim${{ matrix.publish_postfix }}.dmg