Skip to content

Make aasm compiler v6.0 aware#2672

Open
allan-thatch wants to merge 3 commits into
Shopify:mainfrom
thatch-health:aasm-6.0
Open

Make aasm compiler v6.0 aware#2672
allan-thatch wants to merge 3 commits into
Shopify:mainfrom
thatch-health:aasm-6.0

Conversation

@allan-thatch

@allan-thatch allan-thatch commented Jul 14, 2026

Copy link
Copy Markdown

Motivation

Fixes #2671. Also see "Migrating from AASM version 5 to 6".

Implementation

The aasm compiler now (a) withholds plain methods when namespaced and on v6 and (b) adds the namespaced _without_validation! method when on v6.

Tests

I updated the compiler test to accommodate both >v6.0 and <=v6.0 paths

@allan-thatch
allan-thatch requested a review from a team as a code owner July 14, 2026 23:20
@allan-thatch

Copy link
Copy Markdown
Author

I have signed the CLA!


sig { params(opts: T.untyped, block: T.nilable(T.proc.void)).returns(T.untyped) }
def run_without_validation!(*opts, &block); end
def run_foo_without_validation!(*opts, &block); end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Since this version is brand new, I'd prefer if we kept older tests, we have a similar pattern in here. It is then executed as ERB in here.

I think you can define a similar helper in this file:

def aasm_version(selector)
  ::Gem::Requirement.new(selector).satisfied_by?(::Gem::Version.new(::AASM::VERSION))
end

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, perfect! Thanks for linking those. Updated!

@allan-thatch allan-thatch Jul 21, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm realizing now that there's no tooling currently (like Rails in the CI matrix) that actually installs and drives the test suite for the older version of aasm. I'll push up a commit to stub this out in tests vs. adding another variant to the test matrix (this seemed heavy, and not quite on the same level as Ruby/Rails). I've included sample implementations for both below, so LMK if you'd prefer the other!

Test matrix
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cc6424c9..7f487af6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -44,6 +44,7 @@ jobs:
         ruby: ["3.2", "3.3", "3.4", "4.0","head"]
         rails: ["8.0", "current", "main"]
         rubygems: ["4.0.10"]
+        aasm: ["current"]
         exclude:
           - ruby: "3.2"
             rails: "main"
@@ -52,9 +53,13 @@ jobs:
             experimental: true
           - ruby: "head"
             experimental: true
-    name: Ruby ${{ matrix.ruby }} - Rails ${{ matrix.rails }} - RubyGems ${{ matrix.rubygems }}
+          - ruby: "3.4"
+            rails: "current"
+            aasm: "5.5"
+    name: Ruby ${{ matrix.ruby }} - Rails ${{ matrix.rails }} - RubyGems ${{ matrix.rubygems }} - AASM ${{ matrix.aasm }}
     env:
       RAILS_VERSION: ${{ matrix.rails }}
+      AASM_VERSION: ${{ matrix.aasm }}
     steps:
       - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
       - name: Install protobuf
diff --git a/Gemfile b/Gemfile
index 43b343c3..83e695fa 100644
--- a/Gemfile
+++ b/Gemfile
@@ -7,6 +7,8 @@ gemspec
 CURRENT_RAILS_VERSION = "8.1"
 rails_version = ENV.fetch("RAILS_VERSION", CURRENT_RAILS_VERSION)
 
+aasm_version = ENV.fetch("AASM_VERSION", "current")
+
 gem "minitest"
 gem "minitest-hooks"
 gem "minitest-reporters"
@@ -52,7 +54,11 @@ group :development, :test do
   gem "sidekiq"
   gem "nokogiri"
   gem "config"
-  gem "aasm"
+  if aasm_version == "current"
+    gem "aasm"
+  else
+    gem "aasm", "~> #{aasm_version}"
+  end
   gem "bcrypt"
   gem "xpath"
   gem "kredis"
Test stub/helper
diff --git a/spec/tapioca/dsl/compilers/aasm_spec.rb b/spec/tapioca/dsl/compilers/aasm_spec.rb
index 52aebda2..d6df99e2 100644
--- a/spec/tapioca/dsl/compilers/aasm_spec.rb
+++ b/spec/tapioca/dsl/compilers/aasm_spec.rb
@@ -14,6 +14,17 @@ module Tapioca
             require "aasm"
           end
 
+          # Runs the block with `AASM::VERSION` stubbed, so both the aasm < 6 and
+          # aasm >= 6 code paths can be exercised regardless of the installed version.
+          #: (String version) { -> void } -> void
+          def with_aasm_version(version, &block)
+            original = ::AASM::VERSION
+            ::Tapioca::Runtime.silence_warnings { ::AASM.const_set(:VERSION, version) }
+            block.call
+          ensure
+            ::Tapioca::Runtime.silence_warnings { ::AASM.const_set(:VERSION, original) }
+          end
+
           describe "initialize" do
             it "gathers no constants if there are no classes that include AASM" do
               assert_empty(gathered_constants)
@@ -345,7 +356,7 @@ module Tapioca
                 end
               RUBY
 
-              expected = template(<<~RBI)
+              rbi = <<~RBI
                 # typed: strong
 
                 class StateMachine
@@ -476,7 +487,14 @@ module Tapioca
                 end
               RBI
 
-              assert_equal(expected, rbi_for(:StateMachine))
+              # Assert against the currently installed aasm version.
+              assert_equal(template(rbi), rbi_for(:StateMachine))
+
+              # Also exercise the aasm < 6 code path, which no longer matches the
+              # installed version once aasm >= 6 is in use.
+              with_aasm_version("5.5.2") do
+                assert_equal(template(rbi), rbi_for(:StateMachine))
+              end
             end
           end
         end

@allan-thatch
allan-thatch requested a review from KaanOzkan July 20, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

aasm 6.0 compiler emits non-existent event methods for namespaced state machines

2 participants