diff --git a/.dockerignore b/.dockerignore index f4216be09..8cdea307d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -20,3 +20,6 @@ docker-compose.override.yml yarn-error.log yarn-debug.log* .yarn-integrity + +config/credentials/* +config/credentials.yml.enc \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 916bd6cc4..b0874453c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -18,27 +18,28 @@ name: Capistrano Deployment # Controls when the action will run. on: push: - branches: [ stage test] + branches: + - stage + - test # Allows running this workflow manually from the Actions tab workflow_dispatch: inputs: BRANCH: - description: 'Branch/tag to deploy' + description: "Branch/tag to deploy" options: - stage - test - master - default: test + default: stage required: true environment: - description: 'target environment to deploy to' + description: "target environment to deploy to" type: choice options: - staging - - production - - appliance + - agroportal - test - default: test + default: stage jobs: deploy: runs-on: ubuntu-latest @@ -47,45 +48,45 @@ jobs: PRIVATE_CONFIG_REPO: ${{ format('git@github.com:{0}.git', secrets.CONFIG_REPO) }} # Steps represent a sequence of tasks that will be executed as part of the job steps: - - name: set branch/tag and environment to deploy from inputs - run: | - # workflow_dispatch default input doesn't get set on push so we need to set defaults - # via shell parameter expansion - # https://dev.to/mrmike/github-action-handling-input-default-value-5f2g - USER_INPUT_BRANCH=${{ inputs.branch }} - echo "BRANCH=${USER_INPUT_BRANCH:github.head_ref:-master}" >> $GITHUB_ENV + - name: set branch/tag and environment to deploy from inputs + run: | + # workflow_dispatch default input doesn't get set on push so we need to set defaults + # via shell parameter expansion + # https://dev.to/mrmike/github-action-handling-input-default-value-5f2g + USER_INPUT_BRANCH=${{ inputs.branch }} + echo "BRANCH=${USER_INPUT_BRANCH:github.head_ref:-master}" >> $GITHUB_ENV - USER_INPUT_ENVIRONMENT=${{ inputs.environment }} - echo "TARGET=${USER_INPUT_ENVIRONMENT:-staging}" >> $GITHUB_ENV - - CONFIG_REPO=${{ secrets.CONFIG_REPO }} - GH_PAT=${{ secrets.GH_PAT }} - echo "PRIVATE_CONFIG_REPO=https://${GH_PAT}@github.com/${CONFIG_REPO}" >> $GITHUB_ENV - - echo "SSH_JUMPHOST=${{ secrets.SSH_JUMPHOST }}" >> $GITHUB_ENV - echo "SSH_JUMPHOST_USER=${{ secrets.SSH_JUMPHOST_USER }}" >> $GITHUB_ENV - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.7.6 # Not needed with a .ruby-version file - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - - name: get-deployment-config - uses: actions/checkout@v3 - with: - repository: ${{ secrets.CONFIG_REPO }} # repository containing deployment settings - token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT - path: deploy_config - - name: copy-deployment-config - run: cp -r deploy_config/ontoportal_web_ui/${{ inputs.environment }}/* . - # add ssh hostkey so that capistrano doesn't complain - - name: Add jumphost's hostkey to Known Hosts - run: | - mkdir -p ~/.ssh - echo "${{ secrets.SSH_JUMPHOST }}" - ssh-keyscan -H ${{ secrets.SSH_JUMPHOST }} > ~/.ssh/known_hosts - shell: bash - - uses: miloserdow/capistrano-deploy@master - with: - target: ${{ env.TARGET }} # which environment to deploy - deploy_key: ${{ secrets.DEPLOY_ENC_KEY }} # Name of the variable configured in Settings/Secrets of your github project + USER_INPUT_ENVIRONMENT=${{ inputs.environment }} + echo "TARGET=${USER_INPUT_ENVIRONMENT:-staging}" >> $GITHUB_ENV + + CONFIG_REPO=${{ secrets.CONFIG_REPO }} + GH_PAT=${{ secrets.GH_PAT }} + echo "PRIVATE_CONFIG_REPO=https://${GH_PAT}@github.com/${CONFIG_REPO}" >> $GITHUB_ENV + + echo "SSH_JUMPHOST=${{ secrets.SSH_JUMPHOST }}" >> $GITHUB_ENV + echo "SSH_JUMPHOST_USER=${{ secrets.SSH_JUMPHOST_USER }}" >> $GITHUB_ENV + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7.6 # Not needed with a .ruby-version file + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + - name: get-deployment-config + uses: actions/checkout@v3 + with: + repository: ${{ secrets.CONFIG_REPO }} # repository containing deployment settings + token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT + path: deploy_config + - name: copy-deployment-config + run: cp -r deploy_config/ontoportal_web_ui/${{ inputs.environment }}/* . + # add ssh hostkey so that capistrano doesn't complain + - name: Add jumphost's hostkey to Known Hosts + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_JUMPHOST }}" + ssh-keyscan -H ${{ secrets.SSH_JUMPHOST }} > ~/.ssh/known_hosts + shell: bash + - uses: miloserdow/capistrano-deploy@master + with: + target: ${{ env.TARGET }} # which environment to deploy + deploy_key: ${{ secrets.DEPLOY_ENC_KEY }} # Name of the variable configured in Settings/Secrets of your github project diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 5d2de1123..77ce165f9 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -3,11 +3,12 @@ name: Docker branch Images build on: push: branches: + - master - development - stage - test release: - types: [ published ] + types: [published] jobs: push_to_registry: name: Push Docker branch image to Docker Hub diff --git a/Dockerfile b/Dockerfile index 3d5c45f1b..2eb0ea3ba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,10 +38,14 @@ RUN yarn install && yarn build +RUN cp config/bioportal_config_env.rb.sample config/bioportal_config_production.rb +RUN cp config/bioportal_config_env.rb.sample config/bioportal_config_development.rb +RUN cp config/database.yml.sample config/database.yml + # Precompile bootsnap code for faster boot times RUN bundle exec bootsnap precompile --gemfile app/ lib/ -# RUN SECRET_KEY_BASE_DUMMY="1" ./bin/rails assets:precompile +RUN SECRET_KEY_BASE_DUMMY="1" ./bin/rails assets:precompile ENV BINDING="0.0.0.0" EXPOSE 3000 diff --git a/Gemfile b/Gemfile index 59957fd18..98a0d2597 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' # Main Rails gem # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '7.0.7' +gem 'rails', '7.0.3' # JavaScript bundling for Rails gem 'jsbundling-rails' @@ -96,7 +96,8 @@ gem 'flag-icons-rails', '~> 3.4' gem 'iso-639', '~> 0.3.6' # Custom API client -gem 'ontologies_api_client', git: 'https://github.com/ontoportal-lirmm/ontologies_api_ruby_client.git', branch: 'development' +gem 'ontologies_api_client', git: 'https://github.com/ontoportal-lirmm/ontologies_api_ruby_client.git', + branch: 'development' # Ruby 2.7.8 pinned gems (to remove when migrating to Ruby >= 3.0) gem 'ffi', '~> 1.16.3' @@ -105,15 +106,15 @@ gem 'net-http', '~> 0.3.2' # Multi-Provider Authentication gem 'omniauth' -gem 'omniauth-rails_csrf_protection' gem 'omniauth-github' gem 'omniauth-google-oauth2' -gem 'omniauth-orcid' gem 'omniauth-keycloak' +gem 'omniauth-orcid' +gem 'omniauth-rails_csrf_protection' group :staging, :production, :appliance do # Application performance monitoring - gem 'newrelic_rpm' + gem 'newrelic_rpm', '< 9.10.0' # Error monitoring gem 'bugsnag', '~> 6.26' @@ -151,9 +152,9 @@ group :development do # Internationalization tasks # gem 'i18n-debug' + gem 'deepl-rb' gem 'i18n-tasks' gem 'i18n-tasks-csv', '~> 1.1' - gem 'deepl-rb' # Email preview in the browser gem 'letter_opener_web', '~> 2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 39ee30f64..33f34ebe7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -17,67 +17,67 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.0.7) - actionpack (= 7.0.7) - activesupport (= 7.0.7) + actioncable (7.0.3) + actionpack (= 7.0.3) + activesupport (= 7.0.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.7) - actionpack (= 7.0.7) - activejob (= 7.0.7) - activerecord (= 7.0.7) - activestorage (= 7.0.7) - activesupport (= 7.0.7) + actionmailbox (7.0.3) + actionpack (= 7.0.3) + activejob (= 7.0.3) + activerecord (= 7.0.3) + activestorage (= 7.0.3) + activesupport (= 7.0.3) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.7) - actionpack (= 7.0.7) - actionview (= 7.0.7) - activejob (= 7.0.7) - activesupport (= 7.0.7) + actionmailer (7.0.3) + actionpack (= 7.0.3) + actionview (= 7.0.3) + activejob (= 7.0.3) + activesupport (= 7.0.3) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.7) - actionview (= 7.0.7) - activesupport (= 7.0.7) - rack (~> 2.0, >= 2.2.4) + actionpack (7.0.3) + actionview (= 7.0.3) + activesupport (= 7.0.3) + rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.7) - actionpack (= 7.0.7) - activerecord (= 7.0.7) - activestorage (= 7.0.7) - activesupport (= 7.0.7) + actiontext (7.0.3) + actionpack (= 7.0.3) + activerecord (= 7.0.3) + activestorage (= 7.0.3) + activesupport (= 7.0.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.7) - activesupport (= 7.0.7) + actionview (7.0.3) + activesupport (= 7.0.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (7.0.7) - activesupport (= 7.0.7) + activejob (7.0.3) + activesupport (= 7.0.3) globalid (>= 0.3.6) - activemodel (7.0.7) - activesupport (= 7.0.7) - activerecord (7.0.7) - activemodel (= 7.0.7) - activesupport (= 7.0.7) - activestorage (7.0.7) - actionpack (= 7.0.7) - activejob (= 7.0.7) - activerecord (= 7.0.7) - activesupport (= 7.0.7) + activemodel (7.0.3) + activesupport (= 7.0.3) + activerecord (7.0.3) + activemodel (= 7.0.3) + activesupport (= 7.0.3) + activestorage (7.0.3) + actionpack (= 7.0.3) + activejob (= 7.0.3) + activerecord (= 7.0.3) + activesupport (= 7.0.3) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.7) + activesupport (7.0.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -135,7 +135,7 @@ GEM railties (> 3.1) childprocess (5.0.0) coderay (1.1.3) - concurrent-ruby (1.3.1) + concurrent-ruby (1.3.3) crack (1.0.0) bigdecimal rexml @@ -312,7 +312,7 @@ GEM net-protocol net-ssh (7.2.3) netrc (0.11.0) - newrelic_rpm (9.10.1) + newrelic_rpm (9.9.0) nio4r (2.7.3) nokogiri (1.15.6-x86_64-darwin) racc (~> 1.4) @@ -325,7 +325,7 @@ GEM rack (>= 1.2, < 4) snaky_hash (~> 2.0) version_gem (~> 1.1) - oj (3.16.3) + oj (3.16.4) bigdecimal (>= 3.0) omniauth (2.1.2) hashie (>= 3.4.6) @@ -353,8 +353,8 @@ GEM omniauth-rails_csrf_protection (1.0.2) actionpack (>= 4.2) omniauth (~> 2.0) - parallel (1.24.0) - parser (3.3.2.0) + parallel (1.25.1) + parser (3.3.3.0) ast (~> 2.4.1) racc popper_js (1.16.1) @@ -373,20 +373,20 @@ GEM rack (~> 2.2, >= 2.2.4) rack-test (2.1.0) rack (>= 1.3) - rails (7.0.7) - actioncable (= 7.0.7) - actionmailbox (= 7.0.7) - actionmailer (= 7.0.7) - actionpack (= 7.0.7) - actiontext (= 7.0.7) - actionview (= 7.0.7) - activejob (= 7.0.7) - activemodel (= 7.0.7) - activerecord (= 7.0.7) - activestorage (= 7.0.7) - activesupport (= 7.0.7) + rails (7.0.3) + actioncable (= 7.0.3) + actionmailbox (= 7.0.3) + actionmailer (= 7.0.3) + actionpack (= 7.0.3) + actiontext (= 7.0.3) + actionview (= 7.0.3) + activejob (= 7.0.3) + activemodel (= 7.0.3) + activerecord (= 7.0.3) + activestorage (= 7.0.3) + activesupport (= 7.0.3) bundler (>= 1.15.0) - railties (= 7.0.7) + railties (= 7.0.3) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -397,9 +397,9 @@ GEM rails-i18n (7.0.9) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.0.7) - actionpack (= 7.0.7) - activesupport (= 7.0.7) + railties (7.0.3) + actionpack (= 7.0.3) + activesupport (= 7.0.3) method_source rake (>= 12.2) thor (~> 1.0) @@ -415,15 +415,15 @@ GEM json redcarpet (3.6.0) regexp_parser (2.9.2) - reline (0.5.8) + reline (0.5.9) io-console (~> 0.5) rest-client (2.1.0) http-accept (>= 1.7.0, < 2.0) http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - rexml (3.2.8) - strscan (>= 3.0.9) + rexml (3.3.0) + strscan rouge (4.2.1) rspec-core (3.13.0) rspec-support (~> 3.13.0) @@ -493,7 +493,7 @@ GEM sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.5.0) + sprockets-rails (3.5.1) actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) @@ -510,7 +510,7 @@ GEM temple (0.10.3) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - terser (1.2.2) + terser (1.2.3) execjs (>= 0.3.0, < 3) thor (1.3.1) tilt (2.3.0) @@ -593,7 +593,7 @@ DEPENDENCIES mysql2 net-ftp (~> 0.2.0) net-http (~> 0.3.2) - newrelic_rpm + newrelic_rpm (< 9.10.0) oj omniauth omniauth-github @@ -604,7 +604,7 @@ DEPENDENCIES ontologies_api_client! pry puma (~> 5.0) - rails (= 7.0.7) + rails (= 7.0.3) rails-i18n (~> 7.0.0) recaptcha (~> 5.9.0) rest-client diff --git a/app/assets/stylesheets/ontologies.scss b/app/assets/stylesheets/ontologies.scss index 223aeda8f..ccaf70d31 100644 --- a/app/assets/stylesheets/ontologies.scss +++ b/app/assets/stylesheets/ontologies.scss @@ -195,7 +195,7 @@ $widget-table-border-color: #EFEFEF; #bd_content .sidebar { overflow-x: auto; white-space: nowrap; - min-width: 35%; + min-width: 29%; } #search_box:focus { diff --git a/app/controllers/concerns/submission_filter.rb b/app/controllers/concerns/submission_filter.rb index c8677e601..44d4f6e52 100644 --- a/app/controllers/concerns/submission_filter.rb +++ b/app/controllers/concerns/submission_filter.rb @@ -236,7 +236,7 @@ def ontology_hash(ont, submissions) o[:individual_count_formatted] = number_with_delimiter(o[:individual_count], delimiter: ',') o[:note_count] = ont.notes&.length || 0 - o[:project_count] = ont.projects&.length || + o[:project_count] = ont.projects&.length || 0 o[:popularity] = @analytics[ont.acronym] || 0 o[:rank] = sub&[:rank] || 0 diff --git a/app/helpers/fair_score_helper.rb b/app/helpers/fair_score_helper.rb index f3fc4f39c..7abb76eb6 100644 --- a/app/helpers/fair_score_helper.rb +++ b/app/helpers/fair_score_helper.rb @@ -13,23 +13,26 @@ def get_fairness_service_url(apikey = user_apikey) end def get_fairness_json(ontologies_acronyms, apikey = user_apikey) - Rails.cache.fetch("fairness-#{ontologies_acronyms.gsub(',', '-')}-#{apikey}", expires: 24.hours) do + if Rails.cache.exist?("fairness-#{ontologies_acronyms.gsub(',', '-')}-#{apikey}") + out = read_large_data("fairness-#{ontologies_acronyms.gsub(',', '-')}-#{apikey}") + else + out = "{}" begin - out = {} time = Benchmark.realtime do conn = Faraday.new do |conn| conn.options.timeout = 30 end response = conn.get(get_fairness_service_url(apikey) + "&ontologies=#{ontologies_acronyms}&combined") - out = MultiJson.load(response.body.force_encoding('ISO-8859-1').encode('UTF-8')) + out = response.body.force_encoding('ISO-8859-1').encode('UTF-8') + cache_large_data("fairness-#{ontologies_acronyms.gsub(',', '-')}-#{apikey}", out) end puts "Call fairness service for: #{ontologies_acronyms} (#{time}s)" rescue Rails.logger.warn t('fair_score.fairness_unreachable_warning') end - - out end + MultiJson.use :oj + MultiJson.load(out) rescue {} end def get_fair_score(ontologies_acronyms, apikey = user_apikey) @@ -139,5 +142,53 @@ def fairness_link(style: '', ontology: nil) ontology = ontology || 'all' render IconWithTooltipComponent.new(icon: "json.svg",link: "#{get_fairness_service_url}&ontologies=#{ontology}&combined=true", target: '_blank', title: t('fair_score.go_to_api'), size:'small', style: custom_style) end + + private + require 'zlib' + + def cache_large_data(key, data, chunk_size = 1.megabyte) + compressed_data = Zlib::Deflate.deflate(data) + total_size = compressed_data.bytesize + Rails.logger.info "Total compressed data size: #{total_size} bytes" + + # Determine the number of chunks + chunk_count = (total_size.to_f / chunk_size).ceil + + chunk_count.times do |index| + chunk_key = "#{key}_chunk_#{index}" + start_byte = index * chunk_size + end_byte = start_byte + chunk_size - 1 + chunk = compressed_data.byteslice(start_byte..end_byte) + + unless Rails.cache.write(chunk_key, chunk, expires_in: 24.hours) + Rails.logger.error "Failed to write chunk #{index} for key: #{key}" + return false + end + end + + # Store metadata about the chunks + metadata = { chunk_count: chunk_count } + Rails.cache.write("#{key}_metadata", metadata, expires_in: 24.hours) + Rails.cache.write(key, true, expires_in: 24.hours) + end + + def read_large_data(key) + metadata = Rails.cache.read("#{key}_metadata") + return nil unless metadata + + chunk_count = metadata[:chunk_count] + data = '' + + chunk_count.times do |index| + chunk_key = "#{key}_chunk_#{index}" + chunk = Rails.cache.read(chunk_key) + return nil unless chunk + data << chunk + end + + # Decompress data + Zlib::Inflate.inflate(data) + end + end diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index 804ee3b3a..40b5446b8 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -103,6 +103,8 @@ application.register("ontologies-selector", OntologiesSelector) import MappingsController from "./mappings_visualization_controller" application.register('mappings', MappingsController) +import ContentFinderController from "./content_finder_controller" +application.register("content-finder", ContentFinderController) import ConceptsJsonButtonController from "./concepts_json_button_controller.js" application.register('concepts-json', ConceptsJsonButtonController) \ No newline at end of file diff --git a/app/javascript/controllers/label_ajax_controller.js b/app/javascript/controllers/label_ajax_controller.js index 539a26aeb..d3cbcfff4 100644 --- a/app/javascript/controllers/label_ajax_controller.js +++ b/app/javascript/controllers/label_ajax_controller.js @@ -33,7 +33,7 @@ export default class extends Controller { success: this.#ajaxSuccess.bind(this), error: this.#ajaxError.bind(this) }); - },0) + },1) } abort() { diff --git a/app/views/notifier/feedback.html.haml b/app/views/notifier/feedback.html.haml index 5ce9196e3..306d92ee4 100644 --- a/app/views/notifier/feedback.html.haml +++ b/app/views/notifier/feedback.html.haml @@ -5,17 +5,17 @@ %meta{content: "no-cache", name: "turbo-cache-control"}/ %body %p - = t("ontologies.notifier.name", name: @name) + = t("feedback_mail.name", name: @name) %p - = t("ontologies.notifier.email", email: @email) + = t("feedback_mail.email", email: @email) %p - = t("ontologies.notifier.location", location: @location) - %p= t("ontologies.notifier.tags") + = t("feedback_mail.location", location: @location) + %p= t("feedback_mail.tags") %ul - for tag in @tags %li = tag %p %br/ - %strong= t("ontologies.notifier.feedback") + %strong= t("feedback_mail.feedback") = simple_format(@comment) \ No newline at end of file diff --git a/bin/ontoportal b/bin/ontoportal index 80f288cef..a2c030b23 100755 --- a/bin/ontoportal +++ b/bin/ontoportal @@ -135,8 +135,8 @@ dev() { bash_cmd+=" (bundle config unset local.ontologies_api_client) &&" fi done - bash_cmd+=" (bundle check || bundle install || bundle update) && bin/rails db:prepare && bundle exec rails s -b 0.0.0.0 -p 3000" - docker_run_cmd+=" --service-ports rails bash -c \"$bash_cmd\"" + bash_cmd+=" (bundle check || bundle install) && bin/rails db:prepare && bundle exec rails s -b 0.0.0.0 -p 3000" + docker_run_cmd+=" --service-ports dev bash -c \"$bash_cmd\"" echo "$docker_run_cmd" echo "Run: bundle exec rails s -b 0.0.0.0 -p 3000" eval "$docker_run_cmd" @@ -188,7 +188,7 @@ test() { # Function to handle the "run" option run() { echo "Run: $*" - docker compose run --rm -it rails bash -c "$*" + docker compose run --rm -it dev bash -c "$*" } create_config_files diff --git a/config/database.yml.sample b/config/database.yml.sample index 6edf6ed31..2787d5f25 100644 --- a/config/database.yml.sample +++ b/config/database.yml.sample @@ -50,7 +50,6 @@ test: production: <<: *default database: bioportal_ui_production - username: bp_user password: <%= ENV["BIOPORTAL_WEB_UI_DATABASE_PASSWORD"] %> appliance: diff --git a/config/deploy/agroportal.rb b/config/deploy/agroportal.rb new file mode 100644 index 000000000..c01f3fb90 --- /dev/null +++ b/config/deploy/agroportal.rb @@ -0,0 +1,17 @@ +# Simple Role Syntax +# ================== +# Supports bulk-adding hosts to roles, the primary +# server in each group is considered to be the first +# unless any hosts have the primary property set. +# Don't declare `role :all`, it's a meta role +role :app, %w[agroportal.lirmm.fr] +role :db, %w[agroportal.lirmm.fr] # sufficient to run db:migrate only on one system +set :branch, ENV.include?('BRANCH') ? ENV['BRANCH'] : 'master' +# Extended Server Syntax +# ====================== +# This can be used to drop a more detailed server +# definition into the server list. The second argument +# something that quacks like a hash can be used to set +# extended properties on the server. +# server 'example.com', user: 'deploy', roles: %w{web app}, my_property: :my_value +set :log_level, :error diff --git a/config/environment.rb b/config/environment.rb index cac531577..0c158d03b 100755 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,5 +1,19 @@ # Load the Rails application. -require_relative "application" +require_relative 'application' + + +# Remove this after migrating to Rails 7.1 (https://github.com/rails/rails/issues/32947#issuecomment-1356391185) +class Rails::Application + def secret_key_base + if Rails.env.development? || Rails.env.test? || ENV["SECRET_KEY_BASE_DUMMY"] + secrets.secret_key_base ||= generate_development_secret + else + validate_secret_key_base( + ENV["SECRET_KEY_BASE"] || credentials.secret_key_base || secrets.secret_key_base + ) + end + end +end # Initialize the Rails application. Rails.application.initialize! diff --git a/config/environments/production.rb b/config/environments/production.rb index 3eb3961f0..432744722 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. @@ -18,11 +18,11 @@ # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). - config.require_master_key = true + config.require_master_key = ENV['REQUIRE_MASTER_KEY'].present? # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. - config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? # Compress JavaScripts config.assets.js_compressor = :terser @@ -56,7 +56,7 @@ config.log_level = :info # Prepend all log lines with the following tags. - config.log_tags = [ :request_id ] + config.log_tags = [:request_id] # Use a different cache store in production. # config.cache_store = :mem_cache_store @@ -97,12 +97,13 @@ end # Use a different cache store in production. - config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211", { namespace: 'bioportal_web_ui', expires_in: 1.day } + config.cache_store = :mem_cache_store, ENV['MEMCACHE_SERVERS'] || 'localhost:11211', + { namespace: 'bioportal_web_ui', expires_in: 1.day } # Add custom data attributes to sanitize allowed list - config.action_view.sanitized_allowed_attributes = ['id', 'class', 'style', 'data-cls', 'data-ont'] + config.action_view.sanitized_allowed_attributes = %w[id class style data-cls data-ont] - if ENV["RAILS_LOG_TO_STDOUT"].present? + if ENV['RAILS_LOG_TO_STDOUT'].present? logger = ActiveSupport::Logger.new(STDOUT) logger.formatter = config.log_formatter config.logger = ActiveSupport::TaggedLogging.new(logger) diff --git a/config/initializers/graphql_client.rb b/config/initializers/graphql_client.rb index 57760a168..9cf786411 100644 --- a/config/initializers/graphql_client.rb +++ b/config/initializers/graphql_client.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true - -require 'graphql/client' -require 'graphql/client/http' - -module GitHub - HTTPAdapter = GraphQL::Client::HTTP.new('https://api.github.com/graphql') do - def headers(_context) - { 'Authorization': "Bearer #{Rails.application.credentials.dig(:kgcl, :github_access_token)}" } - end - end - - Client = GraphQL::Client.new( - schema: File.join(Rails.root, 'data', 'schema.json').to_s, - execute: HTTPAdapter - ) -end +# Disable as no used in ontoportal-lirmm branch and causing problems with docker image build +# require 'graphql/client' +# require 'graphql/client/http' +# +# module GitHub +# HTTPAdapter = GraphQL::Client::HTTP.new('https://api.github.com/graphql') do +# def headers(_context) +# { 'Authorization': "Bearer #{Rails.application.credentials.dig(:kgcl, :github_access_token)}" } +# end +# end +# +# Client = GraphQL::Client.new( +# schema: File.join(Rails.root, 'data', 'schema.json').to_s, +# execute: HTTPAdapter +# ) +# end diff --git a/config/locales/en.yml b/config/locales/en.yml index 4cf982488..f00316dbc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1471,4 +1471,10 @@ en: description: > This tool/service verifies the resolvability of Uniform Resource Identifiers (URIs) and their content negotiability. It checks whether a given URI is accessible and whether the content associated with it can be negotiated based on the client's preferences. - This functionality ensures the reliability and accessibility of linked resources within the RDF ecosystem, aiding in maintaining data integrity and facilitating seamless integration with external resources. \ No newline at end of file + This functionality ensures the reliability and accessibility of linked resources within the RDF ecosystem, aiding in maintaining data integrity and facilitating seamless integration with external resources. + feedback_mail: + name: "Name: %{name}" + email: "Email: %{email}" + location: "Location: %{location}" + tags: Tags + feedback: Feedback \ No newline at end of file diff --git a/config/locales/fr.yml b/config/locales/fr.yml index d08caa489..2f4812d8d 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1510,4 +1510,9 @@ fr: Il vérifie si un URI donné est accessible et si le contenu associé peut être négocié en fonction des préférences du client. Cette fonctionnalité garantit la fiabilité et l'accessibilité des ressources liées dans l'écosystème RDF, aidant ainsi à maintenir l'intégrité des données et facilitant l'intégration transparente avec des ressources externes. - + feedback_mail: + name: "Nom: %{name}" + email: "E-mail: %{email}" + location: "Emplacement: %{location}" + tags: Tags + feedback: Feedback diff --git a/docker-compose.yml b/docker-compose.yml index d8a79957f..575407eb2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,32 @@ x-app: &default-app - image: agroportal/ontoportal_web_ui:development + image: agroportal/ontoportal_web_ui:master env_file: - ".env" tty: true volumes: - - .:/app - - bundle:/usr/local/bundle + - bundle:/srv/ontoportal/bundle - node:/node_modules - rails_cache:/app/tmp/cache - assets:/app/public/assets - /var/run/docker.sock:/var/run/docker.sock + - .:/app + depends_on: + db: + condition: service_healthy + cache: + condition: service_started + node: + condition: service_started + links: + - db + - cache + environment: &env + BUNDLE_WITHOUT: "" + BUNDLE_PATH: /srv/ontoportal/bundle + DB_HOST: db + CACHE_HOST: cache + ports: + - "3000:3000" tmpfs: - /tmp - /app/tmp/pids @@ -28,12 +45,12 @@ services: healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] timeout: 5s - retries: 3 + retries: 3 cache: image: memcached:latest restart: unless-stopped - command: [ "-m", "1024" ] + command: ["-m", "1024"] networks: - default ports: @@ -41,36 +58,48 @@ services: node: <<: *default-app command: "yarn build --watch" + depends_on: + - cache + - db - rails: + dev: <<: *default-app + + production: + <<: *default-app + command: "bundle exec puma -C config/puma.rb" + environment: + <<: *env + RAILS_ENV: "production" + BUNDLE_WITHOUT: "development test" + BUNDLE_PATH: "/usr/local/bundle" + #SECRET_KEY_BASE: TODO + #RAILS_MASTER_KEY: TODO + BIOPORTAL_WEB_UI_DATABASE_PASSWORD: root + MEMCACHE_SERVERS: "cache:11211" depends_on: db: condition: service_healthy cache: condition: service_started - node: - condition: service_started - links: - - db - - cache - environment: - BUNDLE_WITHOUT: '' - DB_HOST: db - CACHE_HOST: cache - ports: - - "3000:3000" + volumes: + - node:/node_modules + - rails_cache:/app/tmp/cache + - assets:/app/public/assets + - app_ui:/app + test: <<: *default-app depends_on: - db - cache - chrome-server - network_mode: 'host' + network_mode: "host" environment: - BUNDLE_WITHOUT: '' + BUNDLE_WITHOUT: "" DB_HOST: 127.0.0.1 CACHE_HOST: 127.0.0.1 + chrome-server: image: selenium/standalone-chrome:112.0-chromedriver-112.0-grid-4.9.0-20230421 shm_size: 2g @@ -85,3 +114,4 @@ volumes: rails_cache: assets: node: + app_ui: