使用Rails.app.revision追踪部署

Rails 8.2引入了Rails.app.revision,这是一个简单但强大的功能,用于追踪生产环境中运行的代码版本。如果你曾经添加自定义代码来追踪git提交用于错误报告或缓存键,现在这已经内置了。

变更内容

新的Rails.app.revision方法返回当前部署标识符。默认情况下,Rails在两个地方查找:

  1. 应用程序根目录中的REVISION文件(通常由Capistrano等部署工具创建)
  2. 如果不存在REVISION文件,则为当前git提交SHA
Rails.app.revision
# => "3d31d593e6cf0f82fa9bd0338b635af2f30d627b"

为什么这很重要

准确知道正在运行的代码有助于:

  • 错误报告:将修订版附加到异常,以便将bug追溯到特定提交
  • 部署验证:确认最新部署确实已应用
  • 缓存失效:在缓存键中包含修订版以在部署时使缓存失效
  • 监控仪表板:按部署追踪性能指标

在此变更之前,你会写类似这样的代码:

# 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

现在只需Rails.app.revision

如何使用

默认行为

如果你使用Capistrano或创建REVISION文件的类似工具部署,它直接可用:

Rails.app.revision # 从REVISION文件读取

如果你在没有REVISION文件的git仓库中:

Rails.app.revision # 返回当前git SHA

自定义配置

config/application.rb中显式设置:

module MyApp
  class Application < Rails::Application
    # 从环境变量(在容器化部署中常见)
    config.revision = ENV["GIT_SHA"]

    # 或从proc进行延迟求值
    config.revision = -> { File.read("BUILD_ID").strip }
  end
end

错误报告集成

修订版会自动添加到错误报告器上下文:

Rails.error.report(exception)
# 上下文现在包括:
# {
#   rails: {
#     version: "8.2.0",
#     app_revision: "abc123...",
#     environment: "production"
#   }
# }

在缓存键中

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

注意事项

  • 如果不存在REVISION文件且不在git仓库中,返回nil
  • git回退仅在.git目录存在时才有效(某些Docker构建会排除它)
  • 对于容器化部署,最好显式设置config.revision = ENV["GIT_SHA"]

总结

Rails.app.revision是一个小的生活质量改进,它标准化了一个常见模式。如果你已经在手动追踪修订版,现在可以删除该代码并使用内置方法。

有关实现细节,请参阅commitPR #56490