From a3e392f65614a744ca0f2b509301538e2a28bb95 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 17 Dec 2022 20:53:30 +0100 Subject: [PATCH] Allow assets:precompile to be run in a production build step without passing in RAILS_MASTER_KEY (#46760) * Add ENV["SECRET_KEY_BASE_DUMMY"] This is useful when precompiling assets for production as part of a build step that otherwise does not need access to the production secrets. * Test SECRET_KEY_BASE_DUMMY --- railties/CHANGELOG.md | 12 ++++++++++++ railties/lib/rails/application.rb | 8 +++++++- railties/test/application/configuration_test.rb | 14 ++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 4245dd72b3..3fca24ca8b 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,15 @@ +* Add ENV["SECRET_KEY_BASE_DUMMY"] for starting production environment with a generated secret base key, + which can be used to run tasks like `assets:precompile` without making the RAILS_MASTER_KEY available + to the build process. + + Dockerfile layer example: + + ``` + RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile + ``` + + *DHH* + * Show descriptions for all commands in Rails help When calling `rails help` most commands missed their description. We now diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 2fc3fa0ace..fda67476e5 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -461,11 +461,17 @@ def secrets # In development and test, this is randomly generated and stored in a # temporary file in tmp/development_secret.txt. # + # You can also set ENV["SECRET_KEY_BASE_DUMMY"] to trigger the use of a randomly generated + # secret_key_base that's stored in a temporary file. This is useful when precompiling assets for + # production as part of a build step that otherwise does not need access to the production secrets. + # + # Dockerfile example: RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile. + # # In all other environments, we look for it first in ENV["SECRET_KEY_BASE"], # then +credentials.secret_key_base+, and finally +secrets.secret_key_base+. For most applications, # the correct place to store it is in the encrypted credentials file. def secret_key_base - if Rails.env.development? || Rails.env.test? + if Rails.env.development? || Rails.env.test? || ENV["SECRET_KEY_BASE_DUMMY"] secrets.secret_key_base ||= generate_development_secret else validate_secret_key_base( diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 65441eb328..0208300321 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -762,6 +762,20 @@ def index assert_match(/Missing `secret_key_base`./, error.message) end + test "dont raise in production when dummy secret_key_base is used" do + ENV["SECRET_KEY_BASE_DUMMY"] = "1" + + app_file "config/initializers/secret_token.rb", <<-RUBY + Rails.application.credentials.secret_key_base = nil + RUBY + + assert_nothing_raised do + app "production" + end + ensure + ENV["SECRET_KEY_BASE_DUMMY"] = nil + end + test "raise when secret_key_base is not a type of string" do add_to_config <<-RUBY Rails.application.credentials.secret_key_base = 123