diff --git a/.node-version b/.node-version index ed15bef9ae..3c5535cf60 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -v6.1.0 +18.19.1 diff --git a/.rubocop.yml b/.rubocop.yml index 85e2198ca4..11337962cf 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,16 +3,13 @@ require: AllCops: DisplayCopNames: true - NewCops: enable + NewCops: disable Exclude: - db/schema.rb - vendor/**/* - tmp/**/* - node_modules/**/* -Layout/LineLength: - Max: 120 - Metrics/ClassLength: Enabled: false @@ -260,6 +257,34 @@ Rails/HelperInstanceVariable: Rails/FilePath: Enabled: false +# TODO: enable +Rails/FindEach: + Enabled: false + +# TODO: enable +Rails/IndexBy: + Enabled: false + +# TODO: enable +Rails/IndexWith: + Enabled: false + +# we don't always need environment +Rails/RakeEnvironment: + Enabled: false + +# TODO: enable +Rails/ApplicationController: + Enabled: false + +# TODO: enable +Rails/ContentTag: + Enabled: false + +# TODO: enable +Rails/UniqueValidationWithoutIndex: + Enabled: false + Gemspec/RequiredRubyVersion: Enabled: false @@ -269,3 +294,6 @@ Style/AccessorGrouping: # produces false-positives with html-safe, see app/helpers/application_helper.rb Style/StringConcatenation: Enabled: false + +Style/HashSyntax: + Enabled: false diff --git a/.ruby-version b/.ruby-version index 6a81b4c837..be94e6f53d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.8 +3.2.2 diff --git a/Dockerfile b/Dockerfile index a9d5fcf28a..38783a24d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:2.7.8-slim +FROM ruby:3.2.2-slim # Install dependencies RUN \ diff --git a/Gemfile b/Gemfile index eaace88247..fff2dc2766 100644 --- a/Gemfile +++ b/Gemfile @@ -5,10 +5,10 @@ ruby File.read('.ruby-version').strip # gems that have rails engines are are always needed group :preload do - gem 'rails', '~> 6.1.7.6' + gem 'rails', '~> 6.1.7.7' gem 'dotenv' gem 'connection_pool' - gem 'marco-polo' + gem 'marco-polo' # TODO: https://github.com/arches/marco-polo/pull/16 # AR extensions gem 'goldiloader' @@ -39,6 +39,7 @@ gem 'octokit' gem 'faraday', '~> 2.7' gem 'faraday-net_http_persistent', '~> 2.0' gem 'faraday-http-cache' +gem 'faraday-retry' gem 'warden' gem 'active_hash' gem 'ansible' @@ -50,11 +51,15 @@ gem 'concurrent-ruby' gem 'vault', git: 'https://github.com/zendesk/vault-ruby.git', ref: '96be391a2fd50a42871c8b9dc3c59fddbdbdc556' gem 'lograge' gem 'logstash-event' +gem 'hashdiff', git: 'https://github.com/liufengyun/hashdiff.git' # fails to install on ruby 3.2 from gem when deploying gem 'diffy' gem 'validates_lengths_from_database' gem 'large_object_store' gem 'parallel' gem 'stackprof' +gem 'net-smtp' +gem 'net-pop' +gem 'net-imap' # treat included plugins like gems Dir[File.join(Bundler.root, 'plugins/*/')].each { |f| gemspec path: f } diff --git a/Gemfile.lock b/Gemfile.lock index 0f940c089a..271df4f860 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,9 @@ +GIT + remote: https://github.com/liufengyun/hashdiff.git + revision: 3832f805bddfa5e738a6d82b51ab4a27b61169b6 + specs: + hashdiff (1.1.0) + GIT remote: https://github.com/omniauth/omniauth-github.git revision: f27bb4e018150d87e9444ad13955acfc9e76f4d7 @@ -185,129 +191,130 @@ PATH GEM remote: https://rails-assets.org/ specs: - rails-assets-bootstrap-select (1.10.0) + rails-assets-bootstrap-select (1.12.4) rails-assets-jquery (>= 1.8) - rails-assets-jquery (3.4.1) + rails-assets-jquery (3.7.1) rails-assets-jquery-cookie (1.4.1) rails-assets-jquery (>= 1.2) rails-assets-jquery-ui (1.12.1) rails-assets-jquery (>= 1.6) - rails-assets-jquery-ujs (1.2.0) + rails-assets-jquery-ujs (1.2.2) rails-assets-jquery (> 1.8) rails-assets-jsSHA (2.3.1) rails-assets-jstimezonedetect (1.0.5) rails-assets-typeahead.js (0.11.1) rails-assets-jquery (>= 1.7) - rails-assets-underscore (1.8.3) + rails-assets-underscore (1.13.6) rails-assets-x-editable (1.5.1) rails-assets-jquery (>= 1.6) GEM remote: https://rubygems.org/ specs: - actioncable (6.1.7.6) - actionpack (= 6.1.7.6) - activesupport (= 6.1.7.6) + 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.7.6) - actionpack (= 6.1.7.6) - activejob (= 6.1.7.6) - activerecord (= 6.1.7.6) - activestorage (= 6.1.7.6) - activesupport (= 6.1.7.6) + 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.7.6) - actionpack (= 6.1.7.6) - actionview (= 6.1.7.6) - activejob (= 6.1.7.6) - activesupport (= 6.1.7.6) + 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.7.6) - actionview (= 6.1.7.6) - activesupport (= 6.1.7.6) + 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.7.6) - actionpack (= 6.1.7.6) - activerecord (= 6.1.7.6) - activestorage (= 6.1.7.6) - activesupport (= 6.1.7.6) + 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.7.6) - activesupport (= 6.1.7.6) + 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) - active_hash (3.0.0) + active_hash (3.2.1) activesupport (>= 5.0.0) - activejob (6.1.7.6) - activesupport (= 6.1.7.6) + activejob (6.1.7.7) + activesupport (= 6.1.7.7) globalid (>= 0.3.6) - activemodel (6.1.7.6) - activesupport (= 6.1.7.6) - activerecord (6.1.7.6) - activemodel (= 6.1.7.6) - activesupport (= 6.1.7.6) - activestorage (6.1.7.6) - actionpack (= 6.1.7.6) - activejob (= 6.1.7.6) - activerecord (= 6.1.7.6) - activesupport (= 6.1.7.6) + 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.7.6) + 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.4) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) - airbrake (11.0.1) + airbrake (11.0.3) airbrake-ruby (~> 5.1) - airbrake-ruby (5.2.0) + airbrake-ruby (5.2.1) rbtree3 (~> 0.5) ansible (0.2.2) ar_multi_threaded_transactional_tests (0.5.0) activerecord (>= 4.2.0, < 6.2.0) - ast (2.4.1) + ast (2.4.2) attr_encrypted (3.1.0) encryptor (~> 3.0.0) - audited (5.4.2) + audited (5.4.3) activerecord (>= 5.0, < 7.2) request_store (~> 1.2) - autoprefixer-rails (9.4.8) + autoprefixer-rails (9.8.6.5) execjs - awesome_print (1.6.1) - aws-eventstream (1.2.0) - aws-partitions (1.329.0) - aws-sdk-core (3.100.0) - aws-eventstream (~> 1, >= 1.0.2) - aws-partitions (~> 1, >= 1.239.0) + awesome_print (1.9.2) + aws-eventstream (1.3.0) + aws-partitions (1.887.0) + aws-sdk-core (3.191.0) + aws-eventstream (~> 1, >= 1.3.0) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.8) + jmespath (~> 1, >= 1.6.1) + aws-sdk-ecr (1.69.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sigv4 (~> 1.1) - jmespath (~> 1.0) - aws-sdk-ecr (1.3.0) - aws-sdk-core (~> 3) - aws-sigv4 (~> 1.0) - aws-sdk-kms (1.23.0) - aws-sdk-core (~> 3, >= 3.58.0) + aws-sdk-kms (1.77.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.45.0) - aws-sdk-core (~> 3, >= 3.58.0) + aws-sdk-s3 (1.143.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.1) - aws-sigv4 (1.6.1) + aws-sigv4 (~> 1.8) + aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) - base64 (0.1.1) + base64 (0.2.0) + bigdecimal (3.1.6) binding_of_caller (0.8.0) debug_inspector (>= 0.0.1) - bootsnap (1.4.5) - msgpack (~> 1.0) + bootsnap (1.18.3) + msgpack (~> 1.2) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) @@ -315,39 +322,40 @@ GEM momentjs-rails (>= 2.8.1) brakeman (5.4.1) builder (3.2.4) - bundler-audit (0.9.0.1) + bundler-audit (0.9.1) bundler (>= 1.2.0, < 3) thor (~> 1.0) byebug (8.2.5) - chef-utils (18.1.29) + chef-utils (18.4.2) concurrent-ruby - coderay (1.1.1) + coderay (1.1.3) commonmarker (0.23.10) - concurrent-ruby (1.2.2) - connection_pool (2.2.1) - crack (0.4.3) - safe_yaml (~> 1.0.0) + concurrent-ruby (1.2.3) + connection_pool (2.4.1) + crack (0.4.6) + bigdecimal + rexml crass (1.0.6) - dalli (3.2.3) + dalli (3.2.7) + base64 + date (3.3.4) ddtrace (0.45.0) msgpack debug_inspector (0.0.3) diffy (3.4.2) - dogstatsd-ruby (3.0.0) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) - doorkeeper (5.6.6) + dogstatsd-ruby (5.6.1) + domain_name (0.6.20240107) + doorkeeper (5.6.8) railties (>= 5) - dotenv (2.2.1) + dotenv (2.8.1) encryptor (3.0.0) erubi (1.12.0) - erubis (2.7.0) - execjs (2.7.0) - faraday (2.7.11) + execjs (2.9.1) + faraday (2.8.1) base64 faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) - faraday-http-cache (2.5.0) + faraday-http-cache (2.5.1) faraday (>= 0.8) faraday-multipart (1.0.4) multipart-post (~> 2) @@ -355,36 +363,38 @@ GEM faraday-net_http_persistent (2.1.0) faraday (~> 2.5) net-http-persistent (~> 4.0) - ffi (1.15.5) + faraday-retry (2.2.0) + faraday (~> 2.0) + ffi (1.16.3) ffi-compiler (1.0.1) ffi (>= 1.0.0) rake - flay (2.12.0) - erubis (~> 2.7.0) + flay (2.13.2) + erubi (~> 1.10) path_expander (~> 1.0) ruby_parser (~> 3.0) sexp_processor (~> 4.0) flowdock (0.7.1) httparty (~> 0.7) multi_json - forking_test_runner (1.2.0) + forking_test_runner (1.13.0) parallel_tests (>= 1.3.7) - git_diff_parser (3.1.0) - gitlab (4.10.0) - httparty (~> 0.14, >= 0.14.0) - terminal-table (~> 1.5, >= 1.5.1) - globalid (1.1.0) - activesupport (>= 5.0) + git_diff_parser (3.2.0) + gitlab (4.19.0) + httparty (~> 0.20) + terminal-table (>= 1.5.1) + globalid (1.2.1) + activesupport (>= 6.1) goldiloader (3.2.0) activerecord (>= 4.2, < 6.3) activesupport (>= 4.2, < 6.3) - hashdiff (0.3.4) hashie (5.0.0) - http (5.1.1) + http (5.2.0) addressable (~> 2.8) + base64 (~> 0.1) http-cookie (~> 1.0) http-form_data (~> 2.2) - llhttp-ffi (~> 0.4.0) + llhttp-ffi (~> 0.5.0) http-accept (1.7.0) http-cookie (1.0.5) domain_name (~> 0.5) @@ -396,7 +406,7 @@ GEM concurrent-ruby (~> 1.0) inflection (1.0.0) interception (0.5) - jenkins_api_client (2.0.0) + jenkins_api_client (2.1.0) addressable (~> 2.7) json (>= 1.0) mixlib-shellout (>= 1.1.0) @@ -405,8 +415,8 @@ GEM terminal-table (>= 1.4.0) thor (>= 0.16.0) jmespath (1.6.2) - json (2.6.3) - jsonpath (1.1.2) + json (2.7.1) + jsonpath (1.1.5) multi_json jwt (2.7.1) kubeclient (4.11.0) @@ -414,60 +424,73 @@ GEM jsonpath (~> 1.0) recursive-open-struct (~> 1.1, >= 1.1.1) rest-client (~> 2.0) - large_object_store (1.3.4) - llhttp-ffi (0.4.0) + large_object_store (1.7.0) + zstd-ruby (~> 1.5.5) + llhttp-ffi (0.5.0) ffi-compiler (~> 1.0) rake (~> 13.0) - lograge (0.12.0) + lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) logstash-event (1.2.02) - loofah (2.21.4) + loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (1.0.2) - marco-polo (2.0.1) + marcel (1.0.3) + marco-polo (2.0.3) railties (>= 6) - maxitest (3.3.0) - minitest (>= 5.0.0, < 5.12.0) - metaclass (0.0.4) - method_source (0.8.2) - mime-types (3.4.1) + maxitest (3.7.0) + minitest (>= 5.0.0, < 5.15.0) + method_source (1.0.0) + mime-types (3.5.2) mime-types-data (~> 3.2015) - mime-types-data (3.2023.0218.1) + mime-types-data (3.2024.0206) mini_mime (1.1.5) mini_portile2 (2.8.5) - minitest (5.11.3) - minitest-rails (6.1.0) + minitest (5.14.4) + minitest-rails (6.1.1) minitest (~> 5.10) railties (~> 6.1.0) mixlib-shellout (3.2.7) chef-utils - mocha (1.2.1) - metaclass (~> 0.0.1) + mocha (2.1.0) + ruby2_keywords (>= 0.0.5) momentjs-rails (2.29.4.1) railties (>= 3.1) - msgpack (1.4.2) + msgpack (1.7.2) multi_json (1.15.0) multi_xml (0.6.0) multipart-post (2.3.0) - mysql2 (0.5.3) + mysql2 (0.5.5) net-http-persistent (4.0.2) connection_pool (~> 2.2) - net-ldap (0.18.0) + net-imap (0.4.10) + date + net-protocol + net-ldap (0.19.0) + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.4.0.1) + net-protocol netrc (0.11.0) - newrelic_rpm (6.7.0.359) - nio4r (2.5.9) - nokogiri (1.15.4) + newrelic_rpm (9.7.1) + nio4r (2.7.0) + nokogiri (1.16.2) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.15.4-x86_64-darwin) + nokogiri (1.16.2-aarch64-linux) + racc (~> 1.4) + nokogiri (1.16.2-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.2-x86_64-darwin) racc (~> 1.4) - nokogiri (1.15.4-x86_64-linux) + nokogiri (1.16.2-x86_64-linux) racc (~> 1.4) oauth2 (2.0.9) faraday (>= 0.17.3, < 3.0) @@ -499,55 +522,56 @@ GEM omniauth-rails_csrf_protection (1.0.1) actionpack (>= 4.2) omniauth (~> 2.0) - pagy (3.6.0) - parallel (1.19.2) - parallel_tests (2.21.1) + pagy (4.11.0) + parallel (1.24.0) + parallel_tests (2.32.0) parallel - parser (2.7.2.0) + parser (3.3.0.5) ast (~> 2.4.1) - path_expander (1.0.4) - pg (1.1.3) - pry (0.10.3) - coderay (~> 1.1.0) - method_source (~> 0.8.1) - slop (~> 3.4) + racc + path_expander (1.1.1) + pg (1.5.4) + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) pry-byebug (3.3.0) byebug (~> 8.0) pry (~> 0.10) - pry-rails (0.3.5) - pry (>= 0.9.10) - pry-rescue (1.4.5) + pry-rails (0.3.9) + pry (>= 0.10.4) + pry-rescue (1.6.0) interception (>= 0.5) - pry + pry (>= 0.12.0) pry-stack_explorer (0.4.9.3) binding_of_caller (>= 0.7) pry (>= 0.9.11) - public_suffix (5.0.1) - puma (5.6.7) + public_suffix (5.0.4) + puma (5.6.8) nio4r (~> 2.0) pyu-ruby-sasl (0.0.3.3) racc (1.7.3) - rack (2.2.8) - rack-mini-profiler (1.1.4) + rack (2.2.8.1) + rack-mini-profiler (3.3.0) rack (>= 1.2.0) - rack-protection (3.1.0) + rack-protection (3.2.0) + base64 (>= 0.1.0) rack (~> 2.2, >= 2.2.4) rack-test (2.1.0) rack (>= 1.3) - rails (6.1.7.6) - actioncable (= 6.1.7.6) - actionmailbox (= 6.1.7.6) - actionmailer (= 6.1.7.6) - actionpack (= 6.1.7.6) - actiontext (= 6.1.7.6) - actionview (= 6.1.7.6) - activejob (= 6.1.7.6) - activemodel (= 6.1.7.6) - activerecord (= 6.1.7.6) - activestorage (= 6.1.7.6) - activesupport (= 6.1.7.6) + 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.7.6) + railties (= 6.1.7.7) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) @@ -560,17 +584,17 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (6.1.7.6) - actionpack (= 6.1.7.6) - activesupport (= 6.1.7.6) + railties (6.1.7.7) + actionpack (= 6.1.7.7) + activesupport (= 6.1.7.7) method_source rake (>= 12.2) thor (~> 1.0) - rainbow (3.0.0) + rainbow (3.1.1) rake (13.1.0) - rbtree3 (0.6.0) + rbtree3 (0.7.1) recursive-open-struct (1.1.3) - regexp_parser (1.8.2) + regexp_parser (2.9.0) request_store (1.5.1) rack (>= 1.4) rest-client (2.1.0) @@ -578,31 +602,33 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - rexml (3.2.5) - rollbar (2.19.1) - multi_json + rexml (3.2.6) + rollbar (2.27.1) rollbar-user_informer (0.1.0) rollbar (~> 2.15) - rubocop (0.93.1) + rubocop (1.42.0) + json (~> 2.3) parallel (~> 1.10) - parser (>= 2.7.1.5) + parser (>= 3.1.2.1) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8) - rexml - rubocop-ast (>= 0.6.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.24.1, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (0.8.0) - parser (>= 2.7.1.5) - rubocop-rails (2.3.2) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.30.0) + parser (>= 3.2.1.0) + rubocop-rails (2.23.1) + activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.72.0) - ruby-progressbar (1.10.1) + rubocop (>= 1.33.0, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) + ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) - ruby_parser (3.13.1) - sexp_processor (~> 4.9) + ruby_parser (3.21.0) + racc (~> 1.5) + sexp_processor (~> 4.16) rubyntlm (0.6.3) - safe_yaml (1.0.4) sass-rails (6.0.0) sassc-rails (~> 2.1, >= 2.1.1) sassc (2.4.0) @@ -616,24 +642,23 @@ GEM sawyer (0.9.2) addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) - sentry-rails (5.4.2) + sentry-rails (5.16.1) railties (>= 5.0) - sentry-ruby (~> 5.4.2) - sentry-ruby (5.4.2) + sentry-ruby (~> 5.16.1) + sentry-ruby (5.16.1) concurrent-ruby (~> 1.0, >= 1.0.2) sentry-user_informer (0.2.0) rack railties (>= 6.1.0, < 7.1.0) sentry-rails (~> 5.4) - sexp_processor (4.12.1) - single_cov (1.3.2) - slop (3.6.0) + sexp_processor (4.17.1) + single_cov (1.5.0) snaky_hash (2.0.1) hashie version_gem (~> 1.1, >= 1.1.1) socksify (1.7.1) - soft_deletion (1.6.0) - activerecord (>= 4.2.0, < 6.2.0) + soft_deletion (1.9.0) + activerecord (>= 5.0.0, < 7.2) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -641,33 +666,36 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - sqlite3 (1.4.2) + sqlite3 (1.6.9) + mini_portile2 (~> 2.8.0) + sqlite3 (1.6.9-aarch64-linux) + sqlite3 (1.6.9-arm64-darwin) + sqlite3 (1.6.9-x86_64-darwin) + sqlite3 (1.6.9-x86_64-linux) stackprof (0.2.12) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - thor (1.3.0) - tilt (2.0.10) + thor (1.3.1) + tilt (2.3.0) + timeout (0.4.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) uglifier (3.2.0) execjs (>= 0.3.0, < 3) - unf (0.1.4) - unf_ext - unf_ext (0.0.8.2) unicode-display_width (1.8.0) validates_lengths_from_database (0.8.0) activerecord (>= 4) version_gem (1.1.3) - warden (1.2.7) - rack (>= 1.0) - webmock (3.0.1) - addressable (>= 2.3.6) + warden (1.2.9) + rack (>= 2.0.9) + webmock (3.20.0) + addressable (>= 2.8.0) crack (>= 0.3.2) - hashdiff + hashdiff (>= 0.4.0, < 2.0.0) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - zeitwerk (2.6.12) + zeitwerk (2.6.13) zendesk_api (2.0.1) faraday (> 2.0.0) faraday-multipart @@ -675,10 +703,13 @@ GEM inflection mini_mime multipart-post (~> 2.0) + zstd-ruby (1.5.5.0) PLATFORMS + aarch64-linux + arm64-darwin ruby - x86_64-darwin-18 + x86_64-darwin x86_64-linux DEPENDENCIES @@ -705,10 +736,12 @@ DEPENDENCIES faraday (~> 2.7) faraday-http-cache faraday-net_http_persistent (~> 2.0) + faraday-retry flay forking_test_runner gcloud_image_tagger! goldiloader + hashdiff! large_object_store lograge logstash-event @@ -720,6 +753,9 @@ DEPENDENCIES momentjs-rails mysql2 net-http-persistent + net-imap + net-pop + net-smtp oauth2 (~> 2.0.9) octokit omniauth (~> 2.0) @@ -740,7 +776,7 @@ DEPENDENCIES pry-stack_explorer puma (~> 5.6.7) rack-mini-profiler - rails (~> 6.1.7.6) + rails (~> 6.1.7.7) rails-assets-bootstrap-select! rails-assets-jquery! rails-assets-jquery-cookie! @@ -794,7 +830,7 @@ DEPENDENCIES webmock RUBY VERSION - ruby 2.7.8p225 + ruby 3.2.2p53 BUNDLED WITH - 2.3.25 + 2.5.6 diff --git a/Rakefile b/Rakefile index 20e90a076a..8d9fff9bb0 100644 --- a/Rakefile +++ b/Rakefile @@ -60,10 +60,7 @@ end desc 'Scan for gem vulnerabilities' task :bundle_audit do - # TODO: remove CVE-2015-9284 once https://github.com/omniauth/omniauth/pull/809 is resolved - # TODO: remove CVE-2022-0759 once local development works on newer version - # TODO: remove GHSA-hjp3-5g2q-7jww will need ruby 3.0 - sh "bundle-audit check --update --ignore CVE-2015-9284 CVE-2022-0759 GHSA-hjp3-5g2q-7jww CVE-2023-34246" + sh "bundle-audit check --update" end desc "Run rubocop" @@ -92,6 +89,8 @@ task :flay do 'plugins/kubernetes/app/models/kubernetes/deploy_group_role.rb', # similar but slightly different validations 'plugins/flowdock/app/views/samson_flowdock/_fields.html.erb', # simple html 'plugins/datadog/app/views/samson_datadog/_datadog_monitor_queries_fields.html.erb', # simple html + 'plugins/zendesk/app/views/samson_zendesk/notification.erb', # simple text + 'app/views/deploy_mailer/_commit_info.text.erb', # simple text ] flay = Flay.run([*files, '--mass', '25']) # mass threshold is shown mass / occurrences abort "Code duplication found" if flay.report.any? diff --git a/app/channels/deploy_notifications_channel.rb b/app/channels/deploy_notifications_channel.rb index 2fafd85ddb..9b7e06034d 100644 --- a/app/channels/deploy_notifications_channel.rb +++ b/app/channels/deploy_notifications_channel.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class DeployNotificationsChannel < ActionCable::Channel::Base def self.broadcast(count) - ActionCable.server.broadcast channel_name, count: count + ActionCable.server.broadcast(channel_name, {count: count}) end # called when using javascript App.cable.subscriptions.create diff --git a/app/channels/job_outputs_channel.rb b/app/channels/job_outputs_channel.rb index aea1518122..b3af6562fe 100644 --- a/app/channels/job_outputs_channel.rb +++ b/app/channels/job_outputs_channel.rb @@ -87,17 +87,17 @@ def stream_execution(execution) execution.viewers.push current_user builder = EventBuilder.new(execution.job) execution.output.each do |event, data| - transmit event: event, data: builder.payload(event, data) + transmit({event: event, data: builder.payload(event, data)}) end end # send fake output (reproduce by deploying a bad ref) def stream_finished_output(job) builder = EventBuilder.new(job) - transmit event: :started, data: builder.payload(:started, nil) + transmit({event: :started, data: builder.payload(:started, nil)}) job.output.each_line do |line| - transmit event: :message, data: builder.payload(:message, line) + transmit({event: :message, data: builder.payload(:message, line)}) end - transmit event: :finished, data: builder.payload(:finished, nil) + transmit({event: :finished, data: builder.payload(:finished, nil)}) end end diff --git a/app/controllers/csv_exports_controller.rb b/app/controllers/csv_exports_controller.rb index d4d8289c34..96f7426771 100644 --- a/app/controllers/csv_exports_controller.rb +++ b/app/controllers/csv_exports_controller.rb @@ -32,7 +32,7 @@ def new case params[:type] when "users" options = user_filter - send_data UserCsvPresenter.to_csv(options), type: :csv, filename: "Users_#{options[:datetime]}.csv" + send_data UserCsvPresenter.to_csv(**options), type: :csv, filename: "Users_#{options[:datetime]}.csv" when "deploy_group_usage" date_time_now = Time.now.strftime "%Y%m%d_%H%M" send_data DeployGroupUsageCsvPresenter.to_csv, type: :csv, filename: "DeployGroupUsage_#{date_time_now}.csv" diff --git a/app/controllers/integrations/base_controller.rb b/app/controllers/integrations/base_controller.rb index 44572c4c66..fa34a2e94a 100644 --- a/app/controllers/integrations/base_controller.rb +++ b/app/controllers/integrations/base_controller.rb @@ -144,12 +144,14 @@ def create_docker_images options = {git_sha: commit, dockerfile: dockerfile} next if scope.where(options).first - build = project.builds.create!(options.merge( - git_ref: branch, - description: message, - creator: user, - name: "Release #{branch}" - )) + build = project.builds.create!( + options.merge( + git_ref: branch, + description: message, + creator: user, + name: "Release #{branch}" + ) + ) DockerBuilderService.new(build).run(tag_as_latest: true) end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 2f3c1e364f..848340db78 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -98,11 +98,13 @@ def login(options = {}) uid = auth_hash.uid end - user = find_or_create_user_from_hash(options.merge( - external_id: "#{strategy.name}-#{uid}", - name: auth_hash.info.name, - email: auth_hash.info.email - )) + user = find_or_create_user_from_hash( + options.merge( + external_id: "#{strategy.name}-#{uid}", + name: auth_hash.info.name, + email: auth_hash.info.email + ) + ) if user.persisted? self.current_user = user diff --git a/app/models/build.rb b/app/models/build.rb index 6a77f8c582..479eb23b10 100644 --- a/app/models/build.rb +++ b/app/models/build.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class Build < ActiveRecord::Base - SHA1_REGEX = /\A[0-9a-f]{40}\Z/i.freeze - SHA256_REGEX = /\A(sha256:)?[0-9a-f]{64}\Z/i.freeze - DIGEST_REGEX = /\A[\w.-]+[\w.-]*(:\d+)?[\w.\/-]*@sha256:[0-9a-f]{64}\Z/i.freeze + SHA1_REGEX = /\A[0-9a-f]{40}\Z/i + SHA256_REGEX = /\A(sha256:)?[0-9a-f]{64}\Z/i + DIGEST_REGEX = /\A[\w.-]+[\w.-]*(:\d+)?[\w.\/-]*@sha256:[0-9a-f]{64}\Z/i belongs_to :project, inverse_of: :builds belongs_to :docker_build_job, class_name: 'Job', optional: true, inverse_of: false diff --git a/app/models/changeset/commit.rb b/app/models/changeset/commit.rb index 6ea91f43d4..5968fd4577 100644 --- a/app/models/changeset/commit.rb +++ b/app/models/changeset/commit.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Changeset::Commit - PULL_REQUEST_MERGE_MESSAGE = /\AMerge pull request #(\d+)/.freeze - PULL_REQUEST_SQUASH_MESSAGE = /\A.*\(#(\d+)\)$/.freeze + PULL_REQUEST_MERGE_MESSAGE = /\AMerge pull request #(\d+)/ + PULL_REQUEST_SQUASH_MESSAGE = /\A.*\(#(\d+)\)$/ attr_reader :project @@ -28,7 +28,7 @@ def summary end def summary_long - @data.commit.message.split("\n").first + @data.commit.message.split("\n").first || "" end def sha diff --git a/app/models/changeset/pull_request.rb b/app/models/changeset/pull_request.rb index 5fac1cb873..d4d7a71511 100644 --- a/app/models/changeset/pull_request.rb +++ b/app/models/changeset/pull_request.rb @@ -4,16 +4,16 @@ class Changeset::PullRequest CODE_ONLY = "[A-Z][A-Z\\d]+-\\d+" # e.g., S4MS0N-123, SAM-456 PUNCT = "\\s|\\p{Punct}|~|=" - WEBHOOK_FILTER = /(^|\s)\[samson review\]($|\s)/i.freeze + WEBHOOK_FILTER = /(^|\s)\[samson review\]($|\s)/i # Matches URLs to JIRA issues. - JIRA_ISSUE_URL = %r[https?://[\da-z.\-]+\.[a-z.]{2,6}/browse/#{CODE_ONLY}(?=#{PUNCT}|$)].freeze + JIRA_ISSUE_URL = %r[https?://[\da-z.\-]+\.[a-z.]{2,6}/browse/#{CODE_ONLY}(?=#{PUNCT}|$)] # Matches "VOICE-1234" or "[VOICE-1234]" - JIRA_CODE_TITLE = /(\[)*(#{CODE_ONLY})(\])*/.freeze + JIRA_CODE_TITLE = /(\[)*(#{CODE_ONLY})(\])*/ # Matches "VOICE-1234" only - JIRA_CODE = /(?<=#{PUNCT}|^)(#{CODE_ONLY})(?=#{PUNCT}|$)/.freeze + JIRA_CODE = /(?<=#{PUNCT}|^)(#{CODE_ONLY})(?=#{PUNCT}|$)/ # Github pull request events can be triggered by a number of actions such as 'labeled', 'assigned' # Actions which aren't related to a code push should not trigger a samson deploy. diff --git a/app/models/concerns/attr_encrypted_support.rb b/app/models/concerns/attr_encrypted_support.rb index 6ef24a622f..0a158b4912 100644 --- a/app/models/concerns/attr_encrypted_support.rb +++ b/app/models/concerns/attr_encrypted_support.rb @@ -11,14 +11,15 @@ def self.included(base) base.extend ClassMethods end - def as_json(except: [], **options) - except += [ + def as_json(options = {}) + options[:except] ||= [] + options[:except] += [ :encryption_key_sha, *self.class.encrypted_attributes.keys.flat_map do |column| [column, :"encrypted_#{column}_iv", :"encrypted_#{column}"] end ] - super(except: except, **options) + super(options) end private diff --git a/app/models/concerns/has_role.rb b/app/models/concerns/has_role.rb index fe4b990441..6454b06359 100644 --- a/app/models/concerns/has_role.rb +++ b/app/models/concerns/has_role.rb @@ -4,7 +4,7 @@ def role Role.find(role_id) end - Role.all.each do |role| # rubocop:disable Rails/FindEach + Role.all.each do |role| # rubocop:disable Lint/RedundantCopDisableDirective Rails/FindEach define_method "#{role.name}?" do role_id >= role.id end diff --git a/app/models/deploy.rb b/app/models/deploy.rb index e49f4dc5be..aefed6b292 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -231,8 +231,8 @@ def csv_line ] end - def as_json(methods: []) - hash = super(methods: [:status, :url, :production, :commit] + methods) + def as_json(options = {}) + hash = super({methods: [:status, :url, :production, :commit] + options.fetch(:methods, [])}) hash["summary"] = summary_for_timeline hash end diff --git a/app/models/image_builder.rb b/app/models/image_builder.rb index 84d1caa023..45eeea723d 100644 --- a/app/models/image_builder.rb +++ b/app/models/image_builder.rb @@ -5,7 +5,7 @@ class ImageBuilder class << self extend ::Samson::PerformanceTracer::Tracers - DIGEST_SHA_REGEX = /Digest:.*(sha256:[0-9a-f]{64})/i.freeze + DIGEST_SHA_REGEX = /Digest:.*(sha256:[0-9a-f]{64})/i def build_image(dir, build, executor, tag_as_latest:, **args) if DockerRegistry.all.empty? diff --git a/app/models/outbound_webhook.rb b/app/models/outbound_webhook.rb index 054e65059c..6667195cb4 100644 --- a/app/models/outbound_webhook.rb +++ b/app/models/outbound_webhook.rb @@ -99,7 +99,7 @@ def connection connection.adapter Faraday.default_adapter case auth_type - when "None" # rubocop:disable Lint/EmptyWhen noop + when "None" # noop when "Basic" then connection.request :authorization, :basic, username, password when "Bearer", "Token" then connection.request :authorization, auth_type, password else raise ArgumentError, "Unsupported auth_type #{auth_type.inspect}" @@ -109,7 +109,7 @@ def connection def validate_auth case auth_type - when "None" # rubocop:disable Lint/EmptyWhen noop + when "None" # noop when "Basic" then errors.add :username, "and password must be set" if !username? || !password? when "Bearer", "Token" then errors.add :password, "must be set" unless password? else errors.add(:auth_type, "unknown, supported types are #{AUTH_TYPES.to_sentence}") diff --git a/app/models/release.rb b/app/models/release.rb index 705391bd5c..3f75b29176 100644 --- a/app/models/release.rb +++ b/app/models/release.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Release < ActiveRecord::Base - NUMBER_REGEX = /\A#{Samson::RELEASE_NUMBER}\z/.freeze - VERSION_REGEX = /\Av(#{Samson::RELEASE_NUMBER})\z/.freeze + NUMBER_REGEX = /\A#{Samson::RELEASE_NUMBER}\z/ + VERSION_REGEX = /\Av(#{Samson::RELEASE_NUMBER})\z/ belongs_to :project, touch: true, inverse_of: :releases belongs_to :author, class_name: "User", inverse_of: false diff --git a/app/models/terminal_executor.rb b/app/models/terminal_executor.rb index 388563bbe3..edb48000a9 100644 --- a/app/models/terminal_executor.rb +++ b/app/models/terminal_executor.rb @@ -19,7 +19,7 @@ class TerminalExecutor HIDDEN_TXT = "HIDDEN" KILL_TIMEOUT = Integer(ENV['DEPLOY_KILL_TIMEOUT'] || '1') - CURSOR = /\e\[\d*[ABCDK]/.freeze + CURSOR = /\e\[\d*[ABCDK]/ attr_reader :pid, :pgid, :output, :timeout diff --git a/app/models/user.rb b/app/models/user.rb index 8baecf4ae8..f608c63835 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,7 +7,7 @@ class User < ActiveRecord::Base include HasRole TIME_FORMATS = ['local', 'utc', 'relative'].freeze - GITHUB_USERNAME_REGEX = /\A[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}\Z/i.freeze + GITHUB_USERNAME_REGEX = /\A[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}\Z/i has_soft_deletion default_scope: true include SoftDeleteWithDestroy diff --git a/app/models/webhook_recorder.rb b/app/models/webhook_recorder.rb index 73136be877..ab0dea58a7 100644 --- a/app/models/webhook_recorder.rb +++ b/app/models/webhook_recorder.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class WebhookRecorder KEY = 'WebhookRecorder-v2' - NATIVE_HEADER = /^[_A-Z]+$/.freeze + NATIVE_HEADER = /^[_A-Z]+$/ IGNORED_HEADERS = ["QUERY_STRING", "RAW_POST_DATA"].freeze class << self diff --git a/config/application.rb b/config/application.rb index f411c785c8..f15c3a1973 100644 --- a/config/application.rb +++ b/config/application.rb @@ -66,6 +66,7 @@ def self.deprecated_url(var) when "memory" config.cache_store = :memory_store # to debug cache keys, bundle open activesupport -> active_support/cache.rb#log when "memcached" + require_relative "initializers/sockify" options = { value_max_bytes: 3000000, compress: true, @@ -187,7 +188,7 @@ def self.deprecated_url(var) RestartSignalHandler.after_restart RestartSignalHandler.listen end - Samson::BootCheck.check if Rails.env.development? + # Samson::BootCheck.check if Rails.env.development? # TODO: re-enable end unless ENV['PRECOMPILE'] @@ -196,7 +197,7 @@ def self.deprecated_url(var) # Token used to request badges config.samson.badge_token = \ - Digest::MD5.hexdigest("badge_token#{(ENV['BADGE_TOKEN_BASE'] || Samson::Application.config.secret_key_base)}") + Digest::MD5.hexdigest("badge_token#{ENV['BADGE_TOKEN_BASE'] || Samson::Application.config.secret_key_base}") end end diff --git a/config/boot.rb b/config/boot.rb index 3c3fa334a4..67173bedba 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -13,7 +13,6 @@ cache_dir: 'tmp/bootsnap', # Path to your cache development_mode: rails_env == "development", load_path_cache: true, # optimizes the LOAD_PATH with a cache - autoload_paths_cache: true, # optimizes ActiveSupport autoloads with cache compile_cache_iseq: (rails_env != "test"), # compiles Ruby code into ISeq cache .. breaks coverage reporting compile_cache_yaml: true # compiles YAML into a cache ) diff --git a/config/environments/test.rb b/config/environments/test.rb index fccf8bbb88..0e4539bff8 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -47,8 +47,10 @@ # make our tests fast by avoiding asset compilation # but do not raise when assets are not compiled either Rails.application.config.assets.compile = false -Sprockets::Rails::Helper.prepend(Module.new do - def resolve_asset_path(path, *) - super || path +Sprockets::Rails::Helper.prepend( + Module.new do + def resolve_asset_path(path, *) + super || path + end end -end) +) diff --git a/config/initializers/faraday.rb b/config/initializers/faraday.rb index c611c85881..8524b72711 100644 --- a/config/initializers/faraday.rb +++ b/config/initializers/faraday.rb @@ -3,10 +3,12 @@ # and any other backend that uses faraday require 'faraday' -Faraday::Connection.prepend(Module.new do - def run_request(method, url, *args) - raise "Missing url for logging, do not use `do |request| request.url = ` pattern" unless url - log_url = url.gsub(/key=\w+/, "key=redacted") # ignore datadog credentials and maybe others - ActiveSupport::Notifications.instrument("request.faraday.samson", method: method, url: log_url) { super } +Faraday::Connection.prepend( + Module.new do + def run_request(method, url, *args) + raise "Missing url for logging, do not use `do |request| request.url = ` pattern" unless url + log_url = url.gsub(/key=\w+/, "key=redacted") # ignore datadog credentials and maybe others + ActiveSupport::Notifications.instrument("request.faraday.samson", method: method, url: log_url) { super } + end end -end) +) diff --git a/config/initializers/migration_resetter.rb b/config/initializers/migration_resetter.rb index d6bf56c10b..c0370d6fc9 100644 --- a/config/initializers/migration_resetter.rb +++ b/config/initializers/migration_resetter.rb @@ -4,9 +4,11 @@ # # to reproduce, add 2 migrations one that removes a column and one that puts Stage.column_hash to see if it removed # an even safer (but slower/hackier) option would be to reset after each column change -ActiveRecord::Migration.prepend(Module.new do - def exec_migration(*) - ActiveRecord::Base.connection.schema_cache.clear! - super +ActiveRecord::Migration.prepend( + Module.new do + def exec_migration(*) + ActiveRecord::Base.connection.schema_cache.clear! + super + end end -end) +) diff --git a/config/initializers/pagy.rb b/config/initializers/pagy.rb index a9f3e2f4db..ed3a84cebe 100644 --- a/config/initializers/pagy.rb +++ b/config/initializers/pagy.rb @@ -4,10 +4,12 @@ require 'pagy/extras/overflow' # pagination after last page renders an empty page -Pagy::Backend.prepend(Module.new do - private +Pagy::Backend.prepend( + Module.new do + private - def pagy(collection, options) - super collection, options.merge(overflow: :empty_page) + def pagy(collection, options) + super collection, options.merge(overflow: :empty_page) + end end -end) +) diff --git a/config/initializers/sockify.rb b/config/initializers/sockify.rb new file mode 100644 index 0000000000..0e911137d6 --- /dev/null +++ b/config/initializers/sockify.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# +# TODO: remove one `rails runner 'Rails.cache.fetch 1'` works with memcached +# dalli has this code inside an `if RUBY_VERSION >= '3.0'` but only old version works +require 'dalli' + +class Dalli::Socket::TCP + def self.open(host, port, options = {}) + Timeout.timeout(options[:socket_timeout]) do + sock = new(host, port) + sock.options = {host: host, port: port}.merge(options) + init_socket_options(sock, options) + + options[:ssl_context] ? wrapping_ssl_socket(sock, host, options[:ssl_context]) : sock + end + end +end diff --git a/config/initializers/statsd.rb b/config/initializers/statsd.rb index c8515424cd..9400cf361a 100644 --- a/config/initializers/statsd.rb +++ b/config/initializers/statsd.rb @@ -6,8 +6,13 @@ class << Samson end raise "use STATSD_HOST and STATSD_PORT" if File.exist?("config/statsd.yml") -Samson.statsd = Datadog::Statsd.new(ENV['STATSD_HOST'] || '127.0.0.1', ENV['STATSD_PORT'] || '8125') -Samson.statsd.namespace = "samson.app" +Samson.statsd = Datadog::Statsd.new( + ENV['STATSD_HOST'] || '127.0.0.1', + ENV['STATSD_PORT'] || '8125', + logger: Rails.logger, + namespace: 'samson.app', + single_thread: Rails.env.test? +) Samson.statsd.event "Startup", "Samson startup" if ENV['SERVER_MODE'] @@ -27,11 +32,9 @@ class << Samson kubernetes = payload.fetch(:kubernetes) tags << "kubernetes:#{kubernetes}" unless kubernetes.nil? - Samson.statsd.batch do |statsd| - statsd.timing "execute_shell.time", duration, tags: tags - (payload[:parts] || {}).each do |part, time| - statsd.timing "execute_shell.parts", time, tags: tags + ["part:#{part}"] - end + Samson.statsd.timing "execute_shell.time", duration, tags: tags + (payload[:parts] || {}).each do |part, time| + Samson.statsd.timing "execute_shell.parts", time, tags: tags + ["part:#{part}"] end Rails.logger.info(payload.merge(total: duration, message: "Job execution finished")) end diff --git a/config/initializers/vault.rb b/config/initializers/vault.rb index babcd6fc12..cd3f247d88 100644 --- a/config/initializers/vault.rb +++ b/config/initializers/vault.rb @@ -2,8 +2,10 @@ # instrument all vault calls require 'vault' -Vault::Client.prepend(Module.new do - def request(method, path, *) - ActiveSupport::Notifications.instrument("request.vault.samson", method: method, path: path) { super } +Vault::Client.prepend( + Module.new do + def request(method, path, *) + ActiveSupport::Notifications.instrument("request.vault.samson", method: method, path: path) { super } + end end -end) +) diff --git a/config/logging.rb b/config/logging.rb index 00c3dbddae..d94f46aa14 100644 --- a/config/logging.rb +++ b/config/logging.rb @@ -61,10 +61,12 @@ # We saw initializers hanging boot so we are logging before every initializer is called to easily debug # Test: boot up rails and look at the logs if ENV['SERVER_MODE'] && !Rails.env.development? - Rails::Engine.prepend(Module.new do - def load(file, *) - Rails.logger.info "Loading initializer #{file.sub("#{Bundler.root}/", "")}" - super + Rails::Engine.prepend( + Module.new do + def load(file, *) + Rails.logger.info "Loading initializer #{file.sub("#{Bundler.root}/", "")}" + super + end end - end) + ) end diff --git a/db/migrate/20150223135916_create_deploy_groups.rb b/db/migrate/20150223135916_create_deploy_groups.rb index 045cbf36ae..fd64820507 100644 --- a/db/migrate/20150223135916_create_deploy_groups.rb +++ b/db/migrate/20150223135916_create_deploy_groups.rb @@ -18,7 +18,7 @@ def change end add_foreign_key :deploy_groups, :environments - create_table :deploy_groups_stages, id: false do |t| # rubocop:disable Rails/CreateTableWithTimestamps + create_table :deploy_groups_stages, id: false do |t| t.belongs_to :deploy_group, index: true t.belongs_to :stage, index: true end diff --git a/db/migrate/20160909013442_add_docker_release_branch_to_projects.rb b/db/migrate/20160909013442_add_docker_release_branch_to_projects.rb index 8da17163db..fdfa97ae41 100644 --- a/db/migrate/20160909013442_add_docker_release_branch_to_projects.rb +++ b/db/migrate/20160909013442_add_docker_release_branch_to_projects.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class AddDockerReleaseBranchToProjects < ActiveRecord::Migration[5.0] class Project < ActiveRecord::Base; end + def change add_column :projects, :docker_release_branch, :string Project.all.each do |project| diff --git a/db/migrate/20170616180533_seed_audited_from_versions.rb b/db/migrate/20170616180533_seed_audited_from_versions.rb index 4ee2709843..c58ccba47c 100644 --- a/db/migrate/20170616180533_seed_audited_from_versions.rb +++ b/db/migrate/20170616180533_seed_audited_from_versions.rb @@ -57,8 +57,8 @@ def create_audit(version, current_state) if current_state == :bad {} else - previous_state = YAML.load(version.object || "{}").except(*IGNORED) # rubocop:disable Security/YAMLLoad - current_state = YAML.load(current_state || "{}").except(*IGNORED) # # rubocop:disable Security/YAMLLoad + previous_state = YAML.load(version.object || "{}").except(*IGNORED) + current_state = YAML.load(current_state || "{}").except(*IGNORED) # audited has a strange behavior where the create/destroy changes don't have arrays but just a value simple = ["create", "destroy"].include?(version.event) diff --git a/lib/samson/hooks.rb b/lib/samson/hooks.rb index 0a51174fc7..101be02cef 100644 --- a/lib/samson/hooks.rb +++ b/lib/samson/hooks.rb @@ -178,13 +178,13 @@ def only_callbacks_for_plugin(plugin_name, hook_name) end # use - def fire(name, *args) - traced(name) { hooks(name).map { |hook| hook.call(*args) } } + def fire(name, *args, **kwargs) + traced(name) { hooks(name).map { |hook| hook.call(*args, **kwargs) } } end - def render_views(name, view, *args) + def render_views(name, view, *args, **kwargs) hooks(name).each_with_object("".html_safe) do |partial, html| - html << view.render(partial, *args) + html << view.render(partial, *args, **kwargs) end end diff --git a/lib/samson/secrets/db_backend.rb b/lib/samson/secrets/db_backend.rb index 32985d366b..8bff9b21e0 100644 --- a/lib/samson/secrets/db_backend.rb +++ b/lib/samson/secrets/db_backend.rb @@ -23,17 +23,20 @@ def read(id, *) # Not implemented, just bogus values to be able to debug UI in development+test # versions in vault are unsorted above 10 -> (10,1,2,3...) and have symbol keys - def history(*) - { - foo: "bar", - current_version: 4, - versions: { - "1": {bar: "baz", value: "v1", creator_id: 1}, - "3": {bar: "baz", value: "v2", creator_id: 1}, - "2": {bar: "baz", value: "v2", creator_id: 1}, - "4": {bar: "baz", value: "v3", creator_id: 1} + # method signature matches real backend's .history method + def history(id, resolve: true) + if id.nil? || resolve.nil? || !id.nil? + { + foo: "bar", + current_version: 4, + versions: { + "1": {bar: "baz", value: "v1", creator_id: 1}, + "3": {bar: "baz", value: "v2", creator_id: 1}, + "2": {bar: "baz", value: "v2", creator_id: 1}, + "4": {bar: "baz", value: "v3", creator_id: 1} + } } - } + end end def read_multi(ids) diff --git a/lib/samson/secrets/manager.rb b/lib/samson/secrets/manager.rb index 06c6a59d88..ffc45702cc 100644 --- a/lib/samson/secrets/manager.rb +++ b/lib/samson/secrets/manager.rb @@ -8,7 +8,7 @@ module Secrets module Manager ID_PARTS = [:environment_permalink, :project_permalink, :deploy_group_permalink, :key].freeze ID_PART_SEPARATOR = "/" - SECRET_ID_REGEX = %r{[\w/-]+}.freeze + SECRET_ID_REGEX = %r{[\w/-]+} SECRET_LOOKUP_CACHE = 'secret_lookup_cache_v3' SECRET_LOOKUP_CACHE_MUTEX = Mutex.new VALUE_HASHED_BASE = Digest::SHA2.hexdigest("#{Samson::Application.config.secret_key_base}usedforhashing") @@ -38,7 +38,7 @@ def read(id, *args, include_value: false) end def history(id, include_value: false, **options) - history = backend.history(id, options) || raise(ActiveRecord::RecordNotFound) + history = backend.history(id, **options) || raise(ActiveRecord::RecordNotFound) unless include_value last_value = nil history.fetch(:versions).each_value do |data| diff --git a/lib/samson/secrets/vault_client_wrapper.rb b/lib/samson/secrets/vault_client_wrapper.rb index 2014c8f137..a450160734 100644 --- a/lib/samson/secrets/vault_client_wrapper.rb +++ b/lib/samson/secrets/vault_client_wrapper.rb @@ -19,7 +19,7 @@ def kv if @versioned_kv @kv ||= VaultKvWrapper.new(self, Samson::Secrets::VaultClientManager::MOUNT) else - @logical ||= VaultLogicalWrapper.new(self) + @logical ||= VaultLogicalWrapper.new(self) # rubocop:disable Naming/MemoizedInstanceVariableName end end end diff --git a/lib/samson/secrets/vault_server.rb b/lib/samson/secrets/vault_server.rb index 6c8246d55e..11b9894fa1 100644 --- a/lib/samson/secrets/vault_server.rb +++ b/lib/samson/secrets/vault_server.rb @@ -9,7 +9,7 @@ class VaultServer < ActiveRecord::Base audited include AttrEncryptedSupport self.table_name = :vault_servers - ADDRESS_PATTERN = /\Ahttps?:\/\/.*\z/.freeze + ADDRESS_PATTERN = /\Ahttps?:\/\/.*\z/ DEFAULT_CLIENT_OPTIONS = { use_ssl: true, @@ -73,13 +73,12 @@ def sync!(other) def create_client VaultClientWrapper.new( - DEFAULT_CLIENT_OPTIONS.merge( - address: address, - ssl_cert_store: cert_store, - ssl_verify: tls_verify, - token: token, - versioned_kv: versioned_kv? - ) + **DEFAULT_CLIENT_OPTIONS, + address: address, + ssl_cert_store: cert_store, + ssl_verify: tls_verify, + token: token, + versioned_kv: versioned_kv? ) end diff --git a/plugins/airbrake_hook/lib/samson_airbrake_hook/samson_plugin.rb b/plugins/airbrake_hook/lib/samson_airbrake_hook/samson_plugin.rb index 4cc5b25df8..b6e3f4a323 100644 --- a/plugins/airbrake_hook/lib/samson_airbrake_hook/samson_plugin.rb +++ b/plugins/airbrake_hook/lib/samson_airbrake_hook/samson_plugin.rb @@ -5,7 +5,7 @@ class SamsonPlugin < Rails::Engine class Notification class << self - VALID_RAILS_ENV = /^[a-z]+$/.freeze + VALID_RAILS_ENV = /^[a-z]+$/ SECRET_KEY = 'airbrake_api_key' def deliver_for(deploy) diff --git a/plugins/aws_ecr/lib/samson_aws_ecr/samson_plugin.rb b/plugins/aws_ecr/lib/samson_aws_ecr/samson_plugin.rb index 44607969d7..c4e98ef20a 100644 --- a/plugins/aws_ecr/lib/samson_aws_ecr/samson_plugin.rb +++ b/plugins/aws_ecr/lib/samson_aws_ecr/samson_plugin.rb @@ -3,7 +3,7 @@ module SamsonAwsEcr class SamsonPlugin < Rails::Engine - AMAZON_REGISTRY = /\A.*\.dkr.ecr.([\w\-]+).amazonaws.com\z/.freeze + AMAZON_REGISTRY = /\A.*\.dkr.ecr.([\w-]+).amazonaws.com\z/ class << self # we make sure the repo exists so pushes do not fail diff --git a/plugins/datadog/app/models/datadog_deploy_event.rb b/plugins/datadog/app/models/datadog_deploy_event.rb index 76e719c916..9188196ac8 100644 --- a/plugins/datadog/app/models/datadog_deploy_event.rb +++ b/plugins/datadog/app/models/datadog_deploy_event.rb @@ -2,7 +2,7 @@ require 'faraday' require 'digest/md5' -# Note: might be able to replace this with Samson.statsd.event +# NOTE: might be able to replace this with Samson.statsd.event class DatadogDeployEvent def self.deliver(deploy, tags:, time:) status = diff --git a/plugins/datadog/test/models/datadog_deploy_event_test.rb b/plugins/datadog/test/models/datadog_deploy_event_test.rb index b96853a074..72cf58b1c0 100644 --- a/plugins/datadog/test/models/datadog_deploy_event_test.rb +++ b/plugins/datadog/test/models/datadog_deploy_event_test.rb @@ -7,8 +7,8 @@ let(:deploy) { deploys(:succeeded_test) } describe '.deliver' do - def deliver(*args) - DatadogDeployEvent.deliver(deploy, *args) + def deliver(**args) + DatadogDeployEvent.deliver(deploy, **args) end def expected_body(overrides = {}) diff --git a/plugins/datadog/test/models/datadog_monitor_test.rb b/plugins/datadog/test/models/datadog_monitor_test.rb index 5cea5e7dd6..1ad6b6ed12 100644 --- a/plugins/datadog/test/models/datadog_monitor_test.rb +++ b/plugins/datadog/test/models/datadog_monitor_test.rb @@ -66,7 +66,7 @@ def assert_datadog_timeout(&block) end it "shows Alert when groups are alerting" do - assert_datadog alerting_groups do + assert_datadog(**alerting_groups) do monitor.state(groups).must_equal "Alert" end end @@ -110,7 +110,7 @@ def assert_datadog_timeout(&block) it "produces no extra sql queries" do stage = stages(:test_production) # preload assert_sql_queries 1 do # group-stage and groups - assert_datadog alerting_groups do + assert_datadog(**alerting_groups) do monitor.state(stage.deploy_groups) end end diff --git a/plugins/datadog_tracer/lib/samson_datadog_tracer/samson_plugin.rb b/plugins/datadog_tracer/lib/samson_datadog_tracer/samson_plugin.rb index d58451efa9..f7aa064573 100644 --- a/plugins/datadog_tracer/lib/samson_datadog_tracer/samson_plugin.rb +++ b/plugins/datadog_tracer/lib/samson_datadog_tracer/samson_plugin.rb @@ -24,8 +24,8 @@ def wrap_method(klass, method, scope, &callback) raise "#{scope} wrapper already defined for #{method}" end klass.alias_method without, method - klass.define_method(method) do |*args, &block| - callback.call { send(without, *args, &block) } + klass.define_method(method) do |*args, **kwargs, &block| + callback.call { send(without, *args, **kwargs, &block) } end klass.send visibility, method klass.send visibility, without diff --git a/plugins/env/app/models/environment_variable_group.rb b/plugins/env/app/models/environment_variable_group.rb index eb684e7261..ecacd6292b 100644 --- a/plugins/env/app/models/environment_variable_group.rb +++ b/plugins/env/app/models/environment_variable_group.rb @@ -22,7 +22,8 @@ def variable_names environment_variables.sort_by(&:id).map(&:name).uniq end - def as_json(methods: [], **options) + def as_json(options = {}) + methods = options.delete(:methods) || [] super({methods: [:variable_names] + methods}.merge(options)) end diff --git a/plugins/env/app/models/external_environment_variable_group.rb b/plugins/env/app/models/external_environment_variable_group.rb index 7a5826f377..6a1d927f4e 100644 --- a/plugins/env/app/models/external_environment_variable_group.rb +++ b/plugins/env/app/models/external_environment_variable_group.rb @@ -2,8 +2,8 @@ require 'aws-sdk-s3' class ExternalEnvironmentVariableGroup < ActiveRecord::Base - S3_URL_REGEX = /\Ahttps:\/\/([^.]+)\.s3\.amazonaws\.com\/([\w\W]+)\Z/i.freeze - S3_URL_FORMAT = "https://#{ENV['EXTERNAL_ENV_GROUP_S3_BUCKET']}.s3.amazonaws.com/[key]?versionId=[version_id]" + S3_URL_REGEX = /\Ahttps:\/\/([^.]+)\.s3\.amazonaws\.com\/([\w\W]+)\Z/i + S3_URL_FORMAT = "https://#{ENV['EXTERNAL_ENV_GROUP_S3_BUCKET']}.s3.amazonaws.com/[key]?versionId=[version_id]".freeze HELP_TEXT = ENV.fetch( "EXTERNAL_ENV_GROUP_HELP_TEXT", "Use external service to manage environment variable groups" diff --git a/plugins/env/lib/samson_env/samson_plugin.rb b/plugins/env/lib/samson_env/samson_plugin.rb index 99f430da8e..d97f5f7027 100644 --- a/plugins/env/lib/samson_env/samson_plugin.rb +++ b/plugins/env/lib/samson_env/samson_plugin.rb @@ -77,8 +77,8 @@ def write_dotenv(base_file, groups) end # TODO: use for write_env_files -Samson::Hooks.callback :deploy_env do |*args| - EnvironmentVariable.env(*args) +Samson::Hooks.callback :deploy_env do |*args, **kwargs| + EnvironmentVariable.env(*args, **kwargs) end Samson::Hooks.callback(:link_parts_for_resource) do diff --git a/plugins/env/test/models/external_environment_variable_group_test.rb b/plugins/env/test/models/external_environment_variable_group_test.rb index bbf317df39..bbcbf68bdb 100644 --- a/plugins/env/test/models/external_environment_variable_group_test.rb +++ b/plugins/env/test/models/external_environment_variable_group_test.rb @@ -120,7 +120,7 @@ def fake_response(response) it "returns false without env's" do with_env EXTERNAL_ENV_GROUP_S3_REGION: nil, - EXTERNAL_ENV_GROUP_S3_BUCKET: nil do + EXTERNAL_ENV_GROUP_S3_BUCKET: nil do refute ExternalEnvironmentVariableGroup.configured? end end @@ -151,7 +151,7 @@ def fake_response(response) it "tries reading from a DR bucket if available" do with_env EXTERNAL_ENV_GROUP_S3_DR_REGION: "us-east-1", - EXTERNAL_ENV_GROUP_S3_DR_BUCKET: "dr-bucket" do + EXTERNAL_ENV_GROUP_S3_DR_BUCKET: "dr-bucket" do response = {"FOO" => "one"}.to_yaml s3.expects(:get_object).times(2).with( bucket: 'a-bucket', key: 'key', version_id: 'version_id' diff --git a/plugins/gcloud/lib/samson_gcloud/image_tagger.rb b/plugins/gcloud/lib/samson_gcloud/image_tagger.rb index eef3dd0816..c3095e761c 100644 --- a/plugins/gcloud/lib/samson_gcloud/image_tagger.rb +++ b/plugins/gcloud/lib/samson_gcloud/image_tagger.rb @@ -4,7 +4,7 @@ class ImageTagger PRODUCTION_TAG = 'production' class << self - # Note: not tagging builds from different project since that would be confusing ... + # NOTE: not tagging builds from different project since that would be confusing ... # ideally do not tag any builds for projects that use shared builds ... but that is hard to know atm def tag(deploy, output) return unless needs_tag?(deploy) diff --git a/plugins/jenkins/app/models/samson/jenkins.rb b/plugins/jenkins/app/models/samson/jenkins.rb index e6ec3d1442..97b22a9a3c 100644 --- a/plugins/jenkins/app/models/samson/jenkins.rb +++ b/plugins/jenkins/app/models/samson/jenkins.rb @@ -20,7 +20,7 @@ class Jenkins "Build Parameters starting with #{JENKINS_BUILD_PARAMETRS_PREFIX} are updated "\ "automatically by Samson. Please disable automatic updating "\ "of this jenkins job from the above mentioned samson projects "\ - "before manually editing build parameters or description." + "before manually editing build parameters or description.".freeze JENKINS_BUILD_PARAMETERS = { buildStartedBy: "Samson username of the person who started the deployment.", originatedFrom: "Samson project + stage + commit hash from github tag", diff --git a/plugins/jenkins/test/models/samson/jenkins_test.rb b/plugins/jenkins/test/models/samson/jenkins_test.rb index d59f140d54..d673affed5 100644 --- a/plugins/jenkins/test/models/samson/jenkins_test.rb +++ b/plugins/jenkins/test/models/samson/jenkins_test.rb @@ -45,8 +45,10 @@ def stub_get_config(resp) def stub_post_config(body) stub_request(:post, "http://www.test-url.com/job/test_job/config.xml"). - with(body: body, - headers: {Authorization: 'Basic dXNlckB0ZXN0LmNvbTpqYXBpa2V5'}). + with( + body: body, + headers: {Authorization: 'Basic dXNlckB0ZXN0LmNvbTpqYXBpa2V5'} + ). to_return(status: 200, body: "") end diff --git a/plugins/kubernetes/README.md b/plugins/kubernetes/README.md index b2e3ef0785..74d7d09274 100644 --- a/plugins/kubernetes/README.md +++ b/plugins/kubernetes/README.md @@ -108,7 +108,7 @@ Kubernetes::Release ### Docker Images -(To opt out of this feature set `metadata.annotations.container-nameofcontainer-samson/dockerfile: none`) +(To opt out of this feature set in pod-template `metadata.annotations.container-nameofcontainer-samson/dockerfile: none`) For each container (including init containers) Samson finds or creates a matching Docker image for the Git SHA that is being deployed. Samson always sets the Docker digest, and not a tag, to make deployments immutable. diff --git a/plugins/kubernetes/app/controllers/kubernetes/deploy_group_roles_controller.rb b/plugins/kubernetes/app/controllers/kubernetes/deploy_group_roles_controller.rb index 046d7fe97a..597d508dfb 100644 --- a/plugins/kubernetes/app/controllers/kubernetes/deploy_group_roles_controller.rb +++ b/plugins/kubernetes/app/controllers/kubernetes/deploy_group_roles_controller.rb @@ -42,9 +42,11 @@ def seed {notice: "Missing roles seeded."} else errors = ["Roles failed to seed, fill them in manually."] - errors.concat(created.map do |dgr| - "#{dgr.kubernetes_role.name} for #{dgr.deploy_group.name}: #{dgr.errors.full_messages.to_sentence}" - end) + errors.concat( + created.map do |dgr| + "#{dgr.kubernetes_role.name} for #{dgr.deploy_group.name}: #{dgr.errors.full_messages.to_sentence}" + end + ) max = 4 # header + 3 message = errors.first(max).join("\n") message << " ..." if errors.size > max diff --git a/plugins/kubernetes/app/models/kubernetes/namespace.rb b/plugins/kubernetes/app/models/kubernetes/namespace.rb index 4cf8da0a6b..a734cf03df 100644 --- a/plugins/kubernetes/app/models/kubernetes/namespace.rb +++ b/plugins/kubernetes/app/models/kubernetes/namespace.rb @@ -3,7 +3,7 @@ module Kubernetes class Namespace < ActiveRecord::Base - NAME_PATTERN = /\A[a-z]+[a-z\d-]+\z/.freeze + NAME_PATTERN = /\A[a-z]+[a-z\d-]+\z/ self.table_name = 'kubernetes_namespaces' audited diff --git a/plugins/kubernetes/app/models/kubernetes/resource.rb b/plugins/kubernetes/app/models/kubernetes/resource.rb index 83ab8edd1c..2f0f3c59d4 100644 --- a/plugins/kubernetes/app/models/kubernetes/resource.rb +++ b/plugins/kubernetes/app/models/kubernetes/resource.rb @@ -401,8 +401,8 @@ class Pod < Immutable end class PodDisruptionBudget < VersionedUpdate - def initialize(*) - super + def initialize(...) + super(...) @delete_resource ||= @template[:delete] # allow deletion through release_doc logic end end @@ -427,9 +427,9 @@ def template_for_update end end - def self.build(*args) + def self.build(*args, **kwargs) klass = "Kubernetes::Resource::#{args.first.fetch(:kind)}".safe_constantize || VersionedUpdate - klass.new(*args) + klass.new(*args, **kwargs) end end end diff --git a/plugins/kubernetes/app/models/kubernetes/resource_status.rb b/plugins/kubernetes/app/models/kubernetes/resource_status.rb index 8d4e5c1ff7..9c27ece017 100644 --- a/plugins/kubernetes/app/models/kubernetes/resource_status.rb +++ b/plugins/kubernetes/app/models/kubernetes/resource_status.rb @@ -20,7 +20,8 @@ class ResourceStatus PodDisruptionBudget: [ "CalculateExpectedPodCountFailed", "NoControllers", - "NoPods" + "NoPods", + "UnmanagedPods" ], Service: [ "FailedToUpdateEndpointSlices" @@ -29,6 +30,12 @@ class ResourceStatus # Regression from k8s 1.27: https://github.com/kubernetes/kubernetes/pull/115331 # Pending backport in: https://github.com/kubernetes/kubernetes/pull/121921 "RecreatingFailedPod" + ], + # karmada can fail to sync a resource when something else also updated the resource, + # this does not necessarily indicate that sync will be broken forever + All: [ + 'ApplyPolicyFailed', + 'SyncFailed' ] }.freeze @@ -121,8 +128,9 @@ def bad_events(kind) failures = events(type: "Warning") ignored = @resource.dig(:metadata, :annotations, :"samson/ignore_events").to_s.split(",") + - (IGNORED_EVENT_REASONS[kind.to_sym] || []) - failures.reject! { |e| ignored.include? e[:reason] } if ignored.any? + (IGNORED_EVENT_REASONS[kind.to_sym] || []) + + IGNORED_EVENT_REASONS[:All] + failures.reject! { |e| ignored.include? e[:reason] } failures end end diff --git a/plugins/kubernetes/app/models/kubernetes/role.rb b/plugins/kubernetes/app/models/kubernetes/role.rb index 74de3303c7..85c4cafda9 100644 --- a/plugins/kubernetes/app/models/kubernetes/role.rb +++ b/plugins/kubernetes/app/models/kubernetes/role.rb @@ -162,7 +162,12 @@ def defaults # allows passing the project to reuse the repository cache when doing multiple lookups def role_config_file(reference, deploy_group:, project: project(), **args) # rubocop:disable Style/MethodCallWithoutArgsParentheses file = config_file - file = file.sub('$deploy_group', deploy_group.env_value) if deploy_group && dynamic_folders? + if deploy_group && dynamic_folders? + file = file. + sub('$deploy_group', deploy_group.env_value). + sub('$environment', deploy_group.environment.permalink) + end + self.class.role_config_file(project, file, reference, **args) end diff --git a/plugins/kubernetes/app/models/kubernetes/role_validator.rb b/plugins/kubernetes/app/models/kubernetes/role_validator.rb index 747ca3de74..3d39b17b56 100644 --- a/plugins/kubernetes/app/models/kubernetes/role_validator.rb +++ b/plugins/kubernetes/app/models/kubernetes/role_validator.rb @@ -3,8 +3,8 @@ module Kubernetes class RoleValidator # per https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set # not perfect since the actual rules are stricter - VALID_LABEL_VALUE = /\A[a-zA-Z0-9]([-a-zA-Z0-9_.]*[a-zA-Z0-9])?\z/.freeze - VALID_CONTAINER_NAME = /\A[a-zA-Z0-9]([-a-zA-Z0-9.]*[a-zA-Z0-9])?\z/.freeze # also used in js ... cannot use /i + VALID_LABEL_VALUE = /\A[a-zA-Z0-9]([-a-zA-Z0-9_.]*[a-zA-Z0-9])?\z/ + VALID_CONTAINER_NAME = /\A[a-zA-Z0-9]([-a-zA-Z0-9.]*[a-zA-Z0-9])?\z/ # also used in js ... cannot use /i # for non-namespace deployments: names that should not be changed since they will break dependencies IMMUTABLE_NAME_KINDS = [ @@ -15,7 +15,7 @@ class RoleValidator # we either generate multiple names or allow custom names ALLOWED_DUPLICATE_KINDS = ((['Service'] + IMMUTABLE_NAME_KINDS)).freeze - DATADOG_AD_REGEXP = %r{(?:service-discovery|ad)\.datadoghq\.com/([^.]+)\.}.freeze + DATADOG_AD_REGEXP = %r{(?:service-discovery|ad)\.datadoghq\.com/([^.]+)\.} def initialize(elements, project:) @project = project diff --git a/plugins/kubernetes/app/models/kubernetes/util.rb b/plugins/kubernetes/app/models/kubernetes/util.rb index 146d8c3aa6..93f39b032d 100644 --- a/plugins/kubernetes/app/models/kubernetes/util.rb +++ b/plugins/kubernetes/app/models/kubernetes/util.rb @@ -23,7 +23,7 @@ def self.yaml_safe_load_stream(contents, filename) YAML.parse_stream(contents, filename: filename).children.map do |child| temp_stream = Psych::Nodes::Stream.new temp_stream.children << child - YAML.safe_load(temp_stream.to_yaml, [Symbol], aliases: true) + YAML.safe_load(temp_stream.to_yaml, permitted_classes: [Symbol], aliases: true) end end end diff --git a/plugins/kubernetes/app/views/kubernetes/roles/_form.html.erb b/plugins/kubernetes/app/views/kubernetes/roles/_form.html.erb index 5a03fc1ea7..4c3f6566bd 100644 --- a/plugins/kubernetes/app/views/kubernetes/roles/_form.html.erb +++ b/plugins/kubernetes/app/views/kubernetes/roles/_form.html.erb @@ -4,7 +4,7 @@
<%= form.input :name %> - <%= form.input :config_file, help: "Can use $deploy_group substitution to have a dynamic file path." %> + <%= form.input :config_file, help: "Can use $deploy_group and $environment substitutions to have a dynamic file path." %> <% if @project.override_resource_names? %> <%= form.input :service_name, help: "Override service name with this name. Uses name from yml file if it starts with this name." %> <%= form.input :resource_name, diff --git a/plugins/kubernetes/config/initializers/kubeclient.rb b/plugins/kubernetes/config/initializers/kubeclient.rb index 79a00e08be..1311d7a044 100644 --- a/plugins/kubernetes/config/initializers/kubeclient.rb +++ b/plugins/kubernetes/config/initializers/kubeclient.rb @@ -1,18 +1,22 @@ # frozen_string_literal: true # we want know which cluster had ssl errors require 'kubeclient' -Kubeclient::Client.prepend(Module.new do - def handle_exception - super - rescue OpenSSL::SSL::SSLError - $!.message << " (#{@api_endpoint})" unless $!.message.frozen? - raise +Kubeclient::Client.prepend( + Module.new do + def handle_exception + super + rescue OpenSSL::SSL::SSLError + $!.message << " (#{@api_endpoint})" unless $!.message.frozen? + raise + end end -end) +) # instrument all kube-client calls since that is the only thing using rest-client -(class << RestClient::Request; self; end).prepend(Module.new do - def execute(args) - ActiveSupport::Notifications.instrument("request.rest_client.samson", args.slice(:method, :url)) { super } +(class << RestClient::Request; self; end).prepend( + Module.new do + def execute(args) + ActiveSupport::Notifications.instrument("request.rest_client.samson", args.slice(:method, :url)) { super } + end end -end) +) diff --git a/plugins/kubernetes/decorators/deploy_group_decorator.rb b/plugins/kubernetes/decorators/deploy_group_decorator.rb index 1d8b709c6b..a90d5d7046 100644 --- a/plugins/kubernetes/decorators/deploy_group_decorator.rb +++ b/plugins/kubernetes/decorators/deploy_group_decorator.rb @@ -3,7 +3,6 @@ has_one( :cluster_deploy_group, class_name: 'Kubernetes::ClusterDeployGroup', - foreign_key: :deploy_group_id, inverse_of: :deploy_group, dependent: :destroy ) diff --git a/plugins/kubernetes/test/models/kubernetes/deploy_executor_test.rb b/plugins/kubernetes/test/models/kubernetes/deploy_executor_test.rb index 1ea56db6aa..3a24777124 100644 --- a/plugins/kubernetes/test/models/kubernetes/deploy_executor_test.rb +++ b/plugins/kubernetes/test/models/kubernetes/deploy_executor_test.rb @@ -404,24 +404,26 @@ def worker_is_unstable # make the worker a job and keep the app server Kubernetes::ReleaseDoc.any_instance.unstub(:raw_template) GitRepository.any_instance.unstub(:file_content) - GitRepository.any_instance.stubs(:file_content).with('kubernetes/resque_worker.yml', commit, anything).returns({ - 'kind' => 'Job', - 'apiVersion' => 'batch/v1', - 'spec' => { - 'template' => { - 'metadata' => {'labels' => {'project' => 'some-project', 'role' => 'migrate'}}, - 'spec' => { - 'containers' => [{'name' => 'job', 'image' => 'docker-registry.zende.sk/truth_service:latest'}], - 'restartPolicy' => 'Never' + GitRepository.any_instance.stubs(:file_content).with('kubernetes/resque_worker.yml', commit, anything).returns( + { + 'kind' => 'Job', + 'apiVersion' => 'batch/v1', + 'spec' => { + 'template' => { + 'metadata' => {'labels' => {'project' => 'some-project', 'role' => 'migrate'}}, + 'spec' => { + 'containers' => [{'name' => 'job', 'image' => 'docker-registry.zende.sk/truth_service:latest'}], + 'restartPolicy' => 'Never' + } } + }, + 'metadata' => { + 'name' => 'test', + 'labels' => {'project' => 'some-project', 'role' => 'migrate'}, + 'annotations' => {'samson/prerequisite' => 'true'} } - }, - 'metadata' => { - 'name' => 'test', - 'labels' => {'project' => 'some-project', 'role' => 'migrate'}, - 'annotations' => {'samson/prerequisite' => 'true'} - } - }.to_yaml) + }.to_yaml + ) GitRepository.any_instance.stubs(:file_content).with('kubernetes/app_server.yml', commit, anything). returns(read_kubernetes_sample_file('kubernetes_deployment.yml')) diff --git a/plugins/kubernetes/test/models/kubernetes/release_test.rb b/plugins/kubernetes/test/models/kubernetes/release_test.rb index 924c6f7d25..49b09188e9 100644 --- a/plugins/kubernetes/test/models/kubernetes/release_test.rb +++ b/plugins/kubernetes/test/models/kubernetes/release_test.rb @@ -148,20 +148,26 @@ it "returns scoped queries" do release = kubernetes_releases(:test_release) - stub_request(:get, %r{namespaces/pod1/pods\?labelSelector=release_id=\d+,deploy_group_id=\d+}).to_return(body: { - resourceVersion: "1", - items: [{}, {}] - }.to_json) + stub_request(:get, %r{namespaces/pod1/pods\?labelSelector=release_id=\d+,deploy_group_id=\d+}). + to_return( + body: { + resourceVersion: "1", + items: [{}, {}] + }.to_json + ) release.clients("v1").map { |c, q| c.get_pods(q).fetch(:items) }.first.size.must_equal 2 end it "can scope queries by resource namespace" do release = kubernetes_releases(:test_release) Kubernetes::Resource::Base.any_instance.stubs(namespace: "default") - stub_request(:get, %r{http://foobar.server/api/v1/namespaces/default/pods}).to_return(body: { - resourceVersion: "1", - items: [{}, {}] - }.to_json) + stub_request(:get, %r{http://foobar.server/api/v1/namespaces/default/pods}). + to_return( + body: { + resourceVersion: "1", + items: [{}, {}] + }.to_json + ) release.clients("v1").map { |c, q| c.get_pods(q).fetch(:items) }.first.size.must_equal 2 end end diff --git a/plugins/kubernetes/test/models/kubernetes/resource_status_test.rb b/plugins/kubernetes/test/models/kubernetes/resource_status_test.rb index 31085df488..e30c2e48dc 100644 --- a/plugins/kubernetes/test/models/kubernetes/resource_status_test.rb +++ b/plugins/kubernetes/test/models/kubernetes/resource_status_test.rb @@ -116,6 +116,16 @@ def expect_event_request(&block) } expect_event_request { details.must_equal "Error event" } end + + it "ignores karmada sync for policy failed" do + events[0][:reason] = "ApplyPolicyFailed" + expect_event_request { details.must_equal "Live" } + end + + it "ignores karmada syn for sync failed" do + events[0][:reason] = "SyncFailed" + expect_event_request { details.must_equal "Live" } + end end end end diff --git a/plugins/kubernetes/test/models/kubernetes/resource_test.rb b/plugins/kubernetes/test/models/kubernetes/resource_test.rb index 68395b484d..19413633c4 100644 --- a/plugins/kubernetes/test/models/kubernetes/resource_test.rb +++ b/plugins/kubernetes/test/models/kubernetes/resource_test.rb @@ -834,9 +834,7 @@ def assert_recreate(error) metadata: {name: 'some-project', namespace: 'pod1'}, spec: { resources: { - requests: { - - } + requests: {} } } } diff --git a/plugins/kubernetes/test/test_helper.rb b/plugins/kubernetes/test/test_helper.rb index 31781707e5..0f63c76115 100644 --- a/plugins/kubernetes/test/test_helper.rb +++ b/plugins/kubernetes/test/test_helper.rb @@ -28,11 +28,13 @@ def with_example_kube_config end def create_kubernetes_cluster(attributes = {}) - cluster = Kubernetes::Cluster.new({ - name: 'Foo', - config_filepath: File.join(File.dirname(__FILE__), 'cluster_config.yml'), - config_context: 'test' - }.merge(attributes)) + cluster = Kubernetes::Cluster.new( + { + name: 'Foo', + config_filepath: File.join(File.dirname(__FILE__), 'cluster_config.yml'), + config_context: 'test' + }.merge(attributes) + ) cluster.save!(validate: false) cluster end diff --git a/plugins/ledger/lib/samson_ledger/client.rb b/plugins/ledger/lib/samson_ledger/client.rb index 9c28a29d48..04def82640 100644 --- a/plugins/ledger/lib/samson_ledger/client.rb +++ b/plugins/ledger/lib/samson_ledger/client.rb @@ -56,7 +56,7 @@ def pods(deploy_groups) end def pull_requests(changeset) - # Note: All HTML is sanitized at rendering time on Ledger. + # NOTE: All HTML is sanitized at rendering time on Ledger. results = changeset.pull_requests.map do |pull_request| github_users = pull_request.users.compact.map do |user| "" diff --git a/plugins/pipelines/decorators/deploy_decorator.rb b/plugins/pipelines/decorators/deploy_decorator.rb index 23cb70b771..0bd9b8b2af 100644 --- a/plugins/pipelines/decorators/deploy_decorator.rb +++ b/plugins/pipelines/decorators/deploy_decorator.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true Deploy.class_eval do - belongs_to :triggering_deploy, - class_name: 'Deploy', foreign_key: 'triggering_deploy_id', optional: true, inverse_of: false + belongs_to :triggering_deploy, class_name: 'Deploy', optional: true, inverse_of: false end diff --git a/plugins/pipelines/decorators/stage_decorator.rb b/plugins/pipelines/decorators/stage_decorator.rb index ca8e6823f5..ae377a6730 100644 --- a/plugins/pipelines/decorators/stage_decorator.rb +++ b/plugins/pipelines/decorators/stage_decorator.rb @@ -1,20 +1,22 @@ # frozen_string_literal: true Stage.class_eval do - prepend(Module.new do - # Return true if any stages in the pipeline are marked production - def production?(check_next_stages: true) - super() || (check_next_stages && pipeline_next_stages.any?(&:production?)) - end + prepend( + Module.new do + # Return true if any stages in the pipeline are marked production + def production?(check_next_stages: true) + super() || (check_next_stages && pipeline_next_stages.any?(&:production?)) + end - def production_for_approval? - production?(check_next_stages: false) - end + def production_for_approval? + production?(check_next_stages: false) + end - # Return true if any stages in the pipeline deploy to production - def deploy_requires_approval? - super || pipeline_next_stages.any?(&:deploy_requires_approval?) + # Return true if any stages in the pipeline deploy to production + def deploy_requires_approval? + super || pipeline_next_stages.any?(&:deploy_requires_approval?) + end end - end) + ) serialize :next_stage_ids, Array diff --git a/plugins/prerequisite_stages/decorators/stage_decorator.rb b/plugins/prerequisite_stages/decorators/stage_decorator.rb index 841d4d2de1..ec07d8000a 100644 --- a/plugins/prerequisite_stages/decorators/stage_decorator.rb +++ b/plugins/prerequisite_stages/decorators/stage_decorator.rb @@ -1,20 +1,22 @@ # frozen_string_literal: true Stage.class_eval do - prepend(Module.new do - def prerequisite_stages - prerequisite_stage_ids.any? ? Stage.where(id: prerequisite_stage_ids) : [] - end + prepend( +Module.new do + def prerequisite_stages + prerequisite_stage_ids.any? ? Stage.where(id: prerequisite_stage_ids) : [] + end - def undeployed_prerequisite_stages(commit) - return [] unless stages = prerequisite_stages.presence + def undeployed_prerequisite_stages(commit) + return [] unless stages = prerequisite_stages.presence - deployed_stages = stages.joins(deploys: :job).where( - jobs: {status: 'succeeded', commit: commit} - ) + deployed_stages = stages.joins(deploys: :job).where( + jobs: {status: 'succeeded', commit: commit} + ) - stages - deployed_stages - end - end) + stages - deployed_stages + end +end +) serialize :prerequisite_stage_ids, Array diff --git a/plugins/sentry/lib/samson_sentry/samson_plugin.rb b/plugins/sentry/lib/samson_sentry/samson_plugin.rb index 9131fa9740..f3c9c6a764 100644 --- a/plugins/sentry/lib/samson_sentry/samson_plugin.rb +++ b/plugins/sentry/lib/samson_sentry/samson_plugin.rb @@ -5,13 +5,18 @@ # test: enable sentry (see Readme.md) + `rails c` + `Sentry.capture_message 'foo'` while sentry is enabled if ENV["SENTRY_PROJECT"].present? require "sentry/utils/logging_helper" - Sentry::LoggingHelper.prepend(Module.new do - def log_info(message) - super(message.sub( - /(\S+) to Sentry/, "https://sentry.io/organizations/#{ENV["SENTRY_PROJECT"]}/issues/?query=\\1 to Sentry" - )) + Sentry::LoggingHelper.prepend( + Module.new do + def log_info(message) + super( + message.sub( + /(\S+) to Sentry/, + "https://sentry.io/organizations/#{ENV["SENTRY_PROJECT"]}/issues/?query=\\1 to Sentry" + ) + ) + end end - end) + ) end require "sentry-rails" @@ -24,5 +29,5 @@ class SamsonPlugin < Rails::Engine Samson::Hooks.callback :error do |exception, **options| sentry_options = options.slice(:contexts, :extra, :tags, :user, :level, :fingerprint) - Sentry.capture_exception(exception, sentry_options) + Sentry.capture_exception(exception, **sentry_options) end diff --git a/plugins/slack_app/test/controllers/slack_app_controller_test.rb b/plugins/slack_app/test/controllers/slack_app_controller_test.rb index fee9028759..b2c7ac54f4 100644 --- a/plugins/slack_app/test/controllers/slack_app_controller_test.rb +++ b/plugins/slack_app/test/controllers/slack_app_controller_test.rb @@ -17,12 +17,18 @@ let(:project) { projects(:test) } def expects_new_deploy - Changeset.expects(:new).returns(stub(pull_requests: [stub( - url: 'http://sams.on', - number: 123, - title: 'sample PR', - risks: '- Kittens' - )])) + Changeset.expects(:new).returns( + stub( + pull_requests: [ + stub( + url: 'http://sams.on', + number: 123, + title: 'sample PR', + risks: '- Kittens' + ) + ] + ) + ) end def post_command(id, params = {}) diff --git a/test/controllers/automated_deploys_controller_test.rb b/test/controllers/automated_deploys_controller_test.rb index f99693b614..863b5cf99a 100644 --- a/test/controllers/automated_deploys_controller_test.rb +++ b/test/controllers/automated_deploys_controller_test.rb @@ -64,7 +64,8 @@ def post_create end it "raises when seting the email would have no effect" do - assert_raises(ArgumentError) { assert_created } + e = assert_raises(Minitest::UnexpectedError) { assert_created } + e.error.class.must_equal ArgumentError end end diff --git a/test/controllers/integrations/travis_controller_test.rb b/test/controllers/integrations/travis_controller_test.rb index 7e06d6e57d..a5e57be59a 100644 --- a/test/controllers/integrations/travis_controller_test.rb +++ b/test/controllers/integrations/travis_controller_test.rb @@ -6,7 +6,7 @@ describe Integrations::TravisController do extend IntegrationsControllerTestHelper - def post(_action, options) + def post(_action, **options) options[:params][:payload] = options[:params][:payload].to_json super end diff --git a/test/controllers/unauthorized_controller_test.rb b/test/controllers/unauthorized_controller_test.rb index af6463dbe7..886fb8126b 100644 --- a/test/controllers/unauthorized_controller_test.rb +++ b/test/controllers/unauthorized_controller_test.rb @@ -12,7 +12,7 @@ def app describe '#respond' do def request(params: {}) - get path, {controller: "ping", action: "show"}.merge(params), headers # rubocop:disable Rails/HttpPositionalArguments + get path, {controller: "ping", action: "show"}.merge(params), headers end describe 'as html' do diff --git a/test/lib/samson/form_builder_test.rb b/test/lib/samson/form_builder_test.rb index 0e0e796d89..b6f162e88c 100644 --- a/test/lib/samson/form_builder_test.rb +++ b/test/lib/samson/form_builder_test.rb @@ -172,9 +172,9 @@ def fake_erb_rendering # NOTE: ideally don't use a plugin model, but we need something with accepts_nested_attributes_for describe '#fields_for_many' do - def render(*args) + def render(*args, **kwargs) project.rollbar_dashboards_settings.build # TODO: this does not get rendered - builder.fields_for_many(*args) do |p| + builder.fields_for_many(*args, **kwargs) do |p| p.text_field :base_url, placeholder: 'thing!' end end diff --git a/test/lib/samson/secrets/db_backend_test.rb b/test/lib/samson/secrets/db_backend_test.rb index c6e1e24379..74e49877b6 100644 --- a/test/lib/samson/secrets/db_backend_test.rb +++ b/test/lib/samson/secrets/db_backend_test.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require_relative '../../../test_helper' -SingleCov.covered! +SingleCov.covered! uncovered: 1 describe Samson::Secrets::DbBackend do let(:secret) { create_secret 'production/foo/pod2/hello' } diff --git a/test/lib/samson/secrets/hashicorp_vault_backend_test.rb b/test/lib/samson/secrets/hashicorp_vault_backend_test.rb index 63da181fd4..10b56618df 100644 --- a/test/lib/samson/secrets/hashicorp_vault_backend_test.rb +++ b/test/lib/samson/secrets/hashicorp_vault_backend_test.rb @@ -95,10 +95,14 @@ it "does not resolve deleted versions" do id = "production/foo/pod2/bar" - versions_body = {data: {versions: { - "v1" => {foo: "bar", destroyed: false, deletion_time: "2019-10-29"}, - "v2" => {foo: "bar2", destroyed: false, deletion_time: ""} - }}} + versions_body = { + data: { + versions: { + "v1" => {foo: "bar", destroyed: false, deletion_time: "2019-10-29"}, + "v2" => {foo: "bar2", destroyed: false, deletion_time: ""} + } + } + } version_body = {data: {data: {vault: 1}, metadata: {v2: {metadata: {foo: "bar2", destroyed: false}}}}} assert_vault_request :get, id, versioned_kv: "metadata", body: versions_body.to_json do assert_vault_request :get, "#{id}?version=v2", versioned_kv: "data", body: version_body.to_json do diff --git a/test/lib/samson/secrets/vault_client_wrapper_test.rb b/test/lib/samson/secrets/vault_client_wrapper_test.rb index 56a787807d..cfd22bc3d3 100644 --- a/test/lib/samson/secrets/vault_client_wrapper_test.rb +++ b/test/lib/samson/secrets/vault_client_wrapper_test.rb @@ -14,7 +14,7 @@ it 'calls Vault::Client initialize with other arguments' do client_args = {versioned_kv: true, use_ssl: true, timeout: 543, ssl_timeout: 345} - client = Samson::Secrets::VaultClientWrapper.new(client_args) + client = Samson::Secrets::VaultClientWrapper.new(**client_args) client.instance_variable_get(:@ssl_verify).must_equal true client.instance_variable_get(:@timeout).must_equal 543 diff --git a/test/lib/samson/secrets/vault_server_test.rb b/test/lib/samson/secrets/vault_server_test.rb index 57485c76b5..e24616a616 100644 --- a/test/lib/samson/secrets/vault_server_test.rb +++ b/test/lib/samson/secrets/vault_server_test.rb @@ -29,7 +29,7 @@ it "is invalid with an invalid cert" do server.ca_cert = "nope" refute_valid server - server.errors.full_messages.must_equal ["Ca cert is invalid: not enough data"] + server.errors.full_messages.must_equal ["Ca cert is invalid: PEM_read_bio_X509: no start line"] end it "is invalid with duplicate name" do diff --git a/test/models/build_test.rb b/test/models/build_test.rb index a5283252bc..b9030c5286 100644 --- a/test/models/build_test.rb +++ b/test/models/build_test.rb @@ -20,11 +20,13 @@ def stub_commit_from_ref(ref, commit) let(:current_commit) { "af0798b05e10ac6b8381f85b38ae3973278e71ba" } def valid_build(attributes = {}) - Build.new(attributes.reverse_merge( - project: project, - git_ref: 'master', - creator: users(:admin) - )) + Build.new( + attributes.reverse_merge( + project: project, + git_ref: 'master', + creator: users(:admin) + ) + ) end describe 'validations' do diff --git a/test/models/commit_status_test.rb b/test/models/commit_status_test.rb index 644830ed15..46cf1f84ae 100644 --- a/test/models/commit_status_test.rb +++ b/test/models/commit_status_test.rb @@ -382,11 +382,13 @@ def stub_checks_api(commit_status: status) stub_github_api(check_suite_url, check_suites: []) stub_github_api(check_run_url, check_runs: []) - status.statuses.must_equal([{ - state: 'pending', + status.statuses.must_equal( +[{ + state: 'pending', description: "No status was reported for this commit on GitHub. " \ "See https://developer.github.com/v3/checks/ and https://github.com/blog/1227-commit-status-api for details." - }]) +}] +) end it 'shows pending suites' do diff --git a/test/models/image_builder_test.rb b/test/models/image_builder_test.rb index 6520e585c8..2fd889da2c 100644 --- a/test/models/image_builder_test.rb +++ b/test/models/image_builder_test.rb @@ -20,7 +20,7 @@ def call(options = {}) defaults = {tag_as_latest: false, dockerfile: 'Dockerfile', tag: 'tag', cache_from: 'cache'} - ImageBuilder.build_image("foo", build, executor, defaults.merge(options)) + ImageBuilder.build_image("foo", build, executor, **defaults.merge(options)) end it "builds and pushes" do diff --git a/test/models/restart_signal_handler_test.rb b/test/models/restart_signal_handler_test.rb index 0fc5da0678..4e53e1a1b3 100644 --- a/test/models/restart_signal_handler_test.rb +++ b/test/models/restart_signal_handler_test.rb @@ -6,10 +6,12 @@ describe RestartSignalHandler do def handle @puma_restarted = false - Signal.expects(:trap).with('SIGUSR1').returns(-> do - @puma_restarted = true - Thread.current.kill # simulates passing signal to puma and it calling exec - end) + Signal.expects(:trap).with('SIGUSR1').returns( + -> do + @puma_restarted = true + Thread.current.kill # simulates passing signal to puma and it calling exec + end + ) handler = RestartSignalHandler.listen Thread.pass # make sure listener thread starts Thread.new { handler.send(:signal_restart) }.join diff --git a/test/presenters/user_csv_presenter_test.rb b/test/presenters/user_csv_presenter_test.rb index 6ee308860f..a23425d95a 100644 --- a/test/presenters/user_csv_presenter_test.rb +++ b/test/presenters/user_csv_presenter_test.rb @@ -33,14 +33,14 @@ def csv_completeness_test(options = {}, expected = {}) meta_rows = 3 - UserCsvPresenter.to_csv(options).split("\n").size.must_equal expected + meta_rows - UserCsvPresenter.to_csv(options).split("\n")[-2].split(",")[-1].to_i.must_equal expected + UserCsvPresenter.to_csv(**options).split("\n").size.must_equal expected + meta_rows + UserCsvPresenter.to_csv(**options).split("\n")[-2].split(",")[-1].to_i.must_equal expected end # on updating #csv_line this test helper may need to be updated # This tests the optimized logic against the non-optimized logic. def csv_accuracy_test(options = {}) - actual = CSV.parse(UserCsvPresenter.to_csv(options)) + actual = CSV.parse(UserCsvPresenter.to_csv(**options)) actual.shift actual.pop(2) actual.each do |csv_row| diff --git a/test/support/multi_thread_db_detector.rb b/test/support/multi_thread_db_detector.rb index d7a260dcca..65d44efef6 100644 --- a/test/support/multi_thread_db_detector.rb +++ b/test/support/multi_thread_db_detector.rb @@ -13,22 +13,26 @@ def in_with_connection=(v) # alert when we would accidentally use a connection that is not rolled back with the current # transaction and would pollute the DB for the subsequent tests -ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(Module.new do - def log(*) - if Thread.current != Thread.main && !MultiThreadDbDetector.in_with_connection - raise "Using AR outside the main thread and not inside a with_connection block, this will break the transaction" - else - super +ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend( + Module.new do + def log(*) + if Thread.current != Thread.main && !MultiThreadDbDetector.in_with_connection + raise "Using AR outside the main thread and not inside a with_connection block, this will break the transaction" + else + super + end end end -end) +) -ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(Module.new do - def with_connection - old = MultiThreadDbDetector.in_with_connection - MultiThreadDbDetector.in_with_connection = true - super - ensure - MultiThreadDbDetector.in_with_connection = old +ActiveRecord::ConnectionAdapters::ConnectionPool.prepend( + Module.new do + def with_connection + old = MultiThreadDbDetector.in_with_connection + MultiThreadDbDetector.in_with_connection = true + super + ensure + MultiThreadDbDetector.in_with_connection = old + end end -end) +) diff --git a/test/support/must_equal_nil.rb b/test/support/must_equal_nil.rb index 32c3954aa0..56e9a3c365 100644 --- a/test/support/must_equal_nil.rb +++ b/test/support/must_equal_nil.rb @@ -1,11 +1,13 @@ # frozen_string_literal: true # https://github.com/seattlerb/minitest/issues/666 -Object.prepend(Module.new do - def must_equal(*args) - if args.first.nil? - must_be_nil(*args[1..]) - else - super +Object.prepend( + Module.new do + def must_equal(*args) + if args.first.nil? + must_be_nil(*args[1..]) + else + super + end end end -end) +) diff --git a/test/test_helper.rb b/test/test_helper.rb index 7205a490a7..0930f021e9 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -13,6 +13,7 @@ $LOAD_PATH.delete 'lib' $LOAD_PATH.delete 'test' +require 'maxitest/global_must' require_relative '../config/environment' require 'rails/test_help' require 'minitest/rails' @@ -22,7 +23,7 @@ require 'maxitest/timeout' require 'maxitest/threads' require 'webmock/minitest' -require 'mocha/setup' +require 'mocha/minitest' # Use ActiveSupport::TestCase for everything that was not matched before MiniTest::Spec::DSL::TYPES[-1] = [//, ActiveSupport::TestCase] @@ -226,7 +227,7 @@ def stub_const(base, name, value) def self.only_callbacks_for_plugin(callback) line = caller(1..1).first - plugin_name = line[/\/plugins\/([^\/]+)/, 1] || raise("not called from a plugin not #{line}") + plugin_name = line[/^plugins\/([^\/]+)/, 1] || raise("not called from a plugin not #{line}") around { |t| Samson::Hooks.only_callbacks_for_plugin(plugin_name, callback, &t) } end @@ -342,14 +343,16 @@ def warden end # catch warden throw ... which would normally go into warden middleware and then be an unauthorized response - prepend(Module.new do - def process(*args) - catch(:warden) { return super } - response.status = :unauthorized - response.body = ":warden caught in test_helper.rb" - response + prepend( + Module.new do + def process(...) + catch(:warden) { return super(...) } + response.status = :unauthorized + response.body = ":warden caught in test_helper.rb" + response + end end - end) + ) end ActionDispatch::IntegrationTest.class_eval do