railties 8.0.0 → 8.1.2

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.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +126 -137
  3. data/README.rdoc +1 -1
  4. data/lib/minitest/rails_plugin.rb +56 -13
  5. data/lib/rails/application/bootstrap.rb +6 -3
  6. data/lib/rails/application/configuration.rb +36 -16
  7. data/lib/rails/application/default_middleware_stack.rb +1 -1
  8. data/lib/rails/application/finisher.rb +2 -1
  9. data/lib/rails/application/routes_reloader.rb +1 -2
  10. data/lib/rails/application.rb +18 -13
  11. data/lib/rails/application_controller.rb +2 -0
  12. data/lib/rails/code_statistics.rb +6 -3
  13. data/lib/rails/command/base.rb +0 -2
  14. data/lib/rails/command/environment_argument.rb +0 -1
  15. data/lib/rails/command.rb +1 -1
  16. data/lib/rails/commands/app/update_command.rb +5 -0
  17. data/lib/rails/commands/console/irb_console.rb +7 -16
  18. data/lib/rails/commands/credentials/credentials_command.rb +25 -5
  19. data/lib/rails/commands/devcontainer/devcontainer_command.rb +1 -0
  20. data/lib/rails/commands/encrypted/encrypted_command.rb +0 -1
  21. data/lib/rails/commands/test/test_command.rb +0 -2
  22. data/lib/rails/engine/lazy_route_set.rb +8 -11
  23. data/lib/rails/engine.rb +0 -1
  24. data/lib/rails/gem_version.rb +2 -2
  25. data/lib/rails/generators/actions.rb +9 -6
  26. data/lib/rails/generators/app_base.rb +72 -45
  27. data/lib/rails/generators/bundle_helper.rb +34 -0
  28. data/lib/rails/generators/database.rb +1 -1
  29. data/lib/rails/generators/erb/authentication/authentication_generator.rb +2 -0
  30. data/lib/rails/generators/erb/scaffold/templates/partial.html.erb.tt +2 -2
  31. data/lib/rails/generators/generated_attribute.rb +1 -1
  32. data/lib/rails/generators/migration.rb +0 -1
  33. data/lib/rails/generators/rails/app/app_generator.rb +31 -11
  34. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +28 -16
  35. data/lib/rails/generators/rails/app/templates/Gemfile.tt +8 -3
  36. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +5 -0
  37. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +1 -0
  38. data/lib/rails/generators/rails/app/templates/bin/bundler-audit.tt +5 -0
  39. data/lib/rails/generators/rails/app/templates/bin/ci.tt +5 -0
  40. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +1 -1
  41. data/lib/rails/generators/rails/app/templates/bin/setup.tt +1 -0
  42. data/lib/rails/generators/rails/app/templates/config/bundler-audit.yml.tt +5 -0
  43. data/lib/rails/generators/rails/app/templates/config/ci.rb.tt +40 -0
  44. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +10 -2
  45. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +10 -2
  46. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +11 -2
  47. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +16 -6
  48. data/lib/rails/generators/rails/app/templates/config/deploy.yml.tt +25 -18
  49. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +8 -0
  50. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +10 -2
  51. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +4 -0
  52. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_1.rb.tt +74 -0
  53. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +3 -2
  54. data/lib/rails/generators/rails/app/templates/config/storage.yml.tt +0 -7
  55. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +0 -6
  56. data/lib/rails/generators/rails/app/templates/dockerignore.tt +6 -0
  57. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +111 -23
  58. data/lib/rails/generators/rails/app/templates/github/dependabot.yml +2 -2
  59. data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +4 -1
  60. data/lib/rails/generators/rails/app/templates/public/400.html +26 -5
  61. data/lib/rails/generators/rails/app/templates/public/404.html +27 -6
  62. data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +25 -4
  63. data/lib/rails/generators/rails/app/templates/public/422.html +26 -5
  64. data/lib/rails/generators/rails/app/templates/public/500.html +27 -6
  65. data/lib/rails/generators/rails/app/templates/ruby-version.tt +1 -1
  66. data/lib/rails/generators/rails/authentication/authentication_generator.rb +14 -10
  67. data/lib/rails/generators/rails/authentication/templates/app/controllers/concerns/authentication.rb.tt +1 -4
  68. data/lib/rails/generators/rails/authentication/templates/app/controllers/passwords_controller.rb.tt +6 -0
  69. data/lib/rails/generators/rails/authentication/templates/app/controllers/sessions_controller.rb.tt +2 -2
  70. data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.html.erb.tt +3 -1
  71. data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.text.erb.tt +3 -1
  72. data/lib/rails/generators/rails/benchmark/USAGE +1 -1
  73. data/lib/rails/generators/rails/benchmark/templates/benchmark.rb.tt +0 -2
  74. data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
  75. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +8 -1
  76. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +4 -0
  77. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +2 -2
  78. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +1 -1
  79. data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +17 -5
  80. data/lib/rails/generators/rails/master_key/master_key_generator.rb +0 -12
  81. data/lib/rails/generators/rails/plugin/plugin_generator.rb +1 -0
  82. data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +0 -4
  83. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +23 -11
  84. data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +2 -2
  85. data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +2 -2
  86. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +2 -2
  87. data/lib/rails/generators/rails/script/USAGE +1 -1
  88. data/lib/rails/generators/test_unit/authentication/authentication_generator.rb +17 -0
  89. data/lib/rails/generators/test_unit/authentication/templates/test/controllers/passwords_controller_test.rb.tt +67 -0
  90. data/lib/rails/generators/test_unit/authentication/templates/test/controllers/sessions_controller_test.rb +33 -0
  91. data/lib/rails/generators/test_unit/authentication/templates/test/models/user_test.rb.tt +4 -3
  92. data/lib/rails/generators/test_unit/authentication/templates/test/test_helpers/session_test_helper.rb.tt +19 -0
  93. data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +1 -1
  94. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +8 -2
  95. data/lib/rails/generators/test_unit/scaffold/templates/application_system_test_case.rb.tt +5 -0
  96. data/lib/rails/generators/testing/behavior.rb +0 -3
  97. data/lib/rails/generators.rb +8 -6
  98. data/lib/rails/health_controller.rb +10 -2
  99. data/lib/rails/info.rb +4 -4
  100. data/lib/rails/info_controller.rb +4 -5
  101. data/lib/rails/initializable.rb +63 -19
  102. data/lib/rails/rack/silence_request.rb +5 -2
  103. data/lib/rails/railtie/configurable.rb +0 -1
  104. data/lib/rails/railtie.rb +0 -1
  105. data/lib/rails/source_annotation_extractor.rb +6 -2
  106. data/lib/rails/tasks/statistics.rake +3 -21
  107. data/lib/rails/tasks.rb +1 -3
  108. data/lib/rails/templates/rails/info/notes.html.erb +23 -0
  109. data/lib/rails/templates/rails/mailers/email.html.erb +3 -2
  110. data/lib/rails/templates/rails/welcome/index.html.erb +19 -3
  111. data/lib/rails/test_unit/line_filtering.rb +24 -3
  112. data/lib/rails/test_unit/reporter.rb +12 -6
  113. data/lib/rails/test_unit/runner.rb +15 -8
  114. data/lib/rails/test_unit/test_parser.rb +18 -15
  115. data/lib/rails.rb +9 -2
  116. metadata +37 -21
  117. data/lib/rails/console/methods.rb +0 -7
  118. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_0.rb.tt +0 -30
  119. data/lib/rails/generators/test_unit/plugin/plugin_generator.rb +0 -15
  120. data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +0 -7
  121. data/lib/rails/generators/test_unit/plugin/templates/test_helper.rb +0 -2
  122. /data/lib/rails/generators/{rails → test_unit}/authentication/templates/test/mailers/previews/passwords_mailer_preview.rb.tt +0 -0
@@ -218,7 +218,7 @@ module Rails
218
218
  end
219
219
 
220
220
  def base_package
221
- nil
221
+ "default-mysql-client"
222
222
  end
223
223
 
224
224
  def build_package
@@ -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
- <p>
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
- </p>
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.lease_connection.valid_type?(type)
76
+ ActiveRecord::Base.connection_db_config.adapter_class.valid_type?(type)
77
77
  end
78
78
 
79
79
  def valid_index_type?(index_type)
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/concern"
4
3
  require "rails/generators/actions/create_migration"
5
4
 
6
5
  module Rails
@@ -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 "cable.yml" unless options[:update] || options[:skip_action_cable]
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 !options[:skip_action_cable] && !action_cable_config_exist
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
@@ -244,9 +255,10 @@ module Rails
244
255
  end
245
256
 
246
257
  def system_test
247
- empty_directory_with_keep_file "test/system"
248
-
249
- template "test/application_system_test_case.rb"
258
+ if devcontainer? && depends_on_system_test?
259
+ empty_directory_with_keep_file "test/system"
260
+ template "test/application_system_test_case.rb"
261
+ end
250
262
  end
251
263
 
252
264
  def tmp
@@ -272,9 +284,10 @@ module Rails
272
284
  dev: options[:dev],
273
285
  node: using_node?,
274
286
  app_name: app_name,
275
- skip_solid: options[:skip_solid]
287
+ app_folder: File.basename(app_path),
288
+ skip_solid: options[:skip_solid],
289
+ pretend: options[:pretend]
276
290
  }
277
-
278
291
  Rails::Generators::DevcontainerGenerator.new([], devcontainer_options).invoke_all
279
292
  end
280
293
  end
@@ -305,11 +318,19 @@ module Rails
305
318
  :skip_active_job,
306
319
  :skip_active_storage,
307
320
  :skip_bootsnap,
321
+ :skip_brakeman,
322
+ :skip_bundler_audit,
323
+ :skip_ci,
308
324
  :skip_dev_gems,
325
+ :skip_docker,
309
326
  :skip_hotwire,
310
327
  :skip_javascript,
311
328
  :skip_jbuilder,
329
+ :skip_kamal,
330
+ :skip_rubocop,
331
+ :skip_solid,
312
332
  :skip_system_test,
333
+ :skip_thruster
313
334
  ],
314
335
  api: [
315
336
  :skip_asset_pipeline,
@@ -455,7 +476,7 @@ module Rails
455
476
  end
456
477
 
457
478
  def create_system_test_files
458
- build(:system_test) if depends_on_system_test?
479
+ build(:system_test)
459
480
  end
460
481
 
461
482
  def create_storage_files
@@ -563,7 +584,6 @@ module Rails
563
584
  public_task :apply_rails_template
564
585
  public_task :run_bundle
565
586
  public_task :add_bundler_platforms
566
- public_task :generate_bundler_binstub
567
587
  public_task :run_javascript
568
588
  public_task :run_hotwire
569
589
  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
@@ -38,10 +40,17 @@ RUN apt-get update -qq && \
38
40
  ARG NODE_VERSION=<%= node_version %>
39
41
  ARG YARN_VERSION=<%= dockerfile_yarn_version %>
40
42
  ENV PATH=/usr/local/node/bin:$PATH
43
+ <% if yarn_through_corepack? -%>
44
+ RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
45
+ /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
46
+ rm -rf /tmp/node-build-master
47
+ RUN corepack enable && yarn set version $YARN_VERSION
48
+ <% else -%>
41
49
  RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
42
50
  /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
43
51
  npm install -g yarn@$YARN_VERSION && \
44
52
  rm -rf /tmp/node-build-master
53
+ <% end -%>
45
54
 
46
55
  <% end -%>
47
56
  <% if using_bun? -%>
@@ -52,20 +61,23 @@ RUN curl -fsSL https://bun.sh/install | bash -s -- "bun-v${BUN_VERSION}"
52
61
 
53
62
  <% end -%>
54
63
  # Install application gems
64
+ COPY vendor/* ./vendor/
55
65
  COPY Gemfile Gemfile.lock ./
66
+
56
67
  RUN bundle install && \
57
68
  rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git<% if depend_on_bootsnap? -%> && \
58
- bundle exec bootsnap precompile --gemfile<% end %>
69
+ # -j 1 disable parallel compilation to avoid a QEMU bug: https://github.com/rails/bootsnap/issues/495
70
+ bundle exec bootsnap precompile -j 1 --gemfile<% end %>
59
71
 
60
72
  <% if using_node? -%>
61
73
  # Install node modules
62
74
  COPY package.json yarn.lock ./
63
- RUN yarn install --frozen-lockfile
75
+ RUN yarn install --immutable
64
76
 
65
77
  <% end -%>
66
78
  <% if using_bun? -%>
67
79
  # Install node modules
68
- COPY package.json bun.lockb ./
80
+ COPY package.json bun.lock* ./
69
81
  RUN bun install --frozen-lockfile
70
82
 
71
83
  <% end -%>
@@ -73,8 +85,9 @@ RUN bun install --frozen-lockfile
73
85
  COPY . .
74
86
 
75
87
  <% if depend_on_bootsnap? -%>
76
- # Precompile bootsnap code for faster boot times
77
- RUN bundle exec bootsnap precompile app/ lib/
88
+ # Precompile bootsnap code for faster boot times.
89
+ # -j 1 disable parallel compilation to avoid a QEMU bug: https://github.com/rails/bootsnap/issues/495
90
+ RUN bundle exec bootsnap precompile -j 1 app/ lib/
78
91
 
79
92
  <% end -%>
80
93
  <% unless dockerfile_binfile_fixups.empty? -%>
@@ -88,23 +101,22 @@ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
88
101
 
89
102
  <% end -%>
90
103
 
91
- <% if using_node? -%>
104
+ <% if using_node? || using_bun? -%>
92
105
  RUN rm -rf node_modules
93
106
  <% end %>
94
107
 
95
108
  # Final stage for app image
96
109
  FROM base
97
110
 
98
- # Copy built artifacts: gems, application
99
- COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
100
- COPY --from=build /rails /rails
101
-
102
111
  # Run and own only the runtime files as a non-root user for security
103
112
  RUN groupadd --system --gid 1000 rails && \
104
- useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
105
- chown -R rails:rails <%= dockerfile_chown_directories.join(" ") %>
113
+ useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash
106
114
  USER 1000:1000
107
115
 
116
+ # Copy built artifacts: gems, application
117
+ COPY --chown=rails:rails --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
118
+ COPY --chown=rails:rails --from=build /rails /rails
119
+
108
120
  # Entrypoint prepares the database.
109
121
  ENTRYPOINT ["/rails/bin/docker-entrypoint"]
110
122
 
@@ -116,4 +128,4 @@ CMD ["./bin/rails", "server"]
116
128
  # Start server via Thruster by default, this can be overwritten at runtime
117
129
  EXPOSE 80
118
130
  CMD ["./bin/thrust", "./bin/rails", "server"]
119
- <% end -%>
131
+ <% 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
- # gem "image_processing", "~> 1.2"
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/]
@@ -66,15 +71,15 @@ group :development, :test do
66
71
  <%- end -%>
67
72
  end
68
73
  <% end -%>
69
-
70
74
  <%- unless options.api? || options.skip_dev_gems? -%>
75
+
71
76
  group :development do
72
77
  # Use console on exceptions pages [https://github.com/rails/web-console]
73
78
  gem "web-console"
74
79
  end
75
80
  <%- end -%>
76
-
77
81
  <%- if depends_on_system_test? -%>
82
+
78
83
  group :test do
79
84
  # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
80
85
  gem "capybara"
@@ -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 %>
@@ -0,0 +1,5 @@
1
+ require_relative "../config/boot"
2
+ require "bundler/audit/cli"
3
+
4
+ ARGV.concat %w[ --config config/bundler-audit.yml ] if ARGV.empty? || ARGV.include?("check")
5
+ Bundler::Audit::CLI.start
@@ -0,0 +1,5 @@
1
+ require_relative "../config/boot"
2
+ require "active_support/continuous_integration"
3
+
4
+ CI = ActiveSupport::ContinuousIntegration
5
+ require_relative "../config/ci.rb"
@@ -1,7 +1,7 @@
1
1
  require "rubygems"
2
2
  require "bundler/setup"
3
3
 
4
- # explicit rubocop config increases performance slightly while avoiding config confusion.
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")
@@ -31,6 +31,7 @@ FileUtils.chdir APP_ROOT do
31
31
 
32
32
  puts "\n== Preparing database =="
33
33
  system! "bin/rails db:prepare"
34
+ system! "bin/rails db:reset" if ARGV.include?("--reset")
34
35
  <% end -%>
35
36
 
36
37
  puts "\n== Removing old logs and tempfiles =="
@@ -0,0 +1,5 @@
1
+ # Audit all gems listed in the Gemfile for known security problems by running bin/bundler-audit.
2
+ # CVEs that are not relevant to the application can be enumerated on the ignore list below.
3
+
4
+ ignore:
5
+ - CVE-THAT-DOES-NOT-APPLY
@@ -0,0 +1,40 @@
1
+ # Run using bin/ci
2
+
3
+ CI.run do
4
+ step "Setup", "bin/setup --skip-server"
5
+ <% unless options.skip_rubocop? %>
6
+ step "Style: Ruby", "bin/rubocop"
7
+ <% end -%>
8
+
9
+ <% unless options.skip_bundler_audit? -%>
10
+ step "Security: Gem audit", "bin/bundler-audit"
11
+ <% end -%>
12
+ <% if using_node? -%>
13
+ step "Security: Yarn vulnerability audit", "yarn audit"
14
+ <% end -%>
15
+ <% if using_importmap? -%>
16
+ step "Security: Importmap vulnerability audit", "bin/importmap audit"
17
+ <% end -%>
18
+ <% unless options.skip_brakeman? -%>
19
+ step "Security: Brakeman code analysis", "bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error"
20
+ <% end -%>
21
+ <% unless options[:skip_test] -%>
22
+ step "Tests: Rails", "bin/rails test"
23
+ <% unless options.skip_active_record? -%>
24
+ step "Tests: Seeds", "env RAILS_ENV=test bin/rails db:seed:replant"
25
+ <% end -%>
26
+ <% end -%>
27
+
28
+ <% unless options[:skip_test] -%>
29
+ # Optional: Run system tests
30
+ # step "Tests: System", "bin/rails test:system"
31
+ <% end -%>
32
+
33
+ # Optional: set a green GitHub commit status to unblock PR merge.
34
+ # Requires the `gh` CLI and `gh extension install basecamp/gh-signoff`.
35
+ # if success?
36
+ # step "Signoff: All systems go. Ready for merge and deploy.", "gh signoff"
37
+ # else
38
+ # failure "Signoff: CI failed. Do not merge or deploy.", "Fix the issues and try again."
39
+ # end
40
+ end
@@ -1,4 +1,4 @@
1
- # MySQL. Versions 5.5.8 and up are supported.
1
+ # MySQL. Versions 5.6.4 and up are supported.
2
2
  #
3
3
  # Install the MySQL driver
4
4
  # gem install mysql2
@@ -12,7 +12,7 @@
12
12
  default: &default
13
13
  adapter: mysql2
14
14
  encoding: utf8mb4
15
- pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
15
+ max_connections: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
16
16
  username: root
17
17
  password:
18
18
  <% if database.socket -%>
@@ -49,6 +49,14 @@ test:
49
49
  # production:
50
50
  # url: <%%= ENV["MY_APP_DATABASE_URL"] %>
51
51
  #
52
+ <%- unless options.skip_solid? -%>
53
+ # Connection URLs for non-primary databases can also be configured using
54
+ # environment variables. The variable name is formed by concatenating the
55
+ # connection name with `_DATABASE_URL`. For example:
56
+ #
57
+ # CACHE_DATABASE_URL="mysql2://cacheuser:cachepass@localhost/cachedatabase"
58
+ #
59
+ <%- end -%>
52
60
  # Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
53
61
  # for a full overview on how database connection configuration can be specified.
54
62
  #
@@ -3,7 +3,7 @@
3
3
  # Install the pg driver:
4
4
  # gem install pg
5
5
  # On macOS with Homebrew:
6
- # gem install pg -- --with-pg-config=/usr/local/bin/pg_config
6
+ # gem install pg -- --with-pg-config=/opt/homebrew/bin/pg_config
7
7
  # On Windows:
8
8
  # gem install pg
9
9
  # Choose the win32 build.
@@ -17,7 +17,7 @@ default: &default
17
17
  encoding: unicode
18
18
  # For details on connection pooling, see Rails configuration guide
19
19
  # https://guides.rubyonrails.org/configuring.html#database-pooling
20
- pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
20
+ max_connections: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
21
21
  <% if devcontainer? -%>
22
22
  <%% if ENV["DB_HOST"] %>
23
23
  host: <%%= ENV["DB_HOST"] %>
@@ -81,6 +81,14 @@ test:
81
81
  # production:
82
82
  # url: <%%= ENV["MY_APP_DATABASE_URL"] %>
83
83
  #
84
+ <%- unless options.skip_solid? -%>
85
+ # Connection URLs for non-primary databases can also be configured using
86
+ # environment variables. The variable name is formed by concatenating the
87
+ # connection name with `_DATABASE_URL`. For example:
88
+ #
89
+ # CACHE_DATABASE_URL="postgres://cacheuser:cachepass@localhost/cachedatabase"
90
+ #
91
+ <%- end -%>
84
92
  # Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
85
93
  # for a full overview on how database connection configuration can be specified.
86
94
  #
@@ -6,7 +6,7 @@
6
6
  #
7
7
  default: &default
8
8
  adapter: sqlite3
9
- pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
9
+ max_connections: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10
10
  timeout: 5000
11
11
 
12
12
  development:
@@ -20,7 +20,6 @@ test:
20
20
  <<: *default
21
21
  database: storage/test.sqlite3
22
22
 
23
-
24
23
  <%- if options.skip_kamal? -%>
25
24
  # SQLite3 write its data on the local filesystem, as such it requires
26
25
  # persistent disks. If you are deploying to a managed service, you should
@@ -41,6 +40,16 @@ production:
41
40
  <<: *default
42
41
  # database: path/to/persistent/storage/production_cache.sqlite3
43
42
  migrations_paths: db/cache_migrate
43
+ queue:
44
+ <<: *default
45
+ # database: path/to/persistent/storage/production_queue.sqlite3
46
+ migrations_paths: db/queue_migrate
47
+ <%- unless options.skip_action_cable? -%>
48
+ cable:
49
+ <<: *default
50
+ # database: path/to/persistent/storage/production_cable.sqlite3
51
+ migrations_paths: db/cable_migrate
52
+ <%- end -%>
44
53
  <%- end -%>
45
54
  <%- else -%>
46
55
  # Store production database in the storage/ directory, which by default
@@ -1,4 +1,4 @@
1
- # MySQL. Versions 5.5.8 and up are supported.
1
+ # MySQL. Versions 5.6.4 and up are supported.
2
2
  #
3
3
  # Install the MySQL driver
4
4
  # gem install trilogy
@@ -12,17 +12,16 @@
12
12
  default: &default
13
13
  adapter: trilogy
14
14
  encoding: utf8mb4
15
- pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
15
+ max_connections: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
16
16
  username: root
17
17
  password:
18
- <% if database.socket -%>
19
- socket: <%= database.socket %>
20
- <% else -%>
21
18
  host: <%%= ENV.fetch("DB_HOST") { "<%= database.host %>" } %>
22
- <% end -%>
23
19
 
24
20
  development:
25
21
  <<: *default
22
+ <% if database.socket -%>
23
+ socket: <%= database.socket %>
24
+ <% end -%>
26
25
  database: <%= app_name %>_development
27
26
 
28
27
  # Warning: The database defined as "test" will be erased and
@@ -30,6 +29,9 @@ development:
30
29
  # Do not set this db to the same as development or production.
31
30
  test:
32
31
  <<: *default
32
+ <% if database.socket -%>
33
+ socket: <%= database.socket %>
34
+ <% end -%>
33
35
  database: <%= app_name %>_test
34
36
 
35
37
  # As with config/credentials.yml, you never want to store sensitive information,
@@ -49,6 +51,14 @@ test:
49
51
  # production:
50
52
  # url: <%%= ENV["MY_APP_DATABASE_URL"] %>
51
53
  #
54
+ <%- unless options.skip_solid? -%>
55
+ # Connection URLs for non-primary databases can also be configured using
56
+ # environment variables. The variable name is formed by concatenating the
57
+ # connection name with `_DATABASE_URL`. For example:
58
+ #
59
+ # CACHE_DATABASE_URL="trilogy://cacheuser:cachepass@localhost/cachedatabase"
60
+ #
61
+ <%- end -%>
52
62
  # Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
53
63
  # for a full overview on how database connection configuration can be specified.
54
64
  #