Skip to content

Commit

Permalink
Support Rails 8.0 (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
olivier-thatch authored Nov 12, 2024
1 parent 9593738 commit cd3c36a
Show file tree
Hide file tree
Showing 55 changed files with 1,418 additions and 13 deletions.
18 changes: 11 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ version: 2.1
jobs:
lint:
docker:
- image: cimg/ruby:3.1.5
- image: cimg/ruby:3.1.6
working_directory: ~/safer_rails_console
steps:
- checkout
- restore_cache:
keys:
- v2-gems-ruby-3.1.5-{{ checksum "safer_rails_console.gemspec" }}-{{ checksum "Gemfile" }}
- v2-gems-ruby-3.1.5-
- v2-gems-ruby-3.1.6-{{ checksum "safer_rails_console.gemspec" }}-{{ checksum "Gemfile" }}
- v2-gems-ruby-3.1.6-
- run:
name: Install Gems
command: |
Expand All @@ -18,7 +18,7 @@ jobs:
bundle clean
fi
- save_cache:
key: v2-gems-ruby-3.1.5-{{ checksum "safer_rails_console.gemspec" }}-{{ checksum "Gemfile" }}
key: v2-gems-ruby-3.1.6-{{ checksum "safer_rails_console.gemspec" }}-{{ checksum "Gemfile" }}
paths:
- "vendor/bundle"
- "gemfiles/vendor/bundle"
Expand Down Expand Up @@ -82,11 +82,15 @@ workflows:
matrix:
parameters:
ruby_version:
- 3.1.4
- 3.2.2
- 3.3.0
- 3.1.6
- 3.2.6
- 3.3.6
gemfile:
- gemfiles/6.1.gemfile
- gemfiles/7.0.gemfile
- gemfiles/7.1.gemfile
- gemfiles/7.2.gemfile
- gemfiles/8.0.gemfile
exclude:
- ruby_version: 3.1.6
gemfile: gemfiles/8.0.gemfile
4 changes: 4 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ end
appraise '7.2' do
gem 'rails', '~> 7.2.0'
end

appraise '8.0' do
gem 'rails', '~> 8.0.0'
end
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## v0.11.0
- Add support for Rails 8.0. **Thanks [@olivier-thatch](https://github.com/olivier-thatch)**

## v0.10.0
- Drop support for Ruby 3.0.
- Add support for Rails 7.2. **Thanks [@kwent](https://github.com/kwent)**
Expand Down
7 changes: 7 additions & 0 deletions gemfiles/8.0.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "rails", "~> 8.0.0"

gemspec path: "../"
38 changes: 34 additions & 4 deletions lib/safer_rails_console/patches/sandbox/auto_rollback.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,19 @@ def self.handle_and_reraise_exception(error, message = 'PG::ReadOnlySqlTransacti
raise error
end

module PostgreSQLAdapterPatch
# Patch for the PostgreSQL database adapter for Rails 8.0 and above.
module PostgreSQLAdapteRailsPatch
def internal_execute(...)
super
rescue StandardError => e
# rubocop:disable Layout/LineLength
SaferRailsConsole::Patches::Sandbox::AutoRollback.handle_and_reraise_exception(e, 'PG::ReadOnlySqlTransaction')
# rubocop:enable Layout/LineLength
end
end

# Patch for the PostgreSQL database adapter for Rails 6.x and 7.x.
module LegacyPostgreSQLAdapteRailsPatch
def execute_and_clear(...)
super
rescue StandardError => e
Expand All @@ -35,10 +47,24 @@ def execute_and_clear(...)
end

if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(PostgreSQLAdapterPatch)
if SaferRailsConsole::RailsVersion.eight_or_above?
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(PostgreSQLAdapteRailsPatch)
elsif SaferRailsConsole::RailsVersion.six_or_above?
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(LegacyPostgreSQLAdapteRailsPatch)
end
end

# Patch for the MySQL database adapter for Rails 8.0 and above.
module MySQLAdapterRailsPatch
def internal_execute(...)
super
rescue StandardError => e
SaferRailsConsole::Patches::Sandbox::AutoRollback.handle_and_reraise_exception(e, 'READ ONLY transaction')
end
end

module MySQLPatch
# Patch for the MySQL database adapter for Rails 6.x and 7.x.
module LegacyMySQLAdapterRails67Patch
def execute_and_free(...)
super
rescue StandardError => e
Expand All @@ -47,7 +73,11 @@ def execute_and_free(...)
end

if defined?(::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter)
::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.prepend(MySQLPatch)
if SaferRailsConsole::RailsVersion.eight_or_above?
::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.prepend(MySQLAdapterRailsPatch)
elsif SaferRailsConsole::RailsVersion.six_or_above?
::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.prepend(LegacyMySQLAdapterRails67Patch)
end
end
end
end
Expand Down
6 changes: 6 additions & 0 deletions lib/safer_rails_console/rails_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ def six_or_above?

@six_or_above = SaferRailsConsole::RailsVersion::RAILS_VERSION >= ::Gem::Version.new('6.0.0')
end

def eight_or_above?
return @eight_or_above if defined?(@eight_or_above)

@eight_or_above = SaferRailsConsole::RailsVersion::RAILS_VERSION >= ::Gem::Version.new('8.0.0')
end
end
end
end
2 changes: 1 addition & 1 deletion lib/safer_rails_console/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module SaferRailsConsole
VERSION = '0.10.0'
VERSION = '0.11.0'
end
2 changes: 1 addition & 1 deletion safer_rails_console.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rspec_junit_formatter'
spec.add_development_dependency 'salsify_rubocop', '~> 1.27.0'

spec.add_runtime_dependency 'rails', '>= 6.1', '< 7.3'
spec.add_runtime_dependency 'rails', '>= 6.1', '< 8.1'
end
38 changes: 38 additions & 0 deletions spec/internal/rails_8_0/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.

# Ignore git directory.
/.git/
/.gitignore

# Ignore bundler config.
/.bundle

# Ignore all environment files.
/.env*

# Ignore all default key files.
/config/master.key
/config/credentials/*.key

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*

# Ignore storage (uploaded files in development and any SQLite databases).
/storage/*

# Ignore assets.
/node_modules/
/app/assets/builds/*
!/app/assets/builds/.keep
/public/assets

# Ignore CI service files.
/.github

# Ignore development files
/.devcontainer

# Ignore Docker-related files
/.dockerignore
/Dockerfile*
9 changes: 9 additions & 0 deletions spec/internal/rails_8_0/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# See https://git-scm.com/docs/gitattributes for more about git attribute files.

# Mark the database schema as having been generated.
db/schema.rb linguist-generated

# Mark any vendored files as having been vendored.
vendor/* linguist-vendored
config/credentials/*.yml.enc diff=rails_credentials
config/credentials.yml.enc diff=rails_credentials
23 changes: 23 additions & 0 deletions spec/internal/rails_8_0/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# Temporary files generated by your text editor or operating system
# belong in git's global ignore instead:
# `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore`

# Ignore bundler config.
/.bundle

# Ignore all environment files.
/.env*

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*

# Ignore storage (uploaded files in development and any SQLite databases).
/storage/*

/public/assets

# Ignore master key for decrypting credentials and more.
/config/master.key
65 changes: 65 additions & 0 deletions spec/internal/rails_8_0/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# syntax=docker/dockerfile:1
# check=error=true

# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
# docker build -t rails_8_0 .
# docker run -d -p 80:80 -e RAILS_MASTER_KEY=<value from config/master.key> --name rails_8_0 rails_8_0

# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.3.5
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base

# Rails app lives here
WORKDIR /rails

# Install base packages
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl libjemalloc2 postgresql-client && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development"

# Throw-away build stage to reduce size of final image
FROM base AS build

# Install packages needed to build gems
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git libpq-dev pkg-config && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git

# Copy application code
COPY . .




# Final stage for app image
FROM base

# Copy built artifacts: gems, application
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails

# Run and own only the runtime files as a non-root user for security
RUN groupadd --system --gid 1000 rails && \
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
chown -R rails:rails db log tmp
USER 1000:1000

# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start server via Thruster by default, this can be overwritten at runtime
EXPOSE 80
CMD ["./bin/thrust", "./bin/rails", "server"]
14 changes: 14 additions & 0 deletions spec/internal/rails_8_0/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

# Generated with:
# rails new -JABTCM --skip-keeps --skip-active-storage --skip-system-test --skip-bootsnap --skip-hotwire -d postgresql spec/internal/rails_8_0
# Then modified to match the others

source "https://rubygems.org"

gem "mysql2"
gem "pg"
gem "rails", "~> 8.0.0"


gem 'safer_rails_console', path: '../../../'
24 changes: 24 additions & 0 deletions spec/internal/rails_8_0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# README

This README would normally document whatever steps are necessary to get the
application up and running.

Things you may want to cover:

* Ruby version

* System dependencies

* Configuration

* Database creation

* Database initialization

* How to run the test suite

* Services (job queues, cache servers, search engines, etc.)

* Deployment instructions

* ...
6 changes: 6 additions & 0 deletions spec/internal/rails_8_0/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require_relative "config/application"

Rails.application.load_tasks
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* Application styles */
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class ApplicationController < ActionController::Base
# Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
allow_browser versions: :modern
end
2 changes: 2 additions & 0 deletions spec/internal/rails_8_0/app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module ApplicationHelper
end
7 changes: 7 additions & 0 deletions spec/internal/rails_8_0/app/jobs/application_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class ApplicationJob < ActiveJob::Base
# Automatically retry jobs that encountered a deadlock
# retry_on ActiveRecord::Deadlocked

# Most jobs are safe to ignore if the underlying records are no longer available
# discard_on ActiveJob::DeserializationError
end
3 changes: 3 additions & 0 deletions spec/internal/rails_8_0/app/models/application_record.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
end
4 changes: 4 additions & 0 deletions spec/internal/rails_8_0/app/models/model.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class Model < ApplicationRecord
end
27 changes: 27 additions & 0 deletions spec/internal/rails_8_0/app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<title><%= content_for(:title) || "Rails 8 0" %></title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= yield :head %>
<%# Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!) %>
<%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %>

<link rel="icon" href="/icon.png" type="image/png">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/icon.png">

<%# Includes all stylesheet files in app/assets/stylesheets %>
<%= stylesheet_link_tag "application" %>
</head>

<body>
<%= yield %>
</body>
</html>
Loading

0 comments on commit cd3c36a

Please sign in to comment.