diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 42cfb4d04..ebd14e86d 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -86,22 +86,39 @@ jobs:
           path: demo/log
 
   test:
-    name: Test
+    name: Test - Ruby ${{ matrix.ruby }} - Postgres ${{ matrix.pg }} - ${{ matrix.gemfile }}
     runs-on: ubuntu-latest
-    timeout-minutes: 30
+    timeout-minutes: 10
     strategy:
       fail-fast: false
       matrix:
         ruby: ["3.0", 3.1, 3.2, 3.3]
+        gemfile: [rails_6.1, rails_7.0, rails_7.1, rails_7.2, rails_8.0, rails_head]
         pg: [17]
         include:
           - ruby: 3.3
+            gemfile: rails_7.2
             pg: 10
+        exclude:
+          # Rails 7.2 is >= 3.1
+          - ruby: "3.0"
+            gemfile: rails_7.2
+          # Rails 8.0 is >= 3.2
+          - ruby: "3.0"
+            gemfile: rails_8.0
+          - ruby: 3.1
+            gemfile: rails_8.0
+          # Rails head is >= 3.2
+          - ruby: "3.0"
+            gemfile: rails_head
+          - ruby: 3.1
+            gemfile: rails_head
 
     env:
       PGHOST: localhost
       PGUSER: good_job
       RAILS_ENV: test
+      BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
       BUNDLE_JOBS: 4
       BUNDLE_RETRY: 3
       BUNDLE_PATH: vendor/bundle
@@ -125,59 +142,30 @@ jobs:
         uses: actions/checkout@v4
       - name: Update .ruby-version with matrix value
         run: echo "${{ matrix.ruby }}" >| .ruby-version
-      - name: Set Rubygems version
-        id: rubygems
-        run: |
-          if [[ "${{ matrix.ruby }}" == "2.6" || "${{ matrix.ruby }}" == "2.7" || "${{ matrix.ruby }}" == "jruby-9.3" ]]; then
-            echo "version=3.3.27" >> $GITHUB_OUTPUT
-          else
-            echo "version=latest" >> $GITHUB_OUTPUT
-          fi
       # Dependencies
-      - name: Remove Gemfile.lock
-        run: rm Gemfile.lock
-      - name: Set up generic Ruby
-        uses: ruby/setup-ruby@v1
-        with:
-          bundler-cache: false
-      - name: Recreate Gemfile.lock
-        run: bundle lock --update && cat Gemfile.lock
       - name: Set up Ruby and bundle install
         uses: ruby/setup-ruby@v1
         with:
           bundler-cache: true
-          rubygems: ${{ steps.rubygems.outputs.version }}
-      - name: Generate Appraisal Gemfile.lock files
-        run: |
-          bundle exec appraisal bundle lock --update
-      - name: Cache Appraisal gems
-        uses: actions/cache@v4
-        with:
-          path: gemfiles/vendor/bundle
-          key: v1-bundler-${{ runner.os }}-${{ matrix.ruby }}-${{ hashFiles('Gemfile.lock', 'gemfiles/*.gemfile.lock') }}
-          restore-keys: |
-            v1-bundler-${{ runner.os }}-${{ matrix.ruby }}-
-      - name: Install Appraisal gems
-        run: bundle exec appraisal install
+          rubygems: latest
 
       # Test
       - name: Set up test database
-        run: bundle exec appraisal demo/bin/rails db:test:prepare
+        run: bundle exec demo/bin/rails db:test:prepare
       - name: Run Unit tests
         run: |
-          bundle exec appraisal rspec --exclude-pattern "spec/system/**/*_spec.rb, spec/generators/**/*_spec.rb" \
+          bundle exec rspec --exclude-pattern "spec/system/**/*_spec.rb, spec/generators/**/*_spec.rb" \
                                       --require ./spec/support/pre_documentation_formatter.rb \
                                       --format PreDocumentationFormatter
       - name: Run System tests
-        if: ${{ !contains(matrix.ruby, 'jruby') }}
         run: |
-          bundle exec appraisal rspec --require ./spec/support/pre_documentation_formatter.rb \
+          bundle exec rspec --require ./spec/support/pre_documentation_formatter.rb \
                                       --format PreDocumentationFormatter \
                                       spec/system
 
       - name: Run Generators tests
         run: |
-          bundle exec appraisal rspec --require ./spec/support/pre_documentation_formatter.rb \
+          bundle exec rspec --require ./spec/support/pre_documentation_formatter.rb \
                                       --format PreDocumentationFormatter \
                                       spec/generators
 
@@ -186,7 +174,7 @@ jobs:
         uses: actions/upload-artifact@v4
         if: failure()
         with:
-          name: screenshots
+          name: screenshots-${{ matrix.pg }}-${{ matrix.gemfile }}-${{ matrix.ruby }}
           path: |
             demo/tmp/screenshots
             demo/tmp/capybara
@@ -194,5 +182,5 @@ jobs:
         uses: actions/upload-artifact@v4
         if: failure()
         with:
-          name: rails_logs
+          name: rails_logs-${{ matrix.pg }}-${{ matrix.gemfile }}-${{ matrix.ruby }}
           path: demo/log
diff --git a/Appraisals b/Appraisals
deleted file mode 100644
index 6dca6fc74..000000000
--- a/Appraisals
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-ruby_30_or_higher = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0')
-ruby_31_or_higher = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.1')
-ruby_32_or_higher = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2')
-jruby = RUBY_PLATFORM.include?('java')
-
-unless ruby_31_or_higher # https://github.com/rails/rails/issues/44090#issuecomment-1007686519
-  appraise "rails-6.1" do
-    gem "rails", "~> 6.1.0"
-    gem "traces", "~> 0.9.1"
-    gem "puma", "~> 5.6"
-  end
-end
-
-if ruby_30_or_higher && !ruby_31_or_higher && !jruby
-  appraise "rails-7.0" do
-    gem "rails", "~> 7.0.0"
-  end
-end
-
-if ruby_31_or_higher
-  appraise "rails-7.0-ruby-3.1" do
-    gem "rails", "~> 7.0.1" # Ruby 3.1 requires Rails 7.0.1+
-  end
-
-  unless jruby
-    appraise "rails-7.1-ruby-3.1" do
-      gem "rails", "~> 7.1.0"
-    end
-
-    appraise "rails-7.2-ruby-3.1" do
-      gem "rails", "~> 7.2.0"
-    end
-  end
-end
-
-if ruby_32_or_higher && !jruby
-  appraise "rails-8.0-ruby-3.2" do
-    gem "rails", "~> 8.0.0.a"
-  end
-
-  appraise "rails-head" do
-    gem "rails", github: "rails/rails", branch: "main"
-  end
-end
diff --git a/Gemfile b/Gemfile
index e99befcee..0655f4473 100644
--- a/Gemfile
+++ b/Gemfile
@@ -20,10 +20,18 @@ gemspec
 # your gem to rubygems.org.
 
 gem 'activerecord-jdbcpostgresql-adapter', platforms: [:jruby]
-gem 'appraisal'
 gem 'pg', platforms: [:mri, :mingw, :x64_mingw]
 gem 'rack', '~> 2.2'
-gem 'rails'
+
+rails_versions = {
+  "6.1" => "~> 6.1.0",
+  "7.0" => "~> 7.0.1", # Ruby 3.1 requires Rails 7.0.1+
+  "7.1" => "~> 7.1.0",
+  "7.2" => "~> 7.2.0",
+  "8.0" => "~> 8.0.0.a",
+  "head" => { github: "rails/rails", branch: "main" },
+}
+gem 'rails', rails_versions[ENV.fetch("RAILS_VERSION", nil)]
 
 platforms :ruby do
   gem "bootsnap"
diff --git a/Gemfile.lock b/Gemfile.lock
index 1451ee82a..8d8189446 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -96,10 +96,6 @@ GEM
       tzinfo (~> 2.0)
     addressable (2.8.7)
       public_suffix (>= 2.0.2, < 7.0)
-    appraisal (2.5.0)
-      bundler
-      rake
-      thor (>= 0.14.0)
     ast (2.4.2)
     async (2.14.2)
       console (~> 1.25, >= 1.25.2)
@@ -505,7 +501,6 @@ PLATFORMS
 DEPENDENCIES
   activerecord-explain-analyze
   activerecord-jdbcpostgresql-adapter
-  appraisal
   benchmark-ips
   bootsnap
   brakeman
diff --git a/README.md b/README.md
index 8a3f1cbbc..e18f1f483 100644
--- a/README.md
+++ b/README.md
@@ -1715,14 +1715,14 @@ Environment variables that may help with debugging:
 - `LOUD=1`: display all stdout/stderr output from all sources. This is helpful because GoodJob wraps some tests with `quiet { }` for cleaner test output, but it can hinder debugging.
 - `SHOW_BROWSER=1`: Run system tests headfully with Chrome/Chromedriver. Use `binding.irb` in the system tests to pause.
 
-Appraisal can be used to run a test matrix of multiple versions of Rails:
+The gemfiles in `gemfiles/` can be used to run tests against different rails versions:
 
 ```bash
-# Install Appraisal matrix of gemfiles
-bin/appraisal
+# Install dependencies
+BUNDLE_GEMFILE=gemfiles/rails_6.1.gemfile bundle install
 
-# Run tests against matrix
-bin/appraisal bin/rspec
+# Run the tests
+BUNDLE_GEMFILE=gemfiles/rails_6.1.gemfile bin/rspec
 ```
 
 ### Release
diff --git a/bin/appraisal b/bin/appraisal
deleted file mode 100755
index 182bee330..000000000
--- a/bin/appraisal
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require 'bundler/setup'
-load Gem.bin_path('appraisal', 'appraisal')
diff --git a/gemfiles/bin/bundle b/gemfiles/bin/bundle
deleted file mode 100755
index 8d10a164b..000000000
--- a/gemfiles/bin/bundle
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/usr/bin/env ruby
-# frozen_string_literal: true
-
-#
-# This file was generated by Bundler.
-#
-# The application 'bundle' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require "rubygems"
-
-m = Module.new do
-  module_function
-
-  def invoked_as_script?
-    File.expand_path($0) == File.expand_path(__FILE__)
-  end
-
-  def env_var_version
-    ENV["BUNDLER_VERSION"]
-  end
-
-  def cli_arg_version
-    return unless invoked_as_script? # don't want to hijack other binstubs
-    return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
-    bundler_version = nil
-    update_index = nil
-    ARGV.each_with_index do |a, i|
-      if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
-        bundler_version = a
-      end
-      next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
-      bundler_version = $1
-      update_index = i
-    end
-    bundler_version
-  end
-
-  def gemfile
-    gemfile = ENV["BUNDLE_GEMFILE"]
-    return gemfile if gemfile && !gemfile.empty?
-
-    File.expand_path("../rails_7.0_ruby_3.1.gemfile", __dir__)
-  end
-
-  def lockfile
-    lockfile =
-      case File.basename(gemfile)
-      when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
-      else "#{gemfile}.lock"
-      end
-    File.expand_path(lockfile)
-  end
-
-  def lockfile_version
-    return unless File.file?(lockfile)
-    lockfile_contents = File.read(lockfile)
-    return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
-    Regexp.last_match(1)
-  end
-
-  def bundler_requirement
-    @bundler_requirement ||=
-      env_var_version ||
-      cli_arg_version ||
-      bundler_requirement_for(lockfile_version)
-  end
-
-  def bundler_requirement_for(version)
-    return "#{Gem::Requirement.default}.a" unless version
-
-    bundler_gem_version = Gem::Version.new(version)
-
-    bundler_gem_version.approximate_recommendation
-  end
-
-  def load_bundler!
-    ENV["BUNDLE_GEMFILE"] ||= gemfile
-
-    activate_bundler
-  end
-
-  def activate_bundler
-    gem_error = activation_error_handling do
-      gem "bundler", bundler_requirement
-    end
-    return if gem_error.nil?
-    require_error = activation_error_handling do
-      require "bundler/version"
-    end
-    return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
-    warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
-    exit 42
-  end
-
-  def activation_error_handling
-    yield
-    nil
-  rescue StandardError, LoadError => e
-    e
-  end
-end
-
-m.load_bundler!
-
-if m.invoked_as_script?
-  load Gem.bin_path("bundler", "bundle")
-end
diff --git a/gemfiles/rails_6.1.gemfile b/gemfiles/rails_6.1.gemfile
index 98e15b5ae..ee84ef382 100644
--- a/gemfiles/rails_6.1.gemfile
+++ b/gemfiles/rails_6.1.gemfile
@@ -1,53 +1,8 @@
-# This file was generated by Appraisal
-
 source "https://rubygems.org"
 
-gem "activerecord-jdbcpostgresql-adapter", platforms: [:jruby]
-gem "appraisal"
-gem "pg", platforms: [:mri, :mingw, :x64_mingw]
-gem "rack", "~> 2.2"
-gem "rails", "~> 6.1.0"
-gem "traces", "~> 0.9.1"
 gem "puma", "~> 5.6"
+gem "traces", "~> 0.9.1"
 
-platforms :ruby do
-  gem "bootsnap"
-  gem "dotenv-rails"
-  gem "foreman"
-  gem "gem-release"
-  gem "github_changelog_generator", require: false
-
-  group :debug do
-    gem "activerecord-explain-analyze", require: false
-    gem "benchmark-ips"
-    gem "debug"
-    gem "memory_profiler"
-    gem "rack-mini-profiler"
-    gem "rbtrace"
-    gem "stackprof"
-  end
-
-  group :lint do
-    gem "brakeman"
-    gem "easy_translate"
-    gem "erb_lint"
-    gem "i18n-tasks"
-    gem "mdl"
-    gem "rubocop"
-    gem "rubocop-capybara"
-    gem "rubocop-performance"
-    gem "rubocop-rails"
-    gem "rubocop-rspec"
-    gem "rubocop-rspec_rails"
-    gem "sorbet"
-    gem "sorbet-runtime"
-    gem "spoom", require: false
-    gem "tapioca", require: false
-  end
-
-  group :demo, :production do
-    gem "skylight"
-  end
-end
+ENV["RAILS_VERSION"] = "6.1"
 
-gemspec path: "../"
+eval_gemfile "../Gemfile"
diff --git a/gemfiles/rails_7.0.gemfile b/gemfiles/rails_7.0.gemfile
index 6bbaeb520..852c1c882 100644
--- a/gemfiles/rails_7.0.gemfile
+++ b/gemfiles/rails_7.0.gemfile
@@ -1,56 +1,5 @@
-# This file was generated by Appraisal
-
 source "https://rubygems.org"
 
-gem "activerecord-jdbcpostgresql-adapter", platforms: [:jruby]
-gem "appraisal"
-gem "matrix"
-gem "nokogiri"
-gem "pg", platforms: [:mri, :mingw, :x64_mingw]
-gem "rack", "~> 2.2"
-gem "rails", "~> 7.0.0"
-
-platforms :ruby do
-  gem "bootsnap"
-  gem "dotenv-rails"
-  gem "foreman"
-  gem "gem-release"
-  gem "github_changelog_generator", require: false
-  gem "net-imap", require: false
-  gem "net-pop", require: false
-  gem "net-smtp", require: false
-
-  group :debug do
-    gem "activerecord-explain-analyze", require: false
-    gem "benchmark-ips"
-    gem "debug"
-    gem "memory_profiler"
-    gem "rack-mini-profiler"
-    gem "rbtrace"
-    gem "stackprof"
-  end
-
-  group :lint do
-    gem "brakeman"
-    gem "easy_translate"
-    gem "erb_lint"
-    gem "i18n-tasks"
-    gem "mdl"
-    gem "rubocop"
-    gem "rubocop-capybara"
-    gem "rubocop-performance"
-    gem "rubocop-rails"
-    gem "rubocop-rspec"
-    gem "rubocop-rspec_rails"
-    gem "sorbet"
-    gem "sorbet-runtime"
-    gem "spoom", require: false
-    gem "tapioca", require: false
-  end
-
-  group :demo, :production do
-    gem "skylight"
-  end
-end
+ENV["RAILS_VERSION"] = "7.0"
 
-gemspec path: "../"
+eval_gemfile "../Gemfile"
diff --git a/gemfiles/rails_7.0_ruby_3.1.gemfile b/gemfiles/rails_7.0_ruby_3.1.gemfile
deleted file mode 100644
index 18d5dd91a..000000000
--- a/gemfiles/rails_7.0_ruby_3.1.gemfile
+++ /dev/null
@@ -1,51 +0,0 @@
-# This file was generated by Appraisal
-
-source "https://rubygems.org"
-
-gem "activerecord-jdbcpostgresql-adapter", platforms: [:jruby]
-gem "appraisal"
-gem "pg", platforms: [:mri, :mingw, :x64_mingw]
-gem "rack", "~> 2.2"
-gem "rails", "~> 7.0.1"
-
-platforms :ruby do
-  gem "bootsnap"
-  gem "dotenv-rails"
-  gem "foreman"
-  gem "gem-release"
-  gem "github_changelog_generator", require: false
-
-  group :debug do
-    gem "activerecord-explain-analyze", require: false
-    gem "benchmark-ips"
-    gem "debug"
-    gem "memory_profiler"
-    gem "rack-mini-profiler"
-    gem "rbtrace"
-    gem "stackprof"
-  end
-
-  group :lint do
-    gem "brakeman"
-    gem "easy_translate"
-    gem "erb_lint"
-    gem "i18n-tasks"
-    gem "mdl"
-    gem "rubocop"
-    gem "rubocop-capybara"
-    gem "rubocop-performance"
-    gem "rubocop-rails"
-    gem "rubocop-rspec"
-    gem "rubocop-rspec_rails"
-    gem "sorbet"
-    gem "sorbet-runtime"
-    gem "spoom", require: false
-    gem "tapioca", require: false
-  end
-
-  group :demo, :production do
-    gem "skylight"
-  end
-end
-
-gemspec path: "../"
diff --git a/gemfiles/rails_7.1.gemfile b/gemfiles/rails_7.1.gemfile
new file mode 100644
index 000000000..0743be97f
--- /dev/null
+++ b/gemfiles/rails_7.1.gemfile
@@ -0,0 +1,5 @@
+source "https://rubygems.org"
+
+ENV["RAILS_VERSION"] = "7.1"
+
+eval_gemfile "../Gemfile"
diff --git a/gemfiles/rails_7.1_ruby_3.1.gemfile b/gemfiles/rails_7.1_ruby_3.1.gemfile
deleted file mode 100644
index 816642940..000000000
--- a/gemfiles/rails_7.1_ruby_3.1.gemfile
+++ /dev/null
@@ -1,51 +0,0 @@
-# This file was generated by Appraisal
-
-source "https://rubygems.org"
-
-gem "activerecord-jdbcpostgresql-adapter", platforms: [:jruby]
-gem "appraisal"
-gem "pg", platforms: [:mri, :mingw, :x64_mingw]
-gem "rack", "~> 2.2"
-gem "rails", "~> 7.1.0"
-
-platforms :ruby do
-  gem "bootsnap"
-  gem "dotenv-rails"
-  gem "foreman"
-  gem "gem-release"
-  gem "github_changelog_generator", require: false
-
-  group :debug do
-    gem "activerecord-explain-analyze", require: false
-    gem "benchmark-ips"
-    gem "debug"
-    gem "memory_profiler"
-    gem "rack-mini-profiler"
-    gem "rbtrace"
-    gem "stackprof"
-  end
-
-  group :lint do
-    gem "brakeman"
-    gem "easy_translate"
-    gem "erb_lint"
-    gem "i18n-tasks"
-    gem "mdl"
-    gem "rubocop"
-    gem "rubocop-capybara"
-    gem "rubocop-performance"
-    gem "rubocop-rails"
-    gem "rubocop-rspec"
-    gem "rubocop-rspec_rails"
-    gem "sorbet"
-    gem "sorbet-runtime"
-    gem "spoom", require: false
-    gem "tapioca", require: false
-  end
-
-  group :demo, :production do
-    gem "skylight"
-  end
-end
-
-gemspec path: "../"
diff --git a/gemfiles/rails_7.2.gemfile b/gemfiles/rails_7.2.gemfile
new file mode 100644
index 000000000..263d19df3
--- /dev/null
+++ b/gemfiles/rails_7.2.gemfile
@@ -0,0 +1,5 @@
+source "https://rubygems.org"
+
+ENV["RAILS_VERSION"] = "7.2"
+
+eval_gemfile "../Gemfile"
diff --git a/gemfiles/rails_7.2_ruby_3.1.gemfile b/gemfiles/rails_7.2_ruby_3.1.gemfile
deleted file mode 100644
index 81d9081bc..000000000
--- a/gemfiles/rails_7.2_ruby_3.1.gemfile
+++ /dev/null
@@ -1,51 +0,0 @@
-# This file was generated by Appraisal
-
-source "https://rubygems.org"
-
-gem "activerecord-jdbcpostgresql-adapter", platforms: [:jruby]
-gem "appraisal"
-gem "pg", platforms: [:mri, :mingw, :x64_mingw]
-gem "rack", "~> 2.2"
-gem "rails", "~> 7.2.0"
-
-platforms :ruby do
-  gem "bootsnap"
-  gem "dotenv-rails"
-  gem "foreman"
-  gem "gem-release"
-  gem "github_changelog_generator", require: false
-
-  group :debug do
-    gem "activerecord-explain-analyze", require: false
-    gem "benchmark-ips"
-    gem "debug"
-    gem "memory_profiler"
-    gem "rack-mini-profiler"
-    gem "rbtrace"
-    gem "stackprof"
-  end
-
-  group :lint do
-    gem "brakeman"
-    gem "easy_translate"
-    gem "erb_lint"
-    gem "i18n-tasks"
-    gem "mdl"
-    gem "rubocop"
-    gem "rubocop-capybara"
-    gem "rubocop-performance"
-    gem "rubocop-rails"
-    gem "rubocop-rspec"
-    gem "rubocop-rspec_rails"
-    gem "sorbet"
-    gem "sorbet-runtime"
-    gem "spoom", require: false
-    gem "tapioca", require: false
-  end
-
-  group :demo, :production do
-    gem "skylight"
-  end
-end
-
-gemspec path: "../"
diff --git a/gemfiles/rails_8.0.gemfile b/gemfiles/rails_8.0.gemfile
new file mode 100644
index 000000000..87fe17fb3
--- /dev/null
+++ b/gemfiles/rails_8.0.gemfile
@@ -0,0 +1,5 @@
+source "https://rubygems.org"
+
+ENV["RAILS_VERSION"] = "8.0"
+
+eval_gemfile "../Gemfile"
diff --git a/gemfiles/rails_8.0_ruby_3.2.gemfile b/gemfiles/rails_8.0_ruby_3.2.gemfile
deleted file mode 100644
index f3f1fb329..000000000
--- a/gemfiles/rails_8.0_ruby_3.2.gemfile
+++ /dev/null
@@ -1,51 +0,0 @@
-# This file was generated by Appraisal
-
-source "https://rubygems.org"
-
-gem "activerecord-jdbcpostgresql-adapter", platforms: [:jruby]
-gem "appraisal"
-gem "pg", platforms: [:mri, :mingw, :x64_mingw]
-gem "rack", "~> 2.2"
-gem "rails", "~> 8.0.0.a"
-
-platforms :ruby do
-  gem "bootsnap"
-  gem "dotenv-rails"
-  gem "foreman"
-  gem "gem-release"
-  gem "github_changelog_generator", require: false
-
-  group :debug do
-    gem "activerecord-explain-analyze", require: false
-    gem "benchmark-ips"
-    gem "debug"
-    gem "memory_profiler"
-    gem "rack-mini-profiler"
-    gem "rbtrace"
-    gem "stackprof"
-  end
-
-  group :lint do
-    gem "brakeman"
-    gem "easy_translate"
-    gem "erb_lint"
-    gem "i18n-tasks"
-    gem "mdl"
-    gem "rubocop"
-    gem "rubocop-capybara"
-    gem "rubocop-performance"
-    gem "rubocop-rails"
-    gem "rubocop-rspec"
-    gem "rubocop-rspec_rails"
-    gem "sorbet"
-    gem "sorbet-runtime"
-    gem "spoom", require: false
-    gem "tapioca", require: false
-  end
-
-  group :demo, :production do
-    gem "skylight"
-  end
-end
-
-gemspec path: "../"
diff --git a/gemfiles/rails_head.gemfile b/gemfiles/rails_head.gemfile
index d0be1ee60..b9b34c98e 100644
--- a/gemfiles/rails_head.gemfile
+++ b/gemfiles/rails_head.gemfile
@@ -1,51 +1,5 @@
-# This file was generated by Appraisal
-
 source "https://rubygems.org"
 
-gem "activerecord-jdbcpostgresql-adapter", platforms: [:jruby]
-gem "appraisal"
-gem "pg", platforms: [:mri, :mingw, :x64_mingw]
-gem "rack", "~> 2.2"
-gem "rails", branch: "main", git: "https://github.com/rails/rails.git"
-
-platforms :ruby do
-  gem "bootsnap"
-  gem "dotenv-rails"
-  gem "foreman"
-  gem "gem-release"
-  gem "github_changelog_generator", require: false
-
-  group :debug do
-    gem "activerecord-explain-analyze", require: false
-    gem "benchmark-ips"
-    gem "debug"
-    gem "memory_profiler"
-    gem "rack-mini-profiler"
-    gem "rbtrace"
-    gem "stackprof"
-  end
-
-  group :lint do
-    gem "brakeman"
-    gem "easy_translate"
-    gem "erb_lint"
-    gem "i18n-tasks"
-    gem "mdl"
-    gem "rubocop"
-    gem "rubocop-capybara"
-    gem "rubocop-performance"
-    gem "rubocop-rails"
-    gem "rubocop-rspec"
-    gem "rubocop-rspec_rails"
-    gem "sorbet"
-    gem "sorbet-runtime"
-    gem "spoom", require: false
-    gem "tapioca", require: false
-  end
-
-  group :demo, :production do
-    gem "skylight"
-  end
-end
+ENV["RAILS_VERSION"] = "head"
 
-gemspec path: "../"
+eval_gemfile "../Gemfile"