Files
moreminimore-chat/db/migrate/20230515051424_update_article_image_keys.rb
Sojan Jose 81fc35e9e6 chore: upgrade Rails to 7.2.3.1 (#13437)
This upgrades Chatwoot to Rails 7.2.3.1 while retaining the current
Rails 7.0 framework defaults, so the runtime upgrade can be deployed and
observed independently from default-behavior changes.

## What changed

- Upgrade Rails and the compatible dependency set to Rails 7.2.3.1.
- Keep `config.load_defaults 7.0` for a staged, lower-risk rollout.
- Replace the unmaintained Azure Active Storage fork with the maintained
`azure-blob` adapter while preserving the `microsoft` service name.
- Pin Sidekiq 7.3.10 with `connection_pool` 2.x after validating
scheduled-job execution against Redis.
- Update Rails 7.2 compatibility surfaces in Active Record, strong
parameters, migrations, storage, and tests.
- Add read-only production preflight checks, an opt-in Active Storage
smoke script, a deployment runbook, and the full Rails 7.2/8.0/8.1
assessment.

## How to test

1. Sign in and verify the dashboard and conversation UI load normally.
2. Open the agent-management modal and confirm agent data is rendered.
3. Create an API inbox and wait for the asynchronous deletion flow to
complete.
4. Open Super Admin pages, including instance status and account-user
management.
5. Upload and download an attachment using the configured Active Storage
service.
6. Confirm recurring Sidekiq Cron jobs register and execute after
startup.

## Rollout

Follow `docs/rails_upgrades/7_2.md` for pre-deploy checks, deployment
order, smoke tests, monitoring, and rollback. Run `bundle exec rails
runner script/rails_upgrade/preflight.rb` against a
production-equivalent environment before rollout.

## Tracking

- [CW-5863 — Upgrade Rails to
8+](https://linear.app/chatwoot/issue/CW-5863/upgrade-rails-to-8)
- [Rails 7.2 to 8.1 upgrade and production rollout
plan](https://linear.app/chatwoot/document/chatwoot-rails-72-to-81-upgrade-and-production-rollout-plan-44e9f4964cb2)

---------

Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
Co-authored-by: Sony Mathew <2040199+sony-mathew@users.noreply.github.com>
Co-authored-by: Sony Mathew <sony@chatwoot.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2026-08-10 15:49:38 +05:30

60 lines
1.6 KiB
Ruby

class ArticleKeyConverter
def initialize(article)
@article = article
end
def process
new_content = replace(@article.content)
@article.update(content: new_content)
end
private
def convert_key(id)
verifier_name = 'ActiveStorage'
secret_key_base = Rails.application.secret_key_base
key_generator = ActiveSupport::KeyGenerator.new(secret_key_base,
iterations: 1000,
hash_digest_class: OpenSSL::Digest::SHA1)
key_generator = ActiveSupport::CachingKeyGenerator.new(key_generator)
secret = key_generator.generate_key(verifier_name.to_s)
verifier = ActiveSupport::MessageVerifier.new(secret)
begin
ActiveStorage::Blob.find(verifier.verify(id, purpose: :blob_id))
.try(:signed_id)
rescue StandardError
nil
end
end
def replace(text)
keys = get_keys(text)
keys.each do |key|
new_key = convert_key(key)
text = text.gsub(key, new_key) if new_key
end
text
end
def get_keys(text)
uris = text.scan(URI::DEFAULT_PARSER.make_regexp).flatten.select do |x|
x.to_s.include?('rails/active_storage')
end
uris.map { |x| x.split('/')[-2] }
end
end
# rubocop:disable Style/OneClassPerFile
class UpdateArticleImageKeys < ActiveRecord::Migration[7.0]
def change
# Iterate through all articles
Article.find_each do |article|
# Run the ArticleKeyConverter for each one
ArticleKeyConverter.new(article).process
end
end
end
# rubocop:enable Style/OneClassPerFile