diff --git a/.circleci/config.yml b/.circleci/config.yml index ade8260..4f97468 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ jobs: environment: RAILS_ENV: test docker: - - image: cimg/ruby:3.3.4-node + - image: cimg/ruby:3.3.5-node environment: PGHOST: localhost PGUSER: buildlight diff --git a/Dockerfile b/Dockerfile index ee40eeb..075a465 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # syntax = docker/dockerfile:1 # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile -ARG RUBY_VERSION=3.3.4 +ARG RUBY_VERSION=3.3.5 FROM --platform=linux/amd64 ruby:$RUBY_VERSION-alpine AS base LABEL fly_launch_runtime="rails" diff --git a/Gemfile b/Gemfile index 97bc800..628338c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source "https://rubygems.org" -ruby "3.3.4" +ruby "3.3.5" gem "rails", "~> 7.2.1" @@ -8,6 +8,7 @@ gem "pg" gem "bootsnap" gem "dockerfile-rails" gem "honeybadger" +gem "ostruct" # Required by particlerb gem "particlerb" gem "puma" @@ -15,10 +16,6 @@ gem "importmap-rails" gem "cssbundling-rails" gem "propshaft" -# This gem is pulled in via ActionCable, so remove when the PR is merged. -# https://github.com/faye/websocket-driver-ruby/pull/85 -gem "websocket-driver", github: "danielmorrison/websocket-driver-ruby", branch: "support-frozen-by-default" - group :development, :test do gem "debug" gem "factory_bot_rails" diff --git a/Gemfile.lock b/Gemfile.lock index 36fc7de..64781a8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,3 @@ -GIT - remote: https://github.com/danielmorrison/websocket-driver-ruby.git - revision: 0e950c51343045221f8414611994439105e32b86 - branch: support-frozen-by-default - specs: - websocket-driver (0.7.5) - websocket-extensions (>= 0.1.0) - GEM remote: https://rubygems.org/ specs: @@ -100,12 +92,12 @@ GEM rails (>= 3.0.0) drb (2.2.1) erubi (1.13.0) - factory_bot (6.4.6) + factory_bot (6.5.0) activesupport (>= 5.0.0) - factory_bot_rails (6.4.3) - factory_bot (~> 6.4) + factory_bot_rails (6.4.4) + factory_bot (~> 6.5) railties (>= 5.0.0) - faraday (1.10.3) + faraday (1.10.4) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -123,7 +115,7 @@ GEM faraday-httpclient (1.0.1) faraday-multipart (1.0.4) multipart-post (~> 2) - faraday-net_http (1.0.1) + faraday-net_http (1.0.2) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) @@ -134,11 +126,11 @@ GEM thor (>= 0.14.0, < 2) globalid (1.2.1) activesupport (>= 6.1) - honeybadger (5.16.0) + honeybadger (5.18.0) logger i18n (1.14.6) concurrent-ruby (~> 1.0) - importmap-rails (2.0.1) + importmap-rails (2.0.3) actionpack (>= 6.0.0) activesupport (>= 6.0.0) railties (>= 6.0.0) @@ -146,7 +138,7 @@ GEM irb (1.14.1) rdoc (>= 4.0.0) reline (>= 0.4.2) - json (2.7.2) + json (2.7.4) language_server-protocol (3.17.0.3) lint_roller (1.1.0) logger (1.6.1) @@ -163,7 +155,7 @@ GEM mini_portile2 (2.8.7) minitest (5.25.1) msgpack (1.7.3) - multipart-post (2.4.0) + multipart-post (2.4.1) net-imap (0.5.0) date net-protocol @@ -183,6 +175,7 @@ GEM racc (~> 1.4) nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) + ostruct (0.6.0) parallel (1.26.3) parser (3.3.5.0) ast (~> 2.4.1) @@ -190,8 +183,8 @@ GEM particlerb (2.1.0) faraday (>= 0.9.0) faraday_middleware (>= 0.9.0) - pg (1.5.8) - propshaft (0.9.0) + pg (1.5.9) + propshaft (1.1.0) actionpack (>= 7.0.0) activesupport (>= 7.0.0) rack @@ -318,6 +311,8 @@ GEM unicode-display_width (2.6.0) useragent (0.16.10) webrick (1.8.2) + websocket-driver (0.7.6) + websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) zeitwerk (2.7.1) @@ -337,6 +332,7 @@ DEPENDENCIES figaro honeybadger importmap-rails + ostruct particlerb pg propshaft @@ -347,10 +343,9 @@ DEPENDENCIES standard standard-performance standard-rails - websocket-driver! RUBY VERSION - ruby 3.3.4p94 + ruby 3.3.5p100 BUNDLED WITH - 2.5.17 + 2.5.19 diff --git a/app/models/status.rb b/app/models/status.rb index 4fc0a11..a0a5124 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -1,6 +1,8 @@ class Status < ApplicationRecord after_commit :update_devices + scope :red, -> { where(red: true) } + def name "#{username}/#{project_name}" end diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 0000000..40330c0 --- /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 e6834ec..26ad1cb 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 = "buildlight" 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/application.rb b/config/application.rb index 8c2eec7..744502c 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,7 +1,6 @@ require_relative "boot" require "rails" - # Pick the frameworks you want: require "active_model/railtie" require "active_job/railtie" @@ -22,7 +21,7 @@ module Buildlight class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.1 + config.load_defaults 7.2 # 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. @@ -39,5 +38,7 @@ class Application < Rails::Application config.x.debug = ENV["DEBUG"].present? config.x.host = ENV["HOST"] + # Don't generate system test files. + config.generators.system_tests = nil end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 768920d..03549e1 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -14,7 +14,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. @@ -24,23 +24,22 @@ 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 config.cache_store = :null_store end - # 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 @@ -59,18 +58,18 @@ # 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 - # Raises error for missing translations. # 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! end diff --git a/config/environments/production.rb b/config/environments/production.rb index c87acc9..6da74b9 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -23,12 +23,6 @@ # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. # config.public_file_server.enabled = false - # Compress CSS using a preprocessor. - # config.assets.css_compressor = :sass - - # Do not fallback to assets pipeline if a precompiled asset is missed. - config.assets.compile = false - # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" @@ -36,9 +30,6 @@ # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX - # Store uploaded files on the local file system (see config/storage.yml for options). - # config.active_storage.service = :local - # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil # config.action_cable.url = "wss://example.com/cable" @@ -51,6 +42,9 @@ # 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 } @@ -59,7 +53,7 @@ # 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") @@ -71,6 +65,8 @@ # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "buildlight_production" + # 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. diff --git a/config/environments/test.rb b/config/environments/test.rb index 6049334..d1e5467 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -18,10 +18,7 @@ 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 @@ -34,9 +31,8 @@ # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false - # 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. @@ -44,6 +40,10 @@ # 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 @@ -59,6 +59,6 @@ # 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 end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 2eeef96..4873244 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -5,8 +5,3 @@ # 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/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index c2d89e2..c010b83 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -4,5 +4,5 @@ # Use this to limit dissemination of sensitive information. # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. Rails.application.config.filter_parameters += [ - :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn + :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn ] diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb deleted file mode 100644 index 42b3437..0000000 --- a/config/initializers/secret_token.rb +++ /dev/null @@ -1,12 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Your secret key is used for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! - -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -# You can use `rake secret` to generate a secure secret key. - -# Make sure your secret_key_base is kept private -# if you're sharing your code publicly. -Buildlight::Application.config.secret_key_base = ENV["SECRET_TOKEN"] diff --git a/config/puma.rb b/config/puma.rb index 3258d75..03c166f 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,37 +1,34 @@ -# 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. -# -threads_count = ENV.fetch("RAILS_MAX_THREADS", 5) -threads threads_count, 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 webserver 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 + +# 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/public/404.html b/public/404.html index 9a48320..2be3af2 100644 --- a/public/404.html +++ b/public/404.html @@ -2,25 +2,66 @@ The page you were looking for doesn't exist (404) - - +
-

The page you were looking for doesn't exist.

-

You may have mistyped the address or the page may have moved.

+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

diff --git a/public/406-unsupported-browser.html b/public/406-unsupported-browser.html new file mode 100644 index 0000000..7cf1e16 --- /dev/null +++ b/public/406-unsupported-browser.html @@ -0,0 +1,66 @@ + + + + Your browser is not supported (406) + + + + + + +
+
+

Your browser is not supported.

+

Please upgrade your browser to continue.

+
+
+ + diff --git a/public/422.html b/public/422.html index 83660ab..c08eac0 100644 --- a/public/422.html +++ b/public/422.html @@ -2,25 +2,66 @@ The change you wanted was rejected (422) - - +
-

The change you wanted was rejected.

-

Maybe you tried to change something you didn't have access to.

+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

diff --git a/public/500.html b/public/500.html index f3648a0..78a030a 100644 --- a/public/500.html +++ b/public/500.html @@ -2,24 +2,65 @@ We're sorry, but something went wrong (500) - - +
-

We're sorry, but something went wrong.

+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000..f3b5abc Binary files /dev/null and b/public/icon.png differ diff --git a/public/icon.svg b/public/icon.svg new file mode 100644 index 0000000..78307cc --- /dev/null +++ b/public/icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/robots.txt b/public/robots.txt index 085187f..c19f78a 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,5 +1 @@ -# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file -# -# To ban all spiders from the entire site uncomment the next two lines: -# User-Agent: * -# Disallow: / +# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file