From caf94ba272b4e9f74a470d39354b258fcd388b2d Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Tue, 25 Aug 2026 20:19:33 +0000 Subject: [PATCH] Support Ruby 3.4 and 4.0; enable deprecation warnings everywhere MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows an incremental Elastic Beanstalk rollout: the Gemfile now accepts >= 3.4, < 4.1 so the app runs on both the EB "Ruby 3.4 on AL2023" platform (ruby 3.4.10, matching the previous lockfile) and Ruby 4.0.6, the latest 4.0.x and what the "Ruby 4.0 on AL2023" platform ships. - Local tooling (mise, Dockerfile, devcontainer) moves to Ruby 4.0.6 - RSpec CI runs a 3.4 + 4.0 matrix; other workflows follow .tool-versions - buildspec stays on ruby 3.4 in lockstep with the EB platform; bump to 4.0 together with the platform upgrade - Bundler pinned at 4.0.19 (lockfile + EB prebuild hook) — Bundler 2.5.6 emits constant-redefinition warnings under Ruby 4.0's RubyGems - Ruby-level deprecation warnings (Warning[:deprecated]) are enabled globally in boot.rb instead of only dev/test, and production now logs Rails deprecations instead of silencing them Verified on both 3.4.10 and 4.0.6: RSpec 712/712, RuboCop clean, Cucumber rack_test 24/24, Jekyll docs build. Co-Authored-By: Claude Fable 5 --- .devcontainer/Dockerfile | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/rspec.yml | 11 +++++++++-- .platform/hooks/prebuild/01_install_bundler.sh | 3 ++- .rubocop.yml | 2 +- .tool-versions | 2 +- Dockerfile | 2 +- Gemfile | 2 +- Gemfile.lock | 4 ++-- buildspec.yml | 12 +++++++----- config/boot.rb | 5 +++++ config/environments/development.rb | 7 ++----- config/environments/production.rb | 7 +++++-- config/environments/test.rb | 7 ++----- docs/developers.md | 13 ++++++++----- 15 files changed, 48 insertions(+), 33 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index bb44a58b..0de2b192 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,3 +1,3 @@ # Make sure RUBY_VERSION matches the Ruby version in .tool-versions -ARG RUBY_VERSION=3.4.10 +ARG RUBY_VERSION=4.0.6 FROM ghcr.io/rails/devcontainer/images/ruby:$RUBY_VERSION diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9a8eac38..e0c5fdfa 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.4' + ruby-version: '4.0' bundler-cache: true working-directory: docs diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index 78438670..318bba8b 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -8,6 +8,12 @@ on: jobs: rspec: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # Test every Ruby the app supports: the Elastic Beanstalk platform's + # 3.4 and the 4.0 we are rolling forward to (see docs/developers.md). + ruby: ['3.4', '4.0'] services: postgres: image: postgres:17 @@ -35,7 +41,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: .tool-versions + ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: Setup Database run: | @@ -55,7 +61,8 @@ jobs: run: ruby .github/scripts/coverage_summary.rb "RSpec coverage" - name: Submit QLTY Coverage Report uses: qltysh/qlty-action/coverage@v1 - if: env.QLTY_COVERAGE_TOKEN != '' + # Only submit coverage once per run (from the 4.0 job). + if: env.QLTY_COVERAGE_TOKEN != '' && matrix.ruby == '4.0' with: token: ${{ secrets.QLTY_COVERAGE_TOKEN }} files: coverage/.resultset.json diff --git a/.platform/hooks/prebuild/01_install_bundler.sh b/.platform/hooks/prebuild/01_install_bundler.sh index 51b52530..c2549bc6 100644 --- a/.platform/hooks/prebuild/01_install_bundler.sh +++ b/.platform/hooks/prebuild/01_install_bundler.sh @@ -1,4 +1,5 @@ #!/bin/bash dnf remove libpq-devel -y dnf install postgresql17-devel -y -gem install bundler -v 2.5.6 +# Keep in sync with BUNDLED WITH in Gemfile.lock +gem install bundler -v 4.0.19 diff --git a/.rubocop.yml b/.rubocop.yml index 21dc5910..d5f07bb6 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,6 +1,6 @@ AllCops: NewCops: enable - TargetRubyVersion: 3.3 + TargetRubyVersion: 3.4 Exclude: - 'db/**/*' - 'config/**/*' diff --git a/.tool-versions b/.tool-versions index 380cf519..b77860ba 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -ruby 3.4 +ruby 4.0 diff --git a/Dockerfile b/Dockerfile index 7f3d9f5a..bbd80ca2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # syntax = docker/dockerfile:1 # Make sure RUBY_VERSION matches .tool-versions and satisfies the Gemfile's ruby constraint -ARG RUBY_VERSION=3.4.10 +ARG RUBY_VERSION=4.0.6 FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base # Rails app lives here diff --git a/Gemfile b/Gemfile index 325e916b..cbdae691 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ruby '>= 3.3', '< 3.5' +ruby '>= 3.4', '< 4.1' # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" gem 'rails', '~> 8.1.3' diff --git a/Gemfile.lock b/Gemfile.lock index caceda70..6a88ab06 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -688,7 +688,7 @@ DEPENDENCIES webmock RUBY VERSION - ruby 3.4.10 + ruby 4.0.6p0 BUNDLED WITH - 2.5.6 + 4.0.19 diff --git a/buildspec.yml b/buildspec.yml index 414e38ea..34fb5d40 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -8,12 +8,14 @@ version: 0.2 phases: install: # This MUST match the Elastic Beanstalk platform's Ruby version. - # The staging environment runs the "Ruby 3.3 on Amazon Linux 2023" - # platform branch (currently ruby 3.3.11), so building with any other - # version breaks deploys. Bump this only together with an EB platform - # upgrade to a Ruby 3.4 branch. + # The staging and production environments run the "Ruby 3.4 on Amazon + # Linux 2023" platform branch (currently ruby 3.4.10), so building with + # any other version breaks deploys. The app already supports Ruby 4.0 + # (the Gemfile allows >= 3.4, < 4.1); bump this to 4.0 only together + # with the EB platform upgrade to the "Ruby 4.0 on Amazon Linux 2023" + # branch. runtime-versions: - ruby: 3.3 + ruby: 3.4 commands: - echo "Installing system dependencies for build..." diff --git a/config/boot.rb b/config/boot.rb index 988a5ddc..b6563e8f 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,4 +1,9 @@ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) +# Surface Ruby-level deprecation warnings (off by default since Ruby 3.0) in +# every environment — server, console, rake, and Elastic Beanstalk alike — so +# deprecated language/stdlib usage is caught ahead of the next Ruby upgrade. +Warning[:deprecated] = true + require "bundler/setup" # Set up gems listed in the Gemfile. require "bootsnap/setup" # Speed up boot time by caching expensive operations. diff --git a/config/environments/development.rb b/config/environments/development.rb index 1db08070..1b651c44 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -46,13 +46,10 @@ config.action_mailer.default_url_options = { host: "localhost", port: 3000 } - # Print deprecation notices to the Rails logger. + # Print deprecation notices to the Rails logger. (Ruby-level deprecation + # warnings are enabled globally in config/boot.rb.) config.active_support.deprecation = :log - # Surface Ruby-level deprecation warnings (off by default since Ruby 3.0) so - # deprecated language/stdlib usage is visible during local development. - Warning[:deprecated] = true - # Raise exceptions for disallowed deprecations. config.active_support.disallowed_deprecation = :raise diff --git a/config/environments/production.rb b/config/environments/production.rb index 304259f5..ca811ac9 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -110,8 +110,11 @@ # the I18n.default_locale when a translation cannot be found). config.i18n.fallbacks = true - # Don't log any deprecations. - config.active_support.report_deprecations = false + # Log deprecations so upcoming Rails/gem upgrade work is visible in + # production logs. (Ruby-level deprecation warnings are enabled globally in + # config/boot.rb.) + config.active_support.report_deprecations = true + config.active_support.deprecation = :log # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false diff --git a/config/environments/test.rb b/config/environments/test.rb index fc177004..d91f9b5f 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -48,13 +48,10 @@ # ActionMailer::Base.deliveries array. # config.action_mailer.delivery_method = :test - # Print deprecation notices to the stderr. + # Print deprecation notices to the stderr. (Ruby-level deprecation warnings + # are enabled globally in config/boot.rb.) config.active_support.deprecation = :stderr - # Surface Ruby-level deprecation warnings (off by default since Ruby 3.0) so - # deprecated language/stdlib usage is caught in CI and local test runs. - Warning[:deprecated] = true - # Raise exceptions for disallowed deprecations. config.active_support.disallowed_deprecation = :raise diff --git a/docs/developers.md b/docs/developers.md index 40f99c4b..e1c055db 100644 --- a/docs/developers.md +++ b/docs/developers.md @@ -24,12 +24,13 @@ cd flextensions Install `mise`, such as `brew install mise` or any other ruby language manager. -Either Ruby 3.3 or 3.4 will work. CI runs 3.4, but the deployed Elastic -Beanstalk platform runs Ruby 3.3, so the app must remain compatible with -both (the Gemfile allows `>= 3.3, < 3.5`): +Either Ruby 3.4 or 4.0 will work. CI tests both, and the deployed Elastic +Beanstalk platform runs Ruby 3.4 while we roll forward to 4.0, so the app +must remain compatible with both (the Gemfile allows `>= 3.4, < 4.1`). +Prefer 4.0 locally: ``` -mise use ruby@3.4 +mise use ruby@4.0 ``` ### Install dependencies: @@ -146,7 +147,9 @@ recurring jobs — for example when moving them to a dedicated worker started wi ## Deployment (Elastic Beanstalk) -Staging and production run on the *Ruby 3.3 on Amazon Linux 2023* platform, built +Staging and production run on the *Ruby 3.4 on Amazon Linux 2023* platform +(next stop: *Ruby 4.0 on Amazon Linux 2023* — bump `buildspec.yml` together +with the platform), built by CodeBuild (`buildspec.yml`) and deployed by CodePipeline. ### There is deliberately no `Procfile`