Upgrading RailsPress
Guide for upgrading the RailsPress engine between versions.
Quick Upgrade
# 1. Update the gem
$ bundle update railspress-engine
# 2. Copy new migrations
$ rails railspress:install:migrations
# 3. Run migrations
$ rails db:migrate
# 4. Restart your server
Step-by-Step Guide
1. Update the Gem
If using a version constraint in your Gemfile:
gem "railspress-engine", "~> 1.0"
Run:
$ bundle update railspress-engine
If using a git source:
gem "railspress-engine", git: "https://github.com/aviflombaum/railspress-engine", branch: "main"
2. Copy New Migrations
RailsPress includes a rake task to copy engine migrations to your application:
$ rails railspress:install:migrations
This copies any new migrations from the engine to your db/migrate/ folder. Existing migrations are skipped (matched by migration name, not timestamp).
Check what was copied:
$ ls -la db/migrate/*railspress*
3. Review Migration Changes
Before running migrations, review them for any data implications:
# See pending migrations
$ rails db:migrate:status
# Preview a specific migration
$ cat db/migrate/TIMESTAMP_create_railspress_exports.rb
4. Run Migrations
$ rails db:migrate
For production, consider running migrations separately from deployment:
$ RAILS_ENV=production rails db:migrate
5. Check Configuration
New versions may add configuration options. Review the initializer:
Railspress.configure do |config|
config.enable_authors
config.author_class_name = "User"
config.author_display_method = :name
config.enable_post_images
end
Check the Configuration guide for new options.
6. Restart Application
# Development
$ rails restart
# Production (example with Puma)
$ pumactl restart
Migration Internals
How Engine Migrations Work
RailsPress migrations live in railspress/db/migrate/. When you run railspress:install:migrations, Rails copies them to your app with new timestamps.
Engine migration:
railspress/db/migrate/20241218000001_create_railspress_categories.rb
Becomes in your app:
db/migrate/20241224123456_create_railspress_categories.railspress.rb
The .railspress suffix tracks the migration origin.
Migration Naming Convention
RailsPress uses a fixed timestamp prefix pattern:
| Timestamp | Migration |
|---|---|
20241218000001 |
create_railspress_categories |
20241218000002 |
create_railspress_tags |
20241218000003 |
create_railspress_posts |
20241218000004 |
create_railspress_post_tags |
20241218000005 |
create_railspress_imports |
20241218000006 |
create_railspress_exports |
20260415000001 |
create_railspress_api_keys |
20260415000002 |
create_railspress_agent_bootstrap_keys |
New migrations increment the suffix (000007, 000008, etc.).
Checking Migration Status
# See all migrations and their status
$ rails db:migrate:status
# Filter to RailsPress migrations
$ rails db:migrate:status | grep railspress
Rolling Back
If needed, rollback a specific migration:
# Rollback last migration
$ rails db:rollback
# Rollback to specific version
$ rails db:migrate:down VERSION=20241224123456
Troubleshooting
"Migration already exists"
If the rake task reports migrations already exist, they've been copied before. Check:
$ ls db/migrate/*railspress*
Schema Mismatch
If your schema differs from expected migrations:
# Check current schema
$ rails db:schema:dump
$ cat db/schema.rb | grep railspress
# Compare with engine migrations
$ ls railspress/db/migrate/
Missing Tables
If RailsPress tables are missing:
# Re-copy all migrations
$ rails railspress:install:migrations
# Run pending
$ rails db:migrate
Duplicate Migrations
If you have duplicate migrations (same content, different timestamps):
- Check which are already run:
rails db:migrate:status - Delete the unrun duplicate
- If both are run, the second likely failed silently
Latest Release Notes (v1.4.4)
Released: 2026-08-18
RailsPress 1.4.4 is a security hardening release for post and CMS imports. It changes no supported file formats, public APIs, or configuration options, and it requires no migrations or host application code changes.
- SSRF-safe remote images: remote post header-image downloads now go through the
ssrf_filtergem, which the engine installs as a runtime dependency. - Remote image destination validation: loopback, private, link-local, reserved, and other unsafe IPv4 and IPv6 destinations are rejected, and redirect responses are no longer followed.
- Import upload containment: admin uploads are stored under server-generated names, and cleanup canonicalizes its targets before removing files.
- ZIP image containment: absolute, traversal, and symlinked image references that resolve outside the extraction directory are rejected.
- Dependency maintenance: the development lockfile moved to the patched
rails-html-sanitizer 1.7.1andjson 2.21.2releases.
See the v1.4.4 release notes or the full CHANGELOG.
Version-Specific Notes
Upgrading to 1.4.4 (from 1.4.3)
RailsPress 1.4.4 hardens post and CMS imports. Admin uploads are stored under server-generated names, and cleanup only removes canonical paths beneath the Rails temporary directory. Image references inside a ZIP must resolve within their extraction directory, so absolute paths, traversal segments, and symlinks that escape it are rejected.
Remote post header images now use ssrf_filter. Public HTTP and HTTPS images still work, but loopback, private, link-local, reserved, and redirecting destinations are rejected. If a feed you import from serves header images through a redirecting URL, update the frontmatter to the final image URL.
bundle update railspress-engine
The engine installs ssrf_filter automatically. There are no migrations, initializer changes, or host application code changes.
Upgrading to 1.4.3 (from 1.4.2)
RailsPress 1.4.3 renames the engine's built-in query helpers to rp_search, rp_page, and rp_per_page_count. The admin and JSON API use only these names, which leaves your application free to define its own search scope or to use any pagination gem without relying on gem load order. There are no migrations, initializer changes, or immediately required host application changes.
$ bundle update railspress-engine
Migrate direct uses of the old generic names to their rp_ equivalents, or to your application's preferred search and pagination API:
| Deprecated | Use instead |
|---|---|
Railspress::Post.search(q) |
Railspress::Post.rp_search(q) |
.page(params[:page]) |
.rp_page(params[:page]) |
Model.per_page_count |
Model.rp_per_page_count |
The old names are still defined when your model does not already provide them, so existing calls keep working through RailsPress 1.x. They emit deprecation warnings through the :railspress deprecator, which you can configure like any other Rails deprecator via config.active_support.deprecators. They are removed in RailsPress 2.0.
If you previously deferred the RailsPress require so Kaminari's page would win, you can drop that workaround. Remove require: false from the railspress-engine line in your Gemfile and the manual require "railspress" from your initializer.
The built-in title search is also database-agnostic in 1.4.3: it uses adapter-aware Arel instead of PostgreSQL-only ILIKE SQL, so admin search works on SQLite and MySQL too.
Upgrading to 1.4.2 (from 1.4.1)
RailsPress 1.4.2 raises its runtime floors to Rails 8.1.3.1, Lexxy 0.9.29, and image_processing 2.0.3, and it updates CMS helper loading for newer Rails versions. RailsPress owns the Lexxy and image_processing dependencies, so do not add them to your host Gemfile. There are no migrations, initializer changes, or host application code changes.
$ bundle update railspress-engine
If Bundler reports a direct Rails version conflict, unlock Rails at the same time:
$ bundle update rails railspress-engine
If your application uses Vips, verify every deployed environment before restarting:
$ bundle exec ruby -e 'require "vips"; puts Vips::VERSION'
$ vips --version
ruby-vips must be 2.2.1+ and native libvips must be 8.13+. Rails 8.1.3.1 refuses to boot with an older libvips because it cannot disable unsafe operations there. Applications that accepted untrusted image uploads while using Vips on Rails earlier than 8.1.3.1 should follow the Rails security advisory, including rotating application and service credentials that may have been exposed.
Upgrading to 1.4.1 (from 1.4.0)
RailsPress 1.4.1 refines installer guidance and documentation only. There are no migrations, configuration, or host importmap changes.
$ bundle update railspress-engine
Your existing config/initializers/railspress.rb is untouched by the upgrade. If you want the newly surfaced commented settings (author_scope, enable_post_images, enable_focal_points) as a reference, compare against a freshly generated initializer or see Basic Setup. If your app requests resized or converted images, review Active Storage & Image Variants to confirm an image processor is installed.
Upgrading to 1.4.0 (from 1.3.x)
RailsPress 1.4.0 adopts Lexxy's first stable release (0.9.24) and refreshes its dependency set. There are no migrations or host importmap changes.
$ bundle update railspress-engine lexxy
Keep import "railspress" in your host JavaScript entrypoint if you use host-page RailsPress features such as inline editing. No other changes are required.
Upgrading to 1.3.0
This release adds the versioned JSON API and AI-agent onboarding flow, plus new admin key management screens.
Key additions:
/railspress/api/v1endpoints for posts, post imports, categories, tags, and prime handshake.- Agent bootstrap token exchange flow (
rpb_*torp_*). - Agents & API admin screen at
/railspress/admin/api_keys. - Two new encrypted key tables:
railspress_api_keysandrailspress_agent_bootstrap_keys.
Upgrade checklist:
$ bundle update railspress-engine
$ rails railspress:install:migrations
$ rails db:migrate
Required API setup:
- Configure Active Record Encryption keys in your host app.
- Enable API in
config/initializers/railspress.rbwithconfig.enable_api. - Set an API actor method/proc (for example
config.current_api_actor_method = :current_user). - Create a bootstrap or direct API key from
/railspress/admin/api_keys.
Upgrading to 1.2.0 (from 1.0.0+)
This release improved Lexxy dependency and importmap behavior for host apps.
- Lexxy dependency moved to an open lower bound (
>= 0.9.0.beta). - Engine-managed importmap and JS entrypoint now handle Lexxy loading.
- Install generator no longer adds a manual host
lexxyimportmap pin. - Inline editor rendering and rubyzip compatibility fixes were included.
$ bundle update railspress-engine lexxy
$ rails railspress:install:migrations
$ rails db:migrate
Upgrading to 1.0.0
New: Blocks (Content Element CMS), Inline Editing, and content transfer
New configuration:
Railspress.configure do |config|
config.enable_cms
config.inline_editing_check = ->(ctx) { ctx.controller.current_user&.admin? }
end
Upgrading to 0.1.x
Initial release. Run full install:
$ rails generate railspress:install
$ rails db:migrate
CI/CD Considerations
Automated Upgrades
In CI, ensure migrations run before tests:
- name: Setup database
run: |
rails railspress:install:migrations
rails db:create db:migrate
Production Deployments
For zero-downtime deploys, run migrations before deploying new code if they're additive (new tables, new columns with defaults).
For destructive migrations (removing columns), deploy code first, then migrate.
# Typical deploy sequence
$ git pull origin main
$ bundle install
$ rails railspress:install:migrations
$ rails db:migrate
$ rails assets:precompile
# restart app
Getting Help
- Check the Configuration guide for configuration options
- Check the Import & Export guide for import/export features
- Review engine source:
bundle show railspress