railties 8.0.3 → 8.1.0.beta1
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 +72 -232
- data/lib/minitest/rails_plugin.rb +48 -12
- data/lib/rails/application/bootstrap.rb +5 -0
- data/lib/rails/application/configuration.rb +26 -0
- 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/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/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 +3 -3
- data/lib/rails/generators/actions.rb +2 -3
- data/lib/rails/generators/app_base.rb +37 -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 +12 -2
- data/lib/rails/generators/rails/app/templates/Dockerfile.tt +14 -12
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +3 -0
- 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 +34 -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 +5 -5
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +5 -0
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +16 -4
- 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 +66 -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 +101 -19
- data/lib/rails/generators/rails/app/templates/github/dependabot.yml +2 -2
- data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +3 -0
- data/lib/rails/generators/rails/app/templates/public/400.html +1 -1
- data/lib/rails/generators/rails/app/templates/public/404.html +2 -2
- data/lib/rails/generators/rails/app/templates/public/422.html +1 -1
- data/lib/rails/generators/rails/app/templates/public/500.html +2 -2
- data/lib/rails/generators/rails/authentication/authentication_generator.rb +17 -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/test/test_helpers/session_test_helper.rb.tt +15 -0
- 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/templates/devcontainer/Dockerfile.tt +4 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +2 -2
- 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/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 +3 -2
- 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/model/templates/fixtures.yml.tt +1 -1
- 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 +2 -3
- 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/templates/rails/info/notes.html.erb +23 -0
- data/lib/rails/templates/rails/mailers/email.html.erb +3 -2
- data/lib/rails/templates/rails/welcome/index.html.erb +17 -1
- 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 +19 -15
- 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/generators/{test_unit → rails}/authentication/templates/test/mailers/previews/passwords_mailer_preview.rb.tt +0 -0
@@ -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"
|
@@ -493,7 +494,7 @@ module Rails
|
|
493
494
|
def javascript_gemfile_entry
|
494
495
|
return if options[:skip_javascript]
|
495
496
|
|
496
|
-
if
|
497
|
+
if using_importmap?
|
497
498
|
GemfileEntry.floats "importmap-rails", "Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]"
|
498
499
|
else
|
499
500
|
GemfileEntry.floats "jsbundling-rails", "Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails]"
|
@@ -512,9 +513,12 @@ module Rails
|
|
512
513
|
[ turbo_rails_entry, stimulus_rails_entry ]
|
513
514
|
end
|
514
515
|
|
516
|
+
def using_importmap?
|
517
|
+
!options.skip_javascript? && options[:javascript] == "importmap"
|
518
|
+
end
|
519
|
+
|
515
520
|
def using_js_runtime?
|
516
|
-
(options[:
|
517
|
-
(options[:css] && !%w[tailwind sass].include?(options[:css]))
|
521
|
+
!options.skip_javascript? && (!using_importmap? || (options[:css] && !%w[tailwind sass].include?(options[:css])))
|
518
522
|
end
|
519
523
|
|
520
524
|
def using_node?
|
@@ -525,31 +529,35 @@ module Rails
|
|
525
529
|
using_js_runtime? && %w[bun].include?(options[:javascript])
|
526
530
|
end
|
527
531
|
|
532
|
+
def capture_command(command, pattern = nil)
|
533
|
+
output = `#{command}`
|
534
|
+
if pattern
|
535
|
+
output[pattern]
|
536
|
+
else
|
537
|
+
output
|
538
|
+
end
|
539
|
+
rescue SystemCallError
|
540
|
+
nil
|
541
|
+
end
|
542
|
+
|
528
543
|
def node_version
|
529
544
|
if using_node?
|
530
545
|
ENV.fetch("NODE_VERSION") do
|
531
|
-
|
532
|
-
rescue
|
533
|
-
NODE_LTS_VERSION
|
546
|
+
capture_command("node --version", /\d+\.\d+\.\d+/) || NODE_LTS_VERSION
|
534
547
|
end
|
535
548
|
end
|
536
549
|
end
|
537
550
|
|
538
551
|
def dockerfile_yarn_version
|
539
|
-
|
540
|
-
rescue
|
541
|
-
"latest"
|
552
|
+
capture_command("yarn --version", /\d+\.\d+\.\d+/) || "latest"
|
542
553
|
end
|
543
554
|
|
544
555
|
def yarn_through_corepack?
|
545
|
-
|
546
|
-
dockerfile_yarn_version >= "2"
|
556
|
+
using_node? and "#{dockerfile_yarn_version}" >= "2"
|
547
557
|
end
|
548
558
|
|
549
559
|
def dockerfile_bun_version
|
550
|
-
|
551
|
-
rescue
|
552
|
-
BUN_VERSION
|
560
|
+
capture_command("bun --version", /\d+\.\d+\.\d+/) || BUN_VERSION
|
553
561
|
end
|
554
562
|
|
555
563
|
def dockerfile_binfile_fixups
|
@@ -617,11 +625,16 @@ module Rails
|
|
617
625
|
end
|
618
626
|
|
619
627
|
def ci_packages
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
628
|
+
dockerfile_build_packages - [
|
629
|
+
# GitHub Actions doesn't have build-essential,
|
630
|
+
# but it's a meta-packages and all its dependencies are already installed.
|
631
|
+
"build-essential",
|
632
|
+
"git",
|
633
|
+
"pkg-config",
|
634
|
+
"libyaml-dev",
|
635
|
+
"unzip",
|
636
|
+
"python-is-python3",
|
637
|
+
]
|
625
638
|
end
|
626
639
|
|
627
640
|
def css_gemfile_entry
|
@@ -738,12 +751,6 @@ module Rails
|
|
738
751
|
end
|
739
752
|
end
|
740
753
|
|
741
|
-
def generate_bundler_binstub
|
742
|
-
if bundle_install?
|
743
|
-
bundle_command("binstubs bundler")
|
744
|
-
end
|
745
|
-
end
|
746
|
-
|
747
754
|
def jruby?
|
748
755
|
defined?(JRUBY_VERSION)
|
749
756
|
end
|
@@ -758,11 +765,13 @@ module Rails
|
|
758
765
|
end
|
759
766
|
|
760
767
|
def user_default_branch
|
761
|
-
@user_default_branch ||=
|
768
|
+
@user_default_branch ||= capture_command("git config init.defaultbranch").strip.presence || "main"
|
762
769
|
end
|
763
770
|
|
764
771
|
def git_init_command
|
765
|
-
|
772
|
+
if capture_command("git config init.defaultbranch").present?
|
773
|
+
return "git init"
|
774
|
+
end
|
766
775
|
|
767
776
|
git_version = `git --version`[/\d+\.\d+\.\d+/]
|
768
777
|
|
@@ -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)
|
@@ -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 "bundler-audit.yml"
|
130
131
|
template "cable.yml" unless options[:update] || options[: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")
|
@@ -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 !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
|
@@ -570,7 +581,6 @@ module Rails
|
|
570
581
|
public_task :apply_rails_template
|
571
582
|
public_task :run_bundle
|
572
583
|
public_task :add_bundler_platforms
|
573
|
-
public_task :generate_bundler_binstub
|
574
584
|
public_task :run_javascript
|
575
585
|
public_task :run_hotwire
|
576
586
|
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,7 +61,8 @@ 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
|
bundle exec bootsnap precompile --gemfile<% end %>
|
@@ -95,23 +98,22 @@ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
|
|
95
98
|
|
96
99
|
<% end -%>
|
97
100
|
|
98
|
-
<% if using_node? -%>
|
101
|
+
<% if using_node? || using_bun? -%>
|
99
102
|
RUN rm -rf node_modules
|
100
103
|
<% end %>
|
101
104
|
|
102
105
|
# Final stage for app image
|
103
106
|
FROM base
|
104
107
|
|
105
|
-
# Copy built artifacts: gems, application
|
106
|
-
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
|
107
|
-
COPY --from=build /rails /rails
|
108
|
-
|
109
108
|
# Run and own only the runtime files as a non-root user for security
|
110
109
|
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(" ") %>
|
110
|
+
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash
|
113
111
|
USER 1000:1000
|
114
112
|
|
113
|
+
# Copy built artifacts: gems, application
|
114
|
+
COPY --chown=rails:rails --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
|
115
|
+
COPY --chown=rails:rails --from=build /rails /rails
|
116
|
+
|
115
117
|
# Entrypoint prepares the database.
|
116
118
|
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
|
117
119
|
|
@@ -123,4 +125,4 @@ CMD ["./bin/rails", "server"]
|
|
123
125
|
# Start server via Thruster by default, this can be overwritten at runtime
|
124
126
|
EXPOSE 80
|
125
127
|
CMD ["./bin/thrust", "./bin/rails", "server"]
|
126
|
-
<% end -%>
|
128
|
+
<% end -%>
|
@@ -54,6 +54,9 @@ 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
|
+
|
58
|
+
# Audits gems for known security defects (use config/bundler-audit.yml to ignore issues)
|
59
|
+
gem "bundler-audit", require: false
|
57
60
|
<%- unless options.skip_brakeman? -%>
|
58
61
|
|
59
62
|
# 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")
|
@@ -0,0 +1,34 @@
|
|
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
|
+
step "Security: Gem audit", "bin/bundler-audit"
|
10
|
+
<% if using_node? -%>
|
11
|
+
step "Security: Yarn vulnerability audit", "yarn audit"
|
12
|
+
<% end -%>
|
13
|
+
<% if using_importmap? -%>
|
14
|
+
step "Security: Importmap vulnerability audit", "bin/importmap audit"
|
15
|
+
<% end -%>
|
16
|
+
<% unless options.skip_brakeman? -%>
|
17
|
+
step "Security: Brakeman code analysis", "bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error"
|
18
|
+
<% end -%>
|
19
|
+
<% if options[:api] || options[:skip_system_test] -%>
|
20
|
+
step "Tests: Rails", "bin/rails test"
|
21
|
+
<% else %>
|
22
|
+
step "Tests: Rails", "bin/rails test"
|
23
|
+
step "Tests: System", "bin/rails test:system"
|
24
|
+
<% end -%>
|
25
|
+
step "Tests: Seeds", "env RAILS_ENV=test bin/rails db:seed:replant"
|
26
|
+
|
27
|
+
# Optional: set a green GitHub commit status to unblock PR merge.
|
28
|
+
# Requires the `gh` CLI and `gh extension install basecamp/gh-signoff`.
|
29
|
+
# if success?
|
30
|
+
# step "Signoff: All systems go. Ready for merge and deploy.", "gh signoff"
|
31
|
+
# else
|
32
|
+
# failure "Signoff: CI failed. Do not merge or deploy.", "Fix the issues and try again."
|
33
|
+
# end
|
34
|
+
end
|
@@ -12,7 +12,7 @@
|
|
12
12
|
default: &default
|
13
13
|
adapter: mysql2
|
14
14
|
encoding: utf8mb4
|
15
|
-
|
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=/
|
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
|
-
|
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
|
#
|
@@ -12,7 +12,7 @@
|
|
12
12
|
default: &default
|
13
13
|
adapter: trilogy
|
14
14
|
encoding: utf8mb4
|
15
|
-
|
15
|
+
max_connections: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
16
16
|
username: root
|
17
17
|
password:
|
18
18
|
host: <%%= ENV.fetch("DB_HOST") { "<%= database.host %>" } %>
|
@@ -51,6 +51,14 @@ test:
|
|
51
51
|
# production:
|
52
52
|
# url: <%%= ENV["MY_APP_DATABASE_URL"] %>
|
53
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 -%>
|
54
62
|
# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
|
55
63
|
# for a full overview on how database connection configuration can be specified.
|
56
64
|
#
|
@@ -38,7 +38,7 @@ env:
|
|
38
38
|
<% if skip_solid? -%>
|
39
39
|
# clear:
|
40
40
|
# # Set number of cores available to the application on each server (default: 1).
|
41
|
-
# WEB_CONCURRENCY:
|
41
|
+
# WEB_CONCURRENCY: auto
|
42
42
|
|
43
43
|
# # Match this to any external database server to configure Active Record correctly
|
44
44
|
# DB_HOST: 192.168.0.2
|
@@ -71,15 +71,15 @@ aliases:
|
|
71
71
|
console: app exec --interactive --reuse "bin/rails console"
|
72
72
|
shell: app exec --interactive --reuse "bash"
|
73
73
|
logs: app logs -f
|
74
|
-
dbc: app exec --interactive --reuse "bin/rails dbconsole"
|
74
|
+
dbc: app exec --interactive --reuse "bin/rails dbconsole --include-password"
|
75
75
|
|
76
|
-
<% unless skip_storage?
|
76
|
+
<% unless skip_storage? -%>
|
77
77
|
# Use a persistent storage volume for sqlite database files and local Active Storage files.
|
78
78
|
# Recommended to change this to a mounted volume path that is backed up off server.
|
79
79
|
volumes:
|
80
80
|
- "<%= app_name %>_storage:/rails/storage"
|
81
81
|
|
82
|
-
<% end
|
82
|
+
<% end -%>
|
83
83
|
# Bridge fingerprinted assets, like JS and CSS, between versions to avoid
|
84
84
|
# hitting 404 on in-flight requests. Combines all files from new and old
|
85
85
|
# version inside the asset_path.
|
@@ -121,7 +121,7 @@ builder:
|
|
121
121
|
# directories:
|
122
122
|
# - data:/var/lib/mysql
|
123
123
|
# redis:
|
124
|
-
# image:
|
124
|
+
# image: valkey/valkey:8
|
125
125
|
# host: 192.168.0.2
|
126
126
|
# port: 6379
|
127
127
|
# directories:
|