From 72ffe7215db6a8d448630823ff6eb2cc1c9169c2 Mon Sep 17 00:00:00 2001 From: Andrew Tomaka Date: Fri, 21 Jun 2024 23:35:36 -0400 Subject: [PATCH] Start running Rails from the main branch (#16) Reviewed-on: https://git.atomaka.com/atomaka/budget/pulls/16 --- .drone.yml | 12 +- .rubocop.yml | 5 + Dockerfile | 40 ++- Gemfile | 45 ++- Gemfile.lock | 291 +++++++++--------- app/assets/config/manifest.js | 5 - app/helpers/expenses_helper.rb | 2 +- app/helpers/incomes_helper.rb | 2 +- bin/brakeman | 7 + bin/docker-entrypoint | 7 +- bin/rubocop | 8 + bin/setup | 6 +- config/application.rb | 2 +- config/environments/development.rb | 21 +- config/environments/production.rb | 17 +- config/environments/test.rb | 19 +- .../initializers/filter_parameter_logging.rb | 2 +- .../new_framework_defaults_8_0.rb | 10 + config/puma.rb | 75 +++-- public/406-unsupported-browser.html | 66 ++++ public/icon.png | Bin 0 -> 5599 bytes public/icon.svg | 3 + test/application_system_test_case.rb | 2 +- 23 files changed, 405 insertions(+), 242 deletions(-) create mode 100644 .rubocop.yml delete mode 100644 app/assets/config/manifest.js create mode 100755 bin/brakeman create mode 100755 bin/rubocop create mode 100644 config/initializers/new_framework_defaults_8_0.rb create mode 100644 public/406-unsupported-browser.html create mode 100644 public/icon.png create mode 100644 public/icon.svg diff --git a/.drone.yml b/.drone.yml index 795036c..7d73420 100644 --- a/.drone.yml +++ b/.drone.yml @@ -26,7 +26,17 @@ steps: - name: bundle path: /usr/local/bundle commands: - - bin/bundle exec standardrb + - bin/rubocop + depends_on: + - install + +- name: brakeman + image: ruby:3.3.1 + volumes: + - name: bundle + path: /usr/local/bundle + commands: + - bin/brakeman depends_on: - install diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..25f5ca5 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,5 @@ +# Omakase Ruby styling for Rails +inherit_gem: + rubocop-rails-omakase: rubocop.yml + +# Your own specialized rules go here diff --git a/Dockerfile b/Dockerfile index f19c5f1..0639c80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,25 +1,36 @@ # syntax = docker/dockerfile:1 -# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile -ARG RUBY_VERSION=3.2.2 -FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base +# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand: +# docker build -t my-app . +# docker run -d -p 80:80 -p 443:443 --name my-app -e RAILS_MASTER_KEY= my-app + +# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html + +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version +ARG RUBY_VERSION=3.3.1 +FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base # Rails app lives here WORKDIR /rails +# Install base packages +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y curl libjemalloc2 libsqlite3-0 libvips && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + # Set production environment ENV RAILS_ENV="production" \ BUNDLE_DEPLOYMENT="1" \ BUNDLE_PATH="/usr/local/bundle" \ BUNDLE_WITHOUT="development" - # Throw-away build stage to reduce size of final image -FROM base as build +FROM base AS build # Install packages needed to build gems RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y build-essential git libvips pkg-config + apt-get install --no-install-recommends -y build-essential git pkg-config && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives # Install application gems COPY Gemfile Gemfile.lock ./ @@ -27,7 +38,6 @@ RUN bundle install && \ rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ bundle exec bootsnap precompile --gemfile - # Copy application code COPY . . @@ -38,24 +48,20 @@ RUN bundle exec bootsnap precompile app/ lib/ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile + + # Final stage for app image FROM base -# Install packages needed for deployment -RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y curl libsqlite3-0 libvips libjemalloc2 && \ - rm -rf /var/lib/apt/lists /var/cache/apt/archives - # Copy built artifacts: gems, application -COPY --from=build /usr/local/bundle /usr/local/bundle +COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" COPY --from=build /rails /rails # Run and own only the runtime files as a non-root user for security -RUN useradd rails --create-home --shell /bin/bash && \ +RUN groupadd --system --gid 1000 rails && \ + useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ chown -R rails:rails db log storage tmp -USER rails:rails - -ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2 +USER 1000:1000 # Entrypoint prepares the database. ENTRYPOINT ["/rails/bin/docker-entrypoint"] diff --git a/Gemfile b/Gemfile index 519b478..ef1c2ba 100644 --- a/Gemfile +++ b/Gemfile @@ -1,32 +1,61 @@ source "https://rubygems.org" -git_source(:github) { |repo| "https://github.com/#{repo}.git" } -gem "rails", "7.1.3.2" -gem "sprockets-rails" -gem "sqlite3", "< 2" -gem "puma" +gem "rails", github: "rails/rails", branch: "main" +# The modern asset pipeline for Rails [https://github.com/rails/propshaft] +gem "propshaft" +# Use sqlite3 as the database for Active Record +gem "sqlite3", ">= 1.4" +# Use the Puma web server [https://github.com/puma/puma] +gem "puma", ">= 5.0" +# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] gem "importmap-rails" +# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] gem "turbo-rails" +# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] gem "stimulus-rails" +# Build JSON APIs with ease [https://github.com/rails/jbuilder] gem "jbuilder" +# Use Redis adapter to run Action Cable in production +# gem "redis", ">= 4.0.1" +# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] +# gem "kredis" + +# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] +# gem "bcrypt", "~> 3.1.7" + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem "tzinfo-data", platforms: %i[ windows jruby ] + +# Reduces boot times through caching; required in config/boot.rb gem "bootsnap", require: false +# Deploy this application anywhere as a Docker container [https://kamal-deploy.org] +# gem "kamal", require: false + +# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] # gem "image_processing", "~> 1.2" group :development, :test do - gem "debug", platforms: %i[mri mingw x64_mingw] + # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem + gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" + + # Static analysis for security vulnerabilities [https://brakemanscanner.org/] + gem "brakeman", require: false + + # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] + gem "rubocop-rails-omakase", require: false end group :development do - gem "standard" + # Use console on exceptions pages [https://github.com/rails/web-console] gem "web-console" end group :test do + # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] gem "capybara" gem "selenium-webdriver" - gem "webdrivers" end gem "tailwindcss-rails", "~> 2.0" diff --git a/Gemfile.lock b/Gemfile.lock index e7af628..5b0b297 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,35 +1,31 @@ -GEM - remote: https://rubygems.org/ +GIT + remote: https://github.com/rails/rails.git + revision: 5bec50bc70380bb1e70e8fb0a1654130042b1f16 + branch: main specs: - actioncable (7.1.3.2) - actionpack (= 7.1.3.2) - activesupport (= 7.1.3.2) + actioncable (8.0.0.alpha) + actionpack (= 8.0.0.alpha) + activesupport (= 8.0.0.alpha) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3.2) - actionpack (= 7.1.3.2) - activejob (= 7.1.3.2) - activerecord (= 7.1.3.2) - activestorage (= 7.1.3.2) - activesupport (= 7.1.3.2) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.3.2) - actionpack (= 7.1.3.2) - actionview (= 7.1.3.2) - activejob (= 7.1.3.2) - activesupport (= 7.1.3.2) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp + actionmailbox (8.0.0.alpha) + actionpack (= 8.0.0.alpha) + activejob (= 8.0.0.alpha) + activerecord (= 8.0.0.alpha) + activestorage (= 8.0.0.alpha) + activesupport (= 8.0.0.alpha) + mail (>= 2.8.0) + actionmailer (8.0.0.alpha) + actionpack (= 8.0.0.alpha) + actionview (= 8.0.0.alpha) + activejob (= 8.0.0.alpha) + activesupport (= 8.0.0.alpha) + mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.1.3.2) - actionview (= 7.1.3.2) - activesupport (= 7.1.3.2) + actionpack (8.0.0.alpha) + actionview (= 8.0.0.alpha) + activesupport (= 8.0.0.alpha) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -37,53 +33,82 @@ GEM rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.3.2) - actionpack (= 7.1.3.2) - activerecord (= 7.1.3.2) - activestorage (= 7.1.3.2) - activesupport (= 7.1.3.2) + useragent (~> 0.16) + actiontext (8.0.0.alpha) + actionpack (= 8.0.0.alpha) + activerecord (= 8.0.0.alpha) + activestorage (= 8.0.0.alpha) + activesupport (= 8.0.0.alpha) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3.2) - activesupport (= 7.1.3.2) + actionview (8.0.0.alpha) + activesupport (= 8.0.0.alpha) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.3.2) - activesupport (= 7.1.3.2) + activejob (8.0.0.alpha) + activesupport (= 8.0.0.alpha) globalid (>= 0.3.6) - activemodel (7.1.3.2) - activesupport (= 7.1.3.2) - activerecord (7.1.3.2) - activemodel (= 7.1.3.2) - activesupport (= 7.1.3.2) + activemodel (8.0.0.alpha) + activesupport (= 8.0.0.alpha) + activerecord (8.0.0.alpha) + activemodel (= 8.0.0.alpha) + activesupport (= 8.0.0.alpha) timeout (>= 0.4.0) - activestorage (7.1.3.2) - actionpack (= 7.1.3.2) - activejob (= 7.1.3.2) - activerecord (= 7.1.3.2) - activesupport (= 7.1.3.2) + activestorage (8.0.0.alpha) + actionpack (= 8.0.0.alpha) + activejob (= 8.0.0.alpha) + activerecord (= 8.0.0.alpha) + activesupport (= 8.0.0.alpha) marcel (~> 1.0) - activesupport (7.1.3.2) + activesupport (8.0.0.alpha) 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 minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + tzinfo (~> 2.0, >= 2.0.5) + rails (8.0.0.alpha) + actioncable (= 8.0.0.alpha) + actionmailbox (= 8.0.0.alpha) + actionmailer (= 8.0.0.alpha) + actionpack (= 8.0.0.alpha) + actiontext (= 8.0.0.alpha) + actionview (= 8.0.0.alpha) + activejob (= 8.0.0.alpha) + activemodel (= 8.0.0.alpha) + activerecord (= 8.0.0.alpha) + activestorage (= 8.0.0.alpha) + activesupport (= 8.0.0.alpha) + bundler (>= 1.15.0) + railties (= 8.0.0.alpha) + railties (8.0.0.alpha) + actionpack (= 8.0.0.alpha) + activesupport (= 8.0.0.alpha) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) base64 (0.2.0) - bigdecimal (3.1.7) + bigdecimal (3.1.8) bindex (0.8.1) bootsnap (1.18.3) msgpack (~> 1.2) - builder (3.2.4) + brakeman (6.1.2) + racc + builder (3.3.0) capybara (3.40.0) addressable matrix @@ -93,7 +118,7 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - concurrent-ruby (1.2.3) + concurrent-ruby (1.3.3) connection_pool (2.4.1) crass (1.0.6) date (3.3.4) @@ -101,25 +126,25 @@ GEM irb (~> 1.10) reline (>= 0.3.8) drb (2.2.1) - erubi (1.12.0) + erubi (1.13.0) globalid (1.2.1) activesupport (>= 6.1) - i18n (1.14.4) + i18n (1.14.5) concurrent-ruby (~> 1.0) importmap-rails (2.0.1) actionpack (>= 6.0.0) activesupport (>= 6.0.0) railties (>= 6.0.0) io-console (0.7.2) - irb (1.12.0) - rdoc + irb (1.13.2) + rdoc (>= 4.0.0) reline (>= 0.4.2) - jbuilder (2.11.5) + jbuilder (2.12.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) json (2.7.2) language_server-protocol (3.17.0.3) - lint_roller (1.1.0) + logger (1.6.0) loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -131,10 +156,9 @@ GEM marcel (1.0.4) matrix (0.4.2) mini_mime (1.1.5) - minitest (5.22.3) + minitest (5.24.0) msgpack (1.7.2) - mutex_m (0.2.0) - net-imap (0.4.10) + net-imap (0.4.13) date net-protocol net-pop (0.1.2) @@ -143,22 +167,29 @@ GEM timeout net-smtp (0.5.0) net-protocol - nio4r (2.7.1) - nokogiri (1.16.4-arm64-darwin) + nio4r (2.7.3) + nokogiri (1.16.6-aarch64-linux) racc (~> 1.4) - nokogiri (1.16.4-x86_64-linux) + nokogiri (1.16.6-arm64-darwin) racc (~> 1.4) - parallel (1.24.0) - parser (3.3.0.5) + nokogiri (1.16.6-x86_64-linux) + racc (~> 1.4) + parallel (1.25.1) + parser (3.3.3.0) ast (~> 2.4.1) racc + propshaft (0.9.0) + actionpack (>= 7.0.0) + activesupport (>= 7.0.0) + rack + railties (>= 7.0.0) psych (5.1.2) stringio - public_suffix (5.0.5) + public_suffix (6.0.0) puma (6.4.2) nio4r (~> 2.0) - racc (1.7.3) - rack (3.0.10) + racc (1.8.0) + rack (3.1.3) rack-session (2.0.0) rack (>= 3.0.0) rack-test (2.1.0) @@ -166,20 +197,6 @@ GEM rackup (2.1.0) rack (>= 3) webrick (~> 1.8) - rails (7.1.3.2) - actioncable (= 7.1.3.2) - actionmailbox (= 7.1.3.2) - actionmailer (= 7.1.3.2) - actionpack (= 7.1.3.2) - actiontext (= 7.1.3.2) - actionview (= 7.1.3.2) - activejob (= 7.1.3.2) - activemodel (= 7.1.3.2) - activerecord (= 7.1.3.2) - activestorage (= 7.1.3.2) - activesupport (= 7.1.3.2) - bundler (>= 1.15.0) - railties (= 7.1.3.2) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -187,23 +204,16 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.1.3.2) - actionpack (= 7.1.3.2) - activesupport (= 7.1.3.2) - irb - rackup (>= 1.0.0) - rake (>= 12.2) - thor (~> 1.0, >= 1.2.2) - zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.2.1) - rdoc (6.6.3.1) + rdoc (6.7.0) psych (>= 4.0.0) - regexp_parser (2.9.0) - reline (0.5.2) + regexp_parser (2.9.2) + reline (0.5.9) io-console (~> 0.5) - rexml (3.2.6) - rubocop (1.62.1) + rexml (3.3.0) + strscan + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -214,45 +224,45 @@ GEM rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.2) - parser (>= 3.3.0.4) - rubocop-performance (1.20.2) + rubocop-ast (1.31.3) + parser (>= 3.3.1.0) + rubocop-minitest (0.35.0) + rubocop (>= 1.61, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails (2.25.0) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.33.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails-omakase (1.0.0) + rubocop + rubocop-minitest + rubocop-performance + rubocop-rails ruby-progressbar (1.13.0) rubyzip (2.3.2) - selenium-webdriver (4.10.0) + selenium-webdriver (4.22.0) + base64 (~> 0.2) + logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) - sprockets (4.2.1) - concurrent-ruby (~> 1.0) - rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - sprockets (>= 3.0.0) - sqlite3 (1.7.3-arm64-darwin) - sqlite3 (1.7.3-x86_64-linux) - standard (1.35.1) - language_server-protocol (~> 3.17.0.2) - lint_roller (~> 1.0) - rubocop (~> 1.62.0) - standard-custom (~> 1.0.0) - standard-performance (~> 1.3) - standard-custom (1.0.2) - lint_roller (~> 1.0) - rubocop (~> 1.50) - standard-performance (1.3.1) - lint_roller (~> 1.1) - rubocop-performance (~> 1.20.2) + sqlite3 (2.0.2-aarch64-linux-gnu) + sqlite3 (2.0.2-arm64-darwin) + sqlite3 (2.0.2-x86_64-linux-gnu) stimulus-rails (1.3.3) railties (>= 6.0.0) - stringio (3.1.0) - tailwindcss-rails (2.4.0-arm64-darwin) - railties (>= 6.0.0) - tailwindcss-rails (2.4.0-x86_64-linux) - railties (>= 6.0.0) + stringio (3.1.1) + strscan (3.1.0) + tailwindcss-rails (2.6.1-aarch64-linux) + railties (>= 7.0.0) + tailwindcss-rails (2.6.1-arm64-darwin) + railties (>= 7.0.0) + tailwindcss-rails (2.6.1-x86_64-linux) + railties (>= 7.0.0) thor (1.3.1) timeout (0.4.1) turbo-rails (2.0.5) @@ -262,15 +272,12 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) + useragent (0.16.10) web-console (4.2.1) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webdrivers (5.3.1) - nokogiri (~> 1.6) - rubyzip (>= 1.3.0) - selenium-webdriver (~> 4.0, < 4.11) webrick (1.8.1) websocket (1.2.10) websocket-driver (0.7.6) @@ -278,29 +285,31 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.13) + zeitwerk (2.6.16) PLATFORMS + aarch64-linux arm64-darwin-23 x86_64-linux DEPENDENCIES bootsnap + brakeman capybara debug importmap-rails jbuilder - puma - rails (= 7.1.3.2) + propshaft + puma (>= 5.0) + rails! + rubocop-rails-omakase selenium-webdriver - sprockets-rails - sqlite3 (< 2) - standard + sqlite3 (>= 1.4) stimulus-rails tailwindcss-rails (~> 2.0) turbo-rails + tzinfo-data web-console - webdrivers BUNDLED WITH 2.5.9 diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js deleted file mode 100644 index b06fc42..0000000 --- a/app/assets/config/manifest.js +++ /dev/null @@ -1,5 +0,0 @@ -//= link_tree ../images -//= link_directory ../stylesheets .css -//= link_tree ../../javascript .js -//= link_tree ../../../vendor/javascript .js -//= link_tree ../builds diff --git a/app/helpers/expenses_helper.rb b/app/helpers/expenses_helper.rb index 739166e..263c8f3 100644 --- a/app/helpers/expenses_helper.rb +++ b/app/helpers/expenses_helper.rb @@ -2,6 +2,6 @@ module ExpensesHelper def expense_periods Expense .periods - .map { |key, value| [key.titleize, Expense.periods.key(value)] } + .map { |key, value| [ key.titleize, Expense.periods.key(value) ] } end end diff --git a/app/helpers/incomes_helper.rb b/app/helpers/incomes_helper.rb index 9d6b84f..8275806 100644 --- a/app/helpers/incomes_helper.rb +++ b/app/helpers/incomes_helper.rb @@ -2,6 +2,6 @@ module IncomesHelper def members Member .all - .map { |member, value| [member.name, member.id] } + .map { |member, value| [ member.name, member.id ] } end end diff --git a/bin/brakeman b/bin/brakeman new file mode 100755 index 0000000..ace1c9b --- /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/docker-entrypoint b/bin/docker-entrypoint index dffd4ba..840d093 100755 --- a/bin/docker-entrypoint +++ b/bin/docker-entrypoint @@ -1,7 +1,12 @@ #!/bin/bash -e +# Enable jemalloc for reduced memory usage and latency. +if [ -z "${LD_PRELOAD+x}" ] && [ -f /usr/lib/*/libjemalloc.so.2 ]; then + export LD_PRELOAD="$(echo /usr/lib/*/libjemalloc.so.2)" +fi + # If running the rails server then create or migrate existing database -if [ "${*}" == "./bin/rails server" ]; then +if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then ./bin/rails db:prepare fi 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 3cd5a9d..57866ca 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 = "family_budget" 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 3526226..36fd491 100644 --- a/config/application.rb +++ b/config/application.rb @@ -9,7 +9,7 @@ Bundler.require(*Rails.groups) module FamilyBudget class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.1 + config.load_defaults 8.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. diff --git a/config/environments/development.rb b/config/environments/development.rb index 2e7fb48..d969821 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 @@ -41,15 +39,11 @@ Rails.application.configure do 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 - # Raise exceptions for disallowed deprecations. - config.active_support.disallowed_deprecation = :raise - - # Tell Active Support which deprecation messages to disallow. - config.active_support.disallowed_deprecation_warnings = [] - # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load @@ -66,11 +60,14 @@ 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! end diff --git a/config/environments/production.rb b/config/environments/production.rb index 5bee2a4..8f42c8c 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -20,13 +20,13 @@ Rails.application.configure do # 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 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. @@ -51,15 +51,18 @@ Rails.application.configure do # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = false + # 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) + 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 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") @@ -68,7 +71,7 @@ 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 = "family_budget_production" config.action_mailer.perform_caching = false diff --git a/config/environments/test.rb b/config/environments/test.rb index bcb1feb..83d1fa9 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.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. @@ -44,21 +41,19 @@ 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: "www.example.com" } + # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr - # Raise exceptions for disallowed deprecations. - config.active_support.disallowed_deprecation = :raise - - # Tell Active Support which deprecation messages to disallow. - config.active_support.disallowed_deprecation_warnings = [] - # 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 - # 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/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/new_framework_defaults_8_0.rb b/config/initializers/new_framework_defaults_8_0.rb new file mode 100644 index 0000000..d8e7757 --- /dev/null +++ b/config/initializers/new_framework_defaults_8_0.rb @@ -0,0 +1,10 @@ +# Be sure to restart your server when you modify this file. +# +# This file eases your Rails 8.0 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 `8.0`. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. +# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html diff --git a/config/puma.rb b/config/puma.rb index ce4878f..f976b8a 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,43 +1,54 @@ -# 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 `worker_timeout` threshold that Puma will use to wait before -# terminating a worker in development environments. +# Puma starts a configurable number of processes (workers) and each process +# serves each request in a thread from an internal thread pool. # -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 +# prioritize throughput over latency. # -port ENV.fetch("PORT", 3000) +# 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. +# +# The default is set to 3 threads as it's deemed a decent compromise between +# throughput and latency for the average Rails application. +# +# 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 `environment` that Puma will run in. -# -environment ENV.fetch("RAILS_ENV") { "development" } +rails_env = ENV.fetch("RAILS_ENV", "development") +environment rails_env -# Specifies the `pidfile` that Puma will use. -pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } +case rails_env +when "production" + # If you are running more than 1 thread per process, the workers count + # should be equal to the number of processors (CPU cores) in production. + # + # Automatically detect the number of available processors in production. + require "concurrent-ruby" + workers_count = Integer(ENV.fetch("WEB_CONCURRENCY") { Concurrent.available_processor_count }) + workers workers_count if workers_count > 1 -# 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). -# -# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + preload_app! +when "development" + # Specifies a very generous `worker_timeout` so that the worker + # isn't killed by Puma when suspended by a debugger. + worker_timeout 3600 +end -# 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 + +# Only use a pidfile when requested +pidfile ENV["PIDFILE"] if ENV["PIDFILE"] 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/icon.png b/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f3b5abcbde91cf6d7a6a26e514eb7e30f476f950 GIT binary patch literal 5599 zcmeHL-D}fO6hCR_taXJlzs3}~RuB=Iujyo=i*=1|1FN%E=zNfMTjru|Q<6v{J{U!C zBEE}?j6I3sz>fzN!6}L_BKjcuASk~1;Dg|U_@d{g?V8mM`~#9U+>>*Ezw>c(PjYWA z4(;!cgge6k5E&d$G5`S-0}!Ik>CV(0Y#1}s-v_gAHhja2=W1?nBAte9D2HG<(+)uj z!5=W4u*{VKMw#{V@^NNs4TClr!FAA%ID-*gc{R%CFKEzG<6gm*9s_uy)oMGW*=nJf zw{(Mau|2FHfXIv6C0@Wk5k)F=3jo1srV-C{pl&k&)4_&JjYrnbJiul}d0^NCSh(#7h=F;3{|>EU>h z6U8_p;^wK6mAB(1b92>5-HxJ~V}@3?G`&Qq-TbJ2(&~-HsH6F#8mFaAG(45eT3VPO zM|(Jd<+;UZs;w>0Qw}0>D%{~r{uo_Fl5_Bo3ABWi zWo^j^_T3dxG6J6fH8X)$a^%TJ#PU!=LxF=#Fd9EvKx_x>q<(KY%+y-08?kN9dXjXK z**Q=yt-FTU*13ouhCdqq-0&;Ke{T3sQU9IdzhV9LhQIpq*P{N)+}|Mh+a-VV=x?R} c>%+pvTcMWshj-umO}|qP?%A)*_KlqT3uEqhU;qFB literal 0 HcmV?d00001 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/test/application_system_test_case.rb b/test/application_system_test_case.rb index 2ac80b6..e2db3a5 100644 --- a/test/application_system_test_case.rb +++ b/test/application_system_test_case.rb @@ -3,5 +3,5 @@ require "test_helper" class ApplicationSystemTestCase < ActionDispatch::SystemTestCase driven_by :selenium, using: ENV["VISIBLE_SYSTEM_TESTS"].present? ? :chrome : :headless_chrome, - screen_size: [1400, 1400] + screen_size: [ 1400, 1400 ] end