Track Deployments with Rails.app.revision

railsdeploymentmonitoring

Rails 8.2 introduces Rails.app.revision, a simple but powerful addition for tracking which version of your code is running in production. If you’ve ever added custom code to track git commits for error reporting or cache keys, this is now built-in.

What Changed

A new Rails.app.revision method returns the current deployment identifier. By default, Rails looks for it in two places:

  1. A REVISION file in your application root (commonly created by deployment tools like Capistrano)
  2. The current git commit SHA if no REVISION file exists
Rails.app.revision
# => "3d31d593e6cf0f82fa9bd0338b635af2f30d627b"

Why This Matters

Knowing exactly which code is running helps with:

  • Error reporting: Attach the revision to exceptions so you can trace bugs to specific commits
  • Deployment verification: Confirm that your latest deploy actually rolled out
  • Cache busting: Include the revision in cache keys to invalidate caches on deploy
  • Monitoring dashboards: Track performance metrics by deployment

Before this change, you’d write something like:

# config/initializers/revision.rb
REVISION = if File.exist?(Rails.root.join("REVISION"))
  File.read(Rails.root.join("REVISION")).strip
else
  `git rev-parse HEAD`.strip
end

Now it’s just Rails.app.revision.

How to Use It

Default behavior

If you deploy with Capistrano or similar tools that create a REVISION file, it just works:

Rails.app.revision # reads from REVISION file

If you’re in a git repository without a REVISION file:

Rails.app.revision # returns current git SHA

Custom configuration

Set it explicitly in config/application.rb:

module MyApp
  class Application < Rails::Application
    # From environment variable (common in containerized deployments)
    config.revision = ENV["GIT_SHA"]

    # Or from a proc for lazy evaluation
    config.revision = -> { File.read("BUILD_ID").strip }
  end
end

Error reporting integration

The revision is automatically added to the error reporter context:

Rails.error.report(exception)
# Context now includes:
# {
#   rails: {
#     version: "8.2.0",
#     app_revision: "abc123...",
#     environment: "production"
#   }
# }

In cache keys

def cache_key
  "my_data/#{Rails.app.revision}/#{id}"
end

Things to Watch Out For

  • Returns nil if no REVISION file exists and you’re not in a git repository
  • The git fallback only works if the .git directory is present (some Docker builds exclude it)
  • For containerized deployments, prefer setting config.revision = ENV["GIT_SHA"] explicitly

Wrapping Up

Rails.app.revision is a small quality-of-life improvement that standardizes a common pattern. If you’re already tracking revisions manually, you can now delete that code and use the built-in method.

See the commit and PR #56490 for implementation details.