diff --git a/Gemfile b/Gemfile index 5550c1d85..049fdba5c 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ ruby "3.3.0" gem "audits1984", "~> 0.1.7" gem "bootsnap", require: false -gem "console1984", "~> 0.1.29" +gem "console1984", "~> 0.2.1" gem "cssbundling-rails" gem "data_migrate" gem "devise" @@ -18,7 +18,7 @@ gem "dfe-autocomplete", ref: "11738c0" gem "faraday", "~> 2.9" gem "gds_zendesk" -gem "govuk-components", "~> 5.0.2" +gem "govuk-components", "~> 5.7.0" gem "govuk_design_system_formbuilder" gem "govuk_markdown", "~> 2.0" gem "jsbundling-rails" @@ -30,7 +30,7 @@ gem "omniauth-rails_csrf_protection" gem "pg", "~> 1.5" gem "puma", "~> 6.4" gem "rack-attack" -gem "rails", "~> 7.1.3" +gem "rails", "~> 7.2.1" gem "sentry-rails" gem "sidekiq", "< 7" # v7 requires Redis 6.2 that Azure doesn't support yet gem "sidekiq-cron", "~> 1.10" diff --git a/Gemfile.lock b/Gemfile.lock index 7587bc889..a185f65cf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,80 +13,76 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.1.3.4) - actionpack (= 7.1.3.4) - activesupport (= 7.1.3.4) + actioncable (7.2.1) + actionpack (= 7.2.1) + activesupport (= 7.2.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3.4) - actionpack (= 7.1.3.4) - activejob (= 7.1.3.4) - activerecord (= 7.1.3.4) - activestorage (= 7.1.3.4) - activesupport (= 7.1.3.4) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.3.4) - actionpack (= 7.1.3.4) - actionview (= 7.1.3.4) - activejob (= 7.1.3.4) - activesupport (= 7.1.3.4) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp + actionmailbox (7.2.1) + actionpack (= 7.2.1) + activejob (= 7.2.1) + activerecord (= 7.2.1) + activestorage (= 7.2.1) + activesupport (= 7.2.1) + mail (>= 2.8.0) + actionmailer (7.2.1) + actionpack (= 7.2.1) + actionview (= 7.2.1) + activejob (= 7.2.1) + activesupport (= 7.2.1) + mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.1.3.4) - actionview (= 7.1.3.4) - activesupport (= 7.1.3.4) + actionpack (7.2.1) + actionview (= 7.2.1) + activesupport (= 7.2.1) nokogiri (>= 1.8.5) racc - rack (>= 2.2.4) + rack (>= 2.2.4, < 3.2) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.3.4) - actionpack (= 7.1.3.4) - activerecord (= 7.1.3.4) - activestorage (= 7.1.3.4) - activesupport (= 7.1.3.4) + useragent (~> 0.16) + actiontext (7.2.1) + actionpack (= 7.2.1) + activerecord (= 7.2.1) + activestorage (= 7.2.1) + activesupport (= 7.2.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3.4) - activesupport (= 7.1.3.4) + actionview (7.2.1) + activesupport (= 7.2.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.3.4) - activesupport (= 7.1.3.4) + activejob (7.2.1) + activesupport (= 7.2.1) globalid (>= 0.3.6) - activemodel (7.1.3.4) - activesupport (= 7.1.3.4) - activerecord (7.1.3.4) - activemodel (= 7.1.3.4) - activesupport (= 7.1.3.4) + activemodel (7.2.1) + activesupport (= 7.2.1) + activerecord (7.2.1) + activemodel (= 7.2.1) + activesupport (= 7.2.1) timeout (>= 0.4.0) - activestorage (7.1.3.4) - actionpack (= 7.1.3.4) - activejob (= 7.1.3.4) - activerecord (= 7.1.3.4) - activesupport (= 7.1.3.4) + activestorage (7.2.1) + actionpack (= 7.2.1) + activejob (= 7.2.1) + activerecord (= 7.2.1) + activesupport (= 7.2.1) marcel (~> 1.0) - activesupport (7.1.3.4) + activesupport (7.2.1) base64 bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) annotate (3.2.0) @@ -124,8 +120,10 @@ GEM coderay (1.1.3) concurrent-ruby (1.3.4) connection_pool (2.4.1) - console1984 (0.1.29) + console1984 (0.2.1) + irb (~> 1.13) parser + rails (>= 7.0) rainbow crack (0.4.5) rexml @@ -188,10 +186,10 @@ GEM zendesk_api (>= 1.37, < 4.0) globalid (1.2.1) activesupport (>= 6.1) - govuk-components (5.0.2) + govuk-components (5.7.0) html-attributes-utils (~> 1.0.0, >= 1.0.0) - pagy (~> 6.0) - view_component (>= 3.9, < 3.10) + pagy (>= 6, < 10) + view_component (>= 3.9, < 3.17) govuk_design_system_formbuilder (5.0.0) actionview (>= 6.1) activemodel (>= 6.1) @@ -212,10 +210,10 @@ GEM concurrent-ruby (~> 1.0) inflection (1.0.0) io-console (0.7.2) - irb (1.14.0) + irb (1.14.1) rdoc (>= 4.0.0) reline (>= 0.4.2) - jaro_winkler (1.5.4) + jaro_winkler (1.6.0) jsbundling-rails (1.3.0) railties (>= 6.0.0) json (2.7.1) @@ -225,6 +223,7 @@ GEM kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) language_server-protocol (3.17.0.3) + logger (1.6.1) logstop (0.3.1) loofah (2.22.0) crass (~> 1.0.2) @@ -241,27 +240,26 @@ GEM activesupport (>= 5.2.4.6) notifications-ruby-client (~> 5.1) rack (>= 2.1.4.1) - marcel (1.0.2) + marcel (1.0.4) matrix (0.4.2) - method_source (1.0.0) + method_source (1.1.0) mini_mime (1.1.5) minitest (5.25.1) msgpack (1.6.0) multi_xml (0.6.0) multipart-post (2.4.1) - mutex_m (0.2.0) net-http (0.4.1) uri - net-imap (0.4.10) + net-imap (0.4.17) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-smtp (0.4.0.1) + net-smtp (0.5.0) net-protocol - nio4r (2.7.0) + nio4r (2.7.3) nokogiri (1.16.7-arm64-darwin) racc (~> 1.4) nokogiri (1.16.7-x86_64-darwin) @@ -290,7 +288,7 @@ GEM actionpack (>= 4.2) omniauth (~> 2.0) orm_adapter (0.5.0) - pagy (6.4.3) + pagy (9.1.0) parallel (1.24.0) parser (3.3.5.0) ast (~> 2.4.1) @@ -310,7 +308,7 @@ GEM nio4r (~> 2.0) raabro (1.4.0) racc (1.8.1) - rack (2.2.9) + rack (2.2.10) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-protection (3.0.1) @@ -322,20 +320,20 @@ GEM rackup (1.0.0) rack (< 3) webrick - rails (7.1.3.4) - actioncable (= 7.1.3.4) - actionmailbox (= 7.1.3.4) - actionmailer (= 7.1.3.4) - actionpack (= 7.1.3.4) - actiontext (= 7.1.3.4) - actionview (= 7.1.3.4) - activejob (= 7.1.3.4) - activemodel (= 7.1.3.4) - activerecord (= 7.1.3.4) - activestorage (= 7.1.3.4) - activesupport (= 7.1.3.4) + rails (7.2.1) + actioncable (= 7.2.1) + actionmailbox (= 7.2.1) + actionmailer (= 7.2.1) + actionpack (= 7.2.1) + actiontext (= 7.2.1) + actionview (= 7.2.1) + activejob (= 7.2.1) + activemodel (= 7.2.1) + activerecord (= 7.2.1) + activestorage (= 7.2.1) + activesupport (= 7.2.1) bundler (>= 1.15.0) - railties (= 7.1.3.4) + railties (= 7.2.1) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -352,10 +350,10 @@ GEM rack railties (>= 5.1) semantic_logger (~> 4.13) - railties (7.1.3.4) - actionpack (= 7.1.3.4) - activesupport (= 7.1.3.4) - irb + railties (7.2.1) + actionpack (= 7.2.1) + activesupport (= 7.2.1) + irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) @@ -380,18 +378,18 @@ GEM rinku (2.0.6) rladr (1.2.0) rouge (4.4.0) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.1) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.6) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) + rspec-support (~> 3.13.0) rspec-rails (6.1.1) actionpack (>= 6.1) activesupport (>= 6.1) @@ -400,7 +398,7 @@ GEM rspec-expectations (~> 3.12) rspec-mocks (~> 3.12) rspec-support (~> 3.12) - rspec-support (3.12.1) + rspec-support (3.13.1) rubocop (1.60.2) json (~> 2.3) language_server-protocol (>= 3.17.0) @@ -438,6 +436,7 @@ GEM ruby-graphviz (1.2.5) rexml ruby-progressbar (1.13.0) + securerandom (0.3.1) semantic_logger (4.15.0) concurrent-ruby (~> 1.0) sentry-rails (5.19.0) @@ -511,9 +510,10 @@ GEM concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) uri (0.13.0) + useragent (0.16.10) vcr (6.2.0) version_gem (1.1.1) - view_component (3.9.0) + view_component (3.16.0) activesupport (>= 5.2.0, < 8.0) concurrent-ruby (~> 1.0) method_source (~> 1.0) @@ -528,14 +528,14 @@ GEM addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.8.1) + webrick (1.8.2) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) yard (0.9.36) - zeitwerk (2.6.18) + zeitwerk (2.7.0) zendesk_api (3.0.5) faraday (> 2.0.0) faraday-multipart @@ -547,6 +547,7 @@ GEM PLATFORMS arm64-darwin-21 arm64-darwin-23 + arm64-darwin-24 x86_64-darwin-21 x86_64-linux @@ -556,7 +557,7 @@ DEPENDENCIES bootsnap capybara (~> 3.40) capybara-email - console1984 (~> 0.1.29) + console1984 (~> 0.2.1) cssbundling-rails cuprite (~> 0.15) data_migrate @@ -570,7 +571,7 @@ DEPENDENCIES faraday (~> 2.9) foreman (~> 0.87.2) gds_zendesk - govuk-components (~> 5.0.2) + govuk-components (~> 5.7.0) govuk_design_system_formbuilder govuk_markdown (~> 2.0) jsbundling-rails @@ -584,7 +585,7 @@ DEPENDENCIES pry-byebug puma (~> 6.4) rack-attack - rails (~> 7.1.3) + rails (~> 7.2.1) rails-erd rails_semantic_logger rladr (~> 1.2) diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb index 343583e72..18919987b 100644 --- a/app/views/layouts/base.html.erb +++ b/app/views/layouts/base.html.erb @@ -9,8 +9,6 @@ <%= tag :meta, name: 'viewport', content: 'width=device-width, initial-scale=1' %> <%= tag :meta, name: 'theme-color', content: '#0b0c0c' %> - - <%= favicon_link_tag image_path('favicon.ico'), type: nil, sizes: "48x48" %> <%= favicon_link_tag image_path('favicon.svg'), type: 'image/svg+xml', sizes: "any" %> <%= favicon_link_tag image_path('govuk-icon-mask.svg'), rel: 'mask-icon', color: "#0b0c0c", type: nil %> diff --git a/bin/.gitkeep b/bin/.gitkeep old mode 100644 new mode 100755 diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 000000000..40330c0ff --- /dev/null +++ b/bin/rubocop @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +# explicit rubocop config increases performance slightly while avoiding config confusion. +ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) + +load Gem.bin_path("rubocop", "rubocop") diff --git a/bin/setup b/bin/setup index ab68feaa5..31c7296b2 100755 --- a/bin/setup +++ b/bin/setup @@ -1,11 +1,11 @@ #!/usr/bin/env ruby require "fileutils" -# path to your application root. APP_ROOT = File.expand_path("..", __dir__) +APP_NAME = "find-a-lost-trn" def system!(*args) - system(*args) || abort("\n== Command #{args} failed ==") + system(*args, exception: true) end FileUtils.chdir APP_ROOT do @@ -13,12 +13,12 @@ FileUtils.chdir APP_ROOT do # This script is idempotent, so that you can run it at any time and get an expectable outcome. # Add necessary setup steps to this file. - puts "== Installing Ruby dependencies ==" + puts "== Installing dependencies ==" system! "gem install bundler --conservative" system("bundle check") || system!("bundle install") puts "\n== Installing Node dependencies ==" - system("yarn") + system! "yarn" # puts "\n== Copying sample files ==" # unless File.exist?("config/database.yml") @@ -28,15 +28,13 @@ FileUtils.chdir APP_ROOT do puts "\n== Preparing database ==" system! "bin/rails db:prepare" - puts "\n== Running data migrations ==" - system! "bin/rails db:migrate:with_data" - - puts "\n== Formatting db/data_schema.rb ==" - system! "yarn run prettier --write 'db/data_schema.rb'" - puts "\n== Removing old logs and tempfiles ==" system! "bin/rails log:clear tmp:clear" puts "\n== Restarting application server ==" system! "bin/rails restart" + + # puts "\n== Configuring puma-dev ==" + # system "ln -nfs #{APP_ROOT} ~/.puma-dev/#{APP_NAME}" + # system "curl -Is https://#{APP_NAME}.test/up | head -n 1" end diff --git a/config/application.rb b/config/application.rb index df19bcf8f..36407ed8d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -28,6 +28,11 @@ class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 7.0 + # Please, add to the `ignore` list any other `lib` subdirectories that do + # not contain `.rb` files, or that should not be reloaded or eager loaded. + # Common ones are `templates`, `generators`, or `middleware`, for example. + config.autoload_lib(ignore: %w[assets tasks]) + # Configuration for the application, engines, and railties goes here. # # These settings can be overridden in specific environments using the files diff --git a/config/environments/development.rb b/config/environments/development.rb index cf9208c4e..c8b473057 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -8,7 +8,7 @@ # In the development environment your application's code is reloaded any time # it changes. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. - config.cache_classes = false + config.enable_reloading = true # Do not eager load code on boot. config.eager_load = false @@ -16,7 +16,7 @@ # Show full error reports. config.consider_all_requests_local = true - # Enable server timing + # Enable server timing. config.server_timing = true # Enable/disable caching. By default caching is disabled. @@ -26,9 +26,7 @@ config.action_controller.enable_fragment_cache_logging = true config.cache_store = :memory_store - config.public_file_server.headers = { - "Cache-Control" => "public, max-age=#{2.days.to_i}", - } + config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{2.days.to_i}" } else config.action_controller.perform_caching = false @@ -38,6 +36,15 @@ # Store uploaded files on the local file system (see config/storage.yml for options). config.active_storage.service = :local + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + # Disable caching for Action Mailer templates even if Action Controller + # caching is enabled. + config.action_mailer.perform_caching = false + + config.action_mailer.default_url_options = { host: "localhost", port: 3000 } + # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log @@ -53,6 +60,9 @@ # Highlight code that triggered database queries in logs. config.active_record.verbose_query_logs = true + # Highlight code that enqueued background job in logs. + config.active_job.verbose_enqueue_logs = true + # Suppress logger output for asset requests. config.assets.quiet = true @@ -60,16 +70,19 @@ # config.i18n.raise_on_missing_translations = true # Annotate rendered view with file names. - # config.action_view.annotate_rendered_view_with_filenames = true + config.action_view.annotate_rendered_view_with_filenames = true # Uncomment if you wish to allow Action Cable access from any origin. # config.action_cable.disable_request_forgery_protection = true - config.action_mailer.perform_caching = false + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true config.active_job.queue_adapter = :sidekiq - config.action_mailer.default_url_options = { host: "localhost", port: 3000 } config.action_mailer.delivery_method = :file config.action_mailer.raise_delivery_errors = true + + # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. + # config.generators.apply_rubocop_autocorrect_after_generate! end diff --git a/config/environments/production.rb b/config/environments/production.rb index 9cf3348ea..128a89360 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -6,7 +6,7 @@ # Settings specified here will take precedence over those in config/application.rb. # Code is not reloaded between requests. - config.cache_classes = true + config.enable_reloading = false # Eager load code on boot. This eager loads most of Rails and # your application in memory, allowing both threaded web servers @@ -18,18 +18,17 @@ config.consider_all_requests_local = false config.action_controller.perform_caching = true - # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] - # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment + # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files). # config.require_master_key = true - # Disable serving static files from the `/public` folder by default since - # Apache or NGINX already handles this. + # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? # Compress CSS using a preprocessor. # config.assets.css_compressor = :sass - # Do not fallback to assets pipeline if a precompiled asset is missed. + # Do not fall back to assets pipeline if a precompiled asset is missed. config.assets.compile = false # Enable serving of images, stylesheets, and JavaScripts from an asset server. @@ -47,24 +46,45 @@ # config.action_cable.url = "wss://example.com/cable" # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. + # config.assume_ssl = true + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true + config.force_ssl = true + + # Skip http-to-https redirect for the default health check endpoint. + # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } - # Include generic and useful information about system operation, but avoid logging too much - # information to avoid inadvertent exposure of personally identifiable information (PII). - config.log_level = :info + # Log to STDOUT by default + config.logger = ActiveSupport::Logger.new($stdout) + .tap { |logger| logger.formatter = ::Logger::Formatter.new } + .then { |logger| ActiveSupport::TaggedLogging.new(logger) } # Prepend all log lines with the following tags. - config.log_tags = [:request_id] + config.log_tags = [ :request_id ] + + # "info" includes generic and useful information about system operation, but avoids logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). If you + # want to log everything, set the level to "debug". + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") # Use a different cache store in production. config.cache_store = :redis_cache_store, { url: ENV.fetch("REDIS_URL") } # Use a real queuing backend for Active Job (and separate queues per environment). - # config.active_job.queue_adapter = :resque + # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "find_a_lost_trn_production" config.active_job.queue_adapter = :sidekiq + # Disable caching for Action Mailer templates even if Action Controller + # caching is enabled. + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation cannot be found). config.i18n.fallbacks = true @@ -101,4 +121,11 @@ config.log_format = :json # For parsing in Logit config.rails_semantic_logger.add_file_appender = false # Don't log to file config.active_record.logger = nil # Don't log SQL + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } end diff --git a/config/environments/test.rb b/config/environments/test.rb index 08059c78a..f6bff4d8d 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -10,28 +10,25 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # Turn false under Spring and add config.action_view.cache_template_loading = true. - config.cache_classes = false - config.action_view.cache_template_loading = true + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false - # Eager loading loads your whole application. When running a single test locally, - # this probably isn't necessary. It's a good idea to do in a continuous integration - # system, or in some way before deploying your code. + # Eager loading loads your entire application. When running a single test locally, + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. config.eager_load = ENV["CI"].present? # Configure public file server for tests with Cache-Control for performance. - config.public_file_server.enabled = true - config.public_file_server.headers = { - "Cache-Control" => "public, max-age=#{1.hour.to_i}", - } + config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{1.hour.to_i}" } # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false config.cache_store = :memory_store - # Raise exceptions instead of rendering exception templates. - config.action_dispatch.show_exceptions = false + # Render exception templates for rescuable exceptions and raise for other exceptions. + config.action_dispatch.show_exceptions = :rescuable # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false @@ -39,6 +36,19 @@ # Store uploaded files on the local file system in a temporary directory. config.active_storage.service = :test + # Disable caching for Action Mailer templates even if Action Controller + # caching is enabled. + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Unlike controllers, the mailer instance doesn't have any context about the + # incoming request so you'll need to provide the :host parameter yourself. + config.action_mailer.default_url_options = { host: "www.example.com" } + # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr @@ -62,4 +72,7 @@ config.action_mailer.default_url_options = { host: "localhost", port: 3000 } config.active_job.queue_adapter = :test + + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 index 000000000..bd5bcd2b6 --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,12 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = "1.0" + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in the app/assets +# folder are already added. +# Rails.application.config.assets.precompile += %w[ admin.js admin.css ] diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 6925d0c9c..af395e463 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -1,29 +1,26 @@ # frozen_string_literal: true # Be sure to restart your server when you modify this file. -# Define an application-wide content security policy -# For further information see the following documentation -# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy +# Define an application-wide content security policy. +# See the Securing Rails Applications Guide for more information: +# https://guides.rubyonrails.org/security.html#content-security-policy-header -Rails.application.configure do - config.content_security_policy do |policy| - policy.default_src :self, :https - policy.font_src :self, :https, :data - policy.img_src :self, :https, :data - policy.object_src :none - policy.script_src :self, :https - policy.style_src :self, :https - # Specify URI for violation reports - # policy.report_uri "/csp-violation-report-endpoint" - end - - # Generate session nonces for permitted importmap and inline scripts - config.content_security_policy_nonce_generator = ->(request) do - request.session.id.to_s - end - config.content_security_policy_nonce_directives = %w[script-src] - - # Report CSP violations to a specified URI. See: - # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only - # config.content_security_policy_report_only = true -end +# Rails.application.configure do +# config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end +# +# # Generate session nonces for permitted importmap, inline scripts, and inline styles. +# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } +# config.content_security_policy_nonce_directives = %w(script-src style-src) +# +# # Report violations without enforcing the policy. +# # config.content_security_policy_report_only = true +# end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 3f4be87b3..b7ba2cb75 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -2,7 +2,9 @@ # Be sure to restart your server when you modify this file. -# Configure sensitive parameters which will be filtered from the log file. +# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. +# Use this to limit dissemination of sensitive information. +# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. Rails.application.config.filter_parameters += %i[ passw secret diff --git a/config/initializers/new_framework_defaults_7_2.rb b/config/initializers/new_framework_defaults_7_2.rb new file mode 100644 index 000000000..b549c4a25 --- /dev/null +++ b/config/initializers/new_framework_defaults_7_2.rb @@ -0,0 +1,70 @@ +# Be sure to restart your server when you modify this file. +# +# This file eases your Rails 7.2 framework defaults upgrade. +# +# Uncomment each configuration one by one to switch to the new default. +# Once your application is ready to run with all new defaults, you can remove +# this file and set the `config.load_defaults` to `7.2`. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. +# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html + +### +# Controls whether Active Job's `#perform_later` and similar methods automatically defer +# the job queuing to after the current Active Record transaction is committed. +# +# Example: +# Topic.transaction do +# topic = Topic.create(...) +# NewTopicNotificationJob.perform_later(topic) +# end +# +# In this example, if the configuration is set to `:never`, the job will +# be enqueued immediately, even though the `Topic` hasn't been committed yet. +# Because of this, if the job is picked up almost immediately, or if the +# transaction doesn't succeed for some reason, the job will fail to find this +# topic in the database. +# +# If `enqueue_after_transaction_commit` is set to `:default`, the queue adapter +# will define the behaviour. +# +# Note: Active Job backends can disable this feature. This is generally done by +# backends that use the same database as Active Record as a queue, hence they +# don't need this feature. +#++ +# Rails.application.config.active_job.enqueue_after_transaction_commit = :default + +### +# Adds image/webp to the list of content types Active Storage considers as an image +# Prevents automatic conversion to a fallback PNG, and assumes clients support WebP, as they support gif, jpeg, and png. +# This is possible due to broad browser support for WebP, but older browsers and email clients may still not support +# WebP. Requires imagemagick/libvips built with WebP support. +#++ +# Rails.application.config.active_storage.web_image_content_types = %w[image/png image/jpeg image/gif image/webp] + +### +# Enable validation of migration timestamps. When set, an ActiveRecord::InvalidMigrationTimestampError +# will be raised if the timestamp prefix for a migration is more than a day ahead of the timestamp +# associated with the current time. This is done to prevent forward-dating of migration files, which can +# impact migration generation and other migration commands. +# +# Applications with existing timestamped migrations that do not adhere to the +# expected format can disable validation by setting this config to `false`. +#++ +# Rails.application.config.active_record.validate_migration_timestamps = true + +### +# Controls whether the PostgresqlAdapter should decode dates automatically with manual queries. +# +# Example: +# ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date") #=> Date +# +# This query used to return a `String`. +#++ +# Rails.application.config.active_record.postgresql_adapter_decode_dates = true + +### +# Enables YJIT as of Ruby 3.3, to bring sizeable performance improvements. If you are +# deploying to a memory constrained environment you may want to set this to `false`. +#++ +# Rails.application.config.yjit = true diff --git a/config/initializers/pagy.rb b/config/initializers/pagy.rb index 4a3318a37..0ec5f9b87 100644 --- a/config/initializers/pagy.rb +++ b/config/initializers/pagy.rb @@ -1,60 +1,62 @@ # frozen_string_literal: true -require "pagy/extras/support" - -# Pagy initializer file (5.10.1) +# Pagy initializer file (9.1.0) # Customize only what you really need and notice that the core Pagy works also without any of the following lines. # Should you just cherry pick part of this file, please maintain the require-order of the extras -# Pagy DEFAULT Variables -# See https://ddnexus.github.io/pagy/api/pagy#variables -# All the Pagy::DEFAULT are set for all the Pagy instances but can be overridden per instance by just passing them to -# Pagy.new|Pagy::Countless.new|Pagy::Calendar::*.new or any of the #pagy* controller methods -# Instance variables -# See https://ddnexus.github.io/pagy/api/pagy#instance-variables +# Pagy Variables +# See https://ddnexus.github.io/pagy/docs/api/pagy#variables +# You can set any pagy variable as a Pagy::DEFAULT. They can also be overridden per instance by just passing them to +# Pagy.new|Pagy::Countless.new|Pagy::Calendar::*.new or any of the #pagy* controller methods +# Here are the few that make more sense as DEFAULTs: Pagy::DEFAULT[:page] = 1 # default -Pagy::DEFAULT[:items] = 100 # default +Pagy::DEFAULT[:limit] = 100 # default Pagy::DEFAULT[:outset] = 0 # default # Other Variables # See https://ddnexus.github.io/pagy/api/pagy#other-variables Pagy::DEFAULT[:size] = [1, 4, 4, 1] # default Pagy::DEFAULT[:page_param] = :page # default -# The :params can be also set as a lambda e.g ->(params){ params.exclude('useless').merge!('custom' => 'useful') } -# Pagy::DEFAULT[:params] = {} # default -# Pagy::DEFAULT[:fragment] = '#fragment' # example -# Pagy::DEFAULT[:link_extra] = 'data-remote="true"' # example -# Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default -# Pagy::DEFAULT[:cycle] = true # example + +# Pagy::DEFAULT[:limit] = 20 # default +# Pagy::DEFAULT[:size] = 7 # default +# Pagy::DEFAULT[:ends] = true # default +# Pagy::DEFAULT[:page_param] = :page # default +# Pagy::DEFAULT[:count_args] = [] # example for non AR ORMs +# Pagy::DEFAULT[:max_pages] = 3000 # example + # Extras -# See https://ddnexus.github.io/pagy/extras +# See https://ddnexus.github.io/pagy/categories/extra + + +# Legacy Compatibility Extras + +# Size extra: Enable the Array type for the `:size` variable (e.g. `size: [1,4,4,1]`) +# See https://ddnexus.github.io/pagy/docs/extras/size +# require 'pagy/extras/size' # must be required before the other extras + # Backend Extras +# Arel extra: For better performance utilizing grouped ActiveRecord collections: +# See: https://ddnexus.github.io/pagy/docs/extras/arel +# require 'pagy/extras/arel' + # Array extra: Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding -# See https://ddnexus.github.io/pagy/extras/array -require "pagy/extras/array" +# See https://ddnexus.github.io/pagy/docs/extras/array +require 'pagy/extras/array' # Calendar extra: Add pagination filtering by calendar time unit (year, quarter, month, week, day) -# See https://ddnexus.github.io/pagy/extras/calendar +# See https://ddnexus.github.io/pagy/docs/extras/calendar # require 'pagy/extras/calendar' -# Default for each unit -# Pagy::Calendar::Year::DEFAULT[:order] = :asc # Time direction of pagination -# Pagy::Calendar::Year::DEFAULT[:format] = '%Y' # strftime format -# -# Pagy::Calendar::Quarter::DEFAULT[:order] = :asc # Time direction of pagination -# Pagy::Calendar::Quarter::DEFAULT[:format] = '%Y-Q%q' # strftime format -# -# Pagy::Calendar::Month::DEFAULT[:order] = :asc # Time direction of pagination -# Pagy::Calendar::Month::DEFAULT[:format] = '%Y-%m' # strftime format -# -# Pagy::Calendar::Week::DEFAULT[:order] = :asc # Time direction of pagination -# Pagy::Calendar::Week::DEFAULT[:format] = '%Y-%W' # strftime format -# -# Pagy::Calendar::Day::DEFAULT[:order] = :asc # Time direction of pagination -# Pagy::Calendar::Day::DEFAULT[:format] = '%Y-%m-%d' # strftime format +# Default for each calendar unit class in IRB: +# >> Pagy::Calendar::Year::DEFAULT +# >> Pagy::Calendar::Quarter::DEFAULT +# >> Pagy::Calendar::Month::DEFAULT +# >> Pagy::Calendar::Week::DEFAULT +# >> Pagy::Calendar::Day::DEFAULT # # Uncomment the following lines, if you need calendar localization without using the I18n extra # module LocalizePagyCalendar @@ -65,12 +67,12 @@ # Pagy::Calendar.prepend LocalizePagyCalendar # Countless extra: Paginate without any count, saving one query per rendering -# See https://ddnexus.github.io/pagy/extras/countless +# See https://ddnexus.github.io/pagy/docs/extras/countless # require 'pagy/extras/countless' # Pagy::DEFAULT[:countless_minimal] = false # default (eager loading) # Elasticsearch Rails extra: Paginate `ElasticsearchRails::Results` objects -# See https://ddnexus.github.io/pagy/extras/elasticsearch_rails +# See https://ddnexus.github.io/pagy/docs/extras/elasticsearch_rails # Default :pagy_search method: change only if you use also # the searchkick or meilisearch extra that defines the same # Pagy::DEFAULT[:elasticsearch_rails_pagy_search] = :pagy_search @@ -79,15 +81,19 @@ # require 'pagy/extras/elasticsearch_rails' # Headers extra: http response headers (and other helpers) useful for API pagination -# See http://ddnexus.github.io/pagy/extras/headers +# See https://ddnexus.github.io/pagy/docs/extras/headers # require 'pagy/extras/headers' # Pagy::DEFAULT[:headers] = { page: 'Current-Page', -# items: 'Page-Items', +# limit: 'Page-Items', # count: 'Total-Count', # pages: 'Total-Pages' } # default +# Keyset extra: Paginate with the Pagy keyset pagination technique +# See https://ddnexus.github.io/pagy/docs/extras/keyset +# require 'pagy/extras/keyset' + # Meilisearch extra: Paginate `Meilisearch` result objects -# See https://ddnexus.github.io/pagy/extras/meilisearch +# See https://ddnexus.github.io/pagy/docs/extras/meilisearch # Default :pagy_search method: change only if you use also # the elasticsearch_rails or searchkick extra that define the same method # Pagy::DEFAULT[:meilisearch_pagy_search] = :pagy_search @@ -96,18 +102,18 @@ # require 'pagy/extras/meilisearch' # Metadata extra: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc. -# See https://ddnexus.github.io/pagy/extras/metadata -# you must require the frontend helpers internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels -# require 'pagy/extras/frontend_helpers' +# See https://ddnexus.github.io/pagy/docs/extras/metadata +# you must require the JS Tools internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels +# require 'pagy/extras/js_tools' # require 'pagy/extras/metadata' # For performance reasons, you should explicitly set ONLY the metadata you use in the frontend # Pagy::DEFAULT[:metadata] = %i[scaffold_url page prev next last] # example # Searchkick extra: Paginate `Searchkick::Results` objects -# See https://ddnexus.github.io/pagy/extras/searchkick +# See https://ddnexus.github.io/pagy/docs/extras/searchkick # Default :pagy_search method: change only if you use also # the elasticsearch_rails or meilisearch extra that defines the same -# DEFAULT[:searchkick_pagy_search] = :pagy_search +# Pagy::DEFAULT[:searchkick_pagy_search] = :pagy_search # Default original :search method called internally to do the actual search # Pagy::DEFAULT[:searchkick_search] = :search # require 'pagy/extras/searchkick' @@ -117,80 +123,66 @@ # Frontend Extras # Bootstrap extra: Add nav, nav_js and combo_nav_js helpers and templates for Bootstrap pagination -# See https://ddnexus.github.io/pagy/extras/bootstrap +# See https://ddnexus.github.io/pagy/docs/extras/bootstrap # require 'pagy/extras/bootstrap' # Bulma extra: Add nav, nav_js and combo_nav_js helpers and templates for Bulma pagination -# See https://ddnexus.github.io/pagy/extras/bulma +# See https://ddnexus.github.io/pagy/docs/extras/bulma # require 'pagy/extras/bulma' -# Foundation extra: Add nav, nav_js and combo_nav_js helpers and templates for Foundation pagination -# See https://ddnexus.github.io/pagy/extras/foundation -# require 'pagy/extras/foundation' - -# Materialize extra: Add nav, nav_js and combo_nav_js helpers for Materialize pagination -# See https://ddnexus.github.io/pagy/extras/materialize -# require 'pagy/extras/materialize' - -# Navs extra: Add nav_js and combo_nav_js javascript helpers -# Notice: the other frontend extras add their own framework-styled versions, -# so require this extra only if you need the unstyled version -# See https://ddnexus.github.io/pagy/extras/navs -# require 'pagy/extras/navs' - -# Semantic extra: Add nav, nav_js and combo_nav_js helpers for Semantic UI pagination -# See https://ddnexus.github.io/pagy/extras/semantic -# require 'pagy/extras/semantic' - -# UIkit extra: Add nav helper and templates for UIkit pagination -# See https://ddnexus.github.io/pagy/extras/uikit -# require 'pagy/extras/uikit' +# Pagy extra: Add the pagy styled versions of the javascript-powered navs +# and a few other components to the Pagy::Frontend module. +# See https://ddnexus.github.io/pagy/docs/extras/pagy +# require 'pagy/extras/pagy' # Multi size var used by the *_nav_js helpers -# See https://ddnexus.github.io/pagy/extras/navs#steps -# Pagy::DEFAULT[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example +# See https://ddnexus.github.io/pagy/docs/extras/pagy#steps +# Pagy::DEFAULT[:steps] = { 0 => 5, 540 => 7, 720 => 9 } # example + # Feature Extras -# Gearbox extra: Automatically change the number of items per page depending on the page number -# See https://ddnexus.github.io/pagy/extras/gearbox +# Gearbox extra: Automatically change the limit per page depending on the page number +# See https://ddnexus.github.io/pagy/docs/extras/gearbox # require 'pagy/extras/gearbox' # set to false only if you want to make :gearbox_extra an opt-in variable # Pagy::DEFAULT[:gearbox_extra] = false # default true -# Pagy::DEFAULT[:gearbox_items] = [15, 30, 60, 100] # default +# Pagy::DEFAULT[:gearbox_limit] = [15, 30, 60, 100] # default -# Items extra: Allow the client to request a custom number of items per page with an optional selector UI -# See https://ddnexus.github.io/pagy/extras/items -# require 'pagy/extras/items' -# set to false only if you want to make :items_extra an opt-in variable -# Pagy::DEFAULT[:items_extra] = false # default true -# Pagy::DEFAULT[:items_param] = :items # default -# Pagy::DEFAULT[:max_items] = 100 # default +# Limit extra: Allow the client to request a custom limit per page with an optional selector UI +# See https://ddnexus.github.io/pagy/docs/extras/limit +# require 'pagy/extras/limit' +# set to false only if you want to make :limit_extra an opt-in variable +# Pagy::DEFAULT[:limit_extra] = false # default true +# Pagy::DEFAULT[:limit_param] = :limit # default +# Pagy::DEFAULT[:limit_max] = 100 # default # Overflow extra: Allow for easy handling of overflowing pages -# See https://ddnexus.github.io/pagy/extras/overflow +# See https://ddnexus.github.io/pagy/docs/extras/overflow # require 'pagy/extras/overflow' # Pagy::DEFAULT[:overflow] = :empty_page # default (other options: :last_page and :exception) -# Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination -# See https://ddnexus.github.io/pagy/extras/support -# require 'pagy/extras/support' - # Trim extra: Remove the page=1 param from links -# See https://ddnexus.github.io/pagy/extras/trim +# See https://ddnexus.github.io/pagy/docs/extras/trim # require 'pagy/extras/trim' # set to false only if you want to make :trim_extra an opt-in variable # Pagy::DEFAULT[:trim_extra] = false # default true # Standalone extra: Use pagy in non Rack environment/gem -# See https://ddnexus.github.io/pagy/extras/standalone +# See https://ddnexus.github.io/pagy/docs/extras/standalone # require 'pagy/extras/standalone' # Pagy::DEFAULT[:url] = 'http://www.example.com/subdir' # optional default +# Jsonapi extra: Implements JSON:API specifications +# See https://ddnexus.github.io/pagy/docs/extras/jsonapi +# require 'pagy/extras/jsonapi' # must be required after the other extras +# set to false only if you want to make :jsonapi an opt-in variable +# Pagy::DEFAULT[:jsonapi] = false # default true + # Rails # Enable the .js file required by the helpers that use javascript -# (pagy*_nav_js, pagy*_combo_nav_js, and pagy_items_selector_js) -# See https://ddnexus.github.io/pagy/extras#javascript +# (pagy*_nav_js, pagy*_combo_nav_js, and pagy_limit_selector_js) +# See https://ddnexus.github.io/pagy/docs/api/javascript # With the asset pipeline # Sprockets need to look into the pagy javascripts dir, so add it to the assets paths @@ -199,7 +191,7 @@ # I18n # Pagy internal I18n: ~18x faster using ~10x less memory than the i18n gem -# See https://ddnexus.github.io/pagy/api/frontend#i18n +# See https://ddnexus.github.io/pagy/docs/api/i18n # Notice: No need to configure anything in this section if your app uses only "en" # or if you use the i18n extra below # @@ -225,13 +217,12 @@ # filepath: 'path/to/pagy-xyz.yml', # pluralize: lambda{ |count| ... } ) + # I18n extra: uses the standard i18n gem which is ~18x slower using ~10x more memory # than the default pagy internal i18n (see above) -# See https://ddnexus.github.io/pagy/extras/i18n +# See https://ddnexus.github.io/pagy/docs/extras/i18n # require 'pagy/extras/i18n' -# Default i18n key -# Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default # When you are done setting your own default freeze it, so it will not get changed accidentally -Pagy::DEFAULT.freeze +Pagy::DEFAULT.freeze \ No newline at end of file diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb index 50bcf4ead..b635b527e 100644 --- a/config/initializers/permissions_policy.rb +++ b/config/initializers/permissions_policy.rb @@ -1,12 +1,14 @@ # frozen_string_literal: true +# Be sure to restart your server when you modify this file. + # Define an application-wide HTTP permissions policy. For further -# information see https://developers.google.com/web/updates/2018/06/feature-policy -# -# Rails.application.config.permissions_policy do |f| -# f.camera :none -# f.gyroscope :none -# f.microphone :none -# f.usb :none -# f.fullscreen :self -# f.payment :self, "https://secure.example.com" +# information see: https://developers.google.com/web/updates/2018/06/feature-policy + +# Rails.application.config.permissions_policy do |policy| +# policy.camera :none +# policy.gyroscope :none +# policy.microphone :none +# policy.usb :none +# policy.fullscreen :self +# policy.payment :self, "https://secure.example.com" # end diff --git a/config/puma.rb b/config/puma.rb index de5feec98..03c166f4c 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,45 +1,34 @@ -# frozen_string_literal: true +# This configuration file will be evaluated by Puma. The top-level methods that +# are invoked here are part of Puma's configuration DSL. For more information +# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. -# Puma can serve each request in a thread from an internal thread pool. -# The `threads` method setting takes two numbers: a minimum and maximum. -# Any libraries that use thread pools should be configured to match -# the maximum value specified for Puma. Default is set to 5 threads for minimum -# and maximum; this matches the default thread size of Active Record. +# Puma starts a configurable number of processes (workers) and each process +# serves each request in a thread from an internal thread pool. # -max_threads_count = ENV.fetch("RAILS_MAX_THREADS", 5) -min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } -threads min_threads_count, max_threads_count - -# Specifies the `worker_timeout` threshold that Puma will use to wait before -# terminating a worker in development environments. -# -worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" - -# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +# The ideal number of threads per worker depends both on how much time the +# application spends waiting for IO operations and on how much you wish to +# to prioritize throughput over latency. # -port ENV.fetch("PORT", 3000) - -# Specifies the `environment` that Puma will run in. +# As a rule of thumb, increasing the number of threads will increase how much +# traffic a given process can handle (throughput), but due to CRuby's +# Global VM Lock (GVL) it has diminishing returns and will degrade the +# response time (latency) of the application. # -environment ENV.fetch("RAILS_ENV", "development") - -# Specifies the `pidfile` that Puma will use. -pidfile ENV.fetch("PIDFILE", "tmp/pids/server.pid") - -# Specifies the number of `workers` to boot in clustered mode. -# Workers are forked web server processes. If using threads and workers together -# the concurrency of the application would be max `threads` * `workers`. -# Workers do not work on JRuby or Windows (both of which do not support -# processes). +# The default is set to 3 threads as it's deemed a decent compromise between +# throughput and latency for the average Rails application. # -# workers ENV.fetch("WEB_CONCURRENCY") { 2 } +# Any libraries that use a connection pool or another resource pool should +# be configured to provide at least as many connections as the number of +# threads. This includes Active Record's `pool` parameter in `database.yml`. +threads_count = ENV.fetch("RAILS_MAX_THREADS", 3) +threads threads_count, threads_count -# Use the `preload_app!` method when specifying a `workers` number. -# This directive tells Puma to first boot the application and load code -# before forking the application. This takes advantage of Copy On Write -# process behavior so workers use less memory. -# -# preload_app! +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +port ENV.fetch("PORT", 3000) # Allow puma to be restarted by `bin/rails restart` command. plugin :tmp_restart + +# Specify the PID file. Defaults to tmp/pids/server.pid in development. +# In other environments, only set the PID file if requested. +pidfile ENV["PIDFILE"] if ENV["PIDFILE"] diff --git a/db/migrate/20241015082728_add_service_name_to_active_storage_blobs.active_storage.rb b/db/migrate/20241015082728_add_service_name_to_active_storage_blobs.active_storage.rb new file mode 100644 index 000000000..0267f1287 --- /dev/null +++ b/db/migrate/20241015082728_add_service_name_to_active_storage_blobs.active_storage.rb @@ -0,0 +1,22 @@ +# This migration comes from active_storage (originally 20190112182829) +class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0] + def up + return unless table_exists?(:active_storage_blobs) + + unless column_exists?(:active_storage_blobs, :service_name) + add_column :active_storage_blobs, :service_name, :string + + if (configured_service = ActiveStorage::Blob.service.name) + ActiveStorage::Blob.unscoped.update_all(service_name: configured_service) + end + + change_column :active_storage_blobs, :service_name, :string, null: false + end + end + + def down + return unless table_exists?(:active_storage_blobs) + + remove_column :active_storage_blobs, :service_name + end +end diff --git a/db/migrate/20241015082729_create_active_storage_variant_records.active_storage.rb b/db/migrate/20241015082729_create_active_storage_variant_records.active_storage.rb new file mode 100644 index 000000000..94ac83af0 --- /dev/null +++ b/db/migrate/20241015082729_create_active_storage_variant_records.active_storage.rb @@ -0,0 +1,27 @@ +# This migration comes from active_storage (originally 20191206030411) +class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + # Use Active Record's configured type for primary key + create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t| + t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type + t.string :variation_digest, null: false + + t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_key_type + config = Rails.configuration.generators + config.options[config.orm][:primary_key_type] || :primary_key + end + + def blobs_primary_key_type + pkey_name = connection.primary_key(:active_storage_blobs) + pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name } + pkey_column.bigint? ? :bigint : pkey_column.type + end +end diff --git a/db/migrate/20241015082730_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb b/db/migrate/20241015082730_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb new file mode 100644 index 000000000..93c8b85ad --- /dev/null +++ b/db/migrate/20241015082730_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb @@ -0,0 +1,8 @@ +# This migration comes from active_storage (originally 20211119233751) +class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + change_column_null(:active_storage_blobs, :checksum, true) + end +end diff --git a/db/schema.rb b/db/schema.rb index 6c2be8fd7..2b33eb3b2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2022_10_19_115943) do +ActiveRecord::Schema[7.2].define(version: 2024_10_15_082730) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index a2962a63b..9505794c4 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -54,7 +54,7 @@ RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = Rails.root.join("spec/fixtures") + config.fixture_paths = Rails.root.join("spec/fixtures") # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false