railties 7.1.3.4 → 7.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +177 -742
- data/lib/minitest/rails_plugin.rb +5 -2
- data/lib/rails/all.rb +1 -3
- data/lib/rails/api/task.rb +6 -4
- data/lib/rails/application/bootstrap.rb +5 -6
- data/lib/rails/application/configuration.rb +73 -38
- data/lib/rails/application/dummy_config.rb +2 -2
- data/lib/rails/application/finisher.rb +7 -0
- data/lib/rails/application.rb +15 -86
- data/lib/rails/backtrace_cleaner.rb +18 -3
- data/lib/rails/cli.rb +0 -1
- data/lib/rails/command.rb +1 -1
- data/lib/rails/commands/app/update_command.rb +93 -0
- data/lib/rails/commands/boot/boot_command.rb +14 -0
- data/lib/rails/commands/console/console_command.rb +2 -21
- data/lib/rails/commands/console/irb_console.rb +137 -0
- data/lib/rails/commands/credentials/credentials_command.rb +2 -2
- data/lib/rails/commands/dbconsole/dbconsole_command.rb +21 -30
- data/lib/rails/commands/devcontainer/devcontainer_command.rb +39 -0
- data/lib/rails/commands/rake/rake_command.rb +1 -1
- data/lib/rails/commands/runner/runner_command.rb +14 -3
- data/lib/rails/commands/server/server_command.rb +5 -3
- data/lib/rails/commands/test/test_command.rb +2 -0
- data/lib/rails/configuration.rb +10 -1
- data/lib/rails/console/app.rb +5 -32
- data/lib/rails/console/helpers.rb +5 -16
- data/lib/rails/console/methods.rb +23 -0
- data/lib/rails/engine.rb +5 -5
- data/lib/rails/gem_version.rb +3 -3
- data/lib/rails/generators/app_base.rb +70 -49
- data/lib/rails/generators/base.rb +5 -1
- data/lib/rails/generators/database.rb +227 -69
- data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +2 -0
- data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +2 -0
- data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +2 -0
- data/lib/rails/generators/generated_attribute.rb +26 -1
- data/lib/rails/generators/migration.rb +3 -3
- data/lib/rails/generators/rails/app/app_generator.rb +53 -24
- data/lib/rails/generators/rails/app/templates/Dockerfile.tt +22 -15
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +16 -16
- data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
- data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
- data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
- data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
- data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
- data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
- data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +7 -0
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
- data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +14 -7
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +5 -0
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +8 -5
- data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +70 -0
- data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +24 -26
- data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +4 -0
- data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +5 -0
- data/lib/rails/generators/rails/app/templates/dockerignore.tt +13 -0
- data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +138 -0
- data/lib/rails/generators/rails/app/templates/github/dependabot.yml +12 -0
- data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -3
- data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +66 -0
- data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/icon.svg +3 -0
- data/lib/rails/generators/rails/app/templates/rubocop.yml.tt +8 -0
- data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt +1 -1
- data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
- data/lib/rails/generators/rails/db/system/change/change_generator.rb +131 -20
- data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +166 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +3 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +47 -0
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +37 -0
- data/lib/rails/generators/rails/migration/migration_generator.rb +4 -0
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +38 -7
- data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
- data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +5 -1
- data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +2 -0
- data/lib/rails/generators/rails/plugin/templates/bin/rubocop.tt +7 -0
- data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +103 -0
- data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +12 -0
- data/lib/rails/generators/rails/plugin/templates/rubocop.yml.tt +8 -0
- data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt +1 -1
- data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +6 -4
- data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
- data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +15 -1
- data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
- data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
- data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
- data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
- data/lib/rails/generators/testing/assertions.rb +20 -0
- data/lib/rails/generators/testing/behavior.rb +7 -6
- data/lib/rails/generators.rb +1 -1
- data/lib/rails/health_controller.rb +1 -1
- data/lib/rails/info.rb +2 -2
- data/lib/rails/mailers_controller.rb +14 -1
- data/lib/rails/paths.rb +2 -2
- data/lib/rails/pwa_controller.rb +15 -0
- data/lib/rails/rack/logger.rb +15 -7
- data/lib/rails/railtie/configurable.rb +2 -2
- data/lib/rails/railtie.rb +2 -3
- data/lib/rails/tasks/framework.rake +0 -26
- data/lib/rails/tasks/tmp.rake +1 -1
- data/lib/rails/templates/layouts/application.html.erb +1 -1
- data/lib/rails/templates/rails/mailers/email.html.erb +12 -8
- data/lib/rails/templates/rails/welcome/index.html.erb +4 -2
- data/lib/rails/test_help.rb +2 -4
- data/lib/rails/test_unit/reporter.rb +8 -2
- data/lib/rails/test_unit/runner.rb +26 -2
- data/lib/rails/test_unit/test_parser.rb +45 -0
- data/lib/rails.rb +7 -4
- metadata +42 -32
- data/lib/rails/app_updater.rb +0 -40
- data/lib/rails/commands/secrets/USAGE +0 -61
- data/lib/rails/commands/secrets/secrets_command.rb +0 -47
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
- data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
- data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -284
- data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
- data/lib/rails/ruby_version_check.rb +0 -17
- data/lib/rails/secrets.rb +0 -110
data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
#
|
3
|
+
# This file eases your Rails 7.2 framework defaults upgrade.
|
4
|
+
#
|
5
|
+
# Uncomment each configuration one by one to switch to the new default.
|
6
|
+
# Once your application is ready to run with all new defaults, you can remove
|
7
|
+
# this file and set the `config.load_defaults` to `7.2`.
|
8
|
+
#
|
9
|
+
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
|
10
|
+
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
|
11
|
+
|
12
|
+
###
|
13
|
+
# Controls whether Active Job's `#perform_later` and similar methods automatically defer
|
14
|
+
# the job queuing to after the current Active Record transaction is committed.
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
# Topic.transaction do
|
18
|
+
# topic = Topic.create(...)
|
19
|
+
# NewTopicNotificationJob.perform_later(topic)
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# In this example, if the configuration is set to `:never`, the job will
|
23
|
+
# be enqueued immediately, even though the `Topic` hasn't been committed yet.
|
24
|
+
# Because of this, if the job is picked up almost immediately, or if the
|
25
|
+
# transaction doesn't succeed for some reason, the job will fail to find this
|
26
|
+
# topic in the database.
|
27
|
+
#
|
28
|
+
# If `enqueue_after_transaction_commit` is set to `:default`, the queue adapter
|
29
|
+
# will define the behaviour.
|
30
|
+
#
|
31
|
+
# Note: Active Job backends can disable this feature. This is generally done by
|
32
|
+
# backends that use the same database as Active Record as a queue, hence they
|
33
|
+
# don't need this feature.
|
34
|
+
#++
|
35
|
+
# Rails.application.config.active_job.enqueue_after_transaction_commit = :default
|
36
|
+
|
37
|
+
###
|
38
|
+
# Adds image/webp to the list of content types Active Storage considers as an image
|
39
|
+
# Prevents automatic conversion to a fallback PNG, and assumes clients support WebP, as they support gif, jpeg, and png.
|
40
|
+
# This is possible due to broad browser support for WebP, but older browsers and email clients may still not support
|
41
|
+
# WebP. Requires imagemagick/libvips built with WebP support.
|
42
|
+
#++
|
43
|
+
# Rails.application.config.active_storage.web_image_content_types = %w[image/png image/jpeg image/gif image/webp]
|
44
|
+
|
45
|
+
###
|
46
|
+
# Enable validation of migration timestamps. When set, an ActiveRecord::InvalidMigrationTimestampError
|
47
|
+
# will be raised if the timestamp prefix for a migration is more than a day ahead of the timestamp
|
48
|
+
# associated with the current time. This is done to prevent forward-dating of migration files, which can
|
49
|
+
# impact migration generation and other migration commands.
|
50
|
+
#
|
51
|
+
# Applications with existing timestamped migrations that do not adhere to the
|
52
|
+
# expected format can disable validation by setting this config to `false`.
|
53
|
+
#++
|
54
|
+
# Rails.application.config.active_record.validate_migration_timestamps = true
|
55
|
+
|
56
|
+
###
|
57
|
+
# Controls whether the PostgresqlAdapter should decode dates automatically with manual queries.
|
58
|
+
#
|
59
|
+
# Example:
|
60
|
+
# ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date") #=> Date
|
61
|
+
#
|
62
|
+
# This query used to return a `String`.
|
63
|
+
#++
|
64
|
+
# Rails.application.config.active_record.postgresql_adapter_decode_dates = true
|
65
|
+
|
66
|
+
###
|
67
|
+
# Enables YJIT as of Ruby 3.3, to bring sizeable performance improvements. If you are
|
68
|
+
# deploying to a memory constrained environment you may want to set this to `false`.
|
69
|
+
#++
|
70
|
+
# Rails.application.config.yjit = true
|
@@ -2,34 +2,32 @@
|
|
2
2
|
# are invoked here are part of Puma's configuration DSL. For more information
|
3
3
|
# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.
|
4
4
|
|
5
|
-
# Puma
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
#
|
23
|
-
|
5
|
+
# Puma starts a configurable number of processes (workers) and each process
|
6
|
+
# serves each request in a thread from an internal thread pool.
|
7
|
+
#
|
8
|
+
# The ideal number of threads per worker depends both on how much time the
|
9
|
+
# application spends waiting for IO operations and on how much you wish to
|
10
|
+
# to prioritize throughput over latency.
|
11
|
+
#
|
12
|
+
# As a rule of thumb, increasing the number of threads will increase how much
|
13
|
+
# traffic a given process can handle (throughput), but due to CRuby's
|
14
|
+
# Global VM Lock (GVL) it has diminishing returns and will degrade the
|
15
|
+
# response time (latency) of the application.
|
16
|
+
#
|
17
|
+
# The default is set to 3 threads as it's deemed a decent compromise between
|
18
|
+
# throughput and latency for the average Rails application.
|
19
|
+
#
|
20
|
+
# Any libraries that use a connection pool or another resource pool should
|
21
|
+
# be configured to provide at least as many connections as the number of
|
22
|
+
# threads. This includes Active Record's `pool` parameter in `database.yml`.
|
23
|
+
threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
|
24
|
+
threads threads_count, threads_count
|
24
25
|
|
25
26
|
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
26
|
-
port ENV.fetch("PORT"
|
27
|
-
|
28
|
-
# Specifies the `environment` that Puma will run in.
|
29
|
-
environment ENV.fetch("RAILS_ENV") { "development" }
|
30
|
-
|
31
|
-
# Specifies the `pidfile` that Puma will use.
|
32
|
-
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
|
27
|
+
port ENV.fetch("PORT", 3000)
|
33
28
|
|
34
29
|
# Allow puma to be restarted by `bin/rails restart` command.
|
35
30
|
plugin :tmp_restart
|
31
|
+
|
32
|
+
# Only use a pidfile when requested
|
33
|
+
pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
|
@@ -5,6 +5,10 @@ Rails.application.routes.draw do
|
|
5
5
|
# Can be used by load balancers and uptime monitors to verify that the app is live.
|
6
6
|
get "up" => "rails/health#show", as: :rails_health_check
|
7
7
|
|
8
|
+
# Render dynamic PWA files from app/views/pwa/*
|
9
|
+
get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker
|
10
|
+
get "manifest" => "rails/pwa#manifest", as: :pwa_manifest
|
11
|
+
|
8
12
|
# Defines the root path route ("/")
|
9
13
|
# root "posts#index"
|
10
14
|
end
|
@@ -1,5 +1,10 @@
|
|
1
1
|
#!/bin/bash -e
|
2
2
|
|
3
|
+
# Enable jemalloc for reduced memory usage and latency.
|
4
|
+
if [ -z "${LD_PRELOAD+x}" ] && [ -f /usr/lib/*/libjemalloc.so.2 ]; then
|
5
|
+
export LD_PRELOAD="$(echo /usr/lib/*/libjemalloc.so.2)"
|
6
|
+
fi
|
7
|
+
|
3
8
|
<% unless skip_active_record? -%>
|
4
9
|
# If running the rails server then create or migrate existing database
|
5
10
|
if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
# Ignore git directory.
|
4
4
|
/.git/
|
5
|
+
/.gitignore
|
5
6
|
|
6
7
|
# Ignore bundler config.
|
7
8
|
/.bundle
|
@@ -41,3 +42,15 @@
|
|
41
42
|
!/app/assets/builds/.keep
|
42
43
|
/public/assets
|
43
44
|
<% end -%>
|
45
|
+
<% unless options.skip_ci? -%>
|
46
|
+
|
47
|
+
# Ignore CI service files.
|
48
|
+
/.github
|
49
|
+
<% end -%>
|
50
|
+
|
51
|
+
# Ignore development files
|
52
|
+
/.devcontainer
|
53
|
+
|
54
|
+
# Ignore Docker-related files
|
55
|
+
/.dockerignore
|
56
|
+
/Dockerfile*
|
@@ -0,0 +1,138 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
push:
|
6
|
+
branches: [ main ]
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
<%- unless skip_brakeman? -%>
|
10
|
+
scan_ruby:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- name: Checkout code
|
15
|
+
uses: actions/checkout@v4
|
16
|
+
|
17
|
+
- name: Set up Ruby
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: .ruby-version
|
21
|
+
bundler-cache: true
|
22
|
+
|
23
|
+
- name: Scan for common Rails security vulnerabilities using static analysis
|
24
|
+
run: bin/brakeman --no-pager
|
25
|
+
|
26
|
+
<% end -%>
|
27
|
+
<%- if options[:javascript] == "importmap" -%>
|
28
|
+
scan_js:
|
29
|
+
runs-on: ubuntu-latest
|
30
|
+
|
31
|
+
steps:
|
32
|
+
- name: Checkout code
|
33
|
+
uses: actions/checkout@v4
|
34
|
+
|
35
|
+
- name: Set up Ruby
|
36
|
+
uses: ruby/setup-ruby@v1
|
37
|
+
with:
|
38
|
+
ruby-version: .ruby-version
|
39
|
+
bundler-cache: true
|
40
|
+
|
41
|
+
- name: Scan for security vulnerabilities in JavaScript dependencies
|
42
|
+
run: bin/importmap audit
|
43
|
+
|
44
|
+
<% end -%>
|
45
|
+
<%- unless skip_rubocop? -%>
|
46
|
+
lint:
|
47
|
+
runs-on: ubuntu-latest
|
48
|
+
steps:
|
49
|
+
- name: Checkout code
|
50
|
+
uses: actions/checkout@v4
|
51
|
+
|
52
|
+
- name: Set up Ruby
|
53
|
+
uses: ruby/setup-ruby@v1
|
54
|
+
with:
|
55
|
+
ruby-version: .ruby-version
|
56
|
+
bundler-cache: true
|
57
|
+
|
58
|
+
- name: Lint code for consistent style
|
59
|
+
run: bin/rubocop -f github
|
60
|
+
|
61
|
+
<% end -%>
|
62
|
+
<% unless options[:skip_test] -%>
|
63
|
+
test:
|
64
|
+
runs-on: ubuntu-latest
|
65
|
+
|
66
|
+
<%- if options[:database] == "sqlite3" -%>
|
67
|
+
# services:
|
68
|
+
# redis:
|
69
|
+
# image: redis
|
70
|
+
# ports:
|
71
|
+
# - 6379:6379
|
72
|
+
# options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
|
73
|
+
<%- else -%>
|
74
|
+
services:
|
75
|
+
<%- if options[:database] == "mysql" || options[:database] == "trilogy" -%>
|
76
|
+
mysql:
|
77
|
+
image: mysql
|
78
|
+
env:
|
79
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: true
|
80
|
+
ports:
|
81
|
+
- 3306:3306
|
82
|
+
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
83
|
+
<%- elsif options[:database] == "postgresql" -%>
|
84
|
+
postgres:
|
85
|
+
image: postgres
|
86
|
+
env:
|
87
|
+
POSTGRES_USER: postgres
|
88
|
+
POSTGRES_PASSWORD: postgres
|
89
|
+
ports:
|
90
|
+
- 5432:5432
|
91
|
+
options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3
|
92
|
+
<%- end -%>
|
93
|
+
|
94
|
+
# redis:
|
95
|
+
# image: redis
|
96
|
+
# ports:
|
97
|
+
# - 6379:6379
|
98
|
+
# options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
|
99
|
+
|
100
|
+
<%- end -%>
|
101
|
+
steps:
|
102
|
+
- name: Install packages
|
103
|
+
run: sudo apt-get update && sudo apt-get install --no-install-recommends -y google-chrome-stable <%= dockerfile_base_packages.join(" ") %>
|
104
|
+
|
105
|
+
- name: Checkout code
|
106
|
+
uses: actions/checkout@v4
|
107
|
+
|
108
|
+
- name: Set up Ruby
|
109
|
+
uses: ruby/setup-ruby@v1
|
110
|
+
with:
|
111
|
+
ruby-version: .ruby-version
|
112
|
+
bundler-cache: true
|
113
|
+
<%- if using_bun? -%>
|
114
|
+
|
115
|
+
- uses: oven-sh/setup-bun@v1
|
116
|
+
with:
|
117
|
+
bun-version: <%= dockerfile_bun_version %>
|
118
|
+
<%- end -%>
|
119
|
+
|
120
|
+
- name: Run tests
|
121
|
+
env:
|
122
|
+
RAILS_ENV: test
|
123
|
+
<%- if options[:database] == "mysql" || options[:database] == "trilogy" -%>
|
124
|
+
DATABASE_URL: mysql2://127.0.0.1:3306
|
125
|
+
<%- elsif options[:database] == "postgresql" -%>
|
126
|
+
DATABASE_URL: postgres://postgres:postgres@localhost:5432
|
127
|
+
<%- end -%>
|
128
|
+
# REDIS_URL: redis://localhost:6379/0
|
129
|
+
run: bin/rails db:test:prepare test test:system
|
130
|
+
|
131
|
+
- name: Keep screenshots from failed system tests
|
132
|
+
uses: actions/upload-artifact@v4
|
133
|
+
if: failure()
|
134
|
+
with:
|
135
|
+
name: screenshots
|
136
|
+
path: ${{ github.workspace }}/tmp/screenshots
|
137
|
+
if-no-files-found: ignore
|
138
|
+
<% end -%>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
2
|
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
3
|
+
# Temporary files generated by your text editor or operating system
|
4
|
+
# belong in git's global ignore instead:
|
5
|
+
# `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore`
|
6
6
|
|
7
7
|
# Ignore bundler config.
|
8
8
|
/.bundle
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Your browser is not supported (406)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
.rails-default-error-page {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
.rails-default-error-page div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.rails-default-error-page div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
.rails-default-error-page h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.rails-default-error-page div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body class="rails-default-error-page">
|
58
|
+
<!-- This file lives in public/406-unsupported-browser.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>Your browser is not supported.</h1>
|
62
|
+
<p>Please upgrade your browser to continue.</p>
|
63
|
+
</div>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
Binary file
|
@@ -17,7 +17,7 @@ module Rails
|
|
17
17
|
def add_routes
|
18
18
|
return if options[:skip_routes]
|
19
19
|
return if actions.empty?
|
20
|
-
routing_code = actions.map { |action|
|
20
|
+
routing_code = actions.map { |action| %(get "#{file_name}/#{action}") }.join("\n")
|
21
21
|
route routing_code, namespace: regular_class_path
|
22
22
|
end
|
23
23
|
|
@@ -1,15 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rails/generators/base"
|
4
|
+
require "yaml"
|
5
|
+
require "json"
|
4
6
|
|
5
7
|
module Rails
|
6
8
|
module Generators
|
7
9
|
module Db
|
8
10
|
module System
|
9
11
|
class ChangeGenerator < Base # :nodoc:
|
10
|
-
include Database
|
11
12
|
include AppName
|
12
13
|
|
14
|
+
BASE_PACKAGES = %w( curl libvips )
|
15
|
+
BUILD_PACKAGES = %w( build-essential git )
|
16
|
+
|
13
17
|
class_option :to, required: true,
|
14
18
|
desc: "The database system to switch to."
|
15
19
|
|
@@ -21,8 +25,8 @@ module Rails
|
|
21
25
|
def initialize(*)
|
22
26
|
super
|
23
27
|
|
24
|
-
unless DATABASES.include?(options[:to])
|
25
|
-
raise Error, "Invalid value for --to option. Supported preconfigurations are: #{DATABASES.join(", ")}."
|
28
|
+
unless Database::DATABASES.include?(options[:to])
|
29
|
+
raise Error, "Invalid value for --to option. Supported preconfigurations are: #{Database::DATABASES.join(", ")}."
|
26
30
|
end
|
27
31
|
|
28
32
|
opt = options.dup
|
@@ -35,7 +39,7 @@ module Rails
|
|
35
39
|
end
|
36
40
|
|
37
41
|
def edit_gemfile
|
38
|
-
name, version =
|
42
|
+
name, version = database.gem
|
39
43
|
gsub_file("Gemfile", all_database_gems_regex, name)
|
40
44
|
gsub_file("Gemfile", gem_entry_regex_for(name), gem_entry_for(name, *version))
|
41
45
|
end
|
@@ -44,27 +48,44 @@ module Rails
|
|
44
48
|
dockerfile_path = File.expand_path("Dockerfile", destination_root)
|
45
49
|
return unless File.exist?(dockerfile_path)
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
gsub_file("Dockerfile", all_docker_bases_regex, docker_base_packages(database.base_package))
|
52
|
+
gsub_file("Dockerfile", all_docker_builds_regex, docker_build_packages(database.build_package))
|
53
|
+
end
|
54
|
+
|
55
|
+
def edit_devcontainer_files
|
56
|
+
return unless devcontainer?
|
57
|
+
|
58
|
+
edit_devcontainer_json
|
59
|
+
edit_compose_yaml
|
55
60
|
end
|
56
61
|
|
57
62
|
private
|
58
63
|
def all_database_gems
|
59
|
-
|
64
|
+
Database.all.map { |database| database.gem }
|
65
|
+
end
|
66
|
+
|
67
|
+
def all_docker_bases
|
68
|
+
Database.all.map { |database| docker_base_packages(database.base_package) }.uniq
|
69
|
+
end
|
70
|
+
|
71
|
+
def docker_base_packages(database_package)
|
72
|
+
if database_package
|
73
|
+
[database_package].concat(BASE_PACKAGES).sort
|
74
|
+
else
|
75
|
+
BASE_PACKAGES
|
76
|
+
end.join("\s")
|
60
77
|
end
|
61
78
|
|
62
79
|
def all_docker_builds
|
63
|
-
|
80
|
+
Database.all.map { |database| docker_build_packages(database.build_package) }.uniq
|
64
81
|
end
|
65
82
|
|
66
|
-
def
|
67
|
-
|
83
|
+
def docker_build_packages(database_package)
|
84
|
+
if database_package
|
85
|
+
[database_package].concat(BUILD_PACKAGES).sort
|
86
|
+
else
|
87
|
+
BUILD_PACKAGES
|
88
|
+
end.join("\s")
|
68
89
|
end
|
69
90
|
|
70
91
|
def all_database_gems_regex
|
@@ -72,12 +93,12 @@ module Rails
|
|
72
93
|
/(\b#{all_database_gem_names.join('\b|\b')}\b)/
|
73
94
|
end
|
74
95
|
|
75
|
-
def
|
76
|
-
/(\b#{
|
96
|
+
def all_docker_bases_regex
|
97
|
+
/(\b#{all_docker_bases.join('\b|\b')}\b)/
|
77
98
|
end
|
78
99
|
|
79
|
-
def
|
80
|
-
/(\b#{
|
100
|
+
def all_docker_builds_regex
|
101
|
+
/(\b#{all_docker_builds.join('\b|\b')}\b)/
|
81
102
|
end
|
82
103
|
|
83
104
|
def gem_entry_regex_for(gem_name)
|
@@ -88,6 +109,96 @@ module Rails
|
|
88
109
|
gem_name_and_version.map! { |segment| "\"#{segment}\"" }
|
89
110
|
"gem #{gem_name_and_version.join(", ")}"
|
90
111
|
end
|
112
|
+
|
113
|
+
def edit_devcontainer_json
|
114
|
+
return unless devcontainer_json
|
115
|
+
|
116
|
+
update_devcontainer_db_host
|
117
|
+
update_devcontainer_db_feature
|
118
|
+
end
|
119
|
+
|
120
|
+
def edit_compose_yaml
|
121
|
+
compose_yaml_path = File.expand_path(".devcontainer/compose.yaml", destination_root)
|
122
|
+
return unless File.exist?(compose_yaml_path)
|
123
|
+
|
124
|
+
compose_config = YAML.load_file(compose_yaml_path)
|
125
|
+
|
126
|
+
Database.all.each do |database|
|
127
|
+
compose_config["services"].delete(database.name)
|
128
|
+
compose_config["volumes"]&.delete(database.volume)
|
129
|
+
compose_config["services"]["rails-app"]["depends_on"]&.delete(database.name)
|
130
|
+
end
|
131
|
+
|
132
|
+
if database.service
|
133
|
+
compose_config["services"][database.name] = database.service
|
134
|
+
compose_config["volumes"] = { database.volume => nil }.merge(compose_config["volumes"] || {})
|
135
|
+
compose_config["services"]["rails-app"]["depends_on"] = [
|
136
|
+
database.name,
|
137
|
+
compose_config["services"]["rails-app"]["depends_on"]
|
138
|
+
].flatten.compact
|
139
|
+
end
|
140
|
+
|
141
|
+
compose_config.delete("volumes") unless compose_config["volumes"]&.any?
|
142
|
+
compose_config["services"]["rails-app"].delete("depends_on") unless compose_config["services"]["rails-app"]["depends_on"]&.any?
|
143
|
+
|
144
|
+
File.write(compose_yaml_path, compose_config.to_yaml)
|
145
|
+
end
|
146
|
+
|
147
|
+
def update_devcontainer_db_host
|
148
|
+
container_env = devcontainer_json["containerEnv"]
|
149
|
+
db_name = database.name
|
150
|
+
|
151
|
+
if container_env["DB_HOST"]
|
152
|
+
if database.service
|
153
|
+
container_env["DB_HOST"] = db_name
|
154
|
+
else
|
155
|
+
container_env.delete("DB_HOST")
|
156
|
+
end
|
157
|
+
else
|
158
|
+
if database.service
|
159
|
+
container_env["DB_HOST"] = db_name
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
new_json = JSON.pretty_generate(container_env, indent: " ", object_nl: "\n ")
|
164
|
+
|
165
|
+
gsub_file(".devcontainer/devcontainer.json", /("containerEnv"\s*:\s*)(.|\n)*?(^\s{2}})/, "\\1#{new_json}")
|
166
|
+
end
|
167
|
+
|
168
|
+
def update_devcontainer_db_feature
|
169
|
+
features = devcontainer_json["features"]
|
170
|
+
db_feature = database.feature
|
171
|
+
|
172
|
+
Database.all.each do |database|
|
173
|
+
features.delete(database.feature_name)
|
174
|
+
end
|
175
|
+
|
176
|
+
features.merge!(db_feature) if db_feature
|
177
|
+
|
178
|
+
new_json = JSON.pretty_generate(features, indent: " ", object_nl: "\n ")
|
179
|
+
|
180
|
+
gsub_file(".devcontainer/devcontainer.json", /("features"\s*:\s*)(.|\n)*?(^\s{2}})/, "\\1#{new_json}")
|
181
|
+
end
|
182
|
+
|
183
|
+
def devcontainer_json
|
184
|
+
return unless File.exist?(devcontainer_json_path)
|
185
|
+
|
186
|
+
@devcontainer_json ||= JSON.parse(File.read(devcontainer_json_path))
|
187
|
+
end
|
188
|
+
|
189
|
+
def devcontainer_json_path
|
190
|
+
File.expand_path(".devcontainer/devcontainer.json", destination_root)
|
191
|
+
end
|
192
|
+
|
193
|
+
def database
|
194
|
+
@database ||= Database.build(options[:database])
|
195
|
+
end
|
196
|
+
|
197
|
+
def devcontainer?
|
198
|
+
return @devcontainer if defined?(@devcontainer)
|
199
|
+
|
200
|
+
@devcontainer = File.exist?(File.expand_path(".devcontainer", destination_root))
|
201
|
+
end
|
91
202
|
end
|
92
203
|
end
|
93
204
|
end
|