cancel-in-progress: true
env:
os: ubuntu-22.04
- ruby: '3.0'
+ ruby: '3.1'
jobs:
rubocop:
name: RuboCop
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
- rubocop-rake
AllCops:
- TargetRubyVersion: 3.0
+ TargetRubyVersion: 3.1
NewCops: enable
Exclude:
- 'vendor/**/*'
source "https://rubygems.org"
# Require rails
-gem "rails", "~> 7.1.0"
+gem "rails", "~> 7.2.0"
gem "turbo-rails"
# Require json for multi_json
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"
# 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"
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)
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)
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)
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)
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)
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
minitest (~> 5.1)
minitest-focus
multi_json
- multi_xml (~> 0.6.0)
omniauth (~> 2.0.2)
omniauth-facebook
omniauth-github
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
webmock
BUNDLED WITH
- 2.4.19
+ 2.5.11
* **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.
## 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
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"]
# 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
##
# 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
##
# 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
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
)
end
- def message_body(&block)
+ def message_body(&)
render(
:partial => "message_body",
- :locals => { :body => capture(&block) }
+ :locals => { :body => capture(&) }
)
end
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)
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?
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
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
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
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
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
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
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
--- /dev/null
+#!/usr/bin/env ruby
+require "rubygems"
+require "bundler/setup"
+
+ARGV.unshift("--ensure-latest")
+
+load Gem.bin_path("brakeman", "brakeman")
--- /dev/null
+#!/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")
#!/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)
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
# 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.
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
# 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
# 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
# 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
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.
# 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")
# 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
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.
# 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.
# 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
# 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.
--- /dev/null
+# 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
-# 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"]
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
click_on "Logout", :match => :first
end
- def within_sidebar(&block)
- within "#sidebar_content", &block
+ def within_sidebar(&)
+ within("#sidebar_content", &)
end
end
date = friendly_date_ago(Time.now.utc - 4.months)
assert_match %r{^<time title=".*">4 months ago</time>$}, date
end
-
- def test_body_class; end
-
- def test_header_nav_link_class; end
end
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"
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)
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