diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..1cfb0b5 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,6 @@ +FROM mcr.microsoft.com/vscode/devcontainers/base:ubuntu-22.04 + +# Adding the PostgreSQL repository so we can install postgresql-client v15 +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null +RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' diff --git a/.devcontainer/boot.sh b/.devcontainer/boot.sh new file mode 100755 index 0000000..df7cb22 --- /dev/null +++ b/.devcontainer/boot.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +echo "Setting SSH password for vscode user..." +sudo usermod --password "$(echo vscode | openssl passwd -1 -stdin)" vscode + +echo "Updating RubyGems..." +gem update --system -N + +echo "Installing dependencies..." +bundle install +yarn install + +echo "Copying database.yml..." +cp -n .env.devcontainer .env + +echo "Creating database..." +bin/rails db:create db:migrate db:seed + +echo "Done!" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..4dfccd3 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,51 @@ +{ + "name": "Your Project Name", + "dockerComposeFile": "docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", + "features": { + "ghcr.io/devcontainers/features/sshd:1": {}, + "ghcr.io/rocker-org/devcontainer-features/apt-packages:1": { + "packages": "libpq-dev, libvips, postgresql-client-15" + }, + "ghcr.io/devcontainers/features/git:1": { + "version": "latest" + }, + "ghcr.io/devcontainers/features/ruby:1": { + "version": "3.2.2" + }, + "ghcr.io/devcontainers/features/node:1": { + "version": "16.19.0" + }, + "ghcr.io/devcontainers/features/common-utils:2": { + "username": "vscode", + "userUid": 1000, + "userGid": 1000, + "installZsh": true, + "installOhMyZsh": true, + "configureZshAsDefaultShell": true, + "upgradePackages": true + }, + "ghcr.io/devcontainers-contrib/features/zsh-plugins:0": { + "username": "vscode", + "plugins": "bundler rails ruby yarn" + } + }, + + // Configure tool-specific properties. + "customizations": { + "vscode": { + "extensions": ["Shopify.ruby-lsp"] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // This can be used to network with other containers or the host. + "forwardPorts": [2222, 3000, 5433], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": ".devcontainer/boot.sh" + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 0000000..ae8a745 --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,30 @@ +version: "3" + +services: + app: + build: + context: .. + dockerfile: .devcontainer/Dockerfile + volumes: + - ../..:/workspaces:cached + command: sleep infinity + postgres: + image: postgres:15-alpine + restart: unless-stopped + volumes: + - postgres-data:/var/lib/postgresql/data + ports: + - 5433:5432 + environment: + POSTGRES_USER: postgres + POSTGRES_DB: postgres + POSTGRES_PASSWORD: postgres + redis: + image: redis:7-alpine + restart: unless-stopped + volumes: + - redis-data:/data + +volumes: + postgres-data: + redis-data: diff --git a/.devcontainer/readme.md b/.devcontainer/readme.md new file mode 100644 index 0000000..e0b50f5 --- /dev/null +++ b/.devcontainer/readme.md @@ -0,0 +1 @@ +from https://github.com/luizkowalski/devcontainer-rails \ No newline at end of file diff --git a/.env.devcontainer b/.env.devcontainer new file mode 100644 index 0000000..9f7af77 --- /dev/null +++ b/.env.devcontainer @@ -0,0 +1,4 @@ +DATABASE_URL=postgres://postgres:postgres@postgres:5432/bsdsec_development +TEST_DATABASE_URL=postgres://postgres:postgres@postgres:5432/bsdsec_test +TEST_EMAIL=test@example.com +MAILGUN_INGRESS_API_KEY=asdf \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..31d5a1c --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,46 @@ +name: Tests +on: [push, pull_request] +jobs: + test: + runs-on: ubuntu-20.04 + services: + postgres: + image: postgres:10 + env: + POSTGRES_PASSWORD: postgres + ports: ['5432:5432'] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: + - uses: actions/checkout@v2 + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.2.3 + - name: Install Bundler + run: gem install bundler + - name: Install Node + uses: actions/setup-node@v1 + with: + node-version: 16.19.0 + - name: Setup the Rails application + env: + RAILS_ENV: test + run: | + sudo apt-get -yqq install libpq-dev + bundle install --no-deployment --jobs 4 --retry 3 + cp config/database.github.yml config/database.yml + bundle exec rails db:create + bundle exec rails db:migrate + yarn --frozen-lockfile + - name: Run unit tests + run: bundle exec rails test + env: + CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}} + - name: Publish code coverage + uses: paambaati/codeclimate-action@v2.7.5 + env: + CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}} diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..a336baf --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +16.19.0 \ No newline at end of file diff --git a/.ruby-version b/.ruby-version index 49cdd66..b347b11 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.6 +3.2.3 diff --git a/Dockerfile b/Dockerfile index 93cb3ea..53b1446 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ -FROM ruby:2.7.6 +FROM ruby:3.2.3 RUN apt-get update -qq RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -RUN curl -sL https://deb.nodesource.com/setup_14.x | bash +RUN curl -sL https://deb.nodesource.com/setup_16.x | bash RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get install -y nodejs RUN apt-get update && apt-get install -y yarn diff --git a/Gemfile b/Gemfile index 592e7bd..aadcc9c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source 'https://rubygems.org' -ruby "2.7.6" +ruby "3.2.3" # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 6.0' diff --git a/Gemfile.lock b/Gemfile.lock index 84301e4..88bcf09 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,102 +1,99 @@ GEM remote: https://rubygems.org/ specs: - actioncable (6.1.5) - actionpack (= 6.1.5) - activesupport (= 6.1.5) + actioncable (6.1.7.7) + actionpack (= 6.1.7.7) + activesupport (= 6.1.7.7) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.5) - actionpack (= 6.1.5) - activejob (= 6.1.5) - activerecord (= 6.1.5) - activestorage (= 6.1.5) - activesupport (= 6.1.5) + actionmailbox (6.1.7.7) + actionpack (= 6.1.7.7) + activejob (= 6.1.7.7) + activerecord (= 6.1.7.7) + activestorage (= 6.1.7.7) + activesupport (= 6.1.7.7) mail (>= 2.7.1) - actionmailer (6.1.5) - actionpack (= 6.1.5) - actionview (= 6.1.5) - activejob (= 6.1.5) - activesupport (= 6.1.5) + actionmailer (6.1.7.7) + actionpack (= 6.1.7.7) + actionview (= 6.1.7.7) + activejob (= 6.1.7.7) + activesupport (= 6.1.7.7) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.5) - actionview (= 6.1.5) - activesupport (= 6.1.5) + actionpack (6.1.7.7) + actionview (= 6.1.7.7) + activesupport (= 6.1.7.7) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.5) - actionpack (= 6.1.5) - activerecord (= 6.1.5) - activestorage (= 6.1.5) - activesupport (= 6.1.5) + actiontext (6.1.7.7) + actionpack (= 6.1.7.7) + activerecord (= 6.1.7.7) + activestorage (= 6.1.7.7) + activesupport (= 6.1.7.7) nokogiri (>= 1.8.5) - actionview (6.1.5) - activesupport (= 6.1.5) + actionview (6.1.7.7) + activesupport (= 6.1.7.7) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.5) - activesupport (= 6.1.5) + activejob (6.1.7.7) + activesupport (= 6.1.7.7) globalid (>= 0.3.6) - activemodel (6.1.5) - activesupport (= 6.1.5) - activerecord (6.1.5) - activemodel (= 6.1.5) - activesupport (= 6.1.5) - activestorage (6.1.5) - actionpack (= 6.1.5) - activejob (= 6.1.5) - activerecord (= 6.1.5) - activesupport (= 6.1.5) + activemodel (6.1.7.7) + activesupport (= 6.1.7.7) + activerecord (6.1.7.7) + activemodel (= 6.1.7.7) + activesupport (= 6.1.7.7) + activestorage (6.1.7.7) + actionpack (= 6.1.7.7) + activejob (= 6.1.7.7) + activerecord (= 6.1.7.7) + activesupport (= 6.1.7.7) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.5) + activesupport (6.1.7.7) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) - bootsnap (1.11.1) + addressable (2.8.6) + public_suffix (>= 2.0.2, < 6.0) + bootsnap (1.18.3) msgpack (~> 1.2) - buftok (0.2.0) + buftok (0.3.0) builder (3.2.4) byebug (11.1.3) - concurrent-ruby (1.1.10) + concurrent-ruby (1.2.3) crass (1.0.6) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.6) - dotenv-rails (2.7.6) - dotenv (= 2.7.6) - railties (>= 3.2) + date (3.3.4) + domain_name (0.6.20240107) + dotenv (3.1.0) + dotenv-rails (3.1.0) + dotenv (= 3.1.0) + railties (>= 6.1) equalizer (0.0.11) - erubi (1.10.0) - ffi (1.15.5) + erubi (1.12.0) + ffi (1.16.3) ffi-compiler (1.0.1) ffi (>= 1.0.0) rake - friendly_id (5.4.2) + friendly_id (5.5.1) activerecord (>= 4.0.0) - globalid (1.0.0) - activesupport (>= 5.0) - http (4.4.1) - addressable (~> 2.3) + globalid (1.2.1) + activesupport (>= 6.1) + http (5.1.1) + addressable (~> 2.8) http-cookie (~> 1.0) http-form_data (~> 2.2) - http-parser (~> 1.2.0) - http-cookie (1.0.4) + llhttp-ffi (~> 0.4.0) + http-cookie (1.0.5) domain_name (~> 0.5) http-form_data (2.3.0) - http-parser (1.2.3) - ffi-compiler (>= 1.0, < 2.0) - http_parser.rb (0.6.0) - i18n (1.10.0) + i18n (1.14.1) concurrent-ruby (~> 1.0) kaminari (1.2.2) activesupport (>= 4.1.0) @@ -110,106 +107,121 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - listen (3.7.1) + listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.16.0) + llhttp-ffi (0.4.0) + ffi-compiler (~> 1.0) + rake (~> 13.0) + loofah (2.22.0) crass (~> 1.0.2) - nokogiri (>= 1.5.9) - mail (2.7.1) + nokogiri (>= 1.12.0) + mail (2.8.1) mini_mime (>= 0.1.1) - marcel (1.0.2) + net-imap + net-pop + net-smtp + marcel (1.0.4) memoizable (0.4.2) thread_safe (~> 0.3, >= 0.3.1) method_source (1.0.0) - mini_mime (1.1.2) - mini_portile2 (2.8.0) - minitest (5.15.0) - msgpack (1.5.1) - multipart-post (2.1.1) + mini_mime (1.1.5) + mini_portile2 (2.8.5) + minitest (5.22.2) + msgpack (1.7.2) + multipart-post (2.4.0) naught (1.1.0) - newrelic_rpm (8.6.0) - nio4r (2.5.8) - nokogiri (1.13.4) - mini_portile2 (~> 2.8.0) + net-imap (0.4.10) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.4.0.1) + net-protocol + newrelic_rpm (9.7.1) + nio4r (2.7.0) + nokogiri (1.16.2) + mini_portile2 (~> 2.8.2) racc (~> 1.4) - pg (1.3.5) - public_suffix (4.0.7) - puma (5.6.4) + pg (1.5.6) + public_suffix (5.0.4) + puma (6.4.2) nio4r (~> 2.0) - racc (1.6.0) - rack (2.2.3) - rack-proxy (0.7.2) + racc (1.7.3) + rack (2.2.8.1) + rack-proxy (0.7.7) rack - rack-test (1.1.0) - rack (>= 1.0, < 3) - rails (6.1.5) - actioncable (= 6.1.5) - actionmailbox (= 6.1.5) - actionmailer (= 6.1.5) - actionpack (= 6.1.5) - actiontext (= 6.1.5) - actionview (= 6.1.5) - activejob (= 6.1.5) - activemodel (= 6.1.5) - activerecord (= 6.1.5) - activestorage (= 6.1.5) - activesupport (= 6.1.5) + rack-test (2.1.0) + rack (>= 1.3) + rails (6.1.7.7) + actioncable (= 6.1.7.7) + actionmailbox (= 6.1.7.7) + actionmailer (= 6.1.7.7) + actionpack (= 6.1.7.7) + actiontext (= 6.1.7.7) + actionview (= 6.1.7.7) + activejob (= 6.1.7.7) + activemodel (= 6.1.7.7) + activerecord (= 6.1.7.7) + activestorage (= 6.1.7.7) + activesupport (= 6.1.7.7) bundler (>= 1.15.0) - railties (= 6.1.5) + railties (= 6.1.7.7) sprockets-rails (>= 2.0.0) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.4.2) - loofah (~> 2.3) - railties (6.1.5) - actionpack (= 6.1.5) - activesupport (= 6.1.5) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + railties (6.1.7.7) + actionpack (= 6.1.7.7) + activesupport (= 6.1.7.7) method_source rake (>= 12.2) thor (~> 1.0) - rake (13.0.6) - rb-fsevent (0.11.1) + rake (13.1.0) + rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) semantic_range (3.0.0) simple_oauth (0.3.1) - spring (4.0.0) - sprockets (4.0.3) + spring (4.1.3) + sprockets (4.2.1) concurrent-ruby (~> 1.0) - rack (> 1, < 3) + rack (>= 2.2.4, < 4) sprockets-rails (3.4.2) actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - thor (1.2.1) + thor (1.3.1) thread_safe (0.3.6) - twitter (7.0.0) + timeout (0.4.1) + twitter (8.0.1) addressable (~> 2.3) - buftok (~> 0.2.0) + buftok (~> 0.3.0) equalizer (~> 0.0.11) - http (~> 4.0) - http-form_data (~> 2.0) - http_parser.rb (~> 0.6.0) + http (~> 5.1) + http-form_data (~> 2.3) + llhttp-ffi (~> 0.4.0) memoizable (~> 0.4.0) multipart-post (~> 2.0) naught (~> 1.0) simple_oauth (~> 0.3.0) - tzinfo (2.0.4) + tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unf (0.1.4) - unf_ext - unf_ext (0.0.8.1) - webpacker (5.4.3) + webpacker (5.4.4) activesupport (>= 5.2) rack-proxy (>= 0.6.1) railties (>= 5.2) semantic_range (>= 2.3.0) - websocket-driver (0.7.5) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - zeitwerk (2.5.4) + zeitwerk (2.6.13) PLATFORMS ruby @@ -230,7 +242,7 @@ DEPENDENCIES webpacker RUBY VERSION - ruby 2.7.6p219 + ruby 3.2.3p157 BUNDLED WITH 2.1.4 diff --git a/config/environments/development.rb b/config/environments/development.rb index dd4c501..a049abb 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -66,4 +66,6 @@ # Uncomment if you wish to allow Action Cable access from any origin. # config.action_cable.disable_request_forgery_protection = true + + config.hosts << /.*\.github\.dev/ end diff --git a/config/puma.rb b/config/puma.rb index d9b3e83..0a40546 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,43 +1,15 @@ -# 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 +workers Integer(ENV['WEB_CONCURRENCY'] || 2) +threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5) +threads threads_count, threads_count -# Specifies the `worker_timeout` threshold that Puma will use to wait before -# terminating a worker in development environments. -# -worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" +preload_app! -# Specifies the `port` that Puma will listen on to receive requests; default is 3000. -# -port ENV.fetch("PORT") { 3000 } +rackup DefaultRackup if defined?(DefaultRackup) +port ENV['PORT'] || 3000 +environment ENV['RACK_ENV'] || 'development' -# Specifies the `environment` that Puma will run in. -# -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). -# -# 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. -# -# preload_app! - -# Allow puma to be restarted by `rails restart` command. -plugin :tmp_restart +on_worker_boot do + # Worker-specific setup for Rails 4.1 to 5.2, after 5.2 it's not needed + # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot + ActiveRecord::Base.establish_connection +end diff --git a/fly.toml b/fly.toml index 3cb9623..d31f416 100644 --- a/fly.toml +++ b/fly.toml @@ -1,14 +1,15 @@ -# fly.toml app configuration file generated for bsdsec on 2023-08-07T10:58:11+02:00 +# fly.toml app configuration file generated for bsdsec on 2023-09-15T18:52:57+02:00 # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # app = "bsdsec" +primary_region = "fra" kill_signal = "SIGINT" kill_timeout = "5s" [build] - builder = "heroku/buildpacks:20" + builder = "heroku/builder:22" buildpacks = ["heroku/nodejs", "heroku/ruby"] [build.args] SECRET_KEY_BASE = "asdf" diff --git a/package.json b/package.json index bbe3785..34b307c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "BSDSec", "private": true, "engines": { - "node": "14.x" + "node": "16.19.0" }, "dependencies": { "@fortawesome/fontawesome-free": "^5.11.2",