You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails7 RSpec测试加密属性首次CI报key_derivation_salt未配置错误

问题现象

基于Rails 7.0.3框架开发的应用中,某模型配置了encrypted attribute(加密属性),本地验证RSpec用例时行为正常,配置GitHub Actions工作流自动执行测试时出现稳定复现的异常:同一提交的首次CI运行必然失败,手动触发重新运行后全部执行成功。

报错信息如下:

ActiveRecord::Encryption::Errors::Configuration:
       key_derivation_salt is not configured. Please configure it via credential active_record_encryption.key_derivation_salt or by setting config.active_record.encryption.key_derivation_salt
现有配置说明
  • 已在GitHub仓库Secrets中配置了对应的RAILS_MASTER_KEY
  • ActiveRecord加密所需的配置项均存储在加密凭据文件中,配置结构如下:
active_record_encryption:
  primary_key: u▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉
  deterministic_key: 4▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉
  key_derivation_salt: R▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉
  • 原有GitHub Actions工作流精简配置如下:
name: CI
on: [push]
jobs:
  rspec:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - name: Set up Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: ".ruby-version"
    - name: Bundle Install
      run: |
        gem install bundler -v $(grep 'BUNDLED WITH' -A1 Gemfile.lock | tail -n 1 )
        bundle config set --local path 'vendor/bundle'
        bundle install --jobs 4 --retry 3
    - env:
        RAILS_MASTER_KEY: "${{ secrets.RAILS_MASTER_KEY }}"
      run: RAILS_ENV=test bundle exec rspec
  • 诉求:不通过引入RSpec重试/重跑类gem临时规避问题,定位根本原因并彻底修复。
根本原因

该问题是CI环境变量作用域配置错误+冷启动时序竞态叠加老版本checkout动作缺陷导致的,和业务代码逻辑无关:

  1. 原配置中RAILS_MASTER_KEY只绑定在最后执行rspec的单条run指令上,工作流前面的所有步骤(包括bundle安装、Rails预加载、缓存生成流程)都无法读取到该密钥。首次在全新Runner上运行时,Rails冷启动过程中ActiveRecord加密组件的初始化时点早于凭据解密流程,读不到加密配置就会直接抛出salt缺失的错误。
  2. 首次运行失败后手动重跑时,GitHub Actions会复用首次运行生成的工作区缓存、bundle缓存,此时Rails不需要走完整的冷启动初始化流程,加载时序发生变化,加密配置可以正常读取,因此测试会全部通过,是非常典型的首跑必败、重跑必过的时序问题特征。
  3. 原配置使用的actions/checkout@v1是多年前的老旧版本,存在加密凭据文件权限设置错误、代码拉取不完整的已知问题,会进一步放大首次加载的时序异常。
修复方案

按优先级执行以下调整即可彻底解决问题:

  • 修正环境变量作用域,将RAILS_MASTER_KEY和RAILS_ENV配置到job层级,确保整个job生命周期内所有流程都能读取到正确的环境变量;同时升级checkout版本到稳定版,替换冗余的bundle安装逻辑为setup-ruby自带的缓存能力,修改后的工作流配置参考:
name: CI
on: [push]
jobs:
  rspec:
    runs-on: ubuntu-latest
    env:
      RAILS_ENV: test
      RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
    steps:
    - uses: actions/checkout@v3
    - name: Set up Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: ".ruby-version"
        bundler-cache: true
    - name: Verify Encryption Config
      run: bundle exec rails runner "puts ActiveRecord::Encryption.config.key_derivation_salt"
    - name: Run RSpec
      run: bundle exec rspec
  • 校验test环境加密配置的加载时机,打开config/environments/test.rb,确认ActiveRecord加密配置在Rails凭据加载完成后才初始化,可显式指定配置读取逻辑避免提前初始化:
# config/environments/test.rb
Rails.application.configure do
  # 其余原有test环境配置保持不变
  config.active_record.encryption.primary_key = Rails.application.credentials.active_record_encryption[:primary_key]
  config.active_record.encryption.deterministic_key = Rails.application.credentials.active_record_encryption[:deterministic_key]
  config.active_record.encryption.key_derivation_salt = Rails.application.credentials.active_record_encryption[:key_derivation_salt]
end
  • 调整完成后手动清理一次GitHub Actions的历史工作流缓存,避免旧的错误缓存干扰验证结果。

内容的提问来源于stack exchange,提问作者user1065745

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 06:18:26