From abbb2937fcfbe32c0023087ea2790d482da9e5be Mon Sep 17 00:00:00 2001 From: Sascha Karnatz <68833+kulturbande@users.noreply.github.com> Date: Sun, 10 May 2026 15:43:32 +0200 Subject: [PATCH] Require at least AlchemyCMS v8.2.0 It is necessary to increase the minimal allowed Alchemy version to resolve the configuration deprecation notices (will be added in the next PR). Adjust also the test matrix and update the dummy migrations to align the AlchemyCMS 8.2 requirements. --- .github/workflows/test.yml | 10 ++---- Gemfile | 9 ++---- alchemy-solid_errors.gemspec | 2 +- spec/dummy/config/initializers/alchemy.rb | 10 +++--- spec/dummy/config/initializers/devise.rb | 13 ++++---- ..._add_rememberable_column.alchemy_devise.rb | 6 ++++ ...imezone_to_alchemy_users.alchemy_devise.rb | 7 +++++ ...nvert_select_value_for_multiple.alchemy.rb | 12 +++++++ ...1_add_metadata_to_page_versions.alchemy.rb | 10 ++++++ ..._timestamps_to_alchemy_elements.alchemy.rb | 31 +++++++++++++++++++ ..._element_publication_timestamps.alchemy.rb | 14 +++++++++ spec/dummy/db/schema.rb | 10 +++++- 12 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 spec/dummy/db/migrate/20260510133828_add_rememberable_column.alchemy_devise.rb create mode 100644 spec/dummy/db/migrate/20260510133829_add_timezone_to_alchemy_users.alchemy_devise.rb create mode 100644 spec/dummy/db/migrate/20260510133910_convert_select_value_for_multiple.alchemy.rb create mode 100644 spec/dummy/db/migrate/20260510133911_add_metadata_to_page_versions.alchemy.rb create mode 100644 spec/dummy/db/migrate/20260510133912_add_publication_timestamps_to_alchemy_elements.alchemy.rb create mode 100644 spec/dummy/db/migrate/20260510133913_add_index_to_element_publication_timestamps.alchemy.rb diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a114306..83da08c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,18 +12,12 @@ jobs: fail-fast: false matrix: include: - - alchemy_cms: "7.4" + - alchemy_cms: "8.2" rails: "7.2" ruby: "3.3" - - alchemy_cms: "7.4" - rails: "8.0" - ruby: "3.4" - - alchemy_cms: "8.0" + - alchemy_cms: "8.2" rails: "8.0" ruby: "3.4" - - alchemy_cms: "8.1" - rails: "8.1" - ruby: "3.4" - alchemy_cms: "8.2" rails: "8.1" ruby: "3.4" diff --git a/Gemfile b/Gemfile index 40dab72..636730e 100644 --- a/Gemfile +++ b/Gemfile @@ -2,15 +2,12 @@ source "https://rubygems.org" gem "puma" gem "sqlite3" +gem "propshaft" -alchemy_cms_version = ENV.fetch("ALCHEMY_CMS_VERSION", "8.0") -if alchemy_cms_version.start_with?("8.") - gem "propshaft" -end +alchemy_cms_version = ENV.fetch("ALCHEMY_CMS_VERSION", "8.2") gem "alchemy_cms", "~> #{alchemy_cms_version}" -devise_version = (Gem::Version.new(alchemy_cms_version) >= Gem::Version.new("8.0")) ? "8.0" : alchemy_cms_version -gem "alchemy-devise", "~> #{devise_version}" +gem "alchemy-devise", "~> #{alchemy_cms_version}" # Specify your gem's dependencies in alchemy-solid_errors.gemspec. gemspec diff --git a/alchemy-solid_errors.gemspec b/alchemy-solid_errors.gemspec index 692c308..acac3bf 100644 --- a/alchemy-solid_errors.gemspec +++ b/alchemy-solid_errors.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |spec| end spec.add_dependency "rails", ">= 7.2.0", "< 9.0" - spec.add_dependency "alchemy_cms", ">= 7.4.0", "< 9.0" + spec.add_dependency "alchemy_cms", ">= 8.2.0", "< 9.0" spec.add_dependency "solid_errors", ">= 0.7", "< 1.0" spec.add_development_dependency "capybara", ["~> 3.0"] diff --git a/spec/dummy/config/initializers/alchemy.rb b/spec/dummy/config/initializers/alchemy.rb index c9931ad..29e8350 100644 --- a/spec/dummy/config/initializers/alchemy.rb +++ b/spec/dummy/config/initializers/alchemy.rb @@ -1,5 +1,3 @@ -return unless Alchemy::VERSION.start_with?("8.") - Alchemy.configure do |config| # == This is the global Alchemy configuration file # @@ -51,8 +49,8 @@ # config.preview = { # host: https://www.my-static-site.com # auth: - # username: <%= ENV["BASIC_AUTH_USERNAME"] %%> - # password: <%= ENV["BASIC_AUTH_PASSWORD"] %%> + # username: <%= ENV["BASIC_AUTH_USERNAME"] %> + # password: <%= ENV["BASIC_AUTH_PASSWORD"] %> # } # Preview config per site is supported as well. # @@ -60,8 +58,8 @@ # My site name: # host: https://www.my-static-site.com # auth: - # username: <%= ENV["BASIC_AUTH_USERNAME"] %%> - # password: <%= ENV["BASIC_AUTH_PASSWORD"] %%> + # username: <%= ENV["BASIC_AUTH_USERNAME"] %> + # password: <%= ENV["BASIC_AUTH_PASSWORD"] %> # } # === Picture rendering settings diff --git a/spec/dummy/config/initializers/devise.rb b/spec/dummy/config/initializers/devise.rb index 8dabbc5..dc71ce9 100644 --- a/spec/dummy/config/initializers/devise.rb +++ b/spec/dummy/config/initializers/devise.rb @@ -14,7 +14,7 @@ # confirmation, reset password and unlock tokens in the database. # Devise will use the `secret_key_base` as its `secret_key` # by default. You can change it below and use your own secret key. - # config.secret_key = 'ae1026cf46a6d966db7905354bcf688870b1a81baf29ac316383bd9e10968ec08c6b22df66f4a856613e9961184c028221a78e5b9315c7f93b99695ca2a168a2' + # config.secret_key = '97c0164b69e9a67f2e51cb4709d1144c74e3ec50acab7a1eff7d72beceb83e4a7882bfe919e8e278412ad360261e57033ae95b54b8afcfb8593ad1052bbf6545' # ==> Controller configuration # Configure the parent class to the devise controllers. @@ -24,8 +24,7 @@ # Configure the e-mail address which will be shown in Devise::Mailer, # note that it will be overwritten if you use your own mailer class # with default "from" parameter. - alchemy_config = Alchemy::VERSION.start_with?("8.") ? Alchemy.config : Alchemy::Config - config.mailer_sender = alchemy_config.get(:mailer)["mail_from"] + config.mailer_sender = Alchemy.config.mailer.mail_from # Configure the class responsible to send e-mails. config.mailer = "Alchemy::Notifications" @@ -91,7 +90,7 @@ # It will change confirmation, password recovery and other workflows # to behave the same regardless if the e-mail provided was right or wrong. # Does not affect registerable. - # config.paranoid = true + config.paranoid = true # By default Devise will store the user in session. You can skip storage for # particular strategies by setting this option. @@ -127,7 +126,7 @@ config.stretches = Rails.env.test? ? 1 : 12 # Set up a pepper to generate the hashed password. - # config.pepper = '396758d90aba93d3f5f9cdad801782194211a3c77e24c36e24c00308e29853739f675c34f05a8a99e6f79292af8f9bf43a02e0af549e2ea3be53a3ca61c49a45' + # config.pepper = 'd04079d1f21db3f5e441a507c61666698da7d090e21dcc414e72e4998509e08cdc954690ffc964f83afffda313b09dd0ba04751d15d5de8d96aa97ce26a44161' # Send a notification to the original email when the user's email is changed. # config.send_email_changed_notification = false @@ -189,7 +188,7 @@ # ==> Configuration for :timeoutable # The time you want to timeout the user session without activity. After this # time the user will be asked for credentials again. Default is 30 minutes. - config.timeout_in = Rails.env.development? ? nil : alchemy_config.get(:auto_logout_time).minutes + config.timeout_in = Rails.env.development? ? nil : Alchemy.config.auto_logout_time.minutes # ==> Configuration for :lockable # Defines which strategy will be used to lock an account. @@ -303,7 +302,7 @@ # apps is `200 OK` and `302 Found` respectively, but new apps are generated with # these new defaults that match Hotwire/Turbo behavior. # Note: These might become the new default in future versions of Devise. - config.responder.error_status = :unprocessable_entity + config.responder.error_status = :unprocessable_content config.responder.redirect_status = :see_other # ==> Configuration for :registerable diff --git a/spec/dummy/db/migrate/20260510133828_add_rememberable_column.alchemy_devise.rb b/spec/dummy/db/migrate/20260510133828_add_rememberable_column.alchemy_devise.rb new file mode 100644 index 0000000..161b064 --- /dev/null +++ b/spec/dummy/db/migrate/20260510133828_add_rememberable_column.alchemy_devise.rb @@ -0,0 +1,6 @@ +# This migration comes from alchemy_devise (originally 20251127170649) +class AddRememberableColumn < ActiveRecord::Migration[7.1] + def change + add_column :alchemy_users, :remember_created_at, :datetime, if_not_exists: true + end +end diff --git a/spec/dummy/db/migrate/20260510133829_add_timezone_to_alchemy_users.alchemy_devise.rb b/spec/dummy/db/migrate/20260510133829_add_timezone_to_alchemy_users.alchemy_devise.rb new file mode 100644 index 0000000..7583d81 --- /dev/null +++ b/spec/dummy/db/migrate/20260510133829_add_timezone_to_alchemy_users.alchemy_devise.rb @@ -0,0 +1,7 @@ +# This migration comes from alchemy_devise (originally 20260410115756) +class AddTimezoneToAlchemyUsers < ActiveRecord::Migration[7.2] + def change + add_column :alchemy_users, :timezone, :string, if_not_exists: true, + comment: "The timezone of the user, used for displaying dates in the user's timezone" + end +end diff --git a/spec/dummy/db/migrate/20260510133910_convert_select_value_for_multiple.alchemy.rb b/spec/dummy/db/migrate/20260510133910_convert_select_value_for_multiple.alchemy.rb new file mode 100644 index 0000000..837c8f8 --- /dev/null +++ b/spec/dummy/db/migrate/20260510133910_convert_select_value_for_multiple.alchemy.rb @@ -0,0 +1,12 @@ +# This migration comes from alchemy (originally 20251106150010) +class ConvertSelectValueForMultiple < ActiveRecord::Migration[7.1] + def up + say_with_time "Converting Alchemy::Ingredients::Select values to multiple" do + update <<-SQL.squish + UPDATE alchemy_ingredients + SET value = '["' || value || '"]' + WHERE type = 'Alchemy::Ingredients::Select' AND value NOT LIKE '["%"]'; + SQL + end + end +end diff --git a/spec/dummy/db/migrate/20260510133911_add_metadata_to_page_versions.alchemy.rb b/spec/dummy/db/migrate/20260510133911_add_metadata_to_page_versions.alchemy.rb new file mode 100644 index 0000000..9adc6ce --- /dev/null +++ b/spec/dummy/db/migrate/20260510133911_add_metadata_to_page_versions.alchemy.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20260102121232) +class AddMetadataToPageVersions < ActiveRecord::Migration[7.2] + def change + add_column :alchemy_page_versions, :title, :string + add_column :alchemy_page_versions, :meta_description, :text + add_column :alchemy_page_versions, :meta_keywords, :text + end +end diff --git a/spec/dummy/db/migrate/20260510133912_add_publication_timestamps_to_alchemy_elements.alchemy.rb b/spec/dummy/db/migrate/20260510133912_add_publication_timestamps_to_alchemy_elements.alchemy.rb new file mode 100644 index 0000000..0967e8e --- /dev/null +++ b/spec/dummy/db/migrate/20260510133912_add_publication_timestamps_to_alchemy_elements.alchemy.rb @@ -0,0 +1,31 @@ +# This migration comes from alchemy (originally 20260115164704) +class AddPublicationTimestampsToAlchemyElements < ActiveRecord::Migration[7.2] + def up + add_column :alchemy_elements, :public_on, :datetime + add_column :alchemy_elements, :public_until, :datetime + + say_with_time "Populating publication dates" do + update <<-SQL.squish + UPDATE alchemy_elements + SET public_on = created_at + WHERE public = #{connection.quoted_true} + SQL + end + end + + def down + say_with_time "Reverting publication dates" do + update <<-SQL.squish + UPDATE alchemy_elements + SET public = CASE + WHEN public_on IS NOT NULL AND public_on <= CURRENT_TIMESTAMP + THEN #{connection.quoted_true} + ELSE #{connection.quoted_false} + END + SQL + end + + remove_column :alchemy_elements, :public_until + remove_column :alchemy_elements, :public_on + end +end diff --git a/spec/dummy/db/migrate/20260510133913_add_index_to_element_publication_timestamps.alchemy.rb b/spec/dummy/db/migrate/20260510133913_add_index_to_element_publication_timestamps.alchemy.rb new file mode 100644 index 0000000..988cb36 --- /dev/null +++ b/spec/dummy/db/migrate/20260510133913_add_index_to_element_publication_timestamps.alchemy.rb @@ -0,0 +1,14 @@ +# This migration comes from alchemy (originally 20260115164705) +class AddIndexToElementPublicationTimestamps < ActiveRecord::Migration[7.2] + disable_ddl_transaction! if connection.adapter_name.match?(/postgres/i) + + def change + add_index :alchemy_elements, [:public_on, :public_until], algorithm: algorithm + end + + private + + def algorithm + connection.adapter_name.match?(/postgres/i) ? :concurrently : nil + end +end diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb index 94463f7..6413105 100644 --- a/spec/dummy/db/schema.rb +++ b/spec/dummy/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2025_11_15_150241) do +ActiveRecord::Schema[7.2].define(version: 2026_05_10_133913) do create_table "alchemy_attachments", force: :cascade do |t| t.string "name" t.string "file_name" @@ -40,11 +40,14 @@ t.integer "parent_element_id" t.boolean "fixed", default: false, null: false t.integer "page_version_id", null: false + t.datetime "public_on" + t.datetime "public_until" t.index ["creator_id"], name: "index_alchemy_elements_on_creator_id" t.index ["fixed"], name: "index_alchemy_elements_on_fixed" t.index ["page_version_id", "parent_element_id"], name: "idx_alchemy_elements_on_page_version_id_and_parent_element_id" t.index ["page_version_id", "position"], name: "idx_alchemy_elements_on_page_version_id_and_position" t.index ["page_version_id"], name: "index_alchemy_elements_on_page_version_id" + t.index ["public_on", "public_until"], name: "index_alchemy_elements_on_public_on_and_public_until" t.index ["updater_id"], name: "index_alchemy_elements_on_updater_id" end @@ -147,6 +150,9 @@ t.datetime "public_until", precision: nil t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "title" + t.text "meta_description" + t.text "meta_keywords" t.index ["page_id"], name: "index_alchemy_page_versions_on_page_id" t.index ["public_on", "public_until"], name: "index_alchemy_page_versions_on_public_on_and_public_until" end @@ -261,6 +267,8 @@ t.string "reset_password_token" t.datetime "reset_password_sent_at", precision: nil t.string "alchemy_roles", default: "member" + t.datetime "remember_created_at" + t.string "timezone" t.index ["alchemy_roles"], name: "index_alchemy_users_on_alchemy_roles" t.index ["email"], name: "index_alchemy_users_on_email", unique: true t.index ["firstname"], name: "index_alchemy_users_on_firstname"