railties 8.0.3 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +101 -206
 - data/lib/minitest/rails_plugin.rb +48 -12
 - data/lib/rails/application/bootstrap.rb +5 -0
 - data/lib/rails/application/configuration.rb +31 -9
 - data/lib/rails/application/default_middleware_stack.rb +1 -1
 - data/lib/rails/application/finisher.rb +2 -1
 - data/lib/rails/application/routes_reloader.rb +0 -1
 - data/lib/rails/application.rb +1 -3
 - data/lib/rails/code_statistics.rb +4 -1
 - data/lib/rails/command/base.rb +0 -2
 - data/lib/rails/command/environment_argument.rb +0 -1
 - data/lib/rails/command.rb +1 -1
 - data/lib/rails/commands/app/update_command.rb +1 -0
 - data/lib/rails/commands/console/irb_console.rb +4 -4
 - data/lib/rails/commands/credentials/credentials_command.rb +25 -5
 - data/lib/rails/commands/encrypted/encrypted_command.rb +0 -1
 - data/lib/rails/engine.rb +0 -1
 - data/lib/rails/gem_version.rb +2 -2
 - data/lib/rails/generators/actions.rb +2 -3
 - data/lib/rails/generators/app_base.rb +49 -28
 - data/lib/rails/generators/database.rb +1 -1
 - data/lib/rails/generators/erb/authentication/authentication_generator.rb +2 -0
 - data/lib/rails/generators/erb/scaffold/templates/partial.html.erb.tt +2 -2
 - data/lib/rails/generators/generated_attribute.rb +1 -1
 - data/lib/rails/generators/migration.rb +0 -1
 - data/lib/rails/generators/rails/app/app_generator.rb +16 -5
 - data/lib/rails/generators/rails/app/templates/Dockerfile.tt +19 -15
 - data/lib/rails/generators/rails/app/templates/Gemfile.tt +6 -1
 - data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +5 -0
 - data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +1 -0
 - data/lib/rails/generators/rails/app/templates/bin/bundler-audit.tt +5 -0
 - data/lib/rails/generators/rails/app/templates/bin/ci.tt +5 -0
 - data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +1 -1
 - data/lib/rails/generators/rails/app/templates/bin/setup.tt +1 -0
 - data/lib/rails/generators/rails/app/templates/config/bundler-audit.yml.tt +5 -0
 - data/lib/rails/generators/rails/app/templates/config/ci.rb.tt +38 -0
 - data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +9 -1
 - data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +10 -2
 - data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +1 -1
 - data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +9 -1
 - data/lib/rails/generators/rails/app/templates/config/deploy.yml.tt +21 -16
 - data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +8 -0
 - data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +2 -2
 - data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +4 -0
 - data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_1.rb.tt +74 -0
 - data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +3 -2
 - data/lib/rails/generators/rails/app/templates/config/storage.yml.tt +0 -7
 - data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +0 -6
 - data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +107 -21
 - data/lib/rails/generators/rails/app/templates/github/dependabot.yml +2 -2
 - data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +4 -1
 - data/lib/rails/generators/rails/app/templates/public/400.html +26 -5
 - data/lib/rails/generators/rails/app/templates/public/404.html +27 -6
 - data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +25 -4
 - data/lib/rails/generators/rails/app/templates/public/422.html +26 -5
 - data/lib/rails/generators/rails/app/templates/public/500.html +27 -6
 - data/lib/rails/generators/rails/authentication/authentication_generator.rb +8 -6
 - data/lib/rails/generators/rails/authentication/templates/app/controllers/passwords_controller.rb.tt +6 -0
 - data/lib/rails/generators/rails/authentication/templates/app/controllers/sessions_controller.rb.tt +2 -2
 - data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.html.erb.tt +3 -1
 - data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.text.erb.tt +3 -1
 - data/lib/rails/generators/rails/benchmark/USAGE +1 -1
 - data/lib/rails/generators/rails/benchmark/templates/benchmark.rb.tt +0 -2
 - data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +1 -1
 - data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +4 -0
 - data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +2 -2
 - data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +1 -1
 - data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +17 -5
 - data/lib/rails/generators/rails/master_key/master_key_generator.rb +0 -12
 - data/lib/rails/generators/rails/plugin/plugin_generator.rb +1 -0
 - data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +0 -4
 - data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +20 -9
 - data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +2 -2
 - data/lib/rails/generators/rails/script/USAGE +1 -1
 - data/lib/rails/generators/test_unit/authentication/authentication_generator.rb +13 -0
 - data/lib/rails/generators/test_unit/authentication/templates/test/controllers/passwords_controller_test.rb.tt +67 -0
 - data/lib/rails/generators/test_unit/authentication/templates/test/controllers/sessions_controller_test.rb +33 -0
 - data/lib/rails/generators/test_unit/authentication/templates/test/models/user_test.rb.tt +4 -3
 - data/lib/rails/generators/test_unit/authentication/templates/test/test_helpers/session_test_helper.rb.tt +19 -0
 - data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +1 -1
 - data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +4 -2
 - data/lib/rails/generators/testing/behavior.rb +0 -3
 - data/lib/rails/generators.rb +3 -1
 - data/lib/rails/health_controller.rb +8 -2
 - data/lib/rails/info.rb +4 -5
 - data/lib/rails/info_controller.rb +4 -5
 - data/lib/rails/initializable.rb +63 -19
 - data/lib/rails/rack/silence_request.rb +5 -2
 - data/lib/rails/railtie/configurable.rb +0 -1
 - data/lib/rails/railtie.rb +0 -1
 - data/lib/rails/tasks/statistics.rake +3 -21
 - data/lib/rails/tasks.rb +1 -3
 - data/lib/rails/templates/rails/info/notes.html.erb +23 -0
 - data/lib/rails/templates/rails/mailers/email.html.erb +2 -1
 - data/lib/rails/templates/rails/welcome/index.html.erb +19 -3
 - data/lib/rails/test_unit/reporter.rb +5 -4
 - data/lib/rails/test_unit/runner.rb +8 -5
 - data/lib/rails.rb +9 -2
 - metadata +18 -15
 - data/lib/rails/console/methods.rb +0 -7
 - data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_0.rb.tt +0 -30
 - data/lib/rails/generators/test_unit/plugin/plugin_generator.rb +0 -15
 - data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +0 -7
 - data/lib/rails/generators/test_unit/plugin/templates/test_helper.rb +0 -2
 
    
        data/lib/rails/command/base.rb
    CHANGED
    
    
    
        data/lib/rails/command.rb
    CHANGED
    
    
| 
         @@ -73,6 +73,7 @@ module Rails 
     | 
|
| 
       73 
73 
     | 
    
         
             
                          skip_action_text:    !defined?(ActionText::Engine),
         
     | 
| 
       74 
74 
     | 
    
         
             
                          skip_action_cable:   !defined?(ActionCable::Engine),
         
     | 
| 
       75 
75 
     | 
    
         
             
                          skip_brakeman:       skip_gem?("brakeman"),
         
     | 
| 
      
 76 
     | 
    
         
            +
                          skip_bundler_audit:  skip_gem?("bundler-audit"),
         
     | 
| 
       76 
77 
     | 
    
         
             
                          skip_rubocop:        skip_gem?("rubocop"),
         
     | 
| 
       77 
78 
     | 
    
         
             
                          skip_thruster:       skip_gem?("thruster"),
         
     | 
| 
       78 
79 
     | 
    
         
             
                          skip_test:           !defined?(Rails::TestUnitRailtie),
         
     | 
| 
         @@ -91,9 +91,9 @@ module Rails 
     | 
|
| 
       91 
91 
     | 
    
         
             
                    IRB.conf[:IRB_NAME] = @app.name if IRB.conf[:IRB_NAME] == "irb"
         
     | 
| 
       92 
92 
     | 
    
         | 
| 
       93 
93 
     | 
    
         
             
                    IRB.conf[:PROMPT][:RAILS_PROMPT] = {
         
     | 
| 
       94 
     | 
    
         
            -
                      PROMPT_I: "#{prompt_prefix}> ",
         
     | 
| 
       95 
     | 
    
         
            -
                      PROMPT_S: "#{prompt_prefix}%l ",
         
     | 
| 
       96 
     | 
    
         
            -
                      PROMPT_C: "#{prompt_prefix}* ",
         
     | 
| 
      
 94 
     | 
    
         
            +
                      PROMPT_I: "#{prompt_prefix}:%03n> ",
         
     | 
| 
      
 95 
     | 
    
         
            +
                      PROMPT_S: "#{prompt_prefix}:%03n%l ",
         
     | 
| 
      
 96 
     | 
    
         
            +
                      PROMPT_C: "#{prompt_prefix}:%03n* ",
         
     | 
| 
       97 
97 
     | 
    
         
             
                      RETURN: "=> %s\n"
         
     | 
| 
       98 
98 
     | 
    
         
             
                    }
         
     | 
| 
       99 
99 
     | 
    
         | 
| 
         @@ -122,7 +122,7 @@ module Rails 
     | 
|
| 
       122 
122 
     | 
    
         
             
                    when "production"
         
     | 
| 
       123 
123 
     | 
    
         
             
                      IRB::Color.colorize("prod", [:RED])
         
     | 
| 
       124 
124 
     | 
    
         
             
                    else
         
     | 
| 
       125 
     | 
    
         
            -
                      Rails.env
         
     | 
| 
      
 125 
     | 
    
         
            +
                      IRB::Color.colorize(Rails.env, [:MAGENTA])
         
     | 
| 
       126 
126 
     | 
    
         
             
                    end
         
     | 
| 
       127 
127 
     | 
    
         
             
                  end
         
     | 
| 
       128 
128 
     | 
    
         
             
                end
         
     | 
| 
         @@ -35,7 +35,7 @@ module Rails 
     | 
|
| 
       35 
35 
     | 
    
         
             
                  def show
         
     | 
| 
       36 
36 
     | 
    
         
             
                    load_environment_config!
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
                    say credentials.read.presence ||  
     | 
| 
      
 38 
     | 
    
         
            +
                    say credentials.read.presence || missing_credentials!
         
     | 
| 
       39 
39 
     | 
    
         
             
                  end
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
                  desc "diff", "Enroll/disenroll in decrypted diffs of credentials using git"
         
     | 
| 
         @@ -57,6 +57,26 @@ module Rails 
     | 
|
| 
       57 
57 
     | 
    
         
             
                    say credentials.content_path.read
         
     | 
| 
       58 
58 
     | 
    
         
             
                  end
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
      
 60 
     | 
    
         
            +
                  desc "fetch PATH", "Fetch a value in the decrypted credentials"
         
     | 
| 
      
 61 
     | 
    
         
            +
                  def fetch(path)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    load_environment_config!
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                    if (yaml = credentials.read)
         
     | 
| 
      
 65 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 66 
     | 
    
         
            +
                        value = YAML.load(yaml)
         
     | 
| 
      
 67 
     | 
    
         
            +
                        value = path.split(".").inject(value) do |doc, key|
         
     | 
| 
      
 68 
     | 
    
         
            +
                          doc.fetch(key)
         
     | 
| 
      
 69 
     | 
    
         
            +
                        end
         
     | 
| 
      
 70 
     | 
    
         
            +
                        say value.to_s
         
     | 
| 
      
 71 
     | 
    
         
            +
                      rescue KeyError, NoMethodError
         
     | 
| 
      
 72 
     | 
    
         
            +
                        say_error "Invalid or missing credential path: #{path}"
         
     | 
| 
      
 73 
     | 
    
         
            +
                        exit 1
         
     | 
| 
      
 74 
     | 
    
         
            +
                      end
         
     | 
| 
      
 75 
     | 
    
         
            +
                    else
         
     | 
| 
      
 76 
     | 
    
         
            +
                      missing_credentials!
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
       60 
80 
     | 
    
         
             
                  private
         
     | 
| 
       61 
81 
     | 
    
         
             
                    def config
         
     | 
| 
       62 
82 
     | 
    
         
             
                      Rails.application.config.credentials
         
     | 
| 
         @@ -81,7 +101,6 @@ module Rails 
     | 
|
| 
       81 
101 
     | 
    
         | 
| 
       82 
102 
     | 
    
         
             
                      encryption_key_file_generator = Rails::Generators::EncryptionKeyFileGenerator.new
         
     | 
| 
       83 
103 
     | 
    
         
             
                      encryption_key_file_generator.add_key_file(key_path)
         
     | 
| 
       84 
     | 
    
         
            -
                      encryption_key_file_generator.ignore_key_file(key_path)
         
     | 
| 
       85 
104 
     | 
    
         
             
                    end
         
     | 
| 
       86 
105 
     | 
    
         | 
| 
       87 
106 
     | 
    
         
             
                    def ensure_credentials_have_been_added
         
     | 
| 
         @@ -115,12 +134,13 @@ module Rails 
     | 
|
| 
       115 
134 
     | 
    
         
             
                      say "Your application will not be able to load '#{content_path}' until the error has been fixed.", :red
         
     | 
| 
       116 
135 
     | 
    
         
             
                    end
         
     | 
| 
       117 
136 
     | 
    
         | 
| 
       118 
     | 
    
         
            -
                    def  
     | 
| 
      
 137 
     | 
    
         
            +
                    def missing_credentials!
         
     | 
| 
       119 
138 
     | 
    
         
             
                      if !credentials.key?
         
     | 
| 
       120 
     | 
    
         
            -
                        "Missing '#{key_path}' to decrypt credentials. See `#{executable(:help)}`."
         
     | 
| 
      
 139 
     | 
    
         
            +
                        say_error "Missing '#{key_path}' to decrypt credentials. See `#{executable(:help)}`."
         
     | 
| 
       121 
140 
     | 
    
         
             
                      else
         
     | 
| 
       122 
     | 
    
         
            -
                        "File '#{content_path}' does not exist. Use `#{executable(:edit)}` to change that."
         
     | 
| 
      
 141 
     | 
    
         
            +
                        say_error "File '#{content_path}' does not exist. Use `#{executable(:edit)}` to change that."
         
     | 
| 
       123 
142 
     | 
    
         
             
                      end
         
     | 
| 
      
 143 
     | 
    
         
            +
                      exit 1
         
     | 
| 
       124 
144 
     | 
    
         
             
                    end
         
     | 
| 
       125 
145 
     | 
    
         | 
| 
       126 
146 
     | 
    
         
             
                    def relative_path(path)
         
     | 
| 
         @@ -45,7 +45,6 @@ module Rails 
     | 
|
| 
       45 
45 
     | 
    
         
             
                    def ensure_encryption_key_has_been_added
         
     | 
| 
       46 
46 
     | 
    
         
             
                      return if encrypted_configuration.key?
         
     | 
| 
       47 
47 
     | 
    
         
             
                      encryption_key_file_generator.add_key_file(key_path)
         
     | 
| 
       48 
     | 
    
         
            -
                      encryption_key_file_generator.ignore_key_file(key_path)
         
     | 
| 
       49 
48 
     | 
    
         
             
                    end
         
     | 
| 
       50 
49 
     | 
    
         | 
| 
       51 
50 
     | 
    
         
             
                    def ensure_encrypted_configuration_has_been_added
         
     | 
    
        data/lib/rails/engine.rb
    CHANGED
    
    
    
        data/lib/rails/gem_version.rb
    CHANGED
    
    
| 
         @@ -445,11 +445,10 @@ module Rails 
     | 
|
| 
       445 
445 
     | 
    
         | 
| 
       446 
446 
     | 
    
         
             
                  private
         
     | 
| 
       447 
447 
     | 
    
         
             
                    # Define log for backwards compatibility. If just one argument is sent,
         
     | 
| 
       448 
     | 
    
         
            -
                    # invoke +say+, otherwise invoke +say_status+. 
     | 
| 
       449 
     | 
    
         
            -
                    # similarly to +say_status+, this method respects the +quiet?+ option given.
         
     | 
| 
      
 448 
     | 
    
         
            +
                    # invoke +say+, otherwise invoke +say_status+.
         
     | 
| 
       450 
449 
     | 
    
         
             
                    def log(*args) # :doc:
         
     | 
| 
       451 
450 
     | 
    
         
             
                      if args.size == 1
         
     | 
| 
       452 
     | 
    
         
            -
                        say args.first.to_s 
     | 
| 
      
 451 
     | 
    
         
            +
                        say args.first.to_s
         
     | 
| 
       453 
452 
     | 
    
         
             
                      else
         
     | 
| 
       454 
453 
     | 
    
         
             
                        args << (behavior == :invoke ? :green : :red)
         
     | 
| 
       455 
454 
     | 
    
         
             
                        say_status(*args)
         
     | 
| 
         @@ -73,7 +73,8 @@ module Rails 
     | 
|
| 
       73 
73 
     | 
    
         
             
                    class_option :skip_action_cable,   type: :boolean, aliases: "-C", default: nil,
         
     | 
| 
       74 
74 
     | 
    
         
             
                                                       desc: "Skip Action Cable files"
         
     | 
| 
       75 
75 
     | 
    
         | 
| 
       76 
     | 
    
         
            -
                    class_option :skip_asset_pipeline, type: :boolean, aliases: "-A", default: nil
         
     | 
| 
      
 76 
     | 
    
         
            +
                    class_option :skip_asset_pipeline, type: :boolean, aliases: "-A", default: nil,
         
     | 
| 
      
 77 
     | 
    
         
            +
                                                       desc: "Skip the asset pipeline setup"
         
     | 
| 
       77 
78 
     | 
    
         | 
| 
       78 
79 
     | 
    
         
             
                    class_option :skip_javascript,     type: :boolean, aliases: ["-J", "--skip-js"], default: (true if name == "plugin"),
         
     | 
| 
       79 
80 
     | 
    
         
             
                                                       desc: "Skip JavaScript files"
         
     | 
| 
         @@ -105,6 +106,9 @@ module Rails 
     | 
|
| 
       105 
106 
     | 
    
         
             
                    class_option :skip_brakeman,       type: :boolean, default: nil,
         
     | 
| 
       106 
107 
     | 
    
         
             
                                                       desc: "Skip brakeman setup"
         
     | 
| 
       107 
108 
     | 
    
         | 
| 
      
 109 
     | 
    
         
            +
                    class_option :skip_bundler_audit,  type: :boolean, default: nil,
         
     | 
| 
      
 110 
     | 
    
         
            +
                                                       desc: "Skip bundler-audit setup"
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
       108 
112 
     | 
    
         
             
                    class_option :skip_ci,             type: :boolean, default: nil,
         
     | 
| 
       109 
113 
     | 
    
         
             
                                                       desc: "Skip GitHub CI files"
         
     | 
| 
       110 
114 
     | 
    
         | 
| 
         @@ -399,6 +403,10 @@ module Rails 
     | 
|
| 
       399 
403 
     | 
    
         
             
                    options[:skip_brakeman]
         
     | 
| 
       400 
404 
     | 
    
         
             
                  end
         
     | 
| 
       401 
405 
     | 
    
         | 
| 
      
 406 
     | 
    
         
            +
                  def skip_bundler_audit?
         
     | 
| 
      
 407 
     | 
    
         
            +
                    options[:skip_bundler_audit]
         
     | 
| 
      
 408 
     | 
    
         
            +
                  end
         
     | 
| 
      
 409 
     | 
    
         
            +
             
     | 
| 
       402 
410 
     | 
    
         
             
                  def skip_ci?
         
     | 
| 
       403 
411 
     | 
    
         
             
                    options[:skip_ci]
         
     | 
| 
       404 
412 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -493,7 +501,7 @@ module Rails 
     | 
|
| 
       493 
501 
     | 
    
         
             
                  def javascript_gemfile_entry
         
     | 
| 
       494 
502 
     | 
    
         
             
                    return if options[:skip_javascript]
         
     | 
| 
       495 
503 
     | 
    
         | 
| 
       496 
     | 
    
         
            -
                    if  
     | 
| 
      
 504 
     | 
    
         
            +
                    if using_importmap?
         
     | 
| 
       497 
505 
     | 
    
         
             
                      GemfileEntry.floats "importmap-rails", "Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]"
         
     | 
| 
       498 
506 
     | 
    
         
             
                    else
         
     | 
| 
       499 
507 
     | 
    
         
             
                      GemfileEntry.floats "jsbundling-rails", "Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails]"
         
     | 
| 
         @@ -512,9 +520,12 @@ module Rails 
     | 
|
| 
       512 
520 
     | 
    
         
             
                    [ turbo_rails_entry, stimulus_rails_entry ]
         
     | 
| 
       513 
521 
     | 
    
         
             
                  end
         
     | 
| 
       514 
522 
     | 
    
         | 
| 
      
 523 
     | 
    
         
            +
                  def using_importmap?
         
     | 
| 
      
 524 
     | 
    
         
            +
                    !options.skip_javascript? && options[:javascript] == "importmap"
         
     | 
| 
      
 525 
     | 
    
         
            +
                  end
         
     | 
| 
      
 526 
     | 
    
         
            +
             
     | 
| 
       515 
527 
     | 
    
         
             
                  def using_js_runtime?
         
     | 
| 
       516 
     | 
    
         
            -
                    (options[: 
     | 
| 
       517 
     | 
    
         
            -
                      (options[:css] && !%w[tailwind sass].include?(options[:css]))
         
     | 
| 
      
 528 
     | 
    
         
            +
                    !options.skip_javascript? && (!using_importmap? || (options[:css] && !%w[tailwind sass].include?(options[:css])))
         
     | 
| 
       518 
529 
     | 
    
         
             
                  end
         
     | 
| 
       519 
530 
     | 
    
         | 
| 
       520 
531 
     | 
    
         
             
                  def using_node?
         
     | 
| 
         @@ -525,31 +536,35 @@ module Rails 
     | 
|
| 
       525 
536 
     | 
    
         
             
                    using_js_runtime? && %w[bun].include?(options[:javascript])
         
     | 
| 
       526 
537 
     | 
    
         
             
                  end
         
     | 
| 
       527 
538 
     | 
    
         | 
| 
      
 539 
     | 
    
         
            +
                  def capture_command(command, pattern = nil)
         
     | 
| 
      
 540 
     | 
    
         
            +
                    output = `#{command}`
         
     | 
| 
      
 541 
     | 
    
         
            +
                    if pattern
         
     | 
| 
      
 542 
     | 
    
         
            +
                      output[pattern]
         
     | 
| 
      
 543 
     | 
    
         
            +
                    else
         
     | 
| 
      
 544 
     | 
    
         
            +
                      output
         
     | 
| 
      
 545 
     | 
    
         
            +
                    end
         
     | 
| 
      
 546 
     | 
    
         
            +
                  rescue SystemCallError
         
     | 
| 
      
 547 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 548 
     | 
    
         
            +
                  end
         
     | 
| 
      
 549 
     | 
    
         
            +
             
     | 
| 
       528 
550 
     | 
    
         
             
                  def node_version
         
     | 
| 
       529 
551 
     | 
    
         
             
                    if using_node?
         
     | 
| 
       530 
552 
     | 
    
         
             
                      ENV.fetch("NODE_VERSION") do
         
     | 
| 
       531 
     | 
    
         
            -
                         
     | 
| 
       532 
     | 
    
         
            -
                      rescue
         
     | 
| 
       533 
     | 
    
         
            -
                        NODE_LTS_VERSION
         
     | 
| 
      
 553 
     | 
    
         
            +
                        capture_command("node --version", /\d+\.\d+\.\d+/) || NODE_LTS_VERSION
         
     | 
| 
       534 
554 
     | 
    
         
             
                      end
         
     | 
| 
       535 
555 
     | 
    
         
             
                    end
         
     | 
| 
       536 
556 
     | 
    
         
             
                  end
         
     | 
| 
       537 
557 
     | 
    
         | 
| 
       538 
558 
     | 
    
         
             
                  def dockerfile_yarn_version
         
     | 
| 
       539 
     | 
    
         
            -
                     
     | 
| 
       540 
     | 
    
         
            -
                  rescue
         
     | 
| 
       541 
     | 
    
         
            -
                    "latest"
         
     | 
| 
      
 559 
     | 
    
         
            +
                    capture_command("yarn --version", /\d+\.\d+\.\d+/) || "latest"
         
     | 
| 
       542 
560 
     | 
    
         
             
                  end
         
     | 
| 
       543 
561 
     | 
    
         | 
| 
       544 
562 
     | 
    
         
             
                  def yarn_through_corepack?
         
     | 
| 
       545 
     | 
    
         
            -
                     
     | 
| 
       546 
     | 
    
         
            -
                    dockerfile_yarn_version >= "2"
         
     | 
| 
      
 563 
     | 
    
         
            +
                    using_node? and "#{dockerfile_yarn_version}" >= "2"
         
     | 
| 
       547 
564 
     | 
    
         
             
                  end
         
     | 
| 
       548 
565 
     | 
    
         | 
| 
       549 
566 
     | 
    
         
             
                  def dockerfile_bun_version
         
     | 
| 
       550 
     | 
    
         
            -
                     
     | 
| 
       551 
     | 
    
         
            -
                  rescue
         
     | 
| 
       552 
     | 
    
         
            -
                    BUN_VERSION
         
     | 
| 
      
 567 
     | 
    
         
            +
                    capture_command("bun --version", /\d+\.\d+\.\d+/) || BUN_VERSION
         
     | 
| 
       553 
568 
     | 
    
         
             
                  end
         
     | 
| 
       554 
569 
     | 
    
         | 
| 
       555 
570 
     | 
    
         
             
                  def dockerfile_binfile_fixups
         
     | 
| 
         @@ -617,11 +632,16 @@ module Rails 
     | 
|
| 
       617 
632 
     | 
    
         
             
                  end
         
     | 
| 
       618 
633 
     | 
    
         | 
| 
       619 
634 
     | 
    
         
             
                  def ci_packages
         
     | 
| 
       620 
     | 
    
         
            -
                     
     | 
| 
       621 
     | 
    
         
            -
                       
     | 
| 
       622 
     | 
    
         
            -
             
     | 
| 
       623 
     | 
    
         
            -
                       
     | 
| 
       624 
     | 
    
         
            -
             
     | 
| 
      
 635 
     | 
    
         
            +
                    dockerfile_build_packages - [
         
     | 
| 
      
 636 
     | 
    
         
            +
                      # GitHub Actions doesn't have build-essential,
         
     | 
| 
      
 637 
     | 
    
         
            +
                      # but it's a meta-packages and all its dependencies are already installed.
         
     | 
| 
      
 638 
     | 
    
         
            +
                      "build-essential",
         
     | 
| 
      
 639 
     | 
    
         
            +
                      "git",
         
     | 
| 
      
 640 
     | 
    
         
            +
                      "pkg-config",
         
     | 
| 
      
 641 
     | 
    
         
            +
                      "libyaml-dev",
         
     | 
| 
      
 642 
     | 
    
         
            +
                      "unzip",
         
     | 
| 
      
 643 
     | 
    
         
            +
                      "python-is-python3",
         
     | 
| 
      
 644 
     | 
    
         
            +
                    ]
         
     | 
| 
       625 
645 
     | 
    
         
             
                  end
         
     | 
| 
       626 
646 
     | 
    
         | 
| 
       627 
647 
     | 
    
         
             
                  def css_gemfile_entry
         
     | 
| 
         @@ -644,6 +664,11 @@ module Rails 
     | 
|
| 
       644 
664 
     | 
    
         
             
                    end
         
     | 
| 
       645 
665 
     | 
    
         
             
                  end
         
     | 
| 
       646 
666 
     | 
    
         | 
| 
      
 667 
     | 
    
         
            +
                  def rails_command(command, command_options = {})
         
     | 
| 
      
 668 
     | 
    
         
            +
                    command_options[:capture] = true if options[:quiet]
         
     | 
| 
      
 669 
     | 
    
         
            +
                    super
         
     | 
| 
      
 670 
     | 
    
         
            +
                  end
         
     | 
| 
      
 671 
     | 
    
         
            +
             
     | 
| 
       647 
672 
     | 
    
         
             
                  def bundle_install?
         
     | 
| 
       648 
673 
     | 
    
         
             
                    !(options[:skip_bundle] || options[:pretend])
         
     | 
| 
       649 
674 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -738,12 +763,6 @@ module Rails 
     | 
|
| 
       738 
763 
     | 
    
         
             
                    end
         
     | 
| 
       739 
764 
     | 
    
         
             
                  end
         
     | 
| 
       740 
765 
     | 
    
         | 
| 
       741 
     | 
    
         
            -
                  def generate_bundler_binstub
         
     | 
| 
       742 
     | 
    
         
            -
                    if bundle_install?
         
     | 
| 
       743 
     | 
    
         
            -
                      bundle_command("binstubs bundler")
         
     | 
| 
       744 
     | 
    
         
            -
                    end
         
     | 
| 
       745 
     | 
    
         
            -
                  end
         
     | 
| 
       746 
     | 
    
         
            -
             
     | 
| 
       747 
766 
     | 
    
         
             
                  def jruby?
         
     | 
| 
       748 
767 
     | 
    
         
             
                    defined?(JRUBY_VERSION)
         
     | 
| 
       749 
768 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -758,11 +777,13 @@ module Rails 
     | 
|
| 
       758 
777 
     | 
    
         
             
                  end
         
     | 
| 
       759 
778 
     | 
    
         | 
| 
       760 
779 
     | 
    
         
             
                  def user_default_branch
         
     | 
| 
       761 
     | 
    
         
            -
                    @user_default_branch ||=  
     | 
| 
      
 780 
     | 
    
         
            +
                    @user_default_branch ||= capture_command("git config init.defaultbranch").strip.presence || "main"
         
     | 
| 
       762 
781 
     | 
    
         
             
                  end
         
     | 
| 
       763 
782 
     | 
    
         | 
| 
       764 
783 
     | 
    
         
             
                  def git_init_command
         
     | 
| 
       765 
     | 
    
         
            -
                     
     | 
| 
      
 784 
     | 
    
         
            +
                    if capture_command("git config init.defaultbranch").present?
         
     | 
| 
      
 785 
     | 
    
         
            +
                      return "git init"
         
     | 
| 
      
 786 
     | 
    
         
            +
                    end
         
     | 
| 
       766 
787 
     | 
    
         | 
| 
       767 
788 
     | 
    
         
             
                    git_version = `git --version`[/\d+\.\d+\.\d+/]
         
     | 
| 
       768 
789 
     | 
    
         | 
| 
         @@ -5,6 +5,8 @@ require "rails/generators/erb" 
     | 
|
| 
       5 
5 
     | 
    
         
             
            module Erb # :nodoc:
         
     | 
| 
       6 
6 
     | 
    
         
             
              module Generators # :nodoc:
         
     | 
| 
       7 
7 
     | 
    
         
             
                class AuthenticationGenerator < Rails::Generators::Base # :nodoc:
         
     | 
| 
      
 8 
     | 
    
         
            +
                  hide!
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
       8 
10 
     | 
    
         
             
                  def create_files
         
     | 
| 
       9 
11 
     | 
    
         
             
                    template "app/views/passwords/new.html.erb"
         
     | 
| 
       10 
12 
     | 
    
         
             
                    template "app/views/passwords/edit.html.erb"
         
     | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            <div id="<%%= dom_id <%= singular_name %> %>">
         
     | 
| 
       2 
2 
     | 
    
         
             
            <% attributes.reject(&:password_digest?).each do |attribute| -%>
         
     | 
| 
       3 
     | 
    
         
            -
              < 
     | 
| 
      
 3 
     | 
    
         
            +
              <div>
         
     | 
| 
       4 
4 
     | 
    
         
             
                <strong><%= attribute.human_name %>:</strong>
         
     | 
| 
       5 
5 
     | 
    
         
             
            <% if attribute.attachment? -%>
         
     | 
| 
       6 
6 
     | 
    
         
             
                <%%= link_to <%= singular_name %>.<%= attribute.column_name %>.filename, <%= singular_name %>.<%= attribute.column_name %> if <%= singular_name %>.<%= attribute.column_name %>.attached? %>
         
     | 
| 
         @@ -11,7 +11,7 @@ 
     | 
|
| 
       11 
11 
     | 
    
         
             
            <% else -%>
         
     | 
| 
       12 
12 
     | 
    
         
             
                <%%= <%= singular_name %>.<%= attribute.column_name %> %>
         
     | 
| 
       13 
13 
     | 
    
         
             
            <% end -%>
         
     | 
| 
       14 
     | 
    
         
            -
              </ 
     | 
| 
      
 14 
     | 
    
         
            +
              </div>
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
            <% end -%>
         
     | 
| 
       17 
17 
     | 
    
         
             
            </div>
         
     | 
| 
         @@ -73,7 +73,7 @@ module Rails 
     | 
|
| 
       73 
73 
     | 
    
         
             
                    def valid_type?(type)
         
     | 
| 
       74 
74 
     | 
    
         
             
                      DEFAULT_TYPES.include?(type.to_s) ||
         
     | 
| 
       75 
75 
     | 
    
         
             
                        !defined?(ActiveRecord::Base) ||
         
     | 
| 
       76 
     | 
    
         
            -
                        ActiveRecord::Base. 
     | 
| 
      
 76 
     | 
    
         
            +
                        ActiveRecord::Base.connection_db_config.adapter_class.valid_type?(type)
         
     | 
| 
       77 
77 
     | 
    
         
             
                    end
         
     | 
| 
       78 
78 
     | 
    
         | 
| 
       79 
79 
     | 
    
         
             
                    def valid_index_type?(index_type)
         
     | 
| 
         @@ -109,7 +109,7 @@ module Rails 
     | 
|
| 
       109 
109 
     | 
    
         
             
                end
         
     | 
| 
       110 
110 
     | 
    
         | 
| 
       111 
111 
     | 
    
         
             
                def bin
         
     | 
| 
       112 
     | 
    
         
            -
                  exclude_pattern = Regexp.union([(/thrust/ if skip_thruster?), (/rubocop/ if skip_rubocop?), (/brakeman/ if skip_brakeman?)].compact)
         
     | 
| 
      
 112 
     | 
    
         
            +
                  exclude_pattern = Regexp.union([(/thrust/ if skip_thruster?), (/rubocop/ if skip_rubocop?), (/brakeman/ if skip_brakeman?), (/bundler-audit/ if skip_bundler_audit?)].compact)
         
     | 
| 
       113 
113 
     | 
    
         
             
                  directory "bin", { exclude_pattern: exclude_pattern } do |content|
         
     | 
| 
       114 
114 
     | 
    
         
             
                    "#{shebang}\n" + content
         
     | 
| 
       115 
115 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -127,7 +127,9 @@ module Rails 
     | 
|
| 
       127 
127 
     | 
    
         
             
                    template "routes.rb" unless options[:update]
         
     | 
| 
       128 
128 
     | 
    
         
             
                    template "application.rb"
         
     | 
| 
       129 
129 
     | 
    
         
             
                    template "environment.rb"
         
     | 
| 
       130 
     | 
    
         
            -
                    template " 
     | 
| 
      
 130 
     | 
    
         
            +
                    template "bundler-audit.yml" unless skip_bundler_audit?
         
     | 
| 
      
 131 
     | 
    
         
            +
                    template "cable.yml" unless options[:update] || skip_action_cable?
         
     | 
| 
      
 132 
     | 
    
         
            +
                    template "ci.rb"
         
     | 
| 
       131 
133 
     | 
    
         
             
                    template "puma.rb"
         
     | 
| 
       132 
134 
     | 
    
         
             
                    template "storage.yml" unless options[:update] || skip_active_storage?
         
     | 
| 
       133 
135 
     | 
    
         | 
| 
         @@ -140,6 +142,8 @@ module Rails 
     | 
|
| 
       140 
142 
     | 
    
         
             
                def config_when_updating
         
     | 
| 
       141 
143 
     | 
    
         
             
                  action_cable_config_exist       = File.exist?("config/cable.yml")
         
     | 
| 
       142 
144 
     | 
    
         
             
                  active_storage_config_exist     = File.exist?("config/storage.yml")
         
     | 
| 
      
 145 
     | 
    
         
            +
                  ci_config_exist                 = File.exist?("config/ci.rb")
         
     | 
| 
      
 146 
     | 
    
         
            +
                  bundle_audit_config_exist       = File.exist?("config/bundler-audit.yml")
         
     | 
| 
       143 
147 
     | 
    
         
             
                  rack_cors_config_exist          = File.exist?("config/initializers/cors.rb")
         
     | 
| 
       144 
148 
     | 
    
         
             
                  assets_config_exist             = File.exist?("config/initializers/assets.rb")
         
     | 
| 
       145 
149 
     | 
    
         
             
                  asset_app_stylesheet_exist      = File.exist?("app/assets/stylesheets/application.css")
         
     | 
| 
         @@ -149,7 +153,7 @@ module Rails 
     | 
|
| 
       149 
153 
     | 
    
         | 
| 
       150 
154 
     | 
    
         
             
                  config
         
     | 
| 
       151 
155 
     | 
    
         | 
| 
       152 
     | 
    
         
            -
                  if ! 
     | 
| 
      
 156 
     | 
    
         
            +
                  if !skip_action_cable? && !action_cable_config_exist
         
     | 
| 
       153 
157 
     | 
    
         
             
                    template "config/cable.yml"
         
     | 
| 
       154 
158 
     | 
    
         
             
                  end
         
     | 
| 
       155 
159 
     | 
    
         | 
| 
         @@ -157,6 +161,10 @@ module Rails 
     | 
|
| 
       157 
161 
     | 
    
         
             
                    template "config/storage.yml"
         
     | 
| 
       158 
162 
     | 
    
         
             
                  end
         
     | 
| 
       159 
163 
     | 
    
         | 
| 
      
 164 
     | 
    
         
            +
                  if !ci_config_exist
         
     | 
| 
      
 165 
     | 
    
         
            +
                    template "config/ci.rb"
         
     | 
| 
      
 166 
     | 
    
         
            +
                  end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
       160 
168 
     | 
    
         
             
                  if skip_asset_pipeline? && !assets_config_exist
         
     | 
| 
       161 
169 
     | 
    
         
             
                    remove_file "config/initializers/assets.rb"
         
     | 
| 
       162 
170 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -169,6 +177,10 @@ module Rails 
     | 
|
| 
       169 
177 
     | 
    
         
             
                    remove_file "config/initializers/cors.rb"
         
     | 
| 
       170 
178 
     | 
    
         
             
                  end
         
     | 
| 
       171 
179 
     | 
    
         | 
| 
      
 180 
     | 
    
         
            +
                  if !skip_bundler_audit? && !bundle_audit_config_exist
         
     | 
| 
      
 181 
     | 
    
         
            +
                    template "config/bundler-audit.yml"
         
     | 
| 
      
 182 
     | 
    
         
            +
                  end
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
       172 
184 
     | 
    
         
             
                  if options[:api]
         
     | 
| 
       173 
185 
     | 
    
         
             
                    unless csp_config_exist
         
     | 
| 
       174 
186 
     | 
    
         
             
                      remove_file "config/initializers/content_security_policy.rb"
         
     | 
| 
         @@ -182,7 +194,6 @@ module Rails 
     | 
|
| 
       182 
194 
     | 
    
         
             
                  require "rails/generators/rails/master_key/master_key_generator"
         
     | 
| 
       183 
195 
     | 
    
         
             
                  master_key_generator = Rails::Generators::MasterKeyGenerator.new([], quiet: options[:quiet], force: options[:force])
         
     | 
| 
       184 
196 
     | 
    
         
             
                  master_key_generator.add_master_key_file_silently
         
     | 
| 
       185 
     | 
    
         
            -
                  master_key_generator.ignore_master_key_file_silently
         
     | 
| 
       186 
197 
     | 
    
         
             
                end
         
     | 
| 
       187 
198 
     | 
    
         | 
| 
       188 
199 
     | 
    
         
             
                def credentials
         
     | 
| 
         @@ -306,6 +317,7 @@ module Rails 
     | 
|
| 
       306 
317 
     | 
    
         
             
                        :skip_active_storage,
         
     | 
| 
       307 
318 
     | 
    
         
             
                        :skip_bootsnap,
         
     | 
| 
       308 
319 
     | 
    
         
             
                        :skip_brakeman,
         
     | 
| 
      
 320 
     | 
    
         
            +
                        :skip_bundler_audit,
         
     | 
| 
       309 
321 
     | 
    
         
             
                        :skip_ci,
         
     | 
| 
       310 
322 
     | 
    
         
             
                        :skip_dev_gems,
         
     | 
| 
       311 
323 
     | 
    
         
             
                        :skip_docker,
         
     | 
| 
         @@ -570,7 +582,6 @@ module Rails 
     | 
|
| 
       570 
582 
     | 
    
         
             
                  public_task :apply_rails_template
         
     | 
| 
       571 
583 
     | 
    
         
             
                  public_task :run_bundle
         
     | 
| 
       572 
584 
     | 
    
         
             
                  public_task :add_bundler_platforms
         
     | 
| 
       573 
     | 
    
         
            -
                  public_task :generate_bundler_binstub
         
     | 
| 
       574 
585 
     | 
    
         
             
                  public_task :run_javascript
         
     | 
| 
       575 
586 
     | 
    
         
             
                  public_task :run_hotwire
         
     | 
| 
       576 
587 
     | 
    
         
             
                  public_task :run_css
         
     | 
| 
         @@ -17,18 +17,20 @@ WORKDIR /rails 
     | 
|
| 
       17 
17 
     | 
    
         
             
            # Install base packages
         
     | 
| 
       18 
18 
     | 
    
         
             
            RUN apt-get update -qq && \
         
     | 
| 
       19 
19 
     | 
    
         
             
                apt-get install --no-install-recommends -y <%= dockerfile_base_packages.join(" ") %> && \
         
     | 
| 
      
 20 
     | 
    
         
            +
                ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so && \
         
     | 
| 
       20 
21 
     | 
    
         
             
                rm -rf /var/lib/apt/lists /var/cache/apt/archives
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
            # Set production environment
         
     | 
| 
      
 23 
     | 
    
         
            +
            # Set production environment variables and enable jemalloc for reduced memory usage and latency.
         
     | 
| 
       23 
24 
     | 
    
         
             
            ENV RAILS_ENV="production" \
         
     | 
| 
       24 
25 
     | 
    
         
             
                BUNDLE_DEPLOYMENT="1" \
         
     | 
| 
       25 
26 
     | 
    
         
             
                BUNDLE_PATH="/usr/local/bundle" \
         
     | 
| 
       26 
     | 
    
         
            -
                BUNDLE_WITHOUT="development"
         
     | 
| 
      
 27 
     | 
    
         
            +
                BUNDLE_WITHOUT="development" \
         
     | 
| 
      
 28 
     | 
    
         
            +
                LD_PRELOAD="/usr/local/lib/libjemalloc.so"
         
     | 
| 
       27 
29 
     | 
    
         | 
| 
       28 
30 
     | 
    
         
             
            # Throw-away build stage to reduce size of final image
         
     | 
| 
       29 
31 
     | 
    
         
             
            FROM base AS build
         
     | 
| 
       30 
32 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
            # Install packages needed to build gems<%= using_node? ? " and node modules" : "" %>
         
     | 
| 
      
 33 
     | 
    
         
            +
            # Install packages needed to build gems<%= (using_node? || using_bun?) ? " and node modules" : "" %>
         
     | 
| 
       32 
34 
     | 
    
         
             
            RUN apt-get update -qq && \
         
     | 
| 
       33 
35 
     | 
    
         
             
                apt-get install --no-install-recommends -y <%= dockerfile_build_packages.join(" ") %> && \
         
     | 
| 
       34 
36 
     | 
    
         
             
                rm -rf /var/lib/apt/lists /var/cache/apt/archives
         
     | 
| 
         @@ -59,10 +61,12 @@ RUN curl -fsSL https://bun.sh/install | bash -s -- "bun-v${BUN_VERSION}" 
     | 
|
| 
       59 
61 
     | 
    
         | 
| 
       60 
62 
     | 
    
         
             
            <% end -%>
         
     | 
| 
       61 
63 
     | 
    
         
             
            # Install application gems
         
     | 
| 
       62 
     | 
    
         
            -
            COPY Gemfile Gemfile.lock ./
         
     | 
| 
      
 64 
     | 
    
         
            +
            COPY Gemfile Gemfile.lock vendor ./
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
       63 
66 
     | 
    
         
             
            RUN bundle install && \
         
     | 
| 
       64 
67 
     | 
    
         
             
                rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git<% if depend_on_bootsnap? -%> && \
         
     | 
| 
       65 
     | 
    
         
            -
                 
     | 
| 
      
 68 
     | 
    
         
            +
                # -j 1 disable parallel compilation to avoid a QEMU bug: https://github.com/rails/bootsnap/issues/495
         
     | 
| 
      
 69 
     | 
    
         
            +
                bundle exec bootsnap precompile -j 1 --gemfile<% end %>
         
     | 
| 
       66 
70 
     | 
    
         | 
| 
       67 
71 
     | 
    
         
             
            <% if using_node? -%>
         
     | 
| 
       68 
72 
     | 
    
         
             
            # Install node modules
         
     | 
| 
         @@ -80,8 +84,9 @@ RUN bun install --frozen-lockfile 
     | 
|
| 
       80 
84 
     | 
    
         
             
            COPY . .
         
     | 
| 
       81 
85 
     | 
    
         | 
| 
       82 
86 
     | 
    
         
             
            <% if depend_on_bootsnap? -%>
         
     | 
| 
       83 
     | 
    
         
            -
            # Precompile bootsnap code for faster boot times
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
      
 87 
     | 
    
         
            +
            # Precompile bootsnap code for faster boot times.
         
     | 
| 
      
 88 
     | 
    
         
            +
            # -j 1 disable parallel compilation to avoid a QEMU bug: https://github.com/rails/bootsnap/issues/495
         
     | 
| 
      
 89 
     | 
    
         
            +
            RUN bundle exec bootsnap precompile -j 1 app/ lib/
         
     | 
| 
       85 
90 
     | 
    
         | 
| 
       86 
91 
     | 
    
         
             
            <% end -%>
         
     | 
| 
       87 
92 
     | 
    
         
             
            <% unless dockerfile_binfile_fixups.empty? -%>
         
     | 
| 
         @@ -95,23 +100,22 @@ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile 
     | 
|
| 
       95 
100 
     | 
    
         | 
| 
       96 
101 
     | 
    
         
             
            <% end -%>
         
     | 
| 
       97 
102 
     | 
    
         | 
| 
       98 
     | 
    
         
            -
            <% if using_node? -%>
         
     | 
| 
      
 103 
     | 
    
         
            +
            <% if using_node? || using_bun? -%>
         
     | 
| 
       99 
104 
     | 
    
         
             
            RUN rm -rf node_modules
         
     | 
| 
       100 
105 
     | 
    
         
             
            <% end %>
         
     | 
| 
       101 
106 
     | 
    
         | 
| 
       102 
107 
     | 
    
         
             
            # Final stage for app image
         
     | 
| 
       103 
108 
     | 
    
         
             
            FROM base
         
     | 
| 
       104 
109 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
            # Copy built artifacts: gems, application
         
     | 
| 
       106 
     | 
    
         
            -
            COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
         
     | 
| 
       107 
     | 
    
         
            -
            COPY --from=build /rails /rails
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
110 
     | 
    
         
             
            # Run and own only the runtime files as a non-root user for security
         
     | 
| 
       110 
111 
     | 
    
         
             
            RUN groupadd --system --gid 1000 rails && \
         
     | 
| 
       111 
     | 
    
         
            -
                useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash 
     | 
| 
       112 
     | 
    
         
            -
                chown -R rails:rails <%= dockerfile_chown_directories.join(" ") %>
         
     | 
| 
      
 112 
     | 
    
         
            +
                useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash
         
     | 
| 
       113 
113 
     | 
    
         
             
            USER 1000:1000
         
     | 
| 
       114 
114 
     | 
    
         | 
| 
      
 115 
     | 
    
         
            +
            # Copy built artifacts: gems, application
         
     | 
| 
      
 116 
     | 
    
         
            +
            COPY --chown=rails:rails --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
         
     | 
| 
      
 117 
     | 
    
         
            +
            COPY --chown=rails:rails --from=build /rails /rails
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
       115 
119 
     | 
    
         
             
            # Entrypoint prepares the database.
         
     | 
| 
       116 
120 
     | 
    
         
             
            ENTRYPOINT ["/rails/bin/docker-entrypoint"]
         
     | 
| 
       117 
121 
     | 
    
         | 
| 
         @@ -123,4 +127,4 @@ CMD ["./bin/rails", "server"] 
     | 
|
| 
       123 
127 
     | 
    
         
             
            # Start server via Thruster by default, this can be overwritten at runtime
         
     | 
| 
       124 
128 
     | 
    
         
             
            EXPOSE 80
         
     | 
| 
       125 
129 
     | 
    
         
             
            CMD ["./bin/thrust", "./bin/rails", "server"]
         
     | 
| 
       126 
     | 
    
         
            -
            <% end -%>
         
     | 
| 
      
 130 
     | 
    
         
            +
            <% end -%>
         
     | 
| 
         @@ -42,7 +42,7 @@ gem "thruster", require: false 
     | 
|
| 
       42 
42 
     | 
    
         
             
            <% unless skip_active_storage? -%>
         
     | 
| 
       43 
43 
     | 
    
         | 
| 
       44 
44 
     | 
    
         
             
            # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
            gem "image_processing", "~> 1.2"
         
     | 
| 
       46 
46 
     | 
    
         
             
            <% end -%>
         
     | 
| 
       47 
47 
     | 
    
         
             
            <%- if options.api? -%>
         
     | 
| 
       48 
48 
     | 
    
         | 
| 
         @@ -54,6 +54,11 @@ gem "thruster", require: false 
     | 
|
| 
       54 
54 
     | 
    
         
             
            group :development, :test do
         
     | 
| 
       55 
55 
     | 
    
         
             
              # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
         
     | 
| 
       56 
56 
     | 
    
         
             
              gem "debug", platforms: %i[ mri windows ], require: "debug/prelude"
         
     | 
| 
      
 57 
     | 
    
         
            +
            <%- unless options.skip_bundler_audit? -%>
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              # Audits gems for known security defects (use config/bundler-audit.yml to ignore issues)
         
     | 
| 
      
 60 
     | 
    
         
            +
              gem "bundler-audit", require: false
         
     | 
| 
      
 61 
     | 
    
         
            +
            <%- end -%>
         
     | 
| 
       57 
62 
     | 
    
         
             
            <%- unless options.skip_brakeman? -%>
         
     | 
| 
       58 
63 
     | 
    
         | 
| 
       59 
64 
     | 
    
         
             
              # Static analysis for security vulnerabilities [https://brakemanscanner.org/]
         
     | 
| 
         @@ -2,5 +2,10 @@ class ApplicationController < ActionController::<%= options.api? ? "API" : "Base 
     | 
|
| 
       2 
2 
     | 
    
         
             
            <%- unless options.api? -%>
         
     | 
| 
       3 
3 
     | 
    
         
             
              # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
         
     | 
| 
       4 
4 
     | 
    
         
             
              allow_browser versions: :modern
         
     | 
| 
      
 5 
     | 
    
         
            +
            <%- if using_importmap? -%>
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              # Changes to the importmap will invalidate the etag for HTML responses
         
     | 
| 
      
 8 
     | 
    
         
            +
              stale_when_importmap_changes
         
     | 
| 
      
 9 
     | 
    
         
            +
            <% end -%>
         
     | 
| 
       5 
10 
     | 
    
         
             
            <% end -%>
         
     | 
| 
       6 
11 
     | 
    
         
             
            end
         
     | 
| 
         @@ -4,6 +4,7 @@ 
     | 
|
| 
       4 
4 
     | 
    
         
             
                <title><%%= content_for(:title) || "<%= app_name.titleize %>" %></title>
         
     | 
| 
       5 
5 
     | 
    
         
             
                <meta name="viewport" content="width=device-width,initial-scale=1">
         
     | 
| 
       6 
6 
     | 
    
         
             
                <meta name="apple-mobile-web-app-capable" content="yes">
         
     | 
| 
      
 7 
     | 
    
         
            +
                <meta name="application-name" content="<%= app_name.titleize %>">
         
     | 
| 
       7 
8 
     | 
    
         
             
                <meta name="mobile-web-app-capable" content="yes">
         
     | 
| 
       8 
9 
     | 
    
         
             
                <%%= csrf_meta_tags %>
         
     | 
| 
       9 
10 
     | 
    
         
             
                <%%= csp_meta_tag %>
         
     | 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require "rubygems"
         
     | 
| 
       2 
2 
     | 
    
         
             
            require "bundler/setup"
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            #  
     | 
| 
      
 4 
     | 
    
         
            +
            # Explicit RuboCop config increases performance slightly while avoiding config confusion.
         
     | 
| 
       5 
5 
     | 
    
         
             
            ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__))
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            load Gem.bin_path("rubocop", "rubocop")
         
     |