From 93468dd3ceec107f1fc5a00110c2f3ff951941b3 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 13:13:59 +0200 Subject: [PATCH 01/11] Update actions/checkout to v6.0.2 --- .github/workflows/pages.yml | 2 +- .github/workflows/release.yml | 4 ++-- .github/workflows/tests.yml | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 3d252bc0..e6284864 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -9,7 +9,7 @@ jobs: github-pages: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@v6.0.2 - name: Build documentations run: .github/workflows/build-docs.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7c6020dc..73999d12 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: runner: [ubuntu-latest, shopify-ubuntu-arm64] runs-on: ${{ matrix.runner }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@v6.0.2 - name: Setup Go uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest needs: build-debs steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@v6.0.2 - name: Fetch uploaded artifacts uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 with: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 55120d18..450bfeaa 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: MYSQL_VERSION: ${{ matrix.mysql }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version: 1.24.1 @@ -54,7 +54,7 @@ jobs: MYSQL_VERSION: ${{ matrix.mysql }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version: 1.24.1 @@ -85,7 +85,7 @@ jobs: GHOSTFERRY_LOG_BACKEND: ${{ matrix.log_backend }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version: 1.24.1 @@ -106,7 +106,7 @@ jobs: runner: [ubuntu-latest, shopify-ubuntu-arm64] runs-on: ${{ matrix.runner }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version: 1.24.1 From d01bc564cca9e6508289e6b1e4a83c60fc0de523 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 13:20:37 +0200 Subject: [PATCH 02/11] Update actions/setup-go to v6.4.0 --- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 73999d12..e16341e7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v6.0.2 - name: Setup Go - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + uses: actions/setup-go@v6.4.0 with: go-version: 1.24.1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 450bfeaa..3694a2cb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/checkout@v6.0.2 - - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + - uses: actions/setup-go@v6.4.0 with: go-version: 1.24.1 @@ -55,7 +55,7 @@ jobs: steps: - uses: actions/checkout@v6.0.2 - - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + - uses: actions/setup-go@v6.4.0 with: go-version: 1.24.1 @@ -86,7 +86,7 @@ jobs: steps: - uses: actions/checkout@v6.0.2 - - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + - uses: actions/setup-go@v6.4.0 with: go-version: 1.24.1 - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0 @@ -107,7 +107,7 @@ jobs: runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v6.0.2 - - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + - uses: actions/setup-go@v6.4.0 with: go-version: 1.24.1 From cf0ca0d52bcc0b791af8f06a8ff4089ed390875f Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 13:23:20 +0200 Subject: [PATCH 03/11] Relax and update ruby/setup-ruby version --- .github/workflows/tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3694a2cb..bec09e22 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -89,9 +89,8 @@ jobs: - uses: actions/setup-go@v6.4.0 with: go-version: 1.24.1 - - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0 + - uses: ruby/setup-ruby@v1 with: - ruby-version: 3.2 bundler-cache: true - name: Starting up MySQL From 2bab39593d33e1d3cc750bf147349c6e2b7fc242 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 13:28:19 +0200 Subject: [PATCH 04/11] Update actions/*-artifact to latest ones --- .github/workflows/release.yml | 4 ++-- .github/workflows/tests.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e16341e7..c0aa48e1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: run: .github/workflows/build-deb.sh - name: Upload debs - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@v7.0.1 with: name: debs-${{ github.sha }}-${{ matrix.runner }} path: build/ghostferry* @@ -36,7 +36,7 @@ jobs: steps: - uses: actions/checkout@v6.0.2 - name: Fetch uploaded artifacts - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@v8.0.1 with: pattern: debs-${{ github.sha }}-* merge-multiple: true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bec09e22..fbd70236 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -114,7 +114,7 @@ jobs: run: .github/workflows/build-deb.sh --tagged-only - name: Upload debs - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@v7.0.1 with: name: debs-${{ github.sha }}-${{ matrix.runner }} path: build/ghostferry* From 2f758e9ae06ec07a7767d7a29cf6c350f4b698af Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 13:38:30 +0200 Subject: [PATCH 05/11] Update bundler --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index b881a877..0926d8bc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -46,4 +46,4 @@ DEPENDENCIES webrick BUNDLED WITH - 2.2.22 + 4.0.10 From a4020f6c44d516e4acab8ed0b147d3db608bc793 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 13:39:51 +0200 Subject: [PATCH 06/11] Update ruby version --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index be94e6f5..7921bd0c 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.2 +3.4.8 From f9f2e81c160474d9fa9a5e7af7cfb6087d60a692 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 13:41:43 +0200 Subject: [PATCH 07/11] Update development gems --- Gemfile.lock | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0926d8bc..43fa8653 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,34 +1,41 @@ GEM remote: https://rubygems.org/ specs: - ansi (1.5.0) - builder (3.2.4) - byebug (11.1.3) + ansi (1.6.0) + bigdecimal (4.1.1) + builder (3.3.0) + byebug (13.0.0) + reline (>= 0.6.0) coderay (1.1.3) - method_source (1.0.0) - minitest (5.20.0) + io-console (0.8.2) + method_source (1.1.0) + minitest (5.27.0) minitest-fail-fast (0.1.0) minitest (~> 5) - minitest-hooks (1.5.1) + minitest-hooks (1.5.3) minitest (> 5.3) - minitest-reporters (1.6.1) + minitest-reporters (1.8.0) ansi builder - minitest (>= 5.0) + minitest (>= 5.0, < 7) ruby-progressbar - minitest-retry (0.2.2) + minitest-retry (0.3.1) minitest (>= 5.0) - mysql2 (0.5.5) - pry (0.14.2) + mysql2 (0.5.7) + bigdecimal + pry (0.16.0) coderay (~> 1.1) method_source (~> 1.0) - pry-byebug (3.10.1) - byebug (~> 11.0) - pry (>= 0.13, < 0.15) - rake (13.2.1) + reline (>= 0.6.0) + pry-byebug (3.12.0) + byebug (~> 13.0) + pry (>= 0.13, < 0.17) + rake (13.4.1) + reline (0.6.3) + io-console (~> 0.5) ruby-progressbar (1.13.0) tqdm (0.4.1) - webrick (1.8.2) + webrick (1.9.2) PLATFORMS ruby From 10e46f661fbd9818d1b05263cb485de4c7515ec7 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 13:53:35 +0200 Subject: [PATCH 08/11] Update golang version --- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 8 ++++---- dev.yml | 2 +- go.mod | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c0aa48e1..b05ebc8c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v6.4.0 with: - go-version: 1.24.1 + go-version: "1.26.2" - name: Building Ghostferry run: .github/workflows/build-deb.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fbd70236..39cde138 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@v6.4.0 with: - go-version: 1.24.1 + go-version: "1.26.2" - name: Starting up MySQL run: .github/workflows/start-mysql.sh @@ -57,7 +57,7 @@ jobs: - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@v6.4.0 with: - go-version: 1.24.1 + go-version: "1.26.2" - name: Starting up MySQL run: .github/workflows/start-mysql.sh @@ -88,7 +88,7 @@ jobs: - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@v6.4.0 with: - go-version: 1.24.1 + go-version: "1.26.2" - uses: ruby/setup-ruby@v1 with: bundler-cache: true @@ -108,7 +108,7 @@ jobs: - uses: actions/checkout@v6.0.2 - uses: actions/setup-go@v6.4.0 with: - go-version: 1.24.1 + go-version: "1.26.2" - name: Building Ghostferry run: .github/workflows/build-deb.sh --tagged-only diff --git a/dev.yml b/dev.yml index af6fa2d5..bcfe6b9c 100644 --- a/dev.yml +++ b/dev.yml @@ -9,7 +9,7 @@ up: - ruby - bundler - go: - version: "1.24.1" + version: "1.26.2" - podman - custom: name: Go Dependencies diff --git a/go.mod b/go.mod index cc45d577..0dbdbfd0 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/Shopify/ghostferry -go 1.24.1 +go 1.26.2 require ( github.com/DataDog/datadog-go v4.8.2+incompatible From d2ca8b11a2631b5b7ccb5489e8e39078b6fc6ff5 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 13:55:12 +0200 Subject: [PATCH 09/11] Add gem that's not in stdlib anymore --- Gemfile | 2 ++ Gemfile.lock | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Gemfile b/Gemfile index 2903d26b..2afad33c 100644 --- a/Gemfile +++ b/Gemfile @@ -16,3 +16,5 @@ group :development do gem "tqdm" gem "pry-byebug" end + +gem "mutex_m", "~> 0.3.0" diff --git a/Gemfile.lock b/Gemfile.lock index 43fa8653..e4c14075 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -21,6 +21,7 @@ GEM ruby-progressbar minitest-retry (0.3.1) minitest (>= 5.0) + mutex_m (0.3.0) mysql2 (0.5.7) bigdecimal pry (0.16.0) @@ -46,6 +47,7 @@ DEPENDENCIES minitest-hooks minitest-reporters (~> 1.4) minitest-retry + mutex_m (~> 0.3.0) mysql2 pry-byebug rake From a93d3c807b2178b57df5bc8104d217734bc247b6 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 15:00:03 +0200 Subject: [PATCH 10/11] Update Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6b903ef..42b47392 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ All notable changes to this project will be documented in this file. - Align default zerolog log level with logrus (info vs trace) - Introduce slog handler wrapper around our Logger interface and use it with BinlogStreamer +- Updated golang to 1.26.2 +- Updated ruby to 3.4.8 (test dependency) +- Updated github actions (CI dependency) ### Removed From e4044086cf05781633196196302aacca9110deb7 Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Wed, 15 Apr 2026 12:58:45 +0200 Subject: [PATCH 11/11] fix: relax exact-batch-count assertions in interrupt/resume tests TERM is delivered asynchronously via Go's signal channel. The signal handler calls ErrorHandler.Fatal which panics, but there is a race window between send_signal("TERM") returning in the Ruby callback and the signal actually interrupting the data iterator goroutine. A second 200-row batch can complete before the panic propagates, causing the target row count to be 400 instead of the asserted 200. The real correctness invariant is already checked by the subsequent assertions: last_successful_id from the target matches the pagination key in the dumped state. The exact count check adds no additional safety and only makes the tests fragile. Relax both the integer-keyed and UUID-keyed variants to assert_operator :>= 200. --- test/integration/interrupt_resume_test.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/integration/interrupt_resume_test.rb b/test/integration/interrupt_resume_test.rb index 7540b227..6a6e9033 100644 --- a/test/integration/interrupt_resume_test.rb +++ b/test/integration/interrupt_resume_test.rb @@ -19,7 +19,11 @@ def test_interrupt_resume_without_writes_to_source_to_check_target_state_when_in result = target_db.query("SELECT COUNT(*) AS cnt FROM #{DEFAULT_FULL_TABLE_NAME}") count = result.first["cnt"] - assert_equal 200, count + # TERM is delivered asynchronously so the signal may arrive after the + # second batch has already been written. At least one batch (200 rows) + # must have been copied; more is also acceptable as we are verifying + # the last_successful_id later on against the dumped state. + assert_operator count, :>=, 200 result = target_db.query("SELECT MAX(id) AS max_id FROM #{DEFAULT_FULL_TABLE_NAME}") last_successful_id = result.first["max_id"] @@ -701,7 +705,10 @@ def test_interrupt_resume_without_writes_to_source_with_uuid_table result = target_db.query("SELECT COUNT(*) AS cnt FROM #{UUID_FULL_TABLE_NAME}") count = result.first["cnt"] - assert_equal 200, count + # Same as the integer-keyed variant: TERM is async so at least one batch + # (200 rows) must be copied; a second batch landing first is also valid. + # We are verifying the last_successful_id_bytes later on against the dumped state. + assert_operator count, :>=, 200 result = target_db.query("SELECT MAX(uuid) AS max_id FROM #{UUID_FULL_TABLE_NAME}") last_successful_id_bytes = result.first["max_id"]