From 52777edb65cd1b4dec2f53bee271313c9d76be49 Mon Sep 17 00:00:00 2001 From: Christoph Haas Date: Fri, 4 Apr 2025 00:58:27 +0200 Subject: [PATCH] Several changes to adapt Rails 8 --- .gitignore | 2 + Dockerfile | 2 +- Gemfile | 52 ++++++++++---------- Gemfile.lock | 6 ++- bun.lockb | Bin 0 -> 83230 bytes config/cable.yml | 22 ++++----- config/cache.yml | 16 +++++++ config/credentials/development.yml.enc | 1 + config/database.yml | 63 ++++++++++++++----------- config/environments/production.rb | 25 +++++----- db/schema.rb | 6 +-- 11 files changed, 112 insertions(+), 83 deletions(-) create mode 100755 bun.lockb create mode 100644 config/cache.yml create mode 100644 config/credentials/development.yml.enc diff --git a/.gitignore b/.gitignore index a21a562..644767f 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,5 @@ debshots-workspace.code-workspace !/app/assets/builds/.keep /node_modules + +/config/credentials/development.key diff --git a/Dockerfile b/Dockerfile index 05eac30..0900b9d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ WORKDIR /rails # Install base packages RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y curl libjemalloc2 libvips libpq-dev nodejs && \ + apt-get install --no-install-recommends -y curl libjemalloc2 libvips libpq-dev nodejs telnet && \ rm -rf /var/lib/apt/lists /var/cache/apt/archives # Set production environment diff --git a/Gemfile b/Gemfile index be73b9a..5733f85 100644 --- a/Gemfile +++ b/Gemfile @@ -1,23 +1,23 @@ -source "https://rubygems.org" +source 'https://rubygems.org' # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 8.0.2" +gem 'rails', '~> 8.0.2' # The modern asset pipeline for Rails [https://github.com/rails/propshaft] -gem "propshaft" +gem 'propshaft' # Use sqlite3 as the database for Active Record -gem "sqlite3", ">= 2.1" +gem 'sqlite3', '>= 2.1' # Use the Puma web server [https://github.com/puma/puma] -gem "puma", ">= 5.0" +gem 'puma', '>= 5.0' # Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails] -gem "jsbundling-rails" +gem 'jsbundling-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" # Bundle and process CSS [https://github.com/rails/cssbundling-rails] -gem "cssbundling-rails" +gem 'cssbundling-rails' # Build JSON APIs with ease [https://github.com/rails/jbuilder] -gem "jbuilder" +gem 'jbuilder' # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] # gem "bcrypt", "~> 3.1.7" @@ -26,9 +26,9 @@ gem "jbuilder" gem 'shrine', '~> 3.0' # Use the database-backed adapters for Rails.cache, Active Job, and Action Cable -gem "solid_cache" -gem "solid_queue" -gem "solid_cable" +gem 'solid_cable' +gem 'solid_cache' +gem 'solid_queue' # To create variants (different sizes) of screenshot images gem 'fastimage' @@ -36,38 +36,38 @@ gem 'image_processing' gem 'mini_magick' # Reduces boot times through caching; required in config/boot.rb -gem "bootsnap", require: false +gem 'bootsnap', require: false # Deploy this application anywhere as a Docker container [https://kamal-deploy.org] -gem "kamal", require: false +gem 'kamal', require: false # Add HTTP asset caching/compression and X-Sendfile acceleration to Puma [https://github.com/basecamp/thruster/] -gem "thruster", require: false +gem 'thruster', 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 # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem - gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" + gem 'debug', platforms: %i[mri windows], require: 'debug/prelude' # Static analysis for security vulnerabilities [https://brakemanscanner.org/] - gem "brakeman", require: false + gem 'brakeman', require: false # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] - gem "rubocop-rails-omakase", require: false + gem 'rubocop-rails-omakase', require: false end group :development do # Use console on exceptions pages [https://github.com/rails/web-console] # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. - gem "web-console" gem 'listen', '~> 3.5' + gem 'web-console' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring - #gem 'better_errors' - #gem 'binding_of_caller' - #gem 'spring' - #gem 'spring-watcher-listen', '~> 2.0.0' + # gem 'better_errors' + # gem 'binding_of_caller' + # gem 'spring' + # gem 'spring-watcher-listen', '~> 2.0.0' gem 'rails-erd' @@ -102,8 +102,8 @@ end group :test do # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] - gem "capybara" - gem "selenium-webdriver" + gem 'capybara' + gem 'selenium-webdriver' end # TODO… https://github.com/galetahub/simple-captcha @@ -134,7 +134,7 @@ gem 'font-awesome-rails' # gem "recaptcha", require: "recaptcha/rails" -#gem 'sprockets-rails' +# gem 'sprockets-rails' # gem "activemodel-serializers-xml" @@ -159,6 +159,6 @@ gem 'gravtastic' gem 'bzip2-ffi' -#gem "dartsass-rails", "~> 0.5.1" +# gem "dartsass-rails", "~> 0.5.1" gem 'rails-healthcheck' diff --git a/Gemfile.lock b/Gemfile.lock index 95289b0..7b923d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -124,6 +124,9 @@ GEM responders warden (~> 1.2.3) dotenv (3.1.7) + dotenv-rails (3.1.7) + dotenv (= 3.1.7) + railties (>= 6.1) down (5.4.2) addressable (~> 2.8) drb (2.2.1) @@ -480,7 +483,7 @@ GEM activejob (>= 7.2) activerecord (>= 7.2) railties (>= 7.2) - solid_queue (1.1.3) + solid_queue (1.1.4) activejob (>= 7.1) activerecord (>= 7.1) concurrent-ruby (>= 1.3.1) @@ -572,6 +575,7 @@ DEPENDENCIES cssbundling-rails debug devise + dotenv-rails factory_bot_rails fastimage font-awesome-rails diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..64bb49d2c597b461a11dab099d74c63a427a7a7c GIT binary patch literal 83230 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 literal 0 HcmV?d00001 diff --git a/config/cable.yml b/config/cable.yml index 4aee18b..b9adc5a 100644 --- a/config/cable.yml +++ b/config/cable.yml @@ -2,16 +2,16 @@ # and seeing results in the browser, you must do so from the web console (running inside the dev process), # not a terminal started via bin/rails console! Add "console" to any action or any ERB template view # to make the web console appear. -# development: -# adapter: async +development: + adapter: async -# test: -# adapter: test +test: + adapter: test -# production: -# adapter: solid_cable -# connects_to: -# database: -# writing: cable -# polling_interval: 0.1.seconds -# message_retention: 1.day +production: + adapter: solid_cable + connects_to: + database: + writing: cable + polling_interval: 0.1.seconds + message_retention: 1.day diff --git a/config/cache.yml b/config/cache.yml new file mode 100644 index 0000000..19d4908 --- /dev/null +++ b/config/cache.yml @@ -0,0 +1,16 @@ +default: &default + store_options: + # Cap age of oldest cache entry to fulfill retention policies + # max_age: <%= 60.days.to_i %> + max_size: <%= 256.megabytes %> + namespace: <%= Rails.env %> + +development: + <<: *default + +test: + <<: *default + +production: + database: cache + <<: *default diff --git a/config/credentials/development.yml.enc b/config/credentials/development.yml.enc new file mode 100644 index 0000000..0a31a02 --- /dev/null +++ b/config/credentials/development.yml.enc @@ -0,0 +1 @@ +p4iCDmwxjQ5zC6i3QVNCnlW++oxVLD0AKnflI6lsRBQ1bLTcBA3+8EFI9itIiv7WUJYF+0xGz1bqNq8e9Kk+tEq7C1GVgbuS3xEjG2I0Kt1GbTjvl0aeCd7WHR5xWHlCIXmZVhO/OL4SNc876WYpQqwWRwHkPND0QGAmfWOgy2H14V6LVYh1d7fhPdSYBr4b6oPMMQW6fqAjQ8Oq5TVUznRiRLQfFhAYz2DklMAoASjhAWK39U76JWYqu8VCq08+3V/geXYtQfcsvQ1twq08RFcJbZsCG7slOI8fPW5Oq2dCpw==--mvh3V6FOm1I5+pal--y0AKTyuXuwhXl6iMcT29tw== \ No newline at end of file diff --git a/config/database.yml b/config/database.yml index 1305327..3f840e1 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,39 +1,46 @@ -# SQLite. Versions 3.8.0 and up are supported. -# gem install sqlite3 -# -# Ensure the SQLite 3 gem is defined in your Gemfile -# gem 'sqlite3' +default: &default + adapter: postgresql + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + timeout: 5000 + +production: +# Store production database in the storage/ directory, which by default +# is mounted as a persistent Docker volume in config/deploy.yml. + primary: + <<: *default + # database: storage/production.sqlite3 + url: <%= Rails.application.credentials.db.url %> + pool: 10 + cache: + <<: *default + database: storage/production_cache.sqlite3 + migrations_paths: db/cache_migrate + queue: + <<: *default + database: storage/production_queue.sqlite3 + migrations_paths: db/queue_migrate + cable: + <<: *default + database: storage/production_cable.sqlite3 + migrations_paths: db/cable_migrate + development: + <<: *default adapter: postgresql database: debshots_dev username: debshots_dev password: GonwannEn0 host: localhost - pool: 5 - timeout: 5000 +# SQLite. Versions 3.8.0 and up are supported. +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem 'sqlite3' +# # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: - adapter: postgresql - database: debshots_test - username: debshots_test - password: GonwannEn0 - host: localhost - pool: 5 - timeout: 5000 - -# production: -# adapter: postgresql -# database: debshots -# # username: debshots -# # password: GonwannEn0 -# # host: localhost -# pool: 10 -# timeout: 5000 -production: - url: <%= ENV['DATABASE_URL'] %> - adapter: postgresql - pool: 10 - timeout: 5000 + <<: *default + database: storage/test.sqlite3 diff --git a/config/environments/production.rb b/config/environments/production.rb index 0cfc950..9d2857c 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,4 +1,4 @@ -require "active_support/core_ext/integer/time" +require 'active_support/core_ext/integer/time' Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -16,7 +16,7 @@ Rails.application.configure do config.action_controller.perform_caching = true # Cache assets for far-future expiry since they are all digest stamped. - config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } + config.public_file_server.headers = { 'cache-control' => "public, max-age=#{1.year.to_i}" } # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" @@ -34,14 +34,14 @@ Rails.application.configure do # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } # Log to STDOUT with the current request id as a default log tag. - config.log_tags = [ :request_id ] + config.log_tags = [:request_id] config.logger = ActiveSupport::TaggedLogging.logger(STDOUT) # Change to "debug" to log everything (including potentially personally-identifiable information!) - config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") + config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'info') # Prevent health checks from clogging up the logs. - config.silence_healthcheck_path = "/up" + config.silence_healthcheck_path = '/up' # Don't log any deprecations. config.active_support.report_deprecations = false @@ -53,13 +53,12 @@ Rails.application.configure do config.active_job.queue_adapter = :solid_queue config.solid_queue.connects_to = { database: { writing: :queue } } config.action_mailer.smtp_settings = { - # TODO: make configurable through ENV variables - address: 'dokku2.workaround.org', - port: 25, + address: Rails.application.credentials.smtp.server, + port: 25, enable_starttls_auto: false } config.action_mailer.default_url_options = { - host: "screenshots.debian.net", + host: 'screenshots.debian.net', protocol: 'https' } @@ -68,7 +67,7 @@ Rails.application.configure do # config.action_mailer.raise_delivery_errors = false # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "example.com" } + config.action_mailer.default_url_options = { host: 'example.com' } # Specify outgoing SMTP server. Remember to add smtp/* credentials via rails credentials:edit. # config.action_mailer.smtp_settings = { @@ -89,8 +88,8 @@ Rails.application.configure do config.package_sources = [ { description: 'Debian Unstable (Sid)', type: 'apt', url: 'http://ftp.de.debian.org/debian/dists/sid', - architectures: ['i386' ,'amd64'] - #components: ['main','restricted','universe','multiverse'] + architectures: %w[i386 amd64] + # components: ['main','restricted','universe','multiverse'] } ] @@ -107,7 +106,7 @@ Rails.application.configure do # Only use :id for inspections in production. # Needed (at least) for devise.rb to determine the oauth2 callback URL config.base_url = ENV['DEBSHOTS_BASE_URL'] || 'http://localhost:3000' - config.active_record.attributes_for_inspect = [ :id ] + config.active_record.attributes_for_inspect = [:id] # Enable DNS rebinding protection and other `Host` header attacks. # config.hosts = [ diff --git a/db/schema.rb b/db/schema.rb index 73d2029..3aaa19f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,9 +10,9 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_11_26_173151) do +ActiveRecord::Schema[8.0].define(version: 2023_11_26_173151) do # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" + enable_extension "pg_catalog.plpgsql" create_table "action_mailbox_inbound_emails", force: :cascade do |t| t.integer "status", default: 0, null: false @@ -87,7 +87,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_11_26_173151) do t.datetime "updated_at", precision: nil t.integer "visits", default: 0 t.index "(((setweight(to_tsvector('english'::regconfig, COALESCE((name)::text, ''::text)), 'A'::\"char\") || setweight(to_tsvector('english'::regconfig, COALESCE((description)::text, ''::text)), 'B'::\"char\")) || setweight(to_tsvector('english'::regconfig, COALESCE(long_description, ''::text)), 'C'::\"char\")))", name: "packages_fts", using: :gin - t.index ["name"], name: "packages_name_key", unique: true + t.unique_constraint ["name"], name: "packages_name_key" end create_table "screenshots", id: :serial, force: :cascade do |t|