chore: release v4.4.0 #178
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| paths-ignore: | |
| - ".github/badges/**" | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| tests-gcc: | |
| runs-on: ubuntu-latest | |
| env: | |
| DS_MYSQL_TEST_HOST: 127.0.0.1 | |
| DS_MYSQL_TEST_PORT: 3306 | |
| DS_MYSQL_TEST_DATABASE: ds_mysql_test | |
| DS_MYSQL_TEST_USER: ds_mysql_test_user | |
| DS_MYSQL_TEST_PASSWORD: ds_mysql_test_password | |
| services: | |
| mysql: | |
| image: mysql:8.0 | |
| env: | |
| MYSQL_ROOT_PASSWORD: root | |
| MYSQL_DATABASE: ds_mysql_test | |
| MYSQL_USER: ds_mysql_test_user | |
| MYSQL_PASSWORD: ds_mysql_test_password | |
| ports: | |
| - 3306/tcp | |
| options: >- | |
| --health-cmd="mysqladmin ping -h 127.0.0.1 --protocol=tcp" | |
| --health-interval=5s | |
| --health-timeout=10s | |
| --health-retries=10 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Export mapped MySQL service port | |
| run: echo "DS_MYSQL_TEST_PORT=${{ job.services.mysql.ports[3306] }}" >> "$GITHUB_ENV" | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update -q | |
| sudo apt-get install -y --no-install-recommends software-properties-common ca-certificates gpg wget | |
| # Kitware APT repo for CMake 3.31+ | |
| wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc \ | |
| | gpg --dearmor \ | |
| | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null | |
| echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ noble main' \ | |
| | sudo tee /etc/apt/sources.list.d/kitware.list | |
| sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y | |
| sudo apt-get update -q | |
| sudo apt-get install -y --no-install-recommends cmake ninja-build g++-15 gcc-15 \ | |
| libmysqlclient-dev pkg-config | |
| - name: Configure | |
| run: cmake --preset release -DSKIP_DOCKER_MANAGEMENT=ON | |
| env: | |
| CXX: g++-15 | |
| CC: gcc-15 | |
| - name: Build | |
| run: cmake --build --preset release -j4 | |
| - name: Unit tests | |
| run: ctest --preset release -R tests_unit_ds_mysql | |
| - name: Integration tests | |
| run: ctest --preset release -R tests_integration_ds_mysql | |
| tests-clang: | |
| runs-on: ubuntu-latest | |
| env: | |
| DS_MYSQL_TEST_HOST: 127.0.0.1 | |
| DS_MYSQL_TEST_PORT: 3306 | |
| DS_MYSQL_TEST_DATABASE: ds_mysql_test | |
| DS_MYSQL_TEST_USER: ds_mysql_test_user | |
| DS_MYSQL_TEST_PASSWORD: ds_mysql_test_password | |
| services: | |
| mysql: | |
| image: mysql:8.0 | |
| env: | |
| MYSQL_ROOT_PASSWORD: root | |
| MYSQL_DATABASE: ds_mysql_test | |
| MYSQL_USER: ds_mysql_test_user | |
| MYSQL_PASSWORD: ds_mysql_test_password | |
| ports: | |
| - 3306/tcp | |
| options: >- | |
| --health-cmd="mysqladmin ping -h 127.0.0.1 --protocol=tcp" | |
| --health-interval=5s | |
| --health-timeout=10s | |
| --health-retries=10 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Export mapped MySQL service port | |
| run: echo "DS_MYSQL_TEST_PORT=${{ job.services.mysql.ports[3306] }}" >> "$GITHUB_ENV" | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update -q | |
| sudo apt-get install -y software-properties-common ca-certificates gpg wget | |
| # Kitware APT repo for CMake 3.31+ | |
| wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc \ | |
| | gpg --dearmor \ | |
| | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null | |
| echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ noble main' \ | |
| | sudo tee /etc/apt/sources.list.d/kitware.list | |
| wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key \ | |
| | gpg --dearmor \ | |
| | sudo tee /usr/share/keyrings/llvm-archive-keyring.gpg > /dev/null | |
| UBUNTU_CODENAME="$(. /etc/os-release && echo "$VERSION_CODENAME")" | |
| echo "deb [signed-by=/usr/share/keyrings/llvm-archive-keyring.gpg] https://apt.llvm.org/${UBUNTU_CODENAME}/ llvm-toolchain-${UBUNTU_CODENAME}-20 main" \ | |
| | sudo tee /etc/apt/sources.list.d/llvm.list | |
| sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y | |
| sudo apt-get update -q | |
| sudo apt-get install -y cmake ninja-build clang-20 libstdc++-15-dev \ | |
| libmysqlclient-dev pkg-config | |
| - name: Configure | |
| run: cmake --preset release -DSKIP_DOCKER_MANAGEMENT=ON | |
| env: | |
| CXX: clang++-20 | |
| CC: clang-20 | |
| - name: Build | |
| run: cmake --build --preset release -j4 | |
| - name: Unit tests | |
| run: ctest --preset release -R tests_unit_ds_mysql | |
| - name: Integration tests | |
| run: ctest --preset release -R tests_integration_ds_mysql | |
| package-consumer-smoke: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update -q | |
| sudo apt-get install -y software-properties-common ca-certificates gpg wget | |
| wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc \ | |
| | gpg --dearmor \ | |
| | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null | |
| echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ noble main' \ | |
| | sudo tee /etc/apt/sources.list.d/kitware.list | |
| sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y | |
| sudo apt-get update -q | |
| sudo apt-get install -y cmake ninja-build g++-15 gcc-15 libmysqlclient-dev pkg-config libboost-dev | |
| - name: Configure (install enabled) | |
| run: | | |
| cmake --preset release \ | |
| -DSKIP_DOCKER_MANAGEMENT=ON \ | |
| -DBUILD_TESTING=OFF \ | |
| -DBUILD_INTEGRATION_TESTS=OFF \ | |
| -DBUILD_EXAMPLES=OFF \ | |
| -DDSMYSQL_ENABLE_INSTALL=ON | |
| env: | |
| CXX: g++-15 | |
| CC: gcc-15 | |
| - name: Build and install | |
| run: | | |
| cmake --build --preset release -j4 | |
| cmake --install build/release --prefix "$RUNNER_TEMP/dsmysql-install" | |
| - name: External consumer smoke test | |
| run: | | |
| mkdir -p "$RUNNER_TEMP/consumer" | |
| cat > "$RUNNER_TEMP/consumer/CMakeLists.txt" << 'EOF' | |
| cmake_minimum_required(VERSION 3.25) | |
| project(ds_mysql_consumer LANGUAGES CXX) | |
| set(CMAKE_CXX_STANDARD 23) | |
| find_package(ds_mysql CONFIG REQUIRED) | |
| add_executable(consumer main.cpp) | |
| target_link_libraries(consumer PRIVATE ds_mysql::ds_mysql) | |
| EOF | |
| cat > "$RUNNER_TEMP/consumer/main.cpp" << 'EOF' | |
| #include <ds_mysql/version.hpp> | |
| int main() { | |
| return static_cast<int>(ds_mysql::version::major); | |
| } | |
| EOF | |
| cmake -S "$RUNNER_TEMP/consumer" -B "$RUNNER_TEMP/consumer/build" \ | |
| -DCMAKE_PREFIX_PATH="$RUNNER_TEMP/dsmysql-install" | |
| cmake --build "$RUNNER_TEMP/consumer/build" -j4 | |
| tests-msvc: | |
| runs-on: windows-latest | |
| env: | |
| DS_MYSQL_TEST_HOST: 127.0.0.1 | |
| DS_MYSQL_TEST_PORT: 3306 | |
| DS_MYSQL_TEST_DATABASE: ds_mysql_test | |
| DS_MYSQL_TEST_USER: ds_mysql_test_user | |
| DS_MYSQL_TEST_PASSWORD: ds_mysql_test_password | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install dependencies | |
| run: | | |
| choco install cmake ninja --no-progress -y | |
| shell: pwsh | |
| - name: Ensure MySQL is installed | |
| shell: pwsh | |
| run: | | |
| $mysqlCmd = Get-Command mysql -ErrorAction SilentlyContinue | |
| $mysqldCmd = Get-Command mysqld -ErrorAction SilentlyContinue | |
| if (-not $mysqlCmd -or -not $mysqldCmd) { | |
| choco install mysql --no-progress -y | |
| } | |
| $mysqlCmd = Get-Command mysql -ErrorAction SilentlyContinue | |
| $mysqldCmd = Get-Command mysqld -ErrorAction SilentlyContinue | |
| if (-not $mysqlCmd -or -not $mysqldCmd) { | |
| throw "MySQL client/server binaries not available on PATH after installation" | |
| } | |
| - name: Detect MySQL root | |
| shell: pwsh | |
| run: | | |
| $candidateRoots = @() | |
| if (Test-Path "C:\Program Files\MySQL") { | |
| $candidateRoots += (Get-ChildItem "C:\Program Files\MySQL" -Directory -ErrorAction SilentlyContinue | | |
| Where-Object { $_.Name -like "MySQL Server *" } | | |
| Sort-Object Name -Descending | | |
| ForEach-Object { $_.FullName }) | |
| } | |
| $candidateRoots += (Get-ChildItem "C:\ProgramData\chocolatey\lib" -Directory -ErrorAction SilentlyContinue | | |
| Where-Object { $_.Name -like "mysql*" } | | |
| ForEach-Object { | |
| $toolsDir = Join-Path $_.FullName "tools" | |
| if (Test-Path $toolsDir) { | |
| Get-ChildItem $toolsDir -Directory -ErrorAction SilentlyContinue | ForEach-Object { $_.FullName } | |
| } | |
| }) | |
| $candidateRoots = $candidateRoots | Select-Object -Unique | |
| $root = $null | |
| foreach ($candidate in $candidateRoots) { | |
| $includeFile = Join-Path $candidate "include\mysql.h" | |
| $libFile = Join-Path $candidate "lib\libmysql.lib" | |
| if ((Test-Path $includeFile) -and (Test-Path $libFile)) { | |
| $root = $candidate | |
| break | |
| } | |
| } | |
| if (-not $root) { | |
| throw "MySQL installation not found with include/mysql.h and lib/libmysql.lib" | |
| } | |
| Write-Host "Detected MYSQL_ROOT_DIR: $root" | |
| echo "MYSQL_ROOT_DIR=$root" >> $env:GITHUB_ENV | |
| echo "MYSQL_BIN_DIR=$(Join-Path $root 'bin')" >> $env:GITHUB_ENV | |
| echo "$root\bin" >> $env:GITHUB_PATH | |
| echo "$root\lib" >> $env:GITHUB_PATH | |
| - name: Configure | |
| shell: pwsh | |
| run: | | |
| cmake -B build ` | |
| -G "Visual Studio 17 2022" -A x64 ` | |
| -DSKIP_DOCKER_MANAGEMENT=ON ` | |
| -DBUILD_EXAMPLES=OFF ` | |
| "-DMYSQL_ROOT_DIR=$env:MYSQL_ROOT_DIR" | |
| - name: Build | |
| run: cmake --build build --config Release -j4 | |
| - name: Unit tests | |
| run: ctest --test-dir build -C Release -R tests_unit_ds_mysql --output-on-failure | |
| - name: Integration tests | |
| shell: pwsh | |
| run: | | |
| function Find-Tool([string]$toolName) { | |
| $toolBase = [System.IO.Path]::GetFileNameWithoutExtension($toolName) | |
| $fromPath = Get-Command $toolBase -ErrorAction SilentlyContinue | |
| if ($fromPath -and (Test-Path $fromPath.Source)) { | |
| return $fromPath.Source | |
| } | |
| $candidates = @( | |
| (Join-Path $env:MYSQL_BIN_DIR $toolName), | |
| (Join-Path $env:MYSQL_ROOT_DIR $toolName), | |
| (Join-Path $env:MYSQL_ROOT_DIR "bin\$toolName") | |
| ) | |
| foreach ($candidate in $candidates) { | |
| if ($candidate -and (Test-Path $candidate)) { | |
| return $candidate | |
| } | |
| } | |
| $match = Get-ChildItem -Path $env:MYSQL_ROOT_DIR -Filter $toolName -Recurse -ErrorAction SilentlyContinue | | |
| Select-Object -First 1 | |
| if ($match) { | |
| return $match.FullName | |
| } | |
| throw "$toolName not found under MYSQL_ROOT_DIR=$env:MYSQL_ROOT_DIR" | |
| } | |
| $dataDir = Join-Path $env:RUNNER_TEMP ("mysql-data-" + [guid]::NewGuid().ToString("N")) | |
| $stdoutLogFile = Join-Path $env:RUNNER_TEMP "mysql-server.stdout.log" | |
| $stderrLogFile = Join-Path $env:RUNNER_TEMP "mysql-server.stderr.log" | |
| $mysqlExe = Find-Tool "mysql.exe" | |
| $mysqlAdminExe = Find-Tool "mysqladmin.exe" | |
| $mysqldExe = Find-Tool "mysqld.exe" | |
| $process = $null | |
| try { | |
| Write-Host "Using mysql.exe: $mysqlExe" | |
| Write-Host "Using mysqladmin.exe: $mysqlAdminExe" | |
| Write-Host "Using mysqld.exe: $mysqldExe" | |
| New-Item -ItemType Directory -Force -Path $dataDir | Out-Null | |
| & $mysqldExe --initialize-insecure --datadir="$dataDir" --console | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "mysqld --initialize-insecure failed with exit code $LASTEXITCODE" | |
| } | |
| $requestedPort = [int]$env:DS_MYSQL_TEST_PORT | |
| $portsToTry = @($requestedPort, 3307, 3308, 33306) | Select-Object -Unique | |
| $chosenPort = $null | |
| foreach ($port in $portsToTry) { | |
| Write-Host "Trying MySQL port $port" | |
| $process = Start-Process -FilePath $mysqldExe -ArgumentList @( | |
| "--datadir=$dataDir", | |
| "--port=$port", | |
| "--bind-address=$env:DS_MYSQL_TEST_HOST", | |
| "--console" | |
| ) -RedirectStandardOutput $stdoutLogFile -RedirectStandardError $stderrLogFile -PassThru | |
| $ready = $false | |
| for ($attempt = 0; $attempt -lt 45; $attempt++) { | |
| & $mysqlAdminExe --protocol=tcp --host=$env:DS_MYSQL_TEST_HOST --port=$port --user=root ping --silent | |
| if ($LASTEXITCODE -eq 0) { | |
| $ready = $true | |
| break | |
| } | |
| Start-Sleep -Seconds 2 | |
| } | |
| if ($ready) { | |
| $chosenPort = $port | |
| break | |
| } | |
| if ($process -and -not $process.HasExited) { | |
| Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue | |
| } | |
| $process = $null | |
| } | |
| if (-not $chosenPort) { | |
| throw "MySQL server did not become ready on any candidate port" | |
| } | |
| $env:DS_MYSQL_TEST_PORT = [string]$chosenPort | |
| Write-Host "MySQL is ready on port $chosenPort" | |
| $sql = @( | |
| "CREATE DATABASE IF NOT EXISTS $env:DS_MYSQL_TEST_DATABASE;" | |
| "CREATE USER IF NOT EXISTS '$env:DS_MYSQL_TEST_USER'@'%' IDENTIFIED BY '$env:DS_MYSQL_TEST_PASSWORD';" | |
| "GRANT ALL PRIVILEGES ON $env:DS_MYSQL_TEST_DATABASE.* TO '$env:DS_MYSQL_TEST_USER'@'%';" | |
| "FLUSH PRIVILEGES;" | |
| ) -join ' ' | |
| & $mysqlExe --protocol=tcp --host=$env:DS_MYSQL_TEST_HOST --port=$chosenPort --user=root --execute="$sql" | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "Failed to initialize MySQL test database" | |
| } | |
| & $mysqlAdminExe --protocol=tcp --host=$env:DS_MYSQL_TEST_HOST --port=$chosenPort --user=root ping --silent | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "MySQL server stopped responding before running integration tests" | |
| } | |
| ctest --test-dir build -C Release -R tests_integration_ds_mysql --output-on-failure | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "Integration tests failed" | |
| } | |
| } | |
| finally { | |
| if (Test-Path $stdoutLogFile) { | |
| Write-Host "--- mysqld stdout ---" | |
| Get-Content $stdoutLogFile | |
| } | |
| if (Test-Path $stderrLogFile) { | |
| Write-Host "--- mysqld stderr ---" | |
| Get-Content $stderrLogFile | |
| } | |
| if ($process -and -not $process.HasExited) { | |
| Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue | |
| } | |
| } |