From 20a5852800fafcf23a67bdaed0a037f202cbe426 Mon Sep 17 00:00:00 2001 From: Sean McGuire Date: Fri, 23 Oct 2026 11:48:38 -0700 Subject: [PATCH] bump version --- .release-please-manifest.json | 4 +-- CHANGELOG.md | 8 +++++ Gemfile.lock | 2 +- lib/stagehand/local.rb | 4 ++- lib/stagehand/version.rb | 2 +- test/stagehand/local_binary_test.rb | 53 ++++++++++++++++++++++++++--- 6 files changed, 64 insertions(+), 9 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index eba8a04..112b0ef 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.21.0" -} \ No newline at end of file + ".": "3.21.1" +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cf228c..a2b35a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 3.21.1 (2026-10-23) + +Full Changelog: [v3.21.0...v3.21.1](https://github.com/browserbase/stagehand-ruby/compare/v3.21.0...v3.21.1) + +### Bug Fixes + +* **security:** default local-server downloads to [server v3.7.7](https://github.com/browserbase/stagehand/releases/tag/stagehand-server-v3/v3.7.7), which includes Node.js 24.22.1 and Undici 7.30.1 with the October 2026 security fixes. Upgrade the gem and restart applications to download the patched binary into a new gem-versioned cache directory. Explicit `STAGEHAND_SERVER_VERSION` and `STAGEHAND_SEA_BINARY` overrides remain supported; update any override that selects an older server or custom binary separately. + ## 3.21.0 (2026-05-27) Full Changelog: [v3.20.0...v3.21.0](https://github.com/browserbase/stagehand-ruby/compare/v3.20.0...v3.21.0) diff --git a/Gemfile.lock b/Gemfile.lock index adcbab3..513e0a1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GIT PATH remote: . specs: - stagehand (3.21.0) + stagehand (3.21.1) cgi connection_pool diff --git a/lib/stagehand/local.rb b/lib/stagehand/local.rb index 01c47ab..302db49 100644 --- a/lib/stagehand/local.rb +++ b/lib/stagehand/local.rb @@ -11,6 +11,8 @@ module Stagehand module Local STAGEHAND_REPO = "browserbase/stagehand" DEFAULT_USER_AGENT = "stagehand-ruby/local" + # Includes the October 2026 Node.js and Undici security fixes. + DEFAULT_SERVER_VERSION = "stagehand-server-v3/v3.7.7" DEFAULT_HOST = "127.0.0.1" DEFAULT_READY_TIMEOUT_S = 30.0 DOWNLOAD_TIMEOUT_S = 600 @@ -101,7 +103,7 @@ def resolve_binary_path return ensure_executable(cache_path) if File.file?(cache_path) version = ENV["STAGEHAND_SERVER_VERSION"].to_s - version = "latest" if version.empty? + version = DEFAULT_SERVER_VERSION if version.empty? tag = resolve_version(version) download_binary(tag, cache_path) end diff --git a/lib/stagehand/version.rb b/lib/stagehand/version.rb index bffebd2..cb6d989 100644 --- a/lib/stagehand/version.rb +++ b/lib/stagehand/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Stagehand - VERSION = "3.21.0" + VERSION = "3.21.1" end diff --git a/test/stagehand/local_binary_test.rb b/test/stagehand/local_binary_test.rb index c35b84f..20a6cf7 100644 --- a/test/stagehand/local_binary_test.rb +++ b/test/stagehand/local_binary_test.rb @@ -17,10 +17,13 @@ def setup @old_home = Dir.home if ENV.key?("HOME") @old_xdg = ENV["XDG_CACHE_HOME"] @old_local = ENV["LOCALAPPDATA"] + @old_server_version = ENV["STAGEHAND_SERVER_VERSION"] + @old_sea_binary = ENV["STAGEHAND_SEA_BINARY"] ENV["HOME"] = @tmp_home ENV.delete("XDG_CACHE_HOME") ENV.delete("LOCALAPPDATA") ENV.delete("STAGEHAND_SERVER_VERSION") + ENV.delete("STAGEHAND_SEA_BINARY") WebMock.enable! WebMock.disable_net_connect!(allow_localhost: true) end @@ -33,6 +36,8 @@ def teardown end ENV["XDG_CACHE_HOME"] = @old_xdg ENV["LOCALAPPDATA"] = @old_local + ENV["STAGEHAND_SERVER_VERSION"] = @old_server_version + ENV["STAGEHAND_SEA_BINARY"] = @old_sea_binary FileUtils.remove_entry(@tmp_home) if @tmp_home && File.directory?(@tmp_home) WebMock.reset! WebMock.allow_net_connect! @@ -54,7 +59,50 @@ def test_uses_cache_without_network assert_equal(cache_path, path) end + def test_default_downloads_patched_version_ignoring_old_cache + cache_dir = Stagehand::Local::Binary.cache_dir + filename = Stagehand::Local::Binary.binary_filename + old_path = File.join(File.dirname(cache_dir), "ruby_3.21.0", filename) + FileUtils.mkdir_p(File.dirname(old_path)) + File.binwrite(old_path, "old binary") + + url = "https://github.com/browserbase/stagehand/releases/download/stagehand-server-v3/v3.7.7/#{filename}" + stub_request(:get, url).to_return(status: 200, body: "patched binary") + + path = Stagehand::Local::Binary.resolve_binary_path + + assert_equal(File.join(cache_dir, filename), path) + assert_equal("patched binary", File.binread(path)) + assert_equal("old binary", File.binread(old_path)) + assert_requested(:get, url, times: 1) + end + + def test_downloads_explicit_server_version + ENV["STAGEHAND_SERVER_VERSION"] = "v1.2.3" + filename = Stagehand::Local::Binary.binary_filename + url = "https://github.com/browserbase/stagehand/releases/download/stagehand-server-v3/v1.2.3/#{filename}" + stub_request(:get, url).to_return(status: 200, body: "selected binary") + + path = Stagehand::Local::Binary.resolve_binary_path + + assert_equal("selected binary", File.binread(path)) + assert_requested(:get, url, times: 1) + end + + def test_uses_custom_binary_without_network + custom_path = File.join(@tmp_home, "custom-server") + File.binwrite(custom_path, "custom binary") + ENV["STAGEHAND_SEA_BINARY"] = custom_path + + path = Stagehand::Local::Binary.resolve_binary_path + + assert_equal(custom_path, path) + assert_equal("custom binary", File.binread(path)) + assert_not_requested(:get, /github\.com/) + end + def test_downloads_latest_tag_when_missing + ENV["STAGEHAND_SERVER_VERSION"] = "latest" filename = Stagehand::Local::Binary.binary_filename stub_request(:get, "https://api.github.com/repos/browserbase/stagehand/releases?per_page=15") @@ -72,10 +120,7 @@ def test_downloads_latest_tag_when_missing def test_download_error_includes_manual_hint filename = Stagehand::Local::Binary.binary_filename - stub_request(:get, "https://api.github.com/repos/browserbase/stagehand/releases?per_page=15") - .to_return(status: 200, body: [{tag_name: "stagehand-server-v3/v1.2.3"}].to_json) - - stub_request(:get, "https://github.com/browserbase/stagehand/releases/download/stagehand-server-v3/v1.2.3/#{filename}") + stub_request(:get, "https://github.com/browserbase/stagehand/releases/download/stagehand-server-v3/v3.7.7/#{filename}") .to_return(status: 404, body: "not found") err = assert_raises(RuntimeError) { Stagehand::Local::Binary.resolve_binary_path }