Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .config/cucumber.yml

This file was deleted.

167 changes: 22 additions & 145 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,137 +2,37 @@ name: CI

on:
push:
branches: [ master ]
branches: [ master, "upgrade/**" ]
pull_request:
branches: [ master ]

permissions:
contents: read

jobs:
test:
name: Ruby ${{ matrix.ruby-version }}, ${{ matrix.gemfile }}, PG ${{ matrix.postgres-version }}
name: Ruby ${{ matrix.ruby-version }}, ${{ matrix.gemfile }}
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
ruby-version: ['3.1']
gemfile: [rails_6.1]
postgres-version: ['12']

include:
- ruby-version: '2.1'
gemfile: rails_3.2
postgres-version: 10
- ruby-version: '2.1'
gemfile: rails_4.0
postgres-version: 10
- ruby-version: '2.1'
gemfile: rails_4.1
postgres-version: 10
- ruby-version: '2.1'
gemfile: rails_4.2
postgres-version: 12

- ruby-version: '2.2'
gemfile: rails_3.2
postgres-version: 10
- ruby-version: '2.2'
gemfile: rails_4.0
postgres-version: 10
- ruby-version: '2.2'
gemfile: rails_4.1
postgres-version: 10
- ruby-version: '2.2'
gemfile: rails_4.2
postgres-version: 12
- ruby-version: '2.2'
gemfile: rails_5.0
postgres-version: 12
- ruby-version: '2.2'
gemfile: rails_5.1
postgres-version: 12
- ruby-version: '2.2'
gemfile: rails_5.2
postgres-version: 12

- ruby-version: '2.3'
gemfile: rails_3.2
postgres-version: 10
- ruby-version: '2.3'
gemfile: rails_4.2
postgres-version: 12
- ruby-version: '2.3'
gemfile: rails_5.0
postgres-version: 12
- ruby-version: '2.3'
gemfile: rails_5.1
postgres-version: 12
- ruby-version: '2.3'
gemfile: rails_5.2
postgres-version: 12

- ruby-version: '2.4'
gemfile: rails_4.2
postgres-version: 12
- ruby-version: '2.4'
gemfile: rails_5.0
postgres-version: 12
- ruby-version: '2.4'
gemfile: rails_5.1
postgres-version: 12
- ruby-version: '2.4'
gemfile: rails_5.2
postgres-version: 12

- ruby-version: '2.5'
gemfile: rails_5.0
postgres-version: 12
- ruby-version: '2.5'
gemfile: rails_5.1
postgres-version: 12
- ruby-version: '2.5'
gemfile: rails_5.2
postgres-version: 12
- ruby-version: '2.5'
gemfile: rails_6.0
postgres-version: 12
- ruby-version: '2.5'
gemfile: rails_6.1
postgres-version: 12

- ruby-version: '2.6'
gemfile: rails_5.0
postgres-version: 12
- ruby-version: '2.6'
gemfile: rails_5.1
postgres-version: 12
- ruby-version: '2.6'
gemfile: rails_5.2
postgres-version: 12
- ruby-version: '2.6'
gemfile: rails_6.0
postgres-version: 12
- ruby-version: '2.6'
gemfile: rails_6.1
postgres-version: 12

- ruby-version: '2.7'
gemfile: rails_5.2
postgres-version: 12
- ruby-version: '2.7'
gemfile: rails_6.0
postgres-version: 12
- ruby-version: '2.7'
gemfile: rails_6.1
postgres-version: 12

- ruby-version: '3.0'
gemfile: rails_6.0
postgres-version: 12
- ruby-version: '3.0'
gemfile: rails_6.1
postgres-version: 12
# upgrade target
- { ruby-version: '4.0.5', gemfile: rails_8.1 }
- { ruby-version: '3.4', gemfile: rails_8.1 }
- { ruby-version: '3.4', gemfile: rails_8.0 }
- { ruby-version: '3.4', gemfile: rails_7.2 }
- { ruby-version: '3.3', gemfile: rails_7.1 }
- { ruby-version: '3.3', gemfile: rails_7.0 }
# backward compat — explicit Vxx modules. i18n < 1.15 and cucumber 8.x
# are held back (gemspec) for Ruby < 3.2 / < 3.0. Ruby 2.1–2.6 are not
# tested: Bundler 2 needs Ruby >= 2.3 and 2.3–2.6 no longer assemble on
# current runners.
- { ruby-version: '3.2', gemfile: rails_6.1 }
- { ruby-version: '3.1', gemfile: rails_6.1 }
- { ruby-version: '3.0', gemfile: rails_6.1 }
- { ruby-version: '2.7', gemfile: rails_6.1 }
- { ruby-version: '2.7', gemfile: rails_5.2 }

env:
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
Expand All @@ -143,40 +43,17 @@ jobs:

- uses: ankane/setup-postgres@v1
with:
postgres-version: ${{ matrix.postgres-version }}
postgres-version: 16
database: eaco

- name: Decide RubyGems
id: setup-params
run: |
rv="${{ matrix.ruby-version }}"
gf="${{ matrix.gemfile }}"

# Default RubyGems
rubygems=default

# Only for:
# - Ruby 2.3 + rails_3.2
# - Ruby 2.3 + rails_4.2
# - Ruby 2.4 + rails_4.2
if { [ "$rv" = "2.3" ] && { [ "$gf" = "rails_3.2" ] || [ "$gf" = "rails_4.2" ]; }; } ||
{ [ "$rv" = "2.4" ] && [ "$gf" = "rails_4.2" ]; }; then
rubygems=2.7.11
fi

echo "version=$rubygems" >> "$GITHUB_OUTPUT"

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true
rubygems: ${{ steps.setup-params.outputs.version }}

- name: Run Specs
run: |
bundle exec rspec
run: bundle exec rspec

- name: Run Cucumber features
run: |
bundle exec cucumber -f pretty
run: bundle exec cucumber -f progress
42 changes: 42 additions & 0 deletions .github/workflows/smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Smoke

# Fast, Postgres-free authorization smoke for the Ruby 4 / Rails 8.1 upgrade.
# The full pg + cucumber matrix lives in ci.yml; this proves the compatibility
# layer installs and Actor#can? resolves on the new stack (and still on the old
# one) using an in-memory ACL over sqlite.

on:
push:
branches: [ master, "upgrade/**" ]
pull_request:

permissions:
contents: read

jobs:
smoke:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
# upgrade target
- { ruby: "4.0.5", rails: "~> 8.1.0" }
- { ruby: "3.4", rails: "~> 8.1.0" }
- { ruby: "3.4", rails: "~> 7.2.0" }
# backward compat — consumers still on the old stack (explicit V61
# support module, sqlite3 1.4 for Ruby 2.7)
- { ruby: "2.7", rails: "~> 6.1.0", sqlite3: "~> 1.4.0" }
name: "ruby ${{ matrix.ruby }} / rails ${{ matrix.rails }}"
env:
BUNDLE_GEMFILE: test/Gemfile.ci
RAILS_VERSION: ${{ matrix.rails }}
SQLITE3_VERSION: ${{ matrix.sqlite3 }}
steps:
- uses: actions/checkout@v6
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Smoke (authorize on the version stack)
run: bundle exec ruby test/smoke.rb
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ build-iPhoneSimulator/
# for a library or gem, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
Gemfile.lock
test/*.lock
.ruby-version
.ruby-gemset

Expand All @@ -64,3 +65,6 @@ spec/debug.log

features/active_record.yml
features/active_record.log

# Local-only Ruby 4.0.5 smoke runner (AI scratch) — not committed
Dockerfile.ai
8 changes: 8 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,11 @@ end
appraise 'rails-7.2' do
gem 'rails', '~> 7.2.0'
end

appraise 'rails-8.0' do
gem 'rails', '~> 8.0.0'
end

appraise 'rails-8.1' do
gem 'rails', '~> 8.1.0'
end
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ project adheres to [Semantic Versioning](https://semver.org/)
- Remove curly braces from `@see` tags (causes rendering issues)
- Use fully-qualified constant names for `ACL#find_by_role` references (`Eaco::ACL#find_by_role`)

## 1.2.0 - 2026-06-18

### Added
* Rails 8.1 / Ruby 4.0.5 support.
* `Adapters::ActiveRecord::Compatibility::Modern` support module, used for
every Active Record major >= 7. Previously the compatibility layer raised
"Unsupported Active Record version" on anything past 6.1; new Rails majors
no longer require an identical per-version `Vxx` module.
* Self-contained smoke harness (`test/smoke.rb`) plus a CI matrix sweeping
Ruby 4.0.5/3.4/2.7 across Rails 8.1/7.2/6.1.

## 1.1.1 - 2017-03-08

### Fixed
Expand Down
20 changes: 19 additions & 1 deletion eaco.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,30 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "appraisal"
spec.add_development_dependency "rspec"
spec.add_development_dependency "guard-rspec"
spec.add_development_dependency "cucumber"
# Pin cucumber: unpinned, the resolver picks wildly different versions per row
# (10.x on some, the ancient 3.2.0 on Ruby 4) — 3.2.0 needs ostruct and the
# profile ERB path breaks on Ruby 3.4. ~> 9.2 is consistent and Ruby-4 clean,
# but cucumber 9 needs Ruby >= 3.0; the 2.7 row uses the last 8.x line.
if RUBY_VERSION >= '3.0'
spec.add_development_dependency "cucumber", "~> 9.2"
else
spec.add_development_dependency "cucumber", "~> 8.0"
end
spec.add_development_dependency "guard-cucumber"
spec.add_development_dependency "yard-cucumber"
spec.add_development_dependency "coveralls"
spec.add_development_dependency "guard-shell"
spec.add_development_dependency "multi_json"
spec.add_development_dependency "rails"
spec.add_development_dependency "pg"
# Left the default gems on Ruby 3.4+ — declare them there (and only there, so
# older rows don't pull a Ruby-3+ build of them).
if RUBY_VERSION >= '3.4'
spec.add_development_dependency "ostruct"
spec.add_development_dependency "base64"
spec.add_development_dependency "bigdecimal"
end
# i18n 1.15 uses Fiber storage (needs Ruby 3.2+); hold it back on the older
# backward-compat rows so Rails 6.1 boots there.
spec.add_development_dependency "i18n", "< 1.15" if RUBY_VERSION < '3.2'
end
2 changes: 1 addition & 1 deletion features/authorization_parse_error.feature
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Feature: Authorization rules error handling
"""
Then I should receive a DSL error SyntaxError saying
"""
\(feature\):1: syntax error, unexpected '=', expecting end-of-input
\(feature\):1:.+unexpected '='
"""

Scenario: Referencing a non-existing model
Expand Down
7 changes: 7 additions & 0 deletions gemfiles/rails_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: "../"
7 changes: 7 additions & 0 deletions gemfiles/rails_8.1.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.1.0"

gemspec path: "../"
29 changes: 23 additions & 6 deletions lib/eaco/adapters/active_record/compatibility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class Compatibility
autoload :V60, 'eaco/adapters/active_record/compatibility/v60.rb'
autoload :V61, 'eaco/adapters/active_record/compatibility/v61.rb'

autoload :Modern, 'eaco/adapters/active_record/compatibility/modern.rb'

autoload :Scoped, 'eaco/adapters/active_record/compatibility/scoped.rb'
autoload :Sanitized, 'eaco/adapters/active_record/compatibility/sanitized.rb'

Expand Down Expand Up @@ -66,13 +68,28 @@ def active_record_version
# @see check!
#
def support_module
unless self.class.const_defined?(support_module_name)
raise Eaco::Error, <<-EOF
Unsupported Active Record version: #{active_record_version}
EOF
end
return self.class.const_get(support_module_name) if
self.class.const_defined?(support_module_name)

# No exact Vxx module: Active Record 7.0+ all share the same
# requirements, so fall back to {Modern} rather than raising on every
# new Rails release. Genuinely unknown/old versions still raise.
# The major is taken from the looked-up version (so a stubbed
# active_record_version is honoured), not the live constant.
return Modern if active_record_major >= 7

raise Eaco::Error, <<-EOF
Unsupported Active Record version: #{active_record_version}
EOF
end

self.class.const_get support_module_name
##
# @return [Integer] the major of the {#active_record_version} being
# looked up. The minor is always a single digit in Rails, so the
# major is everything but the last character of the joined version.
#
def active_record_major
active_record_version.to_s[0..-2].to_i
end

##
Expand Down
Loading