From: Andy Allan Date: Wed, 2 Oct 2024 16:00:26 +0000 (+0100) Subject: Merge pull request #5070 from tomhughes/rails72 X-Git-Tag: live~671 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/57209683238197d4391103ba3ca4b295a70fbb0a?hp=e8da505518490b071ec4d5a0f52d4d4dd9e70246 Merge pull request #5070 from tomhughes/rails72 Update to rails 7.2.0 --- diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9fc132014..343084b0f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,7 +7,7 @@ concurrency: cancel-in-progress: true env: os: ubuntu-22.04 - ruby: '3.0' + ruby: '3.1' jobs: rubocop: name: RuboCop diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 46ab75482..6e2b77059 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,8 +10,8 @@ jobs: name: Ubuntu ${{ matrix.ubuntu }}, Ruby ${{ matrix.ruby }} strategy: matrix: - ubuntu: [20.04, 22.04] - ruby: ['3.0', '3.1', '3.2', '3.3'] + ubuntu: [22.04, 24.04] + ruby: ['3.1', '3.2', '3.3'] runs-on: ubuntu-${{ matrix.ubuntu }} env: RAILS_ENV: test diff --git a/.rubocop.yml b/.rubocop.yml index c0f0c1fa0..8b6ed0180 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,7 +9,7 @@ require: - rubocop-rake AllCops: - TargetRubyVersion: 3.0 + TargetRubyVersion: 3.1 NewCops: enable Exclude: - 'vendor/**/*' diff --git a/Gemfile b/Gemfile index 27f295eb6..b25255320 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" # Require rails -gem "rails", "~> 7.1.0" +gem "rails", "~> 7.2.0" gem "turbo-rails" # Require json for multi_json @@ -130,7 +130,7 @@ gem "gd2-ffij", ">= 0.4.0" gem "marcel" # Used for browser detection -gem "browser", "< 6" # for ruby 3.0 support +gem "browser", "< 6" # for ruby 3.1 support # Used for S3 object storage gem "aws-sdk-s3" @@ -141,9 +141,6 @@ gem "image_processing" # Used to validate widths gem "unicode-display_width" -# Keep ruby 3.0 compatibility -gem "multi_xml", "~> 0.6.0" - # Gems useful for development group :development do gem "better_errors" diff --git a/Gemfile.lock b/Gemfile.lock index 8872f2e7e..f334b3ac1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,86 +3,82 @@ GEM specs: aasm (5.5.0) concurrent-ruby (~> 1.0) - actioncable (7.1.4) - actionpack (= 7.1.4) - activesupport (= 7.1.4) + actioncable (7.2.0) + actionpack (= 7.2.0) + activesupport (= 7.2.0) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.4) - actionpack (= 7.1.4) - activejob (= 7.1.4) - activerecord (= 7.1.4) - activestorage (= 7.1.4) - activesupport (= 7.1.4) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.4) - actionpack (= 7.1.4) - actionview (= 7.1.4) - activejob (= 7.1.4) - activesupport (= 7.1.4) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp + actionmailbox (7.2.0) + actionpack (= 7.2.0) + activejob (= 7.2.0) + activerecord (= 7.2.0) + activestorage (= 7.2.0) + activesupport (= 7.2.0) + mail (>= 2.8.0) + actionmailer (7.2.0) + actionpack (= 7.2.0) + actionview (= 7.2.0) + activejob (= 7.2.0) + activesupport (= 7.2.0) + mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.1.4) - actionview (= 7.1.4) - activesupport (= 7.1.4) + actionpack (7.2.0) + actionview (= 7.2.0) + activesupport (= 7.2.0) 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) + useragent (~> 0.16) actionpack-page_caching (1.2.4) actionpack (>= 4.0.0) - actiontext (7.1.4) - actionpack (= 7.1.4) - activerecord (= 7.1.4) - activestorage (= 7.1.4) - activesupport (= 7.1.4) + actiontext (7.2.0) + actionpack (= 7.2.0) + activerecord (= 7.2.0) + activestorage (= 7.2.0) + activesupport (= 7.2.0) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.4) - activesupport (= 7.1.4) + actionview (7.2.0) + activesupport (= 7.2.0) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) active_record_union (1.3.0) activerecord (>= 4.0) - activejob (7.1.4) - activesupport (= 7.1.4) + activejob (7.2.0) + activesupport (= 7.2.0) globalid (>= 0.3.6) - activemodel (7.1.4) - activesupport (= 7.1.4) - activerecord (7.1.4) - activemodel (= 7.1.4) - activesupport (= 7.1.4) + activemodel (7.2.0) + activesupport (= 7.2.0) + activerecord (7.2.0) + activemodel (= 7.2.0) + activesupport (= 7.2.0) timeout (>= 0.4.0) activerecord-import (1.8.1) activerecord (>= 4.2) - activestorage (7.1.4) - actionpack (= 7.1.4) - activejob (= 7.1.4) - activerecord (= 7.1.4) - activesupport (= 7.1.4) + activestorage (7.2.0) + actionpack (= 7.2.0) + activejob (= 7.2.0) + activerecord (= 7.2.0) + activesupport (= 7.2.0) marcel (~> 1.0) - activesupport (7.1.4) + activesupport (7.2.0) 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.7) public_suffix (>= 2.0.2, < 7.0) annotate (3.2.0) @@ -346,8 +342,8 @@ GEM minitest (>= 4, < 6) msgpack (1.7.2) multi_json (1.15.0) - multi_xml (0.6.0) - mutex_m (0.2.0) + multi_xml (0.7.1) + bigdecimal (~> 3.1) net-http (0.4.1) uri net-imap (0.4.16) @@ -448,20 +444,20 @@ GEM rackup (1.0.0) rack (< 3) webrick - rails (7.1.4) - actioncable (= 7.1.4) - actionmailbox (= 7.1.4) - actionmailer (= 7.1.4) - actionpack (= 7.1.4) - actiontext (= 7.1.4) - actionview (= 7.1.4) - activejob (= 7.1.4) - activemodel (= 7.1.4) - activerecord (= 7.1.4) - activestorage (= 7.1.4) - activesupport (= 7.1.4) + rails (7.2.0) + actioncable (= 7.2.0) + actionmailbox (= 7.2.0) + actionmailer (= 7.2.0) + actionpack (= 7.2.0) + actiontext (= 7.2.0) + actionview (= 7.2.0) + activejob (= 7.2.0) + activemodel (= 7.2.0) + activerecord (= 7.2.0) + activestorage (= 7.2.0) + activesupport (= 7.2.0) bundler (>= 1.15.0) - railties (= 7.1.4) + railties (= 7.2.0) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -479,10 +475,10 @@ GEM rails_param (1.3.1) actionpack (>= 3.2.0) activesupport (>= 3.2.0) - railties (7.1.4) - actionpack (= 7.1.4) - activesupport (= 7.1.4) - irb + railties (7.2.0) + actionpack (= 7.2.0) + activesupport (= 7.2.0) + irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) @@ -546,6 +542,7 @@ GEM sass-embedded (1.64.2) google-protobuf (~> 3.23) rake (>= 13.0.0) + securerandom (0.3.1) selenium-webdriver (4.23.0) base64 (~> 0.2) logger (~> 1.4) @@ -591,6 +588,7 @@ GEM concurrent-ruby (~> 1.0) unicode-display_width (2.6.0) uri (0.13.1) + useragent (0.16.10) validates_email_format_of (1.8.2) i18n (>= 0.8.0) simpleidn @@ -672,7 +670,6 @@ DEPENDENCIES minitest (~> 5.1) minitest-focus multi_json - multi_xml (~> 0.6.0) omniauth (~> 2.0.2) omniauth-facebook omniauth-github @@ -688,7 +685,7 @@ DEPENDENCIES quad_tile (~> 1.0.1) rack-cors rack-uri_sanitizer - rails (~> 7.1.0) + rails (~> 7.2.0) rails-controller-testing rails-i18n (~> 7.0.0) rails_param @@ -717,4 +714,4 @@ DEPENDENCIES webmock BUNDLED WITH - 2.4.19 + 2.5.11 diff --git a/INSTALL.md b/INSTALL.md index c8e28a62f..8667fb512 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -9,7 +9,7 @@ are two alternatives which make it easier to get a consistent development enviro * **Vagrant** This installs the software into a virtual machine. For Vagrant instructions see [VAGRANT.md](VAGRANT.md). * **Docker** This installs the software using containerization. For Docker instructions see [DOCKER.md](DOCKER.md). -These instructions are based on Ubuntu 22.04 LTS, which is the platform used by the OSMF servers. +These instructions are based on Ubuntu 24.04 LTS, which is the platform used by the OSMF servers. The instructions also work, with only minor amendments, for all other current Ubuntu releases, Fedora and MacOSX We don't recommend attempting to develop or deploy this software on Windows. Some Ruby gems may not be supported. If you need to use Windows the easiest solutions in order are [Docker](DOCKER.md), [Vagrant](VAGRANT.md), and Ubuntu in a virtual machine. @@ -22,12 +22,12 @@ of packages required before you can get the various gems installed. ## Minimum requirements -* Ruby 3.0+ +* Ruby 3.1+ * PostgreSQL 13+ * Bundler (see note below about [developer Ruby setup](#rbenv)) * Javascript Runtime -These can be installed on Ubuntu 22.04 or later with: +These can be installed on Ubuntu 24.04 or later with: ``` sudo apt-get update diff --git a/Vagrantfile b/Vagrantfile index 7895d3b86..c2869cd5f 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -4,7 +4,7 @@ Vagrant.configure("2") do |config| # use official ubuntu image for virtualbox config.vm.provider "virtualbox" do |vb, override| - override.vm.box = "ubuntu/jammy64" + override.vm.box = "ubuntu/noble64" override.vm.synced_folder ".", "/srv/openstreetmap-website" vb.customize ["modifyvm", :id, "--memory", "4096"] vb.customize ["modifyvm", :id, "--cpus", "2"] @@ -16,13 +16,13 @@ Vagrant.configure("2") do |config| # use third party image and sshfs or NFS sharing for lxc config.vm.provider "lxc" do |_, override| - override.vm.box = "generic/ubuntu2204" + override.vm.box = "generic/ubuntu2404" override.vm.synced_folder ".", "/srv/openstreetmap-website", :type => sharing_type end # use third party image and sshfs or NFS sharing for libvirt config.vm.provider "libvirt" do |_, override| - override.vm.box = "generic/ubuntu2204" + override.vm.box = "generic/ubuntu2404" override.vm.synced_folder ".", "/srv/openstreetmap-website", :type => sharing_type end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 5b264db97..84398ad61 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -142,8 +142,8 @@ class ApiController < ApplicationController ## # wrap an api call in a timeout - def api_call_timeout(&block) - Timeout.timeout(Settings.api_timeout, &block) + def api_call_timeout(&) + Timeout.timeout(Settings.api_timeout, &) rescue ActionView::Template::Error => e e = e.cause diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index fdc2ac4e8..7ce804ced 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -215,10 +215,10 @@ class ApplicationController < ActionController::Base ## # wrap a web page in a timeout - def web_timeout(&block) + def web_timeout(&) raise Timeout::Error if Settings.web_timeout.negative? - Timeout.timeout(Settings.web_timeout, &block) + Timeout.timeout(Settings.web_timeout, &) rescue ActionView::Template::Error => e e = e.cause diff --git a/app/helpers/browse_helper.rb b/app/helpers/browse_helper.rb index 9ea384811..69a8f8fa2 100644 --- a/app/helpers/browse_helper.rb +++ b/app/helpers/browse_helper.rb @@ -44,9 +44,9 @@ module BrowseHelper t "printable_name.version", :version => object.version end - def element_strikethrough(object, &block) + def element_strikethrough(object, &) if object.redacted? || !object.visible? - tag.s(&block) + tag.s(&) else yield end diff --git a/app/helpers/user_mailer_helper.rb b/app/helpers/user_mailer_helper.rb index e5d6e39ac..d47827074 100644 --- a/app/helpers/user_mailer_helper.rb +++ b/app/helpers/user_mailer_helper.rb @@ -18,10 +18,10 @@ module UserMailerHelper ) end - def message_body(&block) + def message_body(&) render( :partial => "message_body", - :locals => { :body => capture(&block) } + :locals => { :body => capture(&) } ) end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 86e77703b..dee3dafbe 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -247,8 +247,8 @@ class UserMailer < ApplicationMailer end end - def with_recipient_locale(recipient, &block) - I18n.with_locale(Locale.available.preferred(recipient.preferred_languages), &block) + def with_recipient_locale(recipient, &) + I18n.with_locale(Locale.available.preferred(recipient.preferred_languages), &) end def from_address(name, type, id, token, user_id = nil) diff --git a/app/models/old_node.rb b/app/models/old_node.rb index 4585ed406..f29eed9dd 100644 --- a/app/models/old_node.rb +++ b/app/models/old_node.rb @@ -47,7 +47,7 @@ class OldNode < ApplicationRecord belongs_to :redaction, :optional => true belongs_to :current_node, :class_name => "Node", :foreign_key => "node_id", :inverse_of => :old_nodes - has_many :old_tags, :class_name => "OldNodeTag", :query_constraints => [:node_id, :version], :inverse_of => :old_node + has_many :old_tags, :class_name => "OldNodeTag", :foreign_key => [:node_id, :version], :inverse_of => :old_node def validate_position errors.add(:base, "Node is not in the world") unless in_world? diff --git a/app/models/old_node_tag.rb b/app/models/old_node_tag.rb index 8f632a671..503ecf27a 100644 --- a/app/models/old_node_tag.rb +++ b/app/models/old_node_tag.rb @@ -15,7 +15,7 @@ class OldNodeTag < ApplicationRecord self.table_name = "node_tags" - belongs_to :old_node, :query_constraints => [:node_id, :version], :inverse_of => :old_tags + belongs_to :old_node, :foreign_key => [:node_id, :version], :inverse_of => :old_tags validates :old_node, :associated => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true diff --git a/app/models/old_relation.rb b/app/models/old_relation.rb index 7d5a3fbb4..9f551d839 100644 --- a/app/models/old_relation.rb +++ b/app/models/old_relation.rb @@ -31,8 +31,8 @@ class OldRelation < ApplicationRecord belongs_to :redaction, :optional => true belongs_to :current_relation, :class_name => "Relation", :foreign_key => "relation_id", :inverse_of => :old_relations - has_many :old_members, -> { order(:sequence_id) }, :class_name => "OldRelationMember", :query_constraints => [:relation_id, :version], :inverse_of => :old_relation - has_many :old_tags, :class_name => "OldRelationTag", :query_constraints => [:relation_id, :version], :inverse_of => :old_relation + has_many :old_members, -> { order(:sequence_id) }, :class_name => "OldRelationMember", :foreign_key => [:relation_id, :version], :inverse_of => :old_relation + has_many :old_tags, :class_name => "OldRelationTag", :foreign_key => [:relation_id, :version], :inverse_of => :old_relation validates :changeset, :associated => true validates :timestamp, :presence => true diff --git a/app/models/old_relation_member.rb b/app/models/old_relation_member.rb index 5a1156605..6d5aaf5c9 100644 --- a/app/models/old_relation_member.rb +++ b/app/models/old_relation_member.rb @@ -21,7 +21,7 @@ class OldRelationMember < ApplicationRecord self.table_name = "relation_members" - belongs_to :old_relation, :query_constraints => [:relation_id, :version], :inverse_of => :old_members + belongs_to :old_relation, :foreign_key => [:relation_id, :version], :inverse_of => :old_members # A bit messy, referring to the current tables, should do for the data browser for now belongs_to :member, :polymorphic => true diff --git a/app/models/old_relation_tag.rb b/app/models/old_relation_tag.rb index 31399c00d..39566aeb9 100644 --- a/app/models/old_relation_tag.rb +++ b/app/models/old_relation_tag.rb @@ -15,7 +15,7 @@ class OldRelationTag < ApplicationRecord self.table_name = "relation_tags" - belongs_to :old_relation, :query_constraints => [:relation_id, :version], :inverse_of => :old_tags + belongs_to :old_relation, :foreign_key => [:relation_id, :version], :inverse_of => :old_tags validates :old_relation, :associated => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true diff --git a/app/models/old_way.rb b/app/models/old_way.rb index 8577330c5..0c53f90bd 100644 --- a/app/models/old_way.rb +++ b/app/models/old_way.rb @@ -31,8 +31,8 @@ class OldWay < ApplicationRecord belongs_to :redaction, :optional => true belongs_to :current_way, :class_name => "Way", :foreign_key => "way_id", :inverse_of => :old_ways - has_many :old_nodes, :class_name => "OldWayNode", :query_constraints => [:way_id, :version], :inverse_of => :old_way - has_many :old_tags, :class_name => "OldWayTag", :query_constraints => [:way_id, :version], :inverse_of => :old_way + has_many :old_nodes, :class_name => "OldWayNode", :foreign_key => [:way_id, :version], :inverse_of => :old_way + has_many :old_tags, :class_name => "OldWayTag", :foreign_key => [:way_id, :version], :inverse_of => :old_way validates :changeset, :associated => true validates :timestamp, :presence => true diff --git a/app/models/old_way_node.rb b/app/models/old_way_node.rb index e031aba10..b2a16c16b 100644 --- a/app/models/old_way_node.rb +++ b/app/models/old_way_node.rb @@ -19,7 +19,7 @@ class OldWayNode < ApplicationRecord self.table_name = "way_nodes" - belongs_to :old_way, :query_constraints => [:way_id, :version], :inverse_of => :old_nodes + belongs_to :old_way, :foreign_key => [:way_id, :version], :inverse_of => :old_nodes # A bit messy, referring to current nodes and ways, should do for the data browser for now belongs_to :node belongs_to :way diff --git a/app/models/old_way_tag.rb b/app/models/old_way_tag.rb index 96ec8baf5..82ce132ec 100644 --- a/app/models/old_way_tag.rb +++ b/app/models/old_way_tag.rb @@ -15,7 +15,7 @@ class OldWayTag < ApplicationRecord self.table_name = "way_tags" - belongs_to :old_way, :query_constraints => [:way_id, :version], :inverse_of => :old_tags + belongs_to :old_way, :foreign_key => [:way_id, :version], :inverse_of => :old_tags validates :old_way, :associated => true validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true diff --git a/bin/brakeman b/bin/brakeman new file mode 100755 index 000000000..ace1c9ba0 --- /dev/null +++ b/bin/brakeman @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +ARGV.unshift("--ensure-latest") + +load Gem.bin_path("brakeman", "brakeman") 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 b5accee8a..ff6a47532 100755 --- a/bin/setup +++ b/bin/setup @@ -1,8 +1,8 @@ #!/usr/bin/env ruby require "fileutils" -# path to your application root. APP_ROOT = File.expand_path("..", __dir__) +APP_NAME = "openstreetmap".freeze def system!(*args) system(*args, :exception => true) @@ -30,4 +30,8 @@ FileUtils.chdir APP_ROOT do 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/environments/development.rb b/config/environments/development.rb index bf49d70da..bc4b58748 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -14,7 +14,7 @@ Rails.application.configure do # 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. @@ -24,9 +24,7 @@ Rails.application.configure do 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 @@ -39,8 +37,12 @@ Rails.application.configure do # 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 @@ -59,11 +61,6 @@ Rails.application.configure do # Highlight code that enqueued background job in logs. config.active_job.verbose_enqueue_logs = true - # Debug mode disables concatenation and preprocessing of assets. - # This option may cause significant delays in view rendering with a large - # number of complex assets. - config.assets.debug = true - # Suppress logger output for asset requests. config.assets.quiet = true @@ -74,14 +71,17 @@ Rails.application.configure do # 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 - # Raise error when a before_action's only/except options reference missing actions + # Raise error when a before_action's only/except options reference missing actions. config.action_controller.raise_on_missing_callback_actions = true + # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. + # config.generators.apply_rubocop_autocorrect_after_generate! + # Disable host validation. config.hosts = [] end diff --git a/config/environments/production.rb b/config/environments/production.rb index 5ce25fc2c..9a7e072b4 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -13,21 +13,23 @@ Rails.application.configure do config.eager_load = true # Full error reports are disabled and caching is turned on. - config.consider_all_requests_local = false + config.consider_all_requests_local = false config.action_controller.perform_caching = true # 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 - # Enable static file serving from the `/public` folder (turn off if using NGINX/Apache for it). - config.public_file_server.enabled = true + # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. + # config.public_file_server.enabled = false - # Compress JavaScripts and CSS. + # Compress JavaScripts using a preprocessor. config.assets.js_compressor = Terser.new + + # 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. @@ -52,15 +54,18 @@ Rails.application.configure do # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true + # Skip http-to-https redirect for the default health check endpoint. + # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } + # Log to STDOUT by default - # config.logger = ActiveSupport::Logger.new($stdout) - # .tap { |logger| logger.formatter = Logger::Formatter.new } - # .then { |logger| ActiveSupport::TaggedLogging.new(logger) } + # 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] - # Info include generic and useful information about system operation, but avoids logging too much + # "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") @@ -72,9 +77,11 @@ Rails.application.configure do # config.cache_store = :mem_cache_store # 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 = "openstreetmap_production" + # Disable caching for Action Mailer templates even if Action Controller + # caching is enabled. config.action_mailer.perform_caching = false # Configure caching of static assets diff --git a/config/environments/test.rb b/config/environments/test.rb index 451eecc50..7ac52c5e4 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -18,17 +18,14 @@ Rails.application.configure do 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.consider_all_requests_local = true config.action_controller.perform_caching = false config.cache_store = :null_store - # Raise exceptions instead of rendering exception templates. + # Render exception templates for rescuable exceptions and raise for other exceptions. config.action_dispatch.show_exceptions = :rescuable # Disable request forgery protection in test environment. @@ -40,6 +37,8 @@ Rails.application.configure do # Disable logging in tests, for speed increases. Set to :info to bring back logging config.log_level = :warn + # 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. @@ -47,6 +46,10 @@ Rails.application.configure do # 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 => Settings.server_url } + # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr @@ -65,7 +68,7 @@ Rails.application.configure do # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true - # Raise error when a before_action's only/except options reference missing actions + # Raise error when a before_action's only/except options reference missing actions. config.action_controller.raise_on_missing_callback_actions = true # Use the test adapter for ActiveJob during testing. 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/puma.rb b/config/puma.rb index 283e163b1..60e1b9c67 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,38 +1,33 @@ -# 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. -# -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 +# 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. -# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +# Puma starts a configurable number of processes (workers) and each process +# serves each request in a thread from an internal thread pool. # -port ENV.fetch("PORT", 3000) - -# Specifies the `environment` that Puma will run in. +# 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. # -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). +# 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. # -# workers ENV.fetch("WEB_CONCURRENCY") { 2 } - -# 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. +# The default is set to 3 threads as it's deemed a decent compromise between +# throughput and latency for the average Rails application. # -# preload_app! +# 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 + +# 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 `rails restart` command. +# Allow puma to be restarted by `bin/rails restart` command. plugin :tmp_restart + +# Only use a pidfile when requested +pidfile ENV["PIDFILE"] if ENV["PIDFILE"] diff --git a/lib/classic_pagination/pagination.rb b/lib/classic_pagination/pagination.rb index c7022e0b0..b54b0e9f8 100644 --- a/lib/classic_pagination/pagination.rb +++ b/lib/classic_pagination/pagination.rb @@ -288,7 +288,7 @@ module ActionController end # Successively yields all the paginator's pages to the given block. - def each(&_block) + def each(&) page_count.times do |n| yield self[n + 1] end diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb index 63c8090a8..d2c3d5196 100644 --- a/test/application_system_test_case.rb +++ b/test/application_system_test_case.rb @@ -38,7 +38,7 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase click_on "Logout", :match => :first end - def within_sidebar(&block) - within "#sidebar_content", &block + def within_sidebar(&) + within("#sidebar_content", &) end end diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb index 24d74c85f..524851e63 100644 --- a/test/helpers/application_helper_test.rb +++ b/test/helpers/application_helper_test.rb @@ -88,8 +88,4 @@ class ApplicationHelperTest < ActionView::TestCase date = friendly_date_ago(Time.now.utc - 4.months) assert_match %r{^$}, date end - - def test_body_class; end - - def test_header_nav_link_class; end end diff --git a/test/integration/user_creation_test.rb b/test/integration/user_creation_test.rb index 1b0933d32..f75fde75e 100644 --- a/test/integration/user_creation_test.rb +++ b/test/integration/user_creation_test.rb @@ -171,13 +171,13 @@ class UserCreationTest < ActionDispatch::IntegrationTest end # Check that the user can successfully recover their password - def test_lost_password_recovery_success - # Open the lost password form - # Submit the lost password form - # Check the e-mail - # Submit the reset password token - # Check that the password has changed, and the user can login - end + # def test_lost_password_recovery_success + # Open the lost password form + # Submit the lost password form + # Check the e-mail + # Submit the reset password token + # Check that the password has changed, and the user can login + # end def test_user_create_redirect new_email = "redirect_tester@osm.org" diff --git a/test/system/history_test.rb b/test/system/history_test.rb index 335063db9..679f711b3 100644 --- a/test/system/history_test.rb +++ b/test/system/history_test.rb @@ -28,27 +28,29 @@ class HistoryTest < ApplicationSystemTestCase create_visible_changeset(user, "next-changeset") end - visit "#{user_path(user)}/history" - changesets = find "div.changesets" - changesets.assert_text "bottom-changeset-in-batch-1" - changesets.assert_no_text "bottom-changeset-in-batch-2" - changesets.assert_no_text "first-changeset-in-history" - changesets.assert_selector "ol", :count => 1 - changesets.assert_selector "li", :count => PAGE_SIZE - - changesets.find(".changeset_more a.btn").click - changesets.assert_text "bottom-changeset-in-batch-1" - changesets.assert_text "bottom-changeset-in-batch-2" - changesets.assert_no_text "first-changeset-in-history" - changesets.assert_selector "ol", :count => 1 - changesets.assert_selector "li", :count => 2 * PAGE_SIZE - - changesets.find(".changeset_more a.btn").click - changesets.assert_text "bottom-changeset-in-batch-1" - changesets.assert_text "bottom-changeset-in-batch-2" - changesets.assert_text "first-changeset-in-history" - changesets.assert_selector "ol", :count => 1 - changesets.assert_selector "li", :count => (2 * PAGE_SIZE) + 1 + assert_nothing_raised do + visit "#{user_path(user)}/history" + changesets = find "div.changesets" + changesets.assert_text "bottom-changeset-in-batch-1" + changesets.assert_no_text "bottom-changeset-in-batch-2" + changesets.assert_no_text "first-changeset-in-history" + changesets.assert_selector "ol", :count => 1 + changesets.assert_selector "li", :count => PAGE_SIZE + + changesets.find(".changeset_more a.btn").click + changesets.assert_text "bottom-changeset-in-batch-1" + changesets.assert_text "bottom-changeset-in-batch-2" + changesets.assert_no_text "first-changeset-in-history" + changesets.assert_selector "ol", :count => 1 + changesets.assert_selector "li", :count => 2 * PAGE_SIZE + + changesets.find(".changeset_more a.btn").click + changesets.assert_text "bottom-changeset-in-batch-1" + changesets.assert_text "bottom-changeset-in-batch-2" + changesets.assert_text "first-changeset-in-history" + changesets.assert_selector "ol", :count => 1 + changesets.assert_selector "li", :count => (2 * PAGE_SIZE) + 1 + end end def create_visible_changeset(user, comment) diff --git a/test/test_helper.rb b/test/test_helper.rb index 171028f4b..79d5d0d33 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -340,10 +340,10 @@ module ActiveSupport Settings.merge!(saved_settings) end - def with_user_account_deletion_delay(value, &block) + def with_user_account_deletion_delay(value, &) freeze_time - with_settings(:user_account_deletion_delay => value, &block) + with_settings(:user_account_deletion_delay => value, &) ensure unfreeze_time end