# Copyright (C) Daniel Stenberg, , et al. # # SPDX-License-Identifier: curl name: macOS 'on': push: branches: - master - '*/ci' paths-ignore: - '**/*.md' - '.circleci/**' - 'appveyor.*' - 'packages/**' - 'plan9/**' - 'projects/**' - 'winbuild/**' pull_request: branches: - master paths-ignore: - '**/*.md' - '.circleci/**' - 'appveyor.*' - 'packages/**' - 'plan9/**' - 'projects/**' - 'winbuild/**' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: true permissions: {} # Deprecated Apple APIs and the macos-version-min value required to avoid # deprecation warnings with llvm/clang: # # - 10.7 Lion (2011) - GSS # - 10.8 Mountain Lion (2012) - CFURLCreateDataAndPropertiesFromResource (used by curl Secure Transport code) # - 10.9 Maverick (2013) - LDAP # - 10.14 Mojave (2018) - Secure Transport # # For Secure Transport, curl implements features that require a target # newer than the 10.8 required by `CFURLCreateDataAndPropertiesFromResource`. env: MAKEFLAGS: -j 4 LDFLAGS: -w # suppress 'object file was built for newer macOS version than being linked' warnings jobs: macos: name: "${{ matrix.build.generate && 'CM' || 'AM' }} ${{ matrix.compiler }} ${{ matrix.build.name }}" runs-on: 'macos-latest' timeout-minutes: 45 env: DEVELOPER_DIR: "/Applications/Xcode${{ matrix.build.xcode && format('_{0}', matrix.build.xcode) || '' }}.app/Contents/Developer" CC: ${{ matrix.compiler }} CFLAGS: '' strategy: fail-fast: false matrix: compiler: [clang, llvm@15, gcc-12] build: # automake - name: '!ssl !debug brotli zstd' compiler: clang install: brotli zstd configure: --without-ssl --with-brotli --with-zstd - name: '!ssl !debug' compiler: gcc-12 configure: --without-ssl - name: '!ssl' compiler: clang configure: --enable-debug --without-ssl - name: '!ssl libssh2 AppleIDN' compiler: clang configure: --enable-debug --with-libssh2=$(brew --prefix libssh2) --without-ssl --with-apple-idn - name: 'OpenSSL libssh c-ares' compiler: clang install: libssh configure: --enable-debug --with-libssh --with-openssl=$(brew --prefix openssl) --enable-ares - name: 'OpenSSL libssh' compiler: llvm@15 install: libssh libnghttp3 configure: --enable-debug --with-libssh --with-openssl=$(brew --prefix openssl) --with-openssl-quic - name: '!ssl c-ares' compiler: clang configure: --enable-debug --enable-ares --without-ssl - name: '!ssl HTTP-only' compiler: clang configure: >- --enable-debug --disable-alt-svc --disable-dict --disable-file --disable-ftp --disable-gopher --disable-imap --disable-ldap --disable-pop3 --without-librtmp --disable-rtsp --disable-shared --disable-smb --disable-smtp --disable-telnet --disable-tftp --disable-unix-sockets --without-brotli --without-gssapi --without-libidn2 --without-libpsl --without-librtmp --without-libssh2 --without-libssh --without-wolfssh --without-nghttp2 --disable-ntlm --without-ssl --without-zlib --without-zstd macos-version-min: '10.15' # Catalina (2019) - name: 'SecureTransport libssh2' compiler: clang configure: --enable-debug --with-secure-transport --with-libssh2=$(brew --prefix libssh2) macos-version-min: '10.8' - name: 'SecureTransport libssh2 10.12' compiler: clang configure: --enable-debug --with-secure-transport --with-libssh2=$(brew --prefix libssh2) macos-version-min: '10.12' # for monotonic timers - name: 'SecureTransport libssh2' compiler: gcc-12 configure: --enable-debug --with-secure-transport --with-libssh2=$(brew --prefix libssh2) macos-version-min: '10.8' - name: 'LibreSSL +examples' compiler: clang install: libressl configure: --enable-debug --with-openssl=$(brew --prefix libressl) - name: 'OpenSSL' compiler: clang configure: --enable-debug --with-openssl=$(brew --prefix openssl) - name: 'OpenSSL event-based' compiler: clang configure: --enable-debug --with-openssl=$(brew --prefix openssl) tflags: --test-event - name: 'quictls libssh2 !ldap 10.15' compiler: clang install: quictls configure: --enable-debug --disable-ldap --with-openssl=$(brew --prefix quictls) LDFLAGS="${LDFLAGS} -L$(brew --prefix quictls)/lib" macos-version-min: '10.15' # cmake - name: 'OpenSSL gsasl rtmp AppleIDN' install: gsasl rtmpdump generate: -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) -DCURL_USE_GSASL=ON -DUSE_LIBRTMP=ON -DUSE_APPLE_IDN=ON - name: 'OpenSSL AppleIDN clang-tidy +examples' install: llvm generate: -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) -DUSE_APPLE_IDN=ON -DCURL_CLANG_TIDY=ON -DCLANG_TIDY=$(brew --prefix llvm)/bin/clang-tidy clang-tidy: true chkprefill: _chkprefill - name: 'quictls +static libssh +examples' install: quictls libssh generate: -DOPENSSL_ROOT_DIR=$(brew --prefix quictls) -DBUILD_STATIC_LIBS=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=ON - name: 'SecureTransport debug' generate: -DCURL_USE_SECTRANSP=ON -DENABLE_DEBUG=ON macos-version-min: '10.8' - name: 'LibreSSL !ldap heimdal c-ares +examples' install: libressl heimdal generate: -DOPENSSL_ROOT_DIR=$(brew --prefix libressl) -DENABLE_ARES=ON -DCURL_USE_GSSAPI=ON -DGSS_ROOT_DIR=$(brew --prefix heimdal) -DCURL_DISABLE_LDAP=ON - name: 'wolfSSL !ldap brotli zstd' install: brotli wolfssl zstd generate: -DCURL_USE_WOLFSSL=ON -DCURL_DISABLE_LDAP=ON -DUSE_ECH=ON - name: 'mbedTLS openldap brotli zstd' install: brotli mbedtls zstd openldap generate: -DCURL_USE_MBEDTLS=ON -DLDAP_INCLUDE_DIR="$(brew --prefix openldap)/include" -DLDAP_LIBRARY="$(brew --prefix openldap)/lib/libldap.dylib" -DLDAP_LBER_LIBRARY="$(brew --prefix openldap)/lib/liblber.dylib" - name: 'GnuTLS !ldap krb5' install: gnutls nettle krb5 generate: -DCURL_USE_GNUTLS=ON -DCURL_USE_OPENSSL=OFF -DCURL_USE_GSSAPI=ON -DGSS_ROOT_DIR=$(brew --prefix krb5) -DCURL_DISABLE_LDAP=ON -DUSE_SSLS_EXPORT=ON - name: 'OpenSSL torture !FTP' generate: -DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DENABLE_THREADED_RESOLVER=OFF -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) tflags: -t --shallow=25 !FTP torture: true - name: 'OpenSSL torture FTP' generate: -DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DENABLE_THREADED_RESOLVER=OFF -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) tflags: -t --shallow=20 FTP torture: true exclude: - { compiler: llvm@15, build: { macos-version-min: '10.15' } } - { compiler: llvm@15, build: { torture: true } } - { compiler: gcc-12, build: { torture: true } } - { compiler: llvm@15, build: { clang-tidy: true } } - { compiler: gcc-12, build: { clang-tidy: true } } # opt out jobs from combinations that have the compiler set manually - { compiler: llvm@15, build: { compiler: 'clang' } } - { compiler: llvm@15, build: { compiler: 'gcc-12' } } - { compiler: gcc-12, build: { compiler: 'clang' } } - { compiler: gcc-12, build: { compiler: 'llvm@15' } } - { compiler: clang, build: { compiler: 'gcc-12' } } - { compiler: clang, build: { compiler: 'llvm@15' } } steps: - name: 'brew install' # Run this command with retries because of spurious failures seen # while running the tests, for example # https://github.com/curl/curl/runs/4095721123?check_suite_focus=true run: | echo ${{ matrix.build.generate && 'ninja' || 'automake libtool' }} \ pkgconf libpsl libssh2 \ ${{ !matrix.build.clang-tidy && 'nghttp2 stunnel' || '' }} \ ${{ contains(matrix.build.install_steps, 'pytest') && 'caddy httpd vsftpd' || '' }} \ ${{ matrix.build.install }} | xargs -Ix -n1 echo brew '"x"' > /tmp/Brewfile while [[ $? == 0 ]]; do for i in 1 2 3; do brew update && brew bundle install --file /tmp/Brewfile && break 2 || { echo Error: wait to try again; sleep 10; } done; false Too many retries; done - name: 'brew unlink openssl' if: ${{ contains(matrix.build.install, 'libressl') || contains(matrix.build.install, 'quictls') }} run: | if test -d $(brew --prefix)/include/openssl; then brew unlink openssl fi - name: 'toolchain versions' run: | [[ '${{ matrix.compiler }}' = 'llvm'* ]] && CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" [[ '${{ matrix.compiler }}' = 'gcc'* ]] && "${CC}" --print-sysroot which "${CC}"; "${CC}" --version || true xcodebuild -version || true xcrun --sdk macosx --show-sdk-path 2>/dev/null || true xcrun --sdk macosx --show-sdk-version || true ls -l /Library/Developer/CommandLineTools/SDKs || true echo '::group::macros predefined'; "${CC}" -dM -E - < /dev/null | sort || true; echo '::endgroup::' echo '::group::brew packages installed'; ls -l "$(brew --prefix)/opt"; echo '::endgroup::' - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: persist-credentials: false - name: 'autoreconf' if: ${{ matrix.build.configure }} run: autoreconf -fi - name: 'configure' run: | if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then sysroot="$("${CC}" --print-sysroot)" # Must match the SDK gcc was built for else sysroot="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)" fi if [[ '${{ matrix.compiler }}' = 'llvm'* ]]; then CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" CC+=" --sysroot=${sysroot}" CC+=" --target=$(uname -m)-apple-darwin" fi if [ -n '${{ matrix.build.generate }}' ]; then for _chkprefill in '' ${{ matrix.build.chkprefill }}; do options='' [ -n '${{ matrix.build.macos-version-min }}' ] && options+=' -DCMAKE_OSX_DEPLOYMENT_TARGET=${{ matrix.build.macos-version-min }}' [[ '${{ matrix.build.install_steps }}' = *'pytest'* ]] && options+=' -DTEST_NGHTTPX= -DHTTPD_NGHTTPX=' [ "${_chkprefill}" = '_chkprefill' ] && options+=' -D_CURL_PREFILL=OFF' cmake -B "bld${_chkprefill}" -G Ninja -D_CURL_PREFILL=ON \ -DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON -DCURL_WERROR=ON \ -DCMAKE_OSX_SYSROOT="${sysroot}" \ -DCMAKE_C_COMPILER_TARGET="$(uname -m | sed 's/arm64/aarch64/')-apple-darwin$(uname -r)" \ ${{ matrix.build.generate }} ${options} done if [ -d bld_chkprefill ] && ! diff -u bld/lib/curl_config.h bld_chkprefill/lib/curl_config.h; then echo '::group::reference configure log'; cat bld_chkprefill/CMakeFiles/CMake*.yaml 2>/dev/null || true; echo '::endgroup::' false fi else export CFLAGS if [[ '${{ matrix.compiler }}' = 'llvm'* ]]; then options+=" --target=$(uname -m)-apple-darwin" fi if [ '${{ matrix.compiler }}' != 'clang' ]; then options+=" --with-sysroot=${sysroot}" CFLAGS+=" --sysroot=${sysroot}" fi [ -n '${{ matrix.build.macos-version-min }}' ] && CFLAGS+=' -mmacosx-version-min=${{ matrix.build.macos-version-min }}' [[ '${{ matrix.build.install_steps }}' = *'pytest'* ]] && options+=' --with-test-nghttpx= ac_cv_path_HTTPD_NGHTTPX=' mkdir bld && cd bld && ../configure --enable-unity --enable-test-bundles --enable-warnings --enable-werror \ --disable-dependency-tracking \ --with-libpsl=$(brew --prefix libpsl) \ ${{ matrix.build.configure }} ${options} fi - name: 'configure log' if: ${{ !cancelled() }} run: cat bld/config.log bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true - name: 'curl_config.h' run: | echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::' grep -F '#define' bld/lib/curl_config.h | sort || true - name: 'test configs' run: grep -H -v '^#' bld/tests/config bld/tests/http/config.ini || true - name: 'build-cert' if: contains(matrix.build.generate, '-DCURL_USE_SECTRANSP=ON') || contains(matrix.build.configure, '--with-secure-transport') run: | if [ -n '${{ matrix.build.generate }}' ]; then cmake --build bld --target clean-certs cmake --build bld --target build-certs --parallel 1 else make -C bld/tests/certs clean-certs make -C bld/tests/certs build-certs -j1 fi - name: 'build' run: | if [ -n '${{ matrix.build.generate }}' ]; then cmake --build bld --verbose else make -C bld V=1 fi - name: 'curl version' run: bld/src/curl --disable --version - name: 'build tests' run: | if [ -n '${{ matrix.build.generate }}' ]; then cmake --build bld --target testdeps else make -C bld V=1 -C tests fi - name: 'install test prereqs' if: ${{ !matrix.build.clang-tidy }} run: | python3 -m venv $HOME/venv source $HOME/venv/bin/activate python3 -m pip install -r tests/requirements.txt - name: 'run tests' if: ${{ !matrix.build.clang-tidy }} timeout-minutes: ${{ matrix.build.torture && 20 || 10 }} run: | export TFLAGS='-j20 ${{ matrix.build.tflags }}' if [ -z '${{ matrix.build.torture }}' ]; then TFLAGS+=' ~2037 ~2041' # flaky fi source $HOME/venv/bin/activate rm -f $HOME/.curlrc if [ -n '${{ matrix.build.generate }}' ]; then cmake --build bld --target ${{ matrix.build.torture && 'test-torture' || 'test-ci' }} else make -C bld V=1 ${{ matrix.build.torture && 'test-torture' || 'test-ci' }} fi - name: 'install pytest prereqs' if: ${{ !matrix.build.clang-tidy && contains(matrix.build.install_steps, 'pytest') }} run: | source $HOME/venv/bin/activate python3 -m pip install -r tests/http/requirements.txt - name: 'run pytest' if: ${{ !matrix.build.clang-tidy && contains(matrix.build.install_steps, 'pytest') }} env: CURL_CI: github PYTEST_ADDOPTS: '--color=yes' run: | source $HOME/venv/bin/activate if [ -n '${{ matrix.build.generate }}' ]; then cmake --build bld --verbose --target curl-pytest-ci else make -C bld V=1 pytest-ci fi - name: 'build examples' if: ${{ contains(matrix.build.name, '+examples') }} run: | if [ -n '${{ matrix.build.generate }}' ]; then cmake --build bld --verbose --target curl-examples else make -C bld examples V=1 fi combinations: # Test buildability with host OS, Xcode / SDK, compiler, target-OS, Secure Transport/not, built tool, combinations if: true # Set to `true` to enable this test matrix. It runs quickly. name: "${{ matrix.build == 'cmake' && 'CM' || 'AM' }} ${{ matrix.compiler }} ${{ matrix.image }} ${{ matrix.xcode }} ${{ matrix.config }}" runs-on: ${{ matrix.image }} timeout-minutes: 10 env: DEVELOPER_DIR: "/Applications/Xcode${{ matrix.xcode && format('_{0}', matrix.xcode) || '' }}.app/Contents/Developer" CC: ${{ matrix.compiler }} strategy: fail-fast: false matrix: config: [SecureTransport] # also: OpenSSL compiler: [gcc-12, gcc-13, gcc-14, llvm@15, llvm@18, clang] # Xcode support matrix as of 2024-07, with default macOS SDK versions and OS names, years: # * = default Xcode on the runner. # macos-13: 14.1, 14.2, 14.3.1, 15.0.1, 15.1,*15.2 # macos-14: 15.0.1, 15.1, 15.2, 15.3,*15.4 # macos-15: *16.0, 16.1 # macOSSDK: 13.0, 13.1, 13.3, 14.0, 14.2, 14.2, 14.4, 14.5, 15.0, 15.1 # Ventura (2022) Sonoma (2023) Sequoia (2024) # https://github.com/actions/runner-images/tree/main/images/macos # https://en.wikipedia.org/wiki/MacOS_version_history image: [macos-13, macos-14, macos-15] # Can skip these to reduce jobs: # 15.1 has the same default macOS SDK as 15.2 and identical test results. # 14.1, 15.4 not revealing new fallouts. #xcode: ['14.1', '14.2', '14.3.1', '15.0.1', '15.1', '15.2', '15.3', '15.4', '16.0', '16.1'] # all Xcode #xcode: ['14.1', '14.2', '14.3.1', '15.0.1' , '15.2', '15.3', '15.4', '16.0', '16.1'] # all SDK #xcode: [ '14.2', '14.3.1', '15.0.1' , '15.2', '15.3' , '16.0' ] # coverage xcode: [''] # default Xcodes macos-version-min: [''] build: [autotools, cmake] exclude: # Combinations not covered by runner images: - { image: macos-13, xcode: '15.3' } - { image: macos-13, xcode: '15.4' } - { image: macos-13, xcode: '16.0' } - { image: macos-13, xcode: '16.1' } - { image: macos-14, xcode: '14.1' } - { image: macos-14, xcode: '14.2' } - { image: macos-14, xcode: '14.3.1' } - { image: macos-14, xcode: '16.0' } - { image: macos-14, xcode: '16.1' } - { image: macos-15, xcode: '14.1' } - { image: macos-15, xcode: '14.2' } - { image: macos-15, xcode: '14.3.1' } - { image: macos-15, xcode: '15.0.1' } - { image: macos-15, xcode: '15.1' } - { image: macos-15, xcode: '15.2' } - { image: macos-15, xcode: '15.3' } - { image: macos-15, xcode: '15.4' } - { image: macos-13, compiler: 'llvm@18' } - { image: macos-14, compiler: 'llvm@18' } - { image: macos-15, compiler: 'llvm@15' } # Reduce build combinations, by dropping less interesting ones - { compiler: gcc-12, config: SecureTransport } - { compiler: gcc-13, build: cmake } - { compiler: gcc-14, build: autotools } steps: - name: 'install autotools' if: ${{ matrix.build == 'autotools' }} run: | echo automake libtool | xargs -Ix -n1 echo brew '"x"' > /tmp/Brewfile while [[ $? == 0 ]]; do for i in 1 2 3; do brew update && brew bundle install --file /tmp/Brewfile && break 2 || { echo Error: wait to try again; sleep 10; } done; false Too many retries; done - name: 'toolchain versions' run: | [[ '${{ matrix.compiler }}' = 'llvm'* ]] && CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" [[ '${{ matrix.compiler }}' = 'gcc'* ]] && "${CC}" --print-sysroot which "${CC}"; "${CC}" --version || true xcodebuild -version || true xcrun --sdk macosx --show-sdk-path 2>/dev/null || true xcrun --sdk macosx --show-sdk-version || true ls -l /Library/Developer/CommandLineTools/SDKs || true echo '::group::macros predefined'; "${CC}" -dM -E - < /dev/null | sort || true; echo '::endgroup::' echo '::group::brew packages preinstalled'; ls -l "$(brew --prefix)/opt"; echo '::endgroup::' - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: persist-credentials: false - name: 'autoreconf' if: ${{ matrix.build == 'autotools' }} run: autoreconf -fi - name: 'configure / ${{ matrix.build }}' run: | if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then sysroot="$("${CC}" --print-sysroot)" # Must match the SDK gcc was built for else sysroot="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)" fi if [[ '${{ matrix.compiler }}' = 'llvm'* ]]; then CC="$(brew --prefix ${{ matrix.compiler }})/bin/clang" CC+=" --sysroot=${sysroot}" CC+=" --target=$(uname -m)-apple-darwin" fi if [ '${{ matrix.build }}' = 'cmake' ]; then [ '${{ matrix.config }}' = 'OpenSSL' ] && options+=' -DCURL_USE_OPENSSL=ON' [ '${{ matrix.config }}' = 'SecureTransport' ] && options+=' -DCURL_USE_SECTRANSP=ON' [ -n '${{ matrix.macos-version-min }}' ] && options+=' -DCMAKE_OSX_DEPLOYMENT_TARGET=${{ matrix.macos-version-min }}' # would pick up nghttp2, libidn2, and libssh2 cmake -B bld -D_CURL_PREFILL=ON \ -DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON -DCURL_WERROR=ON \ -DCMAKE_OSX_SYSROOT="${sysroot}" \ -DCMAKE_C_COMPILER_TARGET="$(uname -m | sed 's/arm64/aarch64/')-apple-darwin$(uname -r)" \ -DCMAKE_IGNORE_PREFIX_PATH="$(brew --prefix)" \ -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF \ -DUSE_NGHTTP2=OFF -DUSE_LIBIDN2=OFF \ -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF \ ${options} else export CFLAGS if [[ '${{ matrix.compiler }}' = 'llvm'* ]]; then options+=" --target=$(uname -m)-apple-darwin" fi if [ '${{ matrix.compiler }}' != 'clang' ]; then options+=" --with-sysroot=${sysroot}" CFLAGS+=" --sysroot=${sysroot}" fi [ '${{ matrix.config }}' = 'OpenSSL' ] && options+=" --with-openssl=$(brew --prefix openssl)" [ '${{ matrix.config }}' = 'SecureTransport' ] && options+=' --with-secure-transport' [ -n '${{ matrix.macos-version-min }}' ] && CFLAGS+=' -mmacosx-version-min=${{ matrix.macos-version-min }}' # would pick up nghttp2, libidn2, but libssh2 is disabled by default mkdir bld && cd bld && ../configure --enable-unity --enable-test-bundles --enable-warnings --enable-werror \ --disable-dependency-tracking \ --disable-docs --disable-manual \ --without-nghttp2 --without-libidn2 \ --without-libpsl \ ${options} fi - name: 'configure log' if: ${{ !cancelled() }} run: cat bld/config.log bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true - name: 'curl_config.h' run: | echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::' grep -F '#define' bld/lib/curl_config.h | sort || true - name: 'build / ${{ matrix.build }}' run: make -C bld V=1 VERBOSE=1 - name: 'curl version' run: bld/src/curl --disable --version