name: "Build"

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

env:
  BUILD_DEPS: automake bison flex git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config
  CONFIG_ARGS_FOR_LIBS: >
    --disable-debug
    --disable-dependency-tracking
    --without-cpp
    --without-c_glib
    --without-java
    --without-kotlin
    --without-python
    --without-py3
    --without-ruby
    --without-haxe
    --without-netstd
    --without-perl
    --without-php
    --without-php_extension
    --without-dart
    --without-erlang
    --without-go
    --without-d
    --without-nodejs
    --without-nodets
    --without-lua
    --without-rs
    --without-swift

permissions:
  contents: read

jobs:
  # TODO windows and macos
  compiler:
    strategy:
      matrix:
        os:
          - ubuntu-22.04
          - ubuntu-24.04
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends g++ $BUILD_DEPS

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: ./configure --disable-debug --disable-tests --disable-libs

      - name: Run make
        run: make -j$(nproc)

      - name: Run install
        run: make install

      - name: Run thrift version
        run: /usr/local/bin/thrift -version

      - name: Test Delphi UUIDv8 GUID determinism
        run: |
          # Run the Delphi generator twice on the same input and verify identical output.
          # Tests: cross-platform determinism, service inheritance, struct field-order.
          THRIFT=/usr/local/bin/thrift
          INPUT=test/delphi/UuidV8Test.thrift

          mkdir -p /tmp/delphi-guid-run1 /tmp/delphi-guid-run2
          $THRIFT --gen delphi --out /tmp/delphi-guid-run1 $INPUT
          $THRIFT --gen delphi --out /tmp/delphi-guid-run2 $INPUT
          diff -r /tmp/delphi-guid-run1 /tmp/delphi-guid-run2

          # Also verify GUIDs are non-empty (grep for the GUID attribute pattern)
          grep -qP "^\s+\['\{[0-9A-F]{8}-[0-9A-F]{4}-8[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\}'\]" \
            /tmp/delphi-guid-run1/UuidV8Test.pas \
            && echo "UUIDv8 GUIDs found in output" \
            || { echo "ERROR: No UUIDv8 GUIDs found in Delphi output"; exit 1; }

          # Verify that Point and PointReversed have DIFFERENT GUIDs (field-order sensitivity)
          POINT_GUID=$(grep -A1 "IPoint = interface" /tmp/delphi-guid-run1/UuidV8Test.pas | grep "^\s*\['" | tr -d ' ')
          POINTREV_GUID=$(grep -A1 "IPointReversed = interface" /tmp/delphi-guid-run1/UuidV8Test.pas | grep "^\s*\['" | tr -d ' ')
          [ "$POINT_GUID" != "$POINTREV_GUID" ] \
            && echo "Field-order sensitivity OK (Point vs PointReversed GUIDs differ)" \
            || { echo "ERROR: Point and PointReversed have the same GUID — field order not hashed"; exit 1; }

          # Verify that BaseService and ExtendedService have DIFFERENT GUIDs (parent hash included)
          BASE_GUID=$(grep -A1 "Iface = interface$" /tmp/delphi-guid-run1/UuidV8Test.pas | grep "^\s*\['" | head -1 | tr -d ' ')
          EXT_GUID=$(grep -A1 "Iface = interface(.*Base" /tmp/delphi-guid-run1/UuidV8Test.pas | grep "^\s*\['" | head -1 | tr -d ' ')
          [ "$BASE_GUID" != "$EXT_GUID" ] \
            && echo "Parent-hash inclusion OK (BaseService vs ExtendedService GUIDs differ)" \
            || { echo "ERROR: BaseService and ExtendedService have the same GUID — parent not hashed"; exit 1; }

          echo "All Delphi UUIDv8 GUID determinism tests passed."

      # only upload while building ubuntu-24.04
      - name: Archive built thrift compiler
        if: matrix.os == 'ubuntu-24.04'
        uses: actions/upload-artifact@v7
        with:
          name: thrift-compiler
          path: compiler/cpp/thrift
          retention-days: 3

  compiler-macos:
    strategy:
      matrix:
        os: &macos_versions [macos-15-intel, macos-14, macos-15, macos-26]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          brew install automake bison flex boost libevent openssl libtool pkg-config
          echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: ./configure --disable-debug --disable-tests --disable-libs

      - name: Run make
        run: make -j$(sysctl -n hw.ncpu)

      - name: Run install
        run: sudo make install

      - name: Run thrift version
        run: /usr/local/bin/thrift -version

      - name: Archive built thrift compiler (macOS)
        uses: actions/upload-artifact@v7
        with:
          name: thrift-compiler-${{ matrix.os }}
          path: compiler/cpp/thrift
          retention-days: 3

  lib-php:
    needs: compiler
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        php-version: [7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5]
      fail-fast: false
    steps:
      - uses: actions/checkout@v6

      - name: Set up PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-version }}
          extensions: mbstring, intl, xml, curl
          ini-values: "error_reporting=E_ALL"

      - name: Install Dependencies
        run: composer install

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-php/with-php/' | sed 's/without-php_extension/with-php_extension/' )

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Build Thrift Classes
        run: |
          mkdir -p ./lib/php/test/Resources/packages/php
          mkdir -p ./lib/php/test/Resources/packages/phpv
          mkdir -p ./lib/php/test/Resources/packages/phpvo
          mkdir -p ./lib/php/test/Resources/packages/phpjs
          mkdir -p ./lib/php/test/Resources/packages/phpcm
          compiler/cpp/thrift --gen php:nsglobal="Basic" -r --out ./lib/php/test/Resources/packages/php lib/php/test/Resources/ThriftTest.thrift
          compiler/cpp/thrift --gen php:validate,nsglobal="Validate" -r --out ./lib/php/test/Resources/packages/phpv lib/php/test/Resources/ThriftTest.thrift
          compiler/cpp/thrift --gen php:validate,oop,nsglobal="ValidateOop" -r --out ./lib/php/test/Resources/packages/phpvo lib/php/test/Resources/ThriftTest.thrift
          compiler/cpp/thrift --gen php:json,nsglobal="Json" -r --out ./lib/php/test/Resources/packages/phpjs lib/php/test/Resources/ThriftTest.thrift
          compiler/cpp/thrift --gen php:classmap,server,rest,nsglobal="Classmap" -r --out ./lib/php/test/Resources/packages/phpcm lib/php/test/Resources/ThriftTest.thrift

      - name: Run Tests
        run: vendor/bin/phpunit -c lib/php/phpunit.xml

  lib-go:
    needs: compiler
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        go:
          - '1.25'
          - '1.26'
      fail-fast: false
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-go@v6
        with:
          go-version: ${{ matrix.go }}

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends $BUILD_DEPS

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-go/with-go/')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make for go
        run: make -C lib/go

      - name: Run make check for lib/go
        run: make -C lib/go check

      - name: Run make check for test/go
        run: make -C test/go check

      - name: Run make precross for go test
        run: make -C test/go precross

      - name: Upload go precross artifacts
        if: matrix.go == '1.26'
        uses: actions/upload-artifact@v7
        with:
          name: go-precross
          if-no-files-found: error
          path: |
            test/go/bin/*
          retention-days: 3

  lib-java-kotlin:
    needs: compiler
    runs-on: ubuntu-24.04
    env:
      GRADLE_VERSION: "8.4"
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: 17
          cache: "gradle"

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends $BUILD_DEPS
          sudo apt-get install -y wget unzip ant maven

      - name: Setup gradle
        run: |
          wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip
          (echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae  /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c -)
          unzip -d /tmp /tmp/gradle-$GRADLE_VERSION-bin.zip
          sudo mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle
          sudo ln -s /usr/local/gradle/bin/gradle /usr/local/bin
          gradle --version

      - name: Run spotlessCheck for Java
        run: |
          cd lib/java
          gradle spotlessCheck

      - name: Run ktfmtCheck for Kotlin
        run: |
          cd lib/kotlin
          gradle ktfmtCheck

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-java/with-java/' | sed 's/without-kotlin/with-kotlin/')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make for java
        run: make -C lib/java

      # this will invoke publishToMavenLocal and install locally
      - name: Run make install for java
        run: make -C lib/java install

      - name: Upload java libthrift artifacts
        uses: actions/upload-artifact@v7
        with:
          name: libthrift
          if-no-files-found: error
          path: ~/.m2/repository/org/apache/thrift

      - name: Run make check for java
        run: make -C lib/java check

      - name: Run make precross for java
        run: make -C lib/java precross

      - name: Upload java precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: java-precross
          if-no-files-found: error
          path: |
            lib/java/build/functionalTestJar/
            lib/java/build/runnonblockingclient
            lib/java/build/runclient
            lib/java/build/runnonblockingserver
            lib/java/build/runserver
            lib/java/build/runservletserver
          retention-days: 3

      - name: Run make for kotlin
        run: make -C lib/kotlin

      - name: Run make check for kotlin
        run: make -C lib/kotlin check

      - name: Run make precross for kotlin
        run: make -C lib/kotlin precross

      - name: Upload kotlin precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: kotlin-precross
          if-no-files-found: error
          path: |
            lib/kotlin/cross-test-client/build/install/TestClient/
            lib/kotlin/cross-test-server/build/install/TestServer/
          retention-days: 3

  lib-netstd:
    needs: compiler
    runs-on: ubuntu-24.04
    strategy:
      fail-fast: false
    defaults:
      run:
        shell: bash  # required by net install script
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends $BUILD_DEPS
          sudo apt-get install -y --no-install-recommends curl openssl ca-certificates

# This whole setup is getting worse: https://github.com/dotnet/core/discussions/9258
      - name: Set up .NET SDK (via install script)
        run: |
          # remove any existing install
          sudo apt remove dotnet*
          # install key
          sudo apt install gpg
          wget https://dot.net/v1/dotnet-install.asc
          gpg --import dotnet-install.asc
          # download and verify
          wget https://dot.net/v1/dotnet-install.sh
          wget https://dot.net/v1/dotnet-install.sig
          gpg --verify dotnet-install.sig dotnet-install.sh
          # run install script
          chmod +x dotnet-install.sh
          ./dotnet-install.sh --channel 10.0
          # export env vars
          export DOTNET_ROOT=$HOME/.dotnet
          export PATH=$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools
          dotnet --list-sdks

#      the sdk is installed by default, but keep this step for reference
#      especially newer versions are NOT always pre-installed, so manually again
#      - name: Set up .NET SDK
#        run: |
#          sudo add-apt-repository -y ppa:dotnet/backports
#          sudo apt-get install -y --no-install-recommends dotnet-sdk-10.0
#      end

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure for netstd
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-netstd/with-netstd/')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make for netstd
        run: make -C lib/netstd

      - name: Run make install for netstd
        run: sudo make -C lib/netstd install

      - name: Run make check for netstd
        run: make -C lib/netstd check

      - name: Run make check for test/netstd
        run: make -C test/netstd check

      - name: Run make precross for test/netstd
        run: make -C test/netstd precross

      - name: Upload netstd precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: netstd-precross
          if-no-files-found: error
          path: |
            test/netstd/Client/bin/Release/
            test/netstd/Server/bin/Release/
          retention-days: 3

  lib-swift:
    needs: compiler
    runs-on: ubuntu-24.04
    if: false                     # swift is currently broken and no maintainers around -> see THRIFT-5864
    steps:
      - uses: actions/checkout@v6

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-swift/with-swift/')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make precross for swift
        run: make -C test/swift precross

      - name: Upload swift precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: swift-precross
          if-no-files-found: error
          path: |
            test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug/TestServer
            test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug/TestClient
          retention-days: 3

  lib-rust:
    needs: compiler
    runs-on: ubuntu-24.04
    if: false    # currently broken and no maintainers around -> see THRIFT-5917
    env:
      TOOLCHAIN_VERSION: 1.83.0
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends curl $BUILD_DEPS

      - name: Setup cargo
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
          rustup update
          rustup install $TOOLCHAIN_VERSION
          rustup default $TOOLCHAIN_VERSION
          rustup --version
          cargo --version
          rustc --version

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-rs/with-rs/')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make for rust
        run: make -C lib/rs

      - name: Run make check for rust
        run: make -C lib/rs check

      - name: Run make test for rust
        run: make -C lib/rs/test check

      - name: Run make precross for test rust
        run: make -C test/rs precross

      - name: Upload rust precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: rs-precross
          if-no-files-found: error
          path: |
            test/rs/bin/test_server
            test/rs/bin/test_client
          retention-days: 3

      - name: Run make test_recursive for rust
        run: make -C lib/rs/test_recursive check

  lib-python:
    needs: compiler
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: &python_versions ["3.10", "3.11", "3.12", "3.13", "3.14"]
      fail-fast: false
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends $BUILD_DEPS
          sudo apt-get install -y --no-install-recommends curl openssl ca-certificates

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}

      - name: Python setup
        run: |
          python -m pip install --upgrade pip setuptools wheel flake8 "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1"
          python --version
          pip --version

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-py3/with-py3/')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make for python
        run: make -C lib/py

      - name: Run make install for python
        run: sudo make -C lib/py install

      - name: Run make check for python libs
        run: make -C lib/py check

      - name: Run make check for python code
        run: make -C test/py check

      - name: Run make precross for python
        if: matrix.python-version == '3.12'
        run: make -C test/py precross

      - name: Upload python precross artifacts
        if: matrix.python-version == '3.12'
        uses: actions/upload-artifact@v7
        with:
          name: py-precross
          if-no-files-found: error
          path: |
            lib/py/build/lib.*
            test/py/gen-py
            test/py/TestClient.py
            test/py/TestServer.py
            test/py/util.py
          retention-days: 3

  lib-python-macos:
    needs: compiler-macos
    strategy:
      matrix:
        os: *macos_versions
        python-version: *python_versions
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          brew install automake bison flex boost libevent openssl libtool pkg-config
          echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}

      - name: Python setup
        run: |
          python -m pip install --upgrade pip setuptools wheel flake8 "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1"
          python --version
          pip --version

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-py3/with-py3/')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler-${{ matrix.os }}
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make for python
        run: make -C lib/py

      - name: Run make install for python
        run: |
          sudo make -C lib/py install PY_PREFIX="$(python -c 'import sys; print(sys.prefix)')"

      - name: Run make for python libs
        run: make -C lib/py

      - name: Run make check for python libs
        run: make -C lib/py check

      - name: Run make check for python code
        run: make -C test/py check

  lib-nodejs:
    needs: compiler
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v6

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed -E 's/without-node([tj])s/with-node\1s/g')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run js tests
        run: make -C lib/nodejs check

      - name: Run ts tests
        run: make -C lib/nodets check

      - name: Run js precross
        run: make -C lib/nodejs precross

      - name: Run ts precross
        run: make -C lib/nodets precross

      - name: Upload nodejs precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: nodejs-precross
          if-no-files-found: error
          include-hidden-files: true
          path: |
            lib/nodejs/test/gen-nodejs
            lib/nodets/test/gen-nodejs
            lib/nodets/test-compiled
          retention-days: 3

  lib-cpp:
    needs: compiler
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends g++ $BUILD_DEPS locales
          sudo locale-gen en_US.UTF-8
          sudo locale-gen de_DE.UTF-8
          sudo update-locale

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed -E 's/without-cpp/with-cpp/g')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make for cpp
        run: make -j$(nproc) -C lib/cpp

      - name: Run make check for lib/cpp
        run: make -j$(nproc) -C lib/cpp check

      - name: Run make check for test/cpp
        run: make -j$(nproc) -C test/cpp check

      - name: Run make precross for cpp test
        run: make -j$(nproc) -C test/cpp precross

      - name: Upload cpp precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: cpp-precross
          if-no-files-found: error
          include-hidden-files: true
          path: |
            test/cpp/TestClient
            test/cpp/TestServer
            test/cpp/.libs/TestClient
            test/cpp/.libs/TestServer
            lib/cpp/.libs/*.so
          retention-days: 3

      - name: Upload log files from failed test runs
        uses: actions/upload-artifact@v7
        if: failure()
        with:
          name: lib-cpp-test-log
          path: lib/cpp/test/*.xml
          retention-days: 3

  lib-ruby:
    needs: compiler
    runs-on: ubuntu-24.04
    name: lib-ruby (${{ matrix.ruby-version }}) ${{ matrix.skip-build-ext && 'noext' || '' }}
    strategy:
      matrix:
        ruby-version: ["2.7", "3.0", "3.1", "3.2", "3.3", "3.4", "4.0", "head"]
        skip-build-ext: [false]
        include:
          - ruby-version: "2.7"
            skip-build-ext: true
      fail-fast: false
    env:
      SKIP_BUILD_EXT: ${{ matrix.skip-build-ext && '1' || '' }}
    steps:
      - uses: actions/checkout@v6

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true
          working-directory: lib/rb

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-ruby/with-ruby/')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make for ruby
        run: make -C lib/rb

      - name: Run make check for lib/rb
        run: make -C lib/rb check

      - name: Run make check for test/rb
        run: make -C test/rb check

      - name: Run make precross for ruby test
        run: make -C test/rb precross

      - name: Upload ruby precross artifacts
        # has to match the version used in cross-test
        if: matrix.ruby-version == '2.7' && matrix.skip-build-ext == false
        uses: actions/upload-artifact@v7
        with:
          name: rb-precross
          if-no-files-found: error
          path: |
            test/rb/gen-rb/*
            lib/rb/ext/*.so
          retention-days: 3

  cross-test:
    needs:
      - lib-java-kotlin
      #- lib-swift                     # currently broken and no maintainers around -> see THRIFT-5864
      #- lib-rust                      # currently broken and no maintainers around -> see THRIFT-5917
      - lib-go
      - lib-python
      - lib-cpp
      - lib-ruby
      - lib-nodejs
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        # swift is currently broken and no maintainers around -> see THRIFT-5864
        # rust currently broken and no maintainers around -> see THRIFT-5917
        # kotlin cross test are failing -> see THRIFT-5879
        server_lang: ['java', 'go', 'cpp', 'py', 'rb', 'nodejs', 'nodets']
        # we always use comma join as many client langs as possible, to reduce the number of jobs
        client_lang: ['java,kotlin', 'go,cpp,py,nodejs,nodets', 'rb']
      fail-fast: false
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-python@v6
        with:
          python-version: "3.12"

      - name: Install Python test dependencies
        run: |
          python -m pip install --upgrade pip setuptools
          python -m pip install "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1"

      - uses: actions/setup-java@v5
        with:
          distribution: temurin
          # here we intentionally use an older version so that we also verify Java 17 compiles to it
          java-version: 8
          cache: "gradle"

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: "2.7"
          bundler-cache: true
          working-directory: test/rb

      - name: Install openssl and certificates (for SSL tests)
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends \
            openssl \
            ca-certificates \
            libboost-all-dev \
            libevent-dev

      - name: Download java precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: java-precross
          path: lib/java/build

      - name: Download kotlin precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: kotlin-precross
          path: lib/kotlin

      - name: Download swift precross artifacts
        uses: actions/download-artifact@v8
        if: false   # currently broken and no maintainers around -> see THRIFT-5864
        with:
          name: swift-precross
          path: test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug

      - name: Download rust precross artifacts
        uses: actions/download-artifact@v8
        if: false   # currently broken and no maintainers around -> see THRIFT-5917
        with:
          name: rs-precross
          path: test/rs/bin

      - name: Download go precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: go-precross
          path: test/go/bin

      - name: Download cpp precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: cpp-precross
          path: .

      - name: Download python precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: py-precross
          path: .

      - name: Download ruby precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: rb-precross
          path: .

      - name: Download nodejs and nodets precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: nodejs-precross
          path: lib

      - name: Set back executable flags
        run: |
          chmod a+x lib/java/build/run*
          chmod a+x lib/kotlin/cross-test-client/build/install/TestClient/bin/*
          chmod a+x lib/kotlin/cross-test-server/build/install/TestServer/bin/*
          # THRIFT-5864  chmod a+x test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug/*
          # THRIFT-5917  chmod a+x test/rs/bin/*
          chmod a+x test/go/bin/*
          chmod a+x test/cpp/*
          chmod a+x test/cpp/.libs/*
          chmod a+x lib/cpp/.libs/*.so
          chmod a+x test/py/*.py
          chmod a+x lib/rb/ext/*.so

      - name: Installs for nodets and nodejs
        run: |
          npm install .
          cd lib/nodejs/test/ && npm install .

      - name: Create tmp domain socket folder
        run: mkdir /tmp/v0.16

      - name: Run cross test
        env:
          THRIFT_CROSSTEST_CONCURRENCY: 4
        run: |
          python test/test.py \
            --retry-count 5 \
            --skip-known-failures \
            --server ${{ matrix.server_lang }} \
            --client ${{ matrix.client_lang }}

      - name: Upload log files from failed cross test runs
        uses: actions/upload-artifact@v7
        if: failure()
        with:
          name: cross-test-log_${{ matrix.server_lang }}-${{ matrix.client_lang }}
          path: test/log/
          retention-days: 3
