From 63e084fc875a3ffc1171d28f912919f3faebcd2b Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Mon, 1 Dec 2025 20:30:21 -0800 Subject: [PATCH] CI: test again MySQL 9.5 (innovation release) * Test against all LTS releases * Only test against the latest innovation release, currently 9.5 --- .github/workflows/ci.yml | 2 +- .github/workflows/macos.yml | 22 +++++++++++++++---- contrib/ruby/test/auth_test.rb | 8 +++++++ test/mysql/conf.d/8.4/macos.cnf | 5 +++++ test/mysql/conf.d/9.5/build.cnf | 21 ++++++++++++++++++ .../native_password_user.sh | 21 ++++++++++++++++++ .../native_password_user.sql | 3 --- 7 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 test/mysql/conf.d/8.4/macos.cnf create mode 100644 test/mysql/conf.d/9.5/build.cnf create mode 100755 test/mysql/docker-entrypoint-initdb.d/native_password_user.sh delete mode 100644 test/mysql/docker-entrypoint-initdb.d/native_password_user.sql diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f95d835..d190b43b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - mysql: ["8.0", "8.4"] + mysql: ["8.0", "8.4", "9.5"] distribution: ["debian:bookworm", "ubuntu:noble", "ubuntu:jammy", "ubuntu:focal"] ruby: ["3.3", "3.4"] steps: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 5e091879..eeb15667 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -16,16 +16,22 @@ jobs: runs-on: macos-latest strategy: matrix: - mysql: ["8.0", "8.4"] + mysql: ["8.0", "8.4", "9.5"] steps: - uses: actions/checkout@v6 - name: Setup MySQL run: | brew install mysql@${{ matrix.mysql }} + # Apply macOS-specific config if it exists (e.g., 8.4 needs mysql_native_password=ON) + # Homebrew MySQL reads config from $(brew --prefix)/etc/my.cnf + if [[ -f "test/mysql/conf.d/${{ matrix.mysql }}/macos.cnf" ]]; then + cat test/mysql/conf.d/${{ matrix.mysql }}/macos.cnf >> $(brew --prefix)/etc/my.cnf + fi (unset CI; brew postinstall mysql@${{ matrix.mysql }}) brew services start mysql@${{ matrix.mysql }} sleep 5 $(brew --prefix mysql@${{ matrix.mysql }})/bin/mysql -uroot -e 'CREATE DATABASE test' + $(brew --prefix mysql@${{ matrix.mysql }})/bin/mysql -uroot < test/mysql/docker-entrypoint-initdb.d/caching_sha2_password_user.sql - name: Build run: CFLAGS="-I$(brew --prefix openssl@1.1)/include" LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" make all test/test - name: test @@ -35,7 +41,7 @@ jobs: runs-on: macos-latest strategy: matrix: - mysql: ["8.0"] + mysql: ["8.0", "8.4", "9.5"] ruby: ["3.0", "3.1", "3.2", "3.3", "3.4"] steps: - uses: actions/checkout@v6 @@ -47,12 +53,20 @@ jobs: MYSQL_VERSION: ${{ matrix.mysql }} run: | brew install mysql@${{ matrix.mysql }} + # Apply macOS-specific config if it exists (e.g., 8.4 needs mysql_native_password=ON) + # Homebrew MySQL reads config from $(brew --prefix)/etc/my.cnf + if [[ -f "test/mysql/conf.d/${{ matrix.mysql }}/macos.cnf" ]]; then + cat test/mysql/conf.d/${{ matrix.mysql }}/macos.cnf >> $(brew --prefix)/etc/my.cnf + fi (unset CI; brew postinstall mysql@${{ matrix.mysql }}) brew services start mysql@${{ matrix.mysql }} sleep 5 $(brew --prefix mysql@${{ matrix.mysql }})/bin/mysql -uroot -e 'CREATE DATABASE test' - [[ "$MYSQL_VERSION" == "8.0" ]] && $(brew --prefix mysql@${{ matrix.mysql }})/bin/mysql -uroot < test/mysql/docker-entrypoint-initdb.d/caching_sha2_password_user.sql - $(brew --prefix mysql@${{ matrix.mysql }})/bin/mysql -uroot < test/mysql/docker-entrypoint-initdb.d/native_password_user.sql + $(brew --prefix mysql@${{ matrix.mysql }})/bin/mysql -uroot < test/mysql/docker-entrypoint-initdb.d/caching_sha2_password_user.sql + # mysql_native_password plugin was removed in MySQL 9.x + if [[ ! "${{ matrix.mysql }}" =~ ^9 ]]; then + $(brew --prefix mysql@${{ matrix.mysql }})/bin/mysql -uroot -e "CREATE USER 'native'@'%'; GRANT ALL PRIVILEGES ON test.* TO 'native'@'%'; ALTER USER 'native'@'%' IDENTIFIED WITH mysql_native_password BY 'password';" + fi $(brew --prefix mysql@${{ matrix.mysql }})/bin/mysql -uroot < test/mysql/docker-entrypoint-initdb.d/x509_user.sql $(brew --prefix mysql@${{ matrix.mysql }})/bin/mysql -uroot < test/mysql/docker-entrypoint-initdb.d/cleartext_user.sql - name: Install dependencies diff --git a/contrib/ruby/test/auth_test.rb b/contrib/ruby/test/auth_test.rb index 51f807ee..068fc8de 100644 --- a/contrib/ruby/test/auth_test.rb +++ b/contrib/ruby/test/auth_test.rb @@ -17,7 +17,14 @@ def has_caching_sha2? server_version.split(".", 2)[0].to_i >= 8 end + def has_native_password_plugin? + new_tcp_client.query("SELECT PLUGIN_NAME FROM information_schema.plugins WHERE PLUGIN_NAME = 'mysql_native_password'").count > 0 + rescue Trilogy::Error + false + end + def test_connect_native_with_password + return skip unless has_native_password_plugin? create_and_delete_test_user(username: "native", auth_plugin: "mysql_native_password") do client = new_tcp_client username: "native", password: "password" @@ -86,6 +93,7 @@ def test_connect_without_ssl_or_unix_socket_caching_sha2_raises end def test_connection_error_native + return skip unless has_native_password_plugin? create_and_delete_test_user(username: "native", auth_plugin: "mysql_native_password") do err = assert_raises Trilogy::ConnectionError do diff --git a/test/mysql/conf.d/8.4/macos.cnf b/test/mysql/conf.d/8.4/macos.cnf new file mode 100644 index 00000000..d0518bf9 --- /dev/null +++ b/test/mysql/conf.d/8.4/macos.cnf @@ -0,0 +1,5 @@ +# macOS-specific MySQL configuration (used by brew) +# Docker uses build.cnf which has additional SSL paths + +[mysqld] +mysql_native_password=ON diff --git a/test/mysql/conf.d/9.5/build.cnf b/test/mysql/conf.d/9.5/build.cnf new file mode 100644 index 00000000..62451233 --- /dev/null +++ b/test/mysql/conf.d/9.5/build.cnf @@ -0,0 +1,21 @@ +# This MySQL configuration file is mounted into the Database container (/etc/mysql/conf.d) +# at boot and is picked up automatically. + +[mysqld] + +sql_mode = NO_ENGINE_SUBSTITUTION + +server_id = 1 +gtid_mode = ON +enforce_gtid_consistency = ON +log_bin = mysql-bin.log + +# Since we generate our own certificates for testing purposes, we need to instruct MySQL +# on where to find them. The certifcates are generated as an entrypoint script located at: +# mysql/docker-entrypoint-initdb.d/generate_keys.sh +# The /mysql-certs directory is mounted into both the database container and the app +# container so that they both can have access to the generated certificates. +# -- +ssl_ca = /mysql-certs/ca.pem +ssl_cert = /mysql-certs/server-cert.pem +ssl_key = /mysql-certs/server-key.pem diff --git a/test/mysql/docker-entrypoint-initdb.d/native_password_user.sh b/test/mysql/docker-entrypoint-initdb.d/native_password_user.sh new file mode 100755 index 00000000..83b2238d --- /dev/null +++ b/test/mysql/docker-entrypoint-initdb.d/native_password_user.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# Create native password user only if MySQL version < 9. +# MySQL 9.x completely removed the mysql_native_password plugin. + +set -euo pipefail + +# Get MySQL major version (use -h localhost to avoid MYSQL_HOST env var) +MYSQL_MAJOR_VERSION=$(mysql -h localhost -uroot -N -e "SELECT SUBSTRING_INDEX(VERSION(), '.', 1)") + +if [[ "$MYSQL_MAJOR_VERSION" -lt 9 ]]; then + echo "MySQL $MYSQL_MAJOR_VERSION.x detected, creating native password user..." + mysql -h localhost -uroot <