1# frozen_string_literal: true 2 3module Tooling 4 module Danger 5 module ProjectHelper 6 LOCAL_RULES ||= %w[ 7 changelog 8 ci_config 9 database 10 documentation 11 duplicate_yarn_dependencies 12 eslint 13 gitaly 14 pajamas 15 pipeline 16 prettier 17 product_intelligence 18 utility_css 19 vue_shared_documentation 20 ].freeze 21 22 CI_ONLY_RULES ||= %w[ 23 ce_ee_vue_templates 24 ci_templates 25 datateam 26 feature_flag 27 roulette 28 sidekiq_queues 29 specialization_labels 30 specs 31 z_metadata 32 ].freeze 33 34 MESSAGE_PREFIX = '==>' 35 36 # First-match win, so be sure to put more specific regex at the top... 37 CATEGORIES = { 38 [%r{usage_data\.rb}, %r{^(\+|-).*\s+(count|distinct_count|estimate_batch_distinct_count)\(.*\)(.*)$}] => [:database, :backend, :product_intelligence], 39 40 %r{\A((ee|jh)/)?config/feature_flags/} => :feature_flag, 41 42 %r{doc/api/usage_data.md} => [:product_intelligence], 43 44 %r{\Adoc/.*(\.(md|png|gif|jpg|yml))\z} => :docs, 45 %r{\A(CONTRIBUTING|LICENSE|MAINTENANCE|PHILOSOPHY|PROCESS|README)(\.md)?\z} => :docs, 46 %r{\Adata/whats_new/} => :docs, 47 48 %r{\A((ee|jh)/)?app/finders/(.+/)?integrations/} => [:integrations_be, :database, :backend], 49 [%r{\A((ee|jh)/)?db/(geo/)?(migrate|post_migrate)/}, %r{(:integrations|:\w+_tracker_data)\b}] => [:integrations_be, :database, :migration], 50 [%r{\A((ee|jh)/)?(app|lib)/.+\.rb}, %r{\b(Integrations::|\.execute_(integrations|hooks))\b}] => [:integrations_be, :backend], 51 %r{\A( 52 ((ee|jh)/)?app/((?!.*clusters)(?!.*alert_management)(?!.*views)(?!.*assets).+/)?integration.+ | 53 ((ee|jh)/)?app/((?!.*search).+/)?project_service.+ | 54 ((ee|jh)/)?app/(models|helpers|workers|services|controllers)/(.+/)?(jira_connect.+|.*hook.+) | 55 ((ee|jh)/)?app/controllers/(.+/)?oauth/jira/.+ | 56 ((ee|jh)/)?app/services/(.+/)?jira.+ | 57 ((ee|jh)/)?app/workers/(.+/)?(propagate_integration.+|irker_worker\.rb) | 58 ((ee|jh)/)?lib/(.+/)?(atlassian|data_builder|hook_data)/.+ | 59 ((ee|jh)/)?lib/(.+/)?.*integration.+ | 60 ((ee|jh)/)?lib/(.+/)?api/v3/github\.rb | 61 ((ee|jh)/)?lib/(.+/)?api/github/entities\.rb 62 )\z}x => [:integrations_be, :backend], 63 64 %r{\A( 65 ((ee|jh)/)?app/(views|assets)/((?!.*clusters)(?!.*alerts_settings).+/)?integration.+ | 66 ((ee|jh)/)?app/(views|assets)/(.+/)?jira_connect.+ | 67 ((ee|jh)/)?app/(views|assets)/((?!.*filtered_search).+/)?hooks?.+ 68 )\z}x => [:integrations_fe, :frontend], 69 70 %r{\A( 71 app/assets/javascripts/tracking/.*\.js | 72 spec/frontend/tracking/.*\.js | 73 spec/frontend/tracking_spec\.js 74 )\z}x => [:frontend, :product_intelligence], 75 %r{\A((ee|jh)/)?app/(assets|views)/} => :frontend, 76 %r{\A((ee|jh)/)?public/} => :frontend, 77 %r{\A((ee|jh)/)?spec/(javascripts|frontend|frontend_integration)/} => :frontend, 78 %r{\A((ee|jh)/)?vendor/assets/} => :frontend, 79 %r{\A((ee|jh)/)?scripts/frontend/} => :frontend, 80 %r{(\A|/)( 81 \.babelrc | 82 \.browserslistrc | 83 \.eslintignore | 84 \.eslintrc(\.yml)? | 85 \.nvmrc | 86 \.prettierignore | 87 \.prettierrc | 88 \.stylelintrc | 89 \.haml-lint.yml | 90 \.haml-lint_todo.yml | 91 babel\.config\.js | 92 jest\.config\.js | 93 package\.json | 94 yarn\.lock | 95 config/.+\.js 96 )\z}x => :frontend, 97 98 %r{(\A|/)( 99 \.gitlab/ci/frontend\.gitlab-ci\.yml 100 )\z}x => %i[frontend tooling], 101 102 %r{\A((ee|jh)/)?db/(geo/)?(migrate|post_migrate)/} => [:database, :migration], 103 %r{\A((ee|jh)/)?db/(?!fixtures)[^/]+} => [:database], 104 %r{\A((ee|jh)/)?lib/gitlab/(database|background_migration|sql|github_import)(/|\.rb)} => [:database, :backend], 105 %r{\A(app/services/authorized_project_update/find_records_due_for_refresh_service)(/|\.rb)} => [:database, :backend], 106 %r{\A(app/models/project_authorization|app/services/users/refresh_authorized_projects_service)(/|\.rb)} => [:database, :backend], 107 %r{\A((ee|jh)/)?app/finders/} => [:database, :backend], 108 %r{\Arubocop/cop/migration(/|\.rb)} => :database, 109 110 %r{\A(\.ruby-version\z|\.nvmrc\z|\.tool-versions\z)} => :tooling, 111 %r{\A(\.gitlab-ci\.yml\z|\.gitlab\/ci)} => :tooling, 112 %r{\A\.codeclimate\.yml\z} => :tooling, 113 %r{\Alefthook.yml\z} => :tooling, 114 %r{\A\.editorconfig\z} => :tooling, 115 %r{Dangerfile\z} => :tooling, 116 %r{\A((ee|jh)/)?(danger/|tooling/danger/)} => :tooling, 117 %r{\A((ee|jh)/)?scripts/} => :tooling, 118 %r{\Atooling/} => :tooling, 119 %r{(CODEOWNERS)} => :tooling, 120 %r{(tests.yml)} => :tooling, 121 122 %r{\Alib/gitlab/ci/templates} => :ci_template, 123 124 %r{\A((ee|jh)/)?spec/features/} => :test, 125 %r{\A((ee|jh)/)?spec/support/shared_examples/features/} => :test, 126 %r{\A((ee|jh)/)?spec/support/shared_contexts/features/} => :test, 127 %r{\A((ee|jh)/)?spec/support/helpers/features/} => :test, 128 129 %r{\A((spec/)?lib/generators/gitlab/usage_metric_)} => [:product_intelligence], 130 %r{\A((ee|jh)/)?lib/gitlab/usage_data_counters/.*\.yml\z} => [:product_intelligence], 131 %r{\A((ee|jh)/)?config/(events|metrics)/((.*\.yml)|(schema\.json))\z} => [:product_intelligence], 132 %r{\A((ee|jh)/)?lib/gitlab/usage_data(_counters)?(/|\.rb)} => [:backend, :product_intelligence], 133 %r{\A( 134 lib/gitlab/tracking\.rb | 135 spec/lib/gitlab/tracking_spec\.rb | 136 app/helpers/tracking_helper\.rb | 137 spec/helpers/tracking_helper_spec\.rb | 138 (spec/)?lib/generators/gitlab/usage_metric_\S+ | 139 (spec/)?lib/generators/gitlab/usage_metric_definition/redis_hll_generator(_spec)?\.rb | 140 lib/generators/rails/usage_metric_definition_generator\.rb | 141 spec/lib/generators/usage_metric_definition_generator_spec\.rb | 142 generator_templates/usage_metric_definition/metric_definition\.yml)\z}x => [:backend, :product_intelligence], 143 %r{gitlab/usage_data(_spec)?\.rb} => [:product_intelligence], 144 [%r{\.haml\z}, %r{data: \{ track}] => [:product_intelligence], 145 [%r{\.(rb|haml)\z}, %r{Gitlab::Tracking\.(event|enabled\?|options)$}] => [:product_intelligence], 146 [%r{\.(vue|js)\z}, %r{(Tracking.event|/\btrack\(/|data-track-action)}] => [:product_intelligence], 147 148 %r{\A((ee|jh)/)?app/(?!assets|views)[^/]+} => :backend, 149 %r{\A((ee|jh)/)?(bin|config|generator_templates|lib|rubocop)/} => :backend, 150 %r{\A((ee|jh)/)?spec/migrations} => :database, 151 %r{\A((ee|jh)/)?spec/} => :backend, 152 %r{\A((ee|jh)/)?vendor/} => :backend, 153 %r{\A(Gemfile|Gemfile.lock|Rakefile)\z} => :backend, 154 %r{\A[A-Z_]+_VERSION\z} => :backend, 155 %r{\A\.rubocop(_todo)?\.yml\z} => :backend, 156 %r{\A\.rubocop_todo/.*\.yml\z} => :backend, 157 %r{\Afile_hooks/} => :backend, 158 159 %r{\A((ee|jh)/)?qa/} => :qa, 160 161 %r{\Aworkhorse/.*} => :workhorse, 162 163 # Files that don't fit into any category are marked with :none 164 %r{\A((ee|jh)/)?changelogs/} => :none, 165 %r{\Alocale/gitlab\.pot\z} => :none, 166 167 # GraphQL auto generated doc files and schema 168 %r{\Adoc/api/graphql/reference/} => :backend, 169 170 # Fallbacks in case the above patterns miss anything 171 %r{\.rb\z} => :backend, 172 %r{( 173 \.(md|txt)\z | 174 \.markdownlint\.json 175 )}x => :none, # To reinstate roulette for documentation, set to `:docs`. 176 %r{\.js\z} => :frontend 177 }.freeze 178 179 def local_warning_message 180 "#{MESSAGE_PREFIX} Only the following Danger rules can be run locally: #{LOCAL_RULES.join(', ')}" 181 end 182 module_function :local_warning_message # rubocop:disable Style/AccessModifierDeclarations 183 184 def success_message 185 "#{MESSAGE_PREFIX} No Danger rule violations!" 186 end 187 module_function :success_message # rubocop:disable Style/AccessModifierDeclarations 188 189 def rule_names 190 helper.ci? ? LOCAL_RULES | CI_ONLY_RULES : LOCAL_RULES 191 end 192 193 def all_ee_changes 194 helper.changes.files.grep(%r{\Aee/}) 195 end 196 197 def file_lines(filename) 198 read_file(filename).lines(chomp: true) 199 end 200 201 def labels_to_add 202 @labels_to_add ||= [] 203 end 204 205 private 206 207 def read_file(filename) 208 File.read(filename) 209 end 210 end 211 end 212end 213