diff --git a/.gitignore b/.gitignore index 5660c387f5c..d6c6d41e3ca 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,8 @@ eslint-report.html /.gitlab_pages_secret /.gitlab_kas_secret /.gitlab_suggested_reviewers_secret +/.gitlab_zoekt_username +/.gitlab_zoekt_password /webpack-report/ /crystalball/ /test_results/ diff --git a/.gitlab/ci/audit_event_types.gitlab-ci.yml b/.gitlab/ci/audit_event_types.gitlab-ci.yml new file mode 100644 index 00000000000..f079a3b55e1 --- /dev/null +++ b/.gitlab/ci/audit_event_types.gitlab-ci.yml @@ -0,0 +1,12 @@ +audit-event-types-verify: + variables: + SETUP_DB: "false" + extends: + - .default-retry + - .ruby-cache + - .default-before_script + - .audit-event-types:rules:audit-event-types-verify + stage: lint + needs: [] + script: + - bundle exec rake gitlab:audit_event_types:check_docs diff --git a/.gitlab/ci/benchmark.gitlab-ci.yml b/.gitlab/ci/benchmark.gitlab-ci.yml index 5949a9cd6a9..afad54cb84b 100644 --- a/.gitlab/ci/benchmark.gitlab-ci.yml +++ b/.gitlab/ci/benchmark.gitlab-ci.yml @@ -11,6 +11,7 @@ benchmark-markdown: - section_start "gitaly-test-spawn" "Spawning Gitaly"; scripts/gitaly-test-spawn; section_end "gitaly-test-spawn"; # Do not use 'bundle exec' here - bundle exec rake benchmark:banzai &> benchmark-markdown.txt artifacts: + expire_in: 30 days when: always paths: - benchmark-markdown.txt diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml index 279a7067a74..8061f7e2cd0 100644 --- a/.gitlab/ci/frontend.gitlab-ci.yml +++ b/.gitlab/ci/frontend.gitlab-ci.yml @@ -121,6 +121,7 @@ retrieve-frontend-fixtures: run_timed_command "download_and_extract_fixtures" fi artifacts: + expire_in: 30 days paths: - tmp/tests/frontend/ @@ -216,6 +217,7 @@ graphql-schema-dump: script: - bundle exec rake gitlab:graphql:schema:dump artifacts: + expire_in: 30 days name: graphql-schema paths: - tmp/tests/graphql/gitlab_schema.graphql diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 5ee4d275540..af10b21bd9c 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -1131,6 +1131,16 @@ - <<: *if-default-refs changes: *code-backstage-qa-patterns +############################ +# Audit event types rules # +############################ +.audit-event-types:rules:audit-event-types-verify: + rules: + - <<: *if-not-ee + when: never + - <<: *if-default-refs + changes: *code-backstage-qa-patterns + ################## # Frontend rules # ################## diff --git a/.gitlab/ci/static-analysis.gitlab-ci.yml b/.gitlab/ci/static-analysis.gitlab-ci.yml index 29887881da5..4f990410b9d 100644 --- a/.gitlab/ci/static-analysis.gitlab-ci.yml +++ b/.gitlab/ci/static-analysis.gitlab-ci.yml @@ -64,6 +64,7 @@ generate-apollo-graphql-schema: script: - apollo client:download-schema --config=config/apollo.config.js ${GRAPHQL_SCHEMA_APOLLO_FILE} artifacts: + expire_in: 30 days name: graphql-schema-apollo paths: - "${GRAPHQL_SCHEMA_APOLLO_FILE}" @@ -201,6 +202,7 @@ semgrep-appsec-custom-rules: variables: CUSTOM_RULES_URL: https://gitlab.com/gitlab-com/gl-security/appsec/sast-custom-rules/-/raw/main/gitlab-sast-rules/rules.yml artifacts: + expire_in: 30 days paths: - gl-sast-report.json diff --git a/.gitlab/ci/templates/gem.gitlab-ci.yml b/.gitlab/ci/templates/gem.gitlab-ci.yml index 46c5e1342c6..f1ee3426070 100644 --- a/.gitlab/ci/templates/gem.gitlab-ci.yml +++ b/.gitlab/ci/templates/gem.gitlab-ci.yml @@ -11,6 +11,7 @@ spec: --- .gems:rules:$[[inputs.gem_name]]: rules: + - if: '$CI_PIPELINE_SOURCE == "schedule" && $SCHEDULE_TYPE == "maintenance"' - if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "detached"' changes: - "$[[inputs.gem_path_prefix]]$[[inputs.gem_name]]/**/*" diff --git a/.gitlab/ci/workhorse.gitlab-ci.yml b/.gitlab/ci/workhorse.gitlab-ci.yml index 00c4dc6c9a9..5b128ef6170 100644 --- a/.gitlab/ci/workhorse.gitlab-ci.yml +++ b/.gitlab/ci/workhorse.gitlab-ci.yml @@ -34,6 +34,7 @@ workhorse:test go: - make -C workhorse test-coverage coverage: '/\d+.\d+%/' artifacts: + expire_in: 30 days paths: - workhorse/coverage.html diff --git a/.rubocop.yml b/.rubocop.yml index 85c9b74b6a6..a1d83ff4bd4 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1005,6 +1005,8 @@ Search/NamespacedClass: - 'app/experiments/**/*_experiment.rb' - 'ee/app/experiments/**/*_experiment.rb' - 'lib/gitlab/instrumentation/**/*.rb' + - 'lib/gitlab/usage/metrics/instrumentations/**/*.rb' + - 'ee/lib/gitlab/usage/metrics/instrumentations/**/*.rb' SidekiqLoadBalancing/WorkerDataConsistency: Enabled: true diff --git a/Gemfile b/Gemfile index ea98d098151..31fec96b8a0 100644 --- a/Gemfile +++ b/Gemfile @@ -444,7 +444,7 @@ group :development, :test do end group :development, :test, :danger do - gem 'gitlab-dangerfiles', '~> 3.11.0', require: false + gem 'gitlab-dangerfiles', '~> 3.12.0', require: false end group :development, :test, :coverage do diff --git a/Gemfile.checksum b/Gemfile.checksum index f0f8e77b9c4..074e4b2308a 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -207,7 +207,7 @@ {"name":"gitaly","version":"16.2.0.pre.rc2","platform":"ruby","checksum":"01fa84470399b4d6abba84cf97d17adb2082ca5eccd3130903a3abbc8cb072a0"}, {"name":"gitlab","version":"4.19.0","platform":"ruby","checksum":"3f645e3e195dbc24f0834fbf83e8ccfb2056d8e9712b01a640aad418a6949679"}, {"name":"gitlab-chronic","version":"0.10.5","platform":"ruby","checksum":"f80f18dc699b708870a80685243331290bc10cfeedb6b99c92219722f729c875"}, -{"name":"gitlab-dangerfiles","version":"3.11.0","platform":"ruby","checksum":"9a5cfe03e00c9d489782ad330ece4ce109e6cea1dcaae3eb41a5b5aed234a123"}, +{"name":"gitlab-dangerfiles","version":"3.12.0","platform":"ruby","checksum":"0b260c84530664b5ae9d8cf21658c4658d4c319a0c9cbc4d56ecb6591b097d7d"}, {"name":"gitlab-experiment","version":"0.7.1","platform":"ruby","checksum":"166dddb3aa83428bcaa93c35684ed01dc4d61f321fd2ae40b020806dc54a7824"}, {"name":"gitlab-fog-azure-rm","version":"1.7.0","platform":"ruby","checksum":"969c67943c54ad4c259a6acd040493f13922fbdf2211bb4eca00e71505263dc2"}, {"name":"gitlab-labkit","version":"0.33.0","platform":"ruby","checksum":"d1fba8d30fde314a3f5dee1921ac31860bed4fecd8aa98ac6671f2627479e05b"}, diff --git a/Gemfile.lock b/Gemfile.lock index 3e03bcfc095..dc8990b7a77 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -633,7 +633,7 @@ GEM terminal-table (>= 1.5.1) gitlab-chronic (0.10.5) numerizer (~> 0.2) - gitlab-dangerfiles (3.11.0) + gitlab-dangerfiles (3.12.0) danger (>= 8.4.5) danger-gitlab (>= 8.0.0) rake @@ -1811,7 +1811,7 @@ DEPENDENCIES gettext_i18n_rails_js (~> 1.3) gitaly (~> 16.2.0.pre.rc2) gitlab-chronic (~> 0.10.5) - gitlab-dangerfiles (~> 3.11.0) + gitlab-dangerfiles (~> 3.12.0) gitlab-experiment (~> 0.7.1) gitlab-fog-azure-rm (~> 1.7.0) gitlab-labkit (~> 0.33.0) diff --git a/app/assets/javascripts/diffs/components/diff_row.vue b/app/assets/javascripts/diffs/components/diff_row.vue index 474b5d1443e..7c0937db221 100644 --- a/app/assets/javascripts/diffs/components/diff_row.vue +++ b/app/assets/javascripts/diffs/components/diff_row.vue @@ -333,7 +333,7 @@ export default { class="diff-td line-coverage left-side has-tooltip" >
{{ job.stage.name }}
- #{{ parsedJobId }} + #{{ parsedJobId }}
- {{ $options.i18n.cannotRetry }} + {{ tooltipErrorText }}
diff --git a/app/assets/javascripts/pipelines/graphql/queries/get_pipeline_failed_jobs.query.graphql b/app/assets/javascripts/pipelines/graphql/queries/get_pipeline_failed_jobs.query.graphql index 3d69c5e451b..6b553866f63 100644 --- a/app/assets/javascripts/pipelines/graphql/queries/get_pipeline_failed_jobs.query.graphql +++ b/app/assets/javascripts/pipelines/graphql/queries/get_pipeline_failed_jobs.query.graphql @@ -4,13 +4,14 @@ query getPipelineFailedJobs($fullPath: ID!, $pipelineIid: ID!) { pipeline(iid: $pipelineIid) { id active - jobs(statuses: [FAILED], retried: false, jobKind: BUILD) { + jobs(statuses: [FAILED], retried: false) { count nodes { id allowFailure detailedStatus { id + detailsPath group icon action { @@ -19,6 +20,7 @@ query getPipelineFailedJobs($fullPath: ID!, $pipelineIid: ID!) { icon } } + kind name retried retryable @@ -33,7 +35,6 @@ query getPipelineFailedJobs($fullPath: ID!, $pipelineIid: ID!) { readBuild updateBuild } - webPath } } } diff --git a/app/assets/stylesheets/highlight/diff_custom_colors_addition.scss b/app/assets/stylesheets/highlight/diff_custom_colors_addition.scss index 5f195bc47bf..675a33617bf 100644 --- a/app/assets/stylesheets/highlight/diff_custom_colors_addition.scss +++ b/app/assets/stylesheets/highlight/diff_custom_colors_addition.scss @@ -6,7 +6,7 @@ .line_holder { .diff-line-num, .line-coverage, - .line-codequality, + .line-inline-findings, .line_content { &.new { &:not(.hll) { diff --git a/app/assets/stylesheets/highlight/diff_custom_colors_deletion.scss b/app/assets/stylesheets/highlight/diff_custom_colors_deletion.scss index a8ab43909eb..39b74f10199 100644 --- a/app/assets/stylesheets/highlight/diff_custom_colors_deletion.scss +++ b/app/assets/stylesheets/highlight/diff_custom_colors_deletion.scss @@ -6,7 +6,7 @@ .line_holder { .diff-line-num, .line-coverage, - .line-codequality, + .line-inline-findings, .line_content { &.old { &:not(.hll) { diff --git a/app/assets/stylesheets/highlight/themes/dark.scss b/app/assets/stylesheets/highlight/themes/dark.scss index 9ad7c1b796c..8596d79ca83 100644 --- a/app/assets/stylesheets/highlight/themes/dark.scss +++ b/app/assets/stylesheets/highlight/themes/dark.scss @@ -191,7 +191,7 @@ $dark-il: #de935f; .diff-td.diff-line-num.hll, .diff-td.line-coverage.hll, - .diff-td.line-codequality.hll, + .diff-td.line-inline-findings.hll, .diff-td.line_content.hll, td.diff-line-num.hll, td.line-coverage.hll, @@ -206,11 +206,11 @@ $dark-il: #de935f; .diff-line-num.new, .line-coverage.new, - .line-codequality.new, + .line-inline-findings.new, .line_content.new, .diff-line-num.new-nomappinginraw, .line-coverage.new-nomappinginraw, - .line-codequality.new-nomappinginraw, + .line-inline-findings.new-nomappinginraw, .line_content.new-nomappinginraw { @include diff-background($dark-new-bg, $dark-new-idiff, $dark-border); @@ -222,11 +222,11 @@ $dark-il: #de935f; .diff-line-num.old, .line-coverage.old, - .line-codequality.old, + .line-inline-findings.old, .line_content.old, .diff-line-num.old-nomappinginraw, .line-coverage.old-nomappinginraw, - .line-codequality.old-nomappinginraw, + .line-inline-findings.old-nomappinginraw, .line_content.old-nomappinginraw { @include diff-background($dark-old-bg, $dark-old-idiff, $dark-border); diff --git a/app/assets/stylesheets/highlight/themes/monokai.scss b/app/assets/stylesheets/highlight/themes/monokai.scss index b1d89d3c253..1c323ad15a6 100644 --- a/app/assets/stylesheets/highlight/themes/monokai.scss +++ b/app/assets/stylesheets/highlight/themes/monokai.scss @@ -182,7 +182,7 @@ $monokai-gh: #75715e; .diff-td.diff-line-num.hll, .diff-td.line-coverage.hll, - .diff-td.line-codequality.hll, + .diff-td.line-inline-findings.hll, .diff-td.line_content.hll, td.diff-line-num.hll, td.line-coverage.hll, @@ -197,11 +197,11 @@ $monokai-gh: #75715e; .diff-line-num.new, .line-coverage.new, - .line-codequality.new, + .line-inline-findings.new, .line_content.new, .diff-line-num.new-nomappinginraw, .line-coverage.new-nomappinginraw, - .line-codequality.new-nomappinginraw, + .line-inline-findings.new-nomappinginraw, .line_content.new-nomappinginraw { @include diff-background($monokai-new-bg, $monokai-new-idiff, $monokai-diff-border); @@ -213,11 +213,11 @@ $monokai-gh: #75715e; .diff-line-num.old, .line-coverage.old, - .line-codequality.old, + .line-inline-findings.old, .line_content.old, .diff-line-num.old-nomappinginraw, .line-coverage.old-nomappinginraw, - .line-codequality.old-nomappinginraw, + .line-inline-findings.old-nomappinginraw, .line_content.old-nomappinginraw { @include diff-background($monokai-old-bg, $monokai-old-idiff, $monokai-diff-border); diff --git a/app/assets/stylesheets/highlight/themes/none.scss b/app/assets/stylesheets/highlight/themes/none.scss index 4762aae1d12..f36eaa663e5 100644 --- a/app/assets/stylesheets/highlight/themes/none.scss +++ b/app/assets/stylesheets/highlight/themes/none.scss @@ -81,7 +81,7 @@ } .line-coverage:not(.hll), - .line-codequality:not(.hll) { + .line-inline-findings:not(.hll) { &.old, &.new, &.new-nomappinginraw, diff --git a/app/assets/stylesheets/highlight/themes/solarized-dark.scss b/app/assets/stylesheets/highlight/themes/solarized-dark.scss index 7958959bfc3..e92239c4e11 100644 --- a/app/assets/stylesheets/highlight/themes/solarized-dark.scss +++ b/app/assets/stylesheets/highlight/themes/solarized-dark.scss @@ -185,7 +185,7 @@ $solarized-dark-il: #2aa198; .diff-td.diff-line-num.hll, .diff-td.line-coverage.hll, - .diff-td.line-codequality.hll, + .diff-td.line-inline-findings.hll, .diff-td.line_content.hll, td.diff-line-num.hll, td.line-coverage.hll, @@ -208,11 +208,11 @@ $solarized-dark-il: #2aa198; .diff-line-num.new, .line-coverage.new, - .line-codequality.new, + .line-inline-findings.new, .line_content.new, .diff-line-num.new-nomappinginraw, .line-coverage.new-nomappinginraw, - .line-codequality.new-nomappinginraw, + .line-inline-findings.new-nomappinginraw, .line_content.new-nomappinginraw { @include diff-background($solarized-dark-new-bg, $solarized-dark-new-idiff, $solarized-dark-border); @@ -224,11 +224,11 @@ $solarized-dark-il: #2aa198; .diff-line-num.old, .line-coverage.old, - .line-codequality.old, + .line-inline-findings.old, .line_content.old, .diff-line-num.old-nomappinginraw, .line-coverage.old-nomappinginraw, - .line-codequality.old-nomappinginraw, + .line-inline-findings.old-nomappinginraw, .line_content.old-nomappinginraw { @include diff-background($solarized-dark-old-bg, $solarized-dark-old-idiff, $solarized-dark-border); diff --git a/app/assets/stylesheets/highlight/themes/solarized-light.scss b/app/assets/stylesheets/highlight/themes/solarized-light.scss index f156077c64d..b3aa10c3ace 100644 --- a/app/assets/stylesheets/highlight/themes/solarized-light.scss +++ b/app/assets/stylesheets/highlight/themes/solarized-light.scss @@ -172,7 +172,7 @@ $solarized-light-il: #2aa198; .diff-td.diff-line-num.hll, .diff-td.line-coverage.hll, - .diff-td.line-codequality.hll, + .diff-td.line-inline-findings.hll, .diff-td.line_content.hll, td.diff-line-num.hll, td.line-coverage.hll, @@ -187,11 +187,11 @@ $solarized-light-il: #2aa198; .diff-line-num.new, .line-coverage.new, - .line-codequality.new, + .line-inline-findings.new, .line_content.new, .diff-line-num.new-nomappinginraw, .line-coverage.new-nomappinginraw, - .line-codequality.new-nomappinginraw, + .line-inline-findings.new-nomappinginraw, .line_content.new-nomappinginraw { @include diff-background($solarized-light-new-bg, $solarized-light-new-idiff, $solarized-light-border); @@ -212,11 +212,11 @@ $solarized-light-il: #2aa198; .diff-line-num.old, .line-coverage.old, - .line-codequality.old, + .line-inline-findings.old, .line_content.old, .diff-line-num.old-nomappinginraw, .line-coverage.old-nomappinginraw, - .line-codequality.old-nomappinginraw, + .line-inline-findings.old-nomappinginraw, .line_content.old-nomappinginraw { @include diff-background($solarized-light-old-bg, $solarized-light-old-idiff, $solarized-light-border); diff --git a/app/assets/stylesheets/highlight/white_base.scss b/app/assets/stylesheets/highlight/white_base.scss index 14524e163b2..2631055706f 100644 --- a/app/assets/stylesheets/highlight/white_base.scss +++ b/app/assets/stylesheets/highlight/white_base.scss @@ -253,7 +253,7 @@ pre.code, } .line-coverage, - .line-codequality { + .line-inline-findings { &.old, &.old-nomappinginraw { background-color: $line-removed; diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb index 7ffcb8b9219..0f410d4810d 100644 --- a/app/models/network/graph.rb +++ b/app/models/network/graph.rb @@ -86,6 +86,7 @@ module Network skip = 0 while offset == -1 tmp_commits = find_commits(skip) + if tmp_commits.present? index = tmp_commits.index do |c| c.id == @commit.id @@ -112,15 +113,17 @@ module Network end def find_commits(skip = 0) - opts = { - max_count: self.class.max_count, - skip: skip, - order: :date - } + Gitlab::SafeRequestStore.fetch([@project, :network_graph_commits, skip]) do + opts = { + max_count: self.class.max_count, + skip: skip, + order: :date + } - opts[:ref] = @commit.id if @filter_ref + opts[:ref] = @commit.id if @filter_ref - Gitlab::Git::Commit.find_all(@repo.raw_repository, opts) + Gitlab::Git::Commit.find_all(@repo.raw_repository, opts) + end end def commits_sort_by_ref diff --git a/app/services/issues/relative_position_rebalancing_service.rb b/app/services/issues/relative_position_rebalancing_service.rb index b5c10430e83..a8d0ae01176 100644 --- a/app/services/issues/relative_position_rebalancing_service.rb +++ b/app/services/issues/relative_position_rebalancing_service.rb @@ -10,8 +10,8 @@ module Issues TooManyConcurrentRebalances = Class.new(StandardError) def initialize(projects) - @projects_collection = (projects.is_a?(Array) ? Project.id_in(projects) : projects).projects_order_id_asc - @root_namespace = @projects_collection.take.root_namespace # rubocop:disable CodeReuse/ActiveRecord + @projects_collection = (projects.is_a?(Array) ? Project.id_in(projects) : projects).select(:id).projects_order_id_asc + @root_namespace = @projects_collection.select(:namespace_id).reorder(nil).take.root_namespace # rubocop:disable CodeReuse/ActiveRecord @caching = ::Gitlab::Issues::Rebalancing::State.new(@root_namespace, @projects_collection) end diff --git a/config/feature_flags/development/ai_chat_prompt_alternative.yml b/config/feature_flags/development/ai_chat_prompt_alternative.yml deleted file mode 100644 index f568abcec24..00000000000 --- a/config/feature_flags/development/ai_chat_prompt_alternative.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: ai_chat_prompt_alternative -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125092 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/417230 -milestone: '16.2' -type: development -group: group::ai-enablement -default_enabled: false diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 7968d46dad4..bbdbd68a78b 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -1276,6 +1276,12 @@ production: &base # Default is '.gitlab_suggested_reviewers_secret' relative to Rails.root (i.e. root of the GitLab app). # secret_file: /home/git/gitlab/.gitlab_suggested_reviewers_secret + zoekt: + # Files that contain username and password for basic auth for Zoekt + # Default is '.gitlab_zoekt_username' and '.gitlab_zoekt_password' in Rails.root + # username_file: /home/git/gitlab/.gitlab_zoekt_username + # password_file: /home/git/gitlab/.gitlab_zoekt_password + ## GitLab Elasticsearch settings elasticsearch: indexer_path: /home/git/gitlab-elasticsearch-indexer/ diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index cda625fab13..6c7561ffb89 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -926,6 +926,15 @@ Gitlab.ee do Settings.suggested_reviewers['secret_file'] ||= Rails.root.join('.gitlab_suggested_reviewers_secret') end +# +# Zoekt credentials +# +Gitlab.ee do + Settings['zoekt'] ||= {} + Settings.zoekt['username_file'] ||= Rails.root.join('.gitlab_zoekt_username') + Settings.zoekt['password_file'] ||= Rails.root.join('.gitlab_zoekt_password') +end + # # Repositories # diff --git a/danger/database/Dangerfile b/danger/database/Dangerfile index 1c0e9d72118..6861a04ffc6 100644 --- a/danger/database/Dangerfile +++ b/danger/database/Dangerfile @@ -67,9 +67,7 @@ end return unless helper.ci? return if helper.mr_labels.include?(DATABASE_APPROVED_LABEL) -db_paths_to_review = helper.changes_by_category[:database] - -if helper.mr_labels.include?('database') || db_paths_to_review.any? +if helper.mr_labels.include?('database') || database.changes.any? message 'This merge request adds or changes files that require a ' \ 'review from the [Database team](https://gitlab.com/groups/gl-database/-/group_members).' diff --git a/danger/roulette/Dangerfile b/danger/roulette/Dangerfile index 39b79745ead..960f6a995d4 100644 --- a/danger/roulette/Dangerfile +++ b/danger/roulette/Dangerfile @@ -98,7 +98,7 @@ categories = roulette.prepare_categories(changes.keys - [:unknown]) categories.subtract([:database, :ux, :analytics_instrumentation]) if stable_branch.valid_stable_branch? if changes.any? - random_roulette_spins = roulette.spin(nil, categories, timezone_experiment: false) + random_roulette_spins = roulette.spin(nil, categories) if categories.include?(:ux) # rubocop:disable Style/IfUnlessModifier roulette.assign_pedroms_for_ux_wider_community_contribution(random_roulette_spins) diff --git a/doc/administration/audit_event_streaming/audit_event_types.md b/doc/administration/audit_event_streaming/audit_event_types.md index 61aa5e9e70c..a8fa06dbc64 100644 --- a/doc/administration/audit_event_streaming/audit_event_types.md +++ b/doc/administration/audit_event_streaming/audit_event_types.md @@ -71,6 +71,8 @@ Audit event types are used to [filter streamed audit events](index.md#update-eve | [`destroy_compliance_framework`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74292) | Triggered on successful compliance framework deletion | **{check-circle}** Yes | **{check-circle}** Yes | `compliance_management` | [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/340649) | | [`destroy_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74632) | Event triggered when an external audit event destination is deleted | **{check-circle}** Yes | **{check-circle}** Yes | `audit_events` | [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/344664) | | [`destroy_instance_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125846) | Event triggered when an instance level external audit event destination is deleted | **{check-circle}** Yes | **{check-circle}** Yes | `audit_events` | [16.2](https://gitlab.com/gitlab-org/gitlab/-/issues/404730) | +| [`email_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114546) | Event triggered when an email is created | **{check-circle}** Yes | **{dotted-circle}** No | `compliance_management` | [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | +| [`email_destroyed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114546) | Event triggered when an email is destroyed | **{check-circle}** Yes | **{dotted-circle}** No | `compliance_management` | [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | | [`environment_protected`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108247) | This event is triggered when a protected environment is created. | **{check-circle}** Yes | **{dotted-circle}** No | `environment_management` | [15.8](https://gitlab.com/gitlab-org/gitlab/-/issues/216164) | | [`environment_unprotected`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108247) | This event is triggered when a protected environment is deleted. | **{check-circle}** Yes | **{dotted-circle}** No | `environment_management` | [15.8](https://gitlab.com/gitlab-org/gitlab/-/issues/216164) | | [`epic_closed_by_project_bot`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121485) | Triggered when an epic is closed by a group access token | **{check-circle}** Yes | **{check-circle}** Yes | `portfolio_management` | [16.1](https://gitlab.com/gitlab-org/gitlab/-/issues/323299) | @@ -232,6 +234,7 @@ Audit event types are used to [filter streamed audit events](index.md#update-eve | [`secure_ci_job_token_project_added`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115350) | Event triggered when project added to inbound CI_JOB_TOKEN scope | **{check-circle}** Yes | **{check-circle}** Yes | `verify_security` | [16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/338255) | | [`secure_ci_job_token_project_removed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115350) | Event triggered when project removed from inbound CI_JOB_TOKEN scope | **{check-circle}** Yes | **{check-circle}** Yes | `verify_security` | [16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/338255) | | [`set_runner_associated_projects`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97666) | Event triggered on successful assignment of associated projects to a CI runner | **{check-circle}** Yes | **{check-circle}** Yes | `runner` | [15.4](https://gitlab.com/gitlab-org/gitlab/-/issues/359958) | +| [`smartcard_authentication_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8120) | Event triggered when a user authenticates with smartcard | **{check-circle}** Yes | **{dotted-circle}** No | `compliance_management` | [16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/726) | | [`squash_commit_template_updated`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107533) | Event triggered on updating the merge request squash commit template for a project | **{check-circle}** Yes | **{check-circle}** Yes | `groups_and_projects` | [15.8](https://gitlab.com/gitlab-org/gitlab/-/issues/369314) | | [`squash_option_updated`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84624) | Triggered when squash option setting has been changed. | **{check-circle}** Yes | **{check-circle}** Yes | `groups_and_projects` | [15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/301124) | | [`task_closed_by_project_bot`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121485) | Triggered when a task is closed using a project access token | **{check-circle}** Yes | **{check-circle}** Yes | `team_planning` | [16.1](https://gitlab.com/gitlab-org/gitlab/-/issues/323299) | diff --git a/doc/administration/audit_event_streaming/index.md b/doc/administration/audit_event_streaming/index.md index 72ee00263d1..ee22526068e 100644 --- a/doc/administration/audit_event_streaming/index.md +++ b/doc/administration/audit_event_streaming/index.md @@ -11,6 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w > - Custom HTTP headers UI [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/361630) in GitLab 15.2 [with a flag](../feature_flags.md) named `custom_headers_streaming_audit_events_ui`. Disabled by default. > - Custom HTTP headers UI [made generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/365259) in GitLab 15.3. [Feature flag `custom_headers_streaming_audit_events_ui`](https://gitlab.com/gitlab-org/gitlab/-/issues/365259) removed. > - [Improved user experience](https://gitlab.com/gitlab-org/gitlab/-/issues/367963) in GitLab 15.3. +> - [HTTP destination **Name*** field](https://gitlab.com/gitlab-org/gitlab/-/issues/411357) added in GitLab 16.3. Users can set a streaming destination for a top-level group or instance to receive all audit events about the group, subgroups, and projects, as structured JSON. @@ -49,7 +50,7 @@ To add streaming destinations to a top-level group: 1. Select **Secure > Audit events**. 1. On the main area, select **Streams** tab. 1. Select **Add streaming destination** and select **HTTP endpoint** to show the section for adding destinations. -1. Enter the destination URL to add. +1. In the **Name** and **Destination URL** fields, add a destination name and URL. 1. Optional. Locate the **Custom HTTP headers** table. 1. Ignore the **Active** checkbox because it isn't functional. To track progress on adding functionality to the **Active** checkbox, see [issue 367509](https://gitlab.com/gitlab-org/gitlab/-/issues/367509). @@ -68,7 +69,7 @@ To list the streaming destinations for a top-level group: 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group. 1. Select **Secure > Audit events**. 1. On the main area, select **Streams** tab. -1. Select the stream URL to expand it and see all the custom HTTP headers. +1. Select the stream to expand it and see all the custom HTTP headers. #### Update an HTTP destination @@ -76,12 +77,21 @@ Prerequisites: - Owner role for a group. +To update a streaming destination's name: + +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group. +1. Select **Secure > Audit events**. +1. On the main area, select **Streams** tab. +1. Select the stream to expand. +1. In the **Name** fields, add a destination name to update. +1. Select **Save** to update the streaming destination. + To update a streaming destination's custom HTTP headers: 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group. 1. Select **Secure > Audit events**. 1. On the main area, select **Streams** tab. -1. Select the stream URL to expand. +1. Select the stream to expand. 1. Locate the **Custom HTTP headers** table. 1. Locate the header that you wish to update. 1. Ignore the **Active** checkbox because it isn't functional. To track progress on adding functionality to the @@ -104,7 +114,7 @@ To delete a streaming destination: 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group. 1. Select **Secure > Audit events**. 1. On the main area, select the **Streams** tab. -1. Select the stream URL to expand. +1. Select the stream to expand. 1. Select **Delete destination**. 1. Confirm by selecting **Delete destination** in the dialog. @@ -113,7 +123,7 @@ To delete only the custom HTTP headers for a streaming destination: 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group. 1. Select **Secure > Audit events**. 1. On the main area, select the **Streams** tab. -1. Select the stream URL to expand. +1. Select the stream to expand. 1. Locate the **Custom HTTP headers** table. 1. Locate the header that you wish to remove. 1. To the right of the header, select **Delete** (**{remove}**). @@ -138,7 +148,7 @@ To list streaming destinations and see the verification tokens: 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group. 1. Select **Secure > Audit events**. 1. On the main area, select the **Streams**. -1. Select the stream URL to expand. +1. Select the stream to expand. 1. Locate the **Verification token** input. #### Update event filters @@ -155,7 +165,7 @@ To update a streaming destination's event filters: 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group. 1. Select **Secure > Audit events**. 1. On the main area, select the **Streams** tab. -1. Select the stream URL to expand. +1. Select the stream to expand. 1. Locate the **Filter by audit event type** dropdown list. 1. Select the dropdown list and select or clear the required event types. 1. Select **Save** to update the event filters. @@ -260,7 +270,7 @@ To add a streaming destination for an instance: 1. On the left sidebar, select **Monitoring > Audit Events**. 1. On the main area, select **Streams** tab. 1. Select **Add streaming destination** and select **HTTP endpoint** to show the section for adding destinations. -1. Enter the destination URL to add. +1. In the **Name** and **Destination URL** fields, add a destination name and URL. 1. Optional. To add custom HTTP headers, select **Add header** to create a new name and value pair, and input their values. Repeat this step for as many name and value pairs are required. You can add up to 20 headers per streaming destination. 1. Ignore the **Active** checkbox because it isn't functional. To track progress on adding functionality to the **Active** checkbox, see [issue 367509](https://gitlab.com/gitlab-org/gitlab/-/issues/367509). @@ -280,6 +290,7 @@ To list the streaming destinations for an instance: 1. Select **Admin Area**. 1. On the left sidebar, select **Monitoring > Audit Events**. 1. On the main area, select **Streams** tab. +1. Select the stream to expand it and see all the custom HTTP headers. ### Update an HTTP destination @@ -287,12 +298,23 @@ Prerequisites: - Administrator access on the instance. -To update the streaming destinations for an instance: +To update a instance streaming destination's name: 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). -1. Select **Secure > Audit events**. -1. On the main area, select the **Streams** tab. -1. To the right of the item, select **Edit** (**{pencil}**). +1. Select **Admin Area**. +1. On the left sidebar, select **Monitoring > Audit Events**. +1. On the main area, select **Streams** tab. +1. Select the stream to expand. +1. In the **Name** fields, add a destination name to update. +1. Select **Save** to update the streaming destination. + +To update a instance streaming destination's custom HTTP headers: + +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. +1. On the left sidebar, select **Monitoring > Audit Events**. +1. On the main area, select **Streams** tab. +1. Select the stream to expand. 1. Locate the **Custom HTTP headers** table. 1. Locate the header that you wish to update. 1. Ignore the **Active** checkbox because it isn't functional. To track progress on adding functionality to the @@ -316,7 +338,7 @@ To delete the streaming destinations for an instance: 1. Select **Admin Area**. 1. On the left sidebar, select **Monitoring > Audit Events**. 1. On the main area, select the **Streams** tab. -1. Select the stream URL to expand. +1. Select the stream to expand. 1. Select **Delete destination**. 1. Confirm by selecting **Delete destination** in the dialog. diff --git a/doc/development/internal_analytics/service_ping/implement.md b/doc/development/internal_analytics/service_ping/implement.md index 3b8243377a3..5c5be64ccb9 100644 --- a/doc/development/internal_analytics/service_ping/implement.md +++ b/doc/development/internal_analytics/service_ping/implement.md @@ -21,7 +21,6 @@ To implement a new metric in Service Ping, follow these steps: 1. [Generate the SQL query](#generate-the-sql-query) 1. [Optimize queries with Database Lab](#optimize-queries-with-database-lab) 1. [Add the metric definition to the Metrics Dictionary](#add-the-metric-definition) -1. [Add the metric to the Versions Application](#add-the-metric-to-the-versions-application) 1. [Create a merge request](#create-a-merge-request) 1. [Verify your metric](#verify-your-metric) 1. [Set up and test Service Ping locally](#set-up-and-test-service-ping-locally) @@ -678,10 +677,6 @@ For more details, see the [database review guide](../../database_review.md#prepa See the [Metrics Dictionary guide](metrics_dictionary.md) for more information. -## Add the metric to the Versions Application - -Check if the new metric must be added to the Versions Application. See the `usage_data` [schema](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com/-/blob/main/db/schema.rb#L152) and Service Data [parameters accepted](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com/-/blob/main/app/services/usage_ping.rb). Any metrics added under the `counts` key are saved in the `stats` column. - ## Create a merge request Create a merge request for the new Service Ping metric, and do the following: diff --git a/doc/development/internal_analytics/service_ping/review_guidelines.md b/doc/development/internal_analytics/service_ping/review_guidelines.md index 31b6c3f5580..8a46de7086e 100644 --- a/doc/development/internal_analytics/service_ping/review_guidelines.md +++ b/doc/development/internal_analytics/service_ping/review_guidelines.md @@ -51,7 +51,7 @@ are regular backend changes. #### The Analytics Instrumentation **reviewer** should - Perform a first-pass review on the merge request and suggest improvements to the author. -- Check the [metrics location](metrics_dictionary.md#metric-key_path) in +- Check the [metric's location](metrics_dictionary.md#metric-key_path) in the Service Ping JSON payload. - Add the `~database` label and ask for a [database review](../../database_review.md) for metrics that are based on Database. @@ -66,6 +66,7 @@ are regular backend changes. - Check the file location. Consider the time frame, and if the file should be under `ee`. - Check the tiers. - If a metric was changed or removed: Make sure the MR author notified the Customer Success Ops team (`@csops-team`), Analytics Engineers (`@gitlab-data/analytics-engineers`), and Product Analysts (`@gitlab-data/product-analysts`) by `@` mentioning those groups in a comment on the issue for the MR and all of these groups have acknowledged the removal. +- Make sure that the new metric is available in Service Ping payload, by running: `Gitlab::Usage::ServicePingReport.for(output: :all_metrics_values).dig(*'key_path'.split('.'))` with `key_path` substituted by the new metric's key_path. - Metrics instrumentations - Recommend using metrics instrumentation for new metrics, [if possible](metrics_instrumentation.md#support-for-instrumentation-classes). - Approve the MR, and relabel the MR with `~"analytics instrumentation::approved"`. diff --git a/gems/gem.gitlab-ci.yml b/gems/gem.gitlab-ci.yml index 5f7a6ba280a..069bd85d0fb 100644 --- a/gems/gem.gitlab-ci.yml +++ b/gems/gem.gitlab-ci.yml @@ -13,7 +13,10 @@ spec: workflow: name: '$PIPELINE_NAME' rules: - - if: $CI_MERGE_REQUEST_ID + - if: '$CI_PIPELINE_SOURCE == "schedule" && $SCHEDULE_TYPE == "maintenance"' + variables: + PIPELINE_NAME: '[$[[inputs.gem_name]] gem] Ruby $RUBY_VERSION $SCHEDULE_TYPE $CI_PIPELINE_SOURCE pipeline' + - if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "detached"' variables: PIPELINE_NAME: '[$[[inputs.gem_name]] gem] Ruby $RUBY_VERSION $CI_MERGE_REQUEST_EVENT_TYPE MR pipeline' diff --git a/lib/gitlab/internal_events/event_definitions.rb b/lib/gitlab/internal_events/event_definitions.rb index e1c9faa12de..f3c8092bcb0 100644 --- a/lib/gitlab/internal_events/event_definitions.rb +++ b/lib/gitlab/internal_events/event_definitions.rb @@ -8,10 +8,6 @@ module Gitlab class << self VALID_UNIQUE_VALUES = %w[user.id project.id namespace.id].freeze - def clear_events - @events = nil - end - def load_configurations @events = load_metric_definitions nil diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c186dc5ac60..bc68eae0088 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6649,6 +6649,9 @@ msgstr "" msgid "AuditStreams|Deleting the streaming destination %{destination} will stop audit events being streamed" msgstr "" +msgid "AuditStreams|Destination Name" +msgstr "" + msgid "AuditStreams|Destination URL" msgstr "" @@ -26761,10 +26764,13 @@ msgstr "" msgid "Job|We could not find this element" msgstr "" -msgid "Job|You do not have permission to read this job's log" +msgid "Job|You cannot rerun trigger jobs from this list." msgstr "" -msgid "Job|You do not have permission to retry this job" +msgid "Job|You do not have permission to read this job's log." +msgstr "" + +msgid "Job|You do not have permission to run this job again." msgstr "" msgid "Job|allowed to fail" diff --git a/spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_job_details_spec.js b/spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_job_details_spec.js index 4ba1b82e971..9cd8ea66797 100644 --- a/spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_job_details_spec.js +++ b/spec/frontend/pipelines/components/pipelines_list/failure_widget/failed_job_details_spec.js @@ -8,6 +8,7 @@ import { createAlert } from '~/alert'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import FailedJobDetails from '~/pipelines/components/pipelines_list/failure_widget/failed_job_details.vue'; import RetryMrFailedJobMutation from '~/pipelines/graphql/mutations/retry_mr_failed_job.mutation.graphql'; +import { BRIDGE_KIND } from '~/pipelines/components/graph/constants'; import { job } from './mock'; Vue.use(VueApollo); @@ -94,6 +95,16 @@ describe('FailedJobDetails component', () => { }); }); + describe('when the job is a bridge', () => { + beforeEach(() => { + createComponent({ props: { job: { ...job, kind: BRIDGE_KIND } } }); + }); + + it('disables the retry button', () => { + expect(findRetryButton().props().disabled).toBe(true); + }); + }); + describe('when the job is retryable', () => { describe('and user has permission to update the build', () => { beforeEach(() => { @@ -183,7 +194,7 @@ describe('FailedJobDetails component', () => { it('shows a permission error message', () => { expect(findVisibleJobLog().text()).toBe( - "You do not have permission to read this job's log", + "You do not have permission to read this job's log.", ); }); }); diff --git a/spec/frontend/pipelines/components/pipelines_list/failure_widget/mock.js b/spec/frontend/pipelines/components/pipelines_list/failure_widget/mock.js index b047b57fc34..318d787a984 100644 --- a/spec/frontend/pipelines/components/pipelines_list/failure_widget/mock.js +++ b/spec/frontend/pipelines/components/pipelines_list/failure_widget/mock.js @@ -3,17 +3,19 @@ export const job = { allowFailure: false, detailedStatus: { id: 'status', + detailsPath: '/jobs/5241', action: { id: 'action', path: '/retry', icon: 'retry', }, group: 'running', - icon: 'running-icon', + icon: 'status_running_icon', }, name: 'job-name', retried: false, retryable: true, + kind: 'BUILD', stage: { id: '1', name: 'build', @@ -25,7 +27,6 @@ export const job = { readBuild: true, updateBuild: true, }, - webPath: '/', }; export const allowedToFailJob = { diff --git a/spec/lib/gitlab/internal_events/event_definitions_spec.rb b/spec/lib/gitlab/internal_events/event_definitions_spec.rb index f6f79d9d906..0eba3cdbcb3 100644 --- a/spec/lib/gitlab/internal_events/event_definitions_spec.rb +++ b/spec/lib/gitlab/internal_events/event_definitions_spec.rb @@ -4,7 +4,7 @@ require "spec_helper" RSpec.describe Gitlab::InternalEvents::EventDefinitions, feature_category: :product_analytics do after(:all) do - described_class.clear_events + described_class.instance_variable_set(:@events, nil) end context 'when using actual metric definitions' do diff --git a/spec/models/network/graph_spec.rb b/spec/models/network/graph_spec.rb index 16894bf28f1..d0c73d6285c 100644 --- a/spec/models/network/graph_spec.rb +++ b/spec/models/network/graph_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Network::Graph do +RSpec.describe Network::Graph, feature_category: :source_code_management do let(:project) { create(:project, :repository) } let!(:note_on_commit) { create(:note_on_commit, project: project) } @@ -36,6 +36,12 @@ RSpec.describe Network::Graph do expect(commits).to all(be_kind_of(Network::Commit)) end + it 'only fetches the commits once', :request_store do + expect(Gitlab::Git::Commit).to receive(:find_all).once.and_call_original + + graph + end + it 'sorts commits by commit date (descending)' do # Remove duplicate timestamps because they make it harder to # assert that the commits are sorted as expected. diff --git a/spec/tooling/danger/database_spec.rb b/spec/tooling/danger/database_spec.rb index ddcfa279dc3..a342014cf6b 100644 --- a/spec/tooling/danger/database_spec.rb +++ b/spec/tooling/danger/database_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'rspec-parameterized' require 'gitlab-dangerfiles' require 'danger' require 'danger/plugins/internal/helper' @@ -41,11 +42,98 @@ RSpec.describe Tooling::Danger::Database, feature_category: :tooling do let(:cutoff) { Date.parse('2022-10-01') - 21 } - subject(:database) { fake_danger.new } + subject(:database) { fake_danger.new(helper: fake_helper) } describe '#find_migration_files_before' do it 'returns migrations that are before the cutoff' do expect(database.find_migration_files_before(migration_files, cutoff).length).to eq(8) end end + + describe '#changes' do + using RSpec::Parameterized::TableSyntax + + where do + { + 'with database changes to a migration file' => { + modified_files: %w[ + db/migrate/20230720114001_test_migration.rb + db/schema_migrations/20230720114001 + db/structure.sql + app/models/test.rb + ], + changed_lines: [], + changes_by_category: { + database: %w[ + db/migrate/20230720114001_test_migration.rb + db/schema_migrations/20230720114001 + db/structure.sql + ] + }, + impacted_files: %w[ + db/migrate/20230720114001_test_migration.rb + db/schema_migrations/20230720114001 + db/structure.sql + ] + }, + 'with non-database changes' => { + modified_files: %w[ + app/models/test.rb + ], + changed_lines: %w[ + +# Comment explaining scope :blah + ], + changes_by_category: { + database: [] + }, + impacted_files: [] + }, + 'with database changes in a doc' => { + modified_files: %w[doc/development/database/test.md], + changed_lines: [ + '+scope :blah, ->() { where(hidden: false) }' + ], + changes_by_category: { + database: [] + }, + impacted_files: [] + }, + 'with database changes in a model' => { + modified_files: %w[app/models/test.rb], + changed_lines: [ + '+# Comment explaining scope :blah', + '+scope :blah, ->() { where(hidden: false) }' + ], + changes_by_category: { + database: [] + }, + impacted_files: %w[app/models/test.rb] + }, + 'with database changes in a concern' => { + modified_files: %w[app/models/concerns/test.rb], + changed_lines: [ + '- .where(hidden: false)', + '+ .where(hidden: true)' + ], + changes_by_category: { + database: [] + }, + impacted_files: %w[app/models/concerns/test.rb] + } + } + end + + with_them do + before do + allow(fake_helper).to receive(:modified_files).and_return(modified_files) + allow(fake_helper).to receive(:all_changed_files).and_return(modified_files) + allow(fake_helper).to receive(:changed_lines).and_return(changed_lines) + allow(fake_helper).to receive(:changes_by_category).and_return(changes_by_category) + end + + it 'returns database changes' do + expect(database.changes).to match impacted_files + end + end + end end diff --git a/tooling/danger/database.rb b/tooling/danger/database.rb index 4cfac7c4af4..71b3ed1a1a5 100644 --- a/tooling/danger/database.rb +++ b/tooling/danger/database.rb @@ -5,6 +5,8 @@ module Tooling module Database TIMESTAMP_MATCHER = /(?\d{14})/ MIGRATION_MATCHER = %r{\A(ee/)?db/(geo/)?(post_)?migrate/} + MODEL_PATHS = %r{\A(ee/)?app/models/} + MODEL_CHANGES = %r{^[^#\n]*?(?:scope :|where\(|joins\()} def find_migration_files_before(file_names, cutoff) migrations = file_names.select { |f| f.match?(MIGRATION_MATCHER) } @@ -15,6 +17,20 @@ module Tooling timestamp < cutoff end end + + def changes + changed_database_paths + changed_model_paths + end + + def changed_database_paths + helper.changes_by_category[:database] + end + + def changed_model_paths + helper.all_changed_files.grep(MODEL_PATHS).select do |file| + helper.changed_lines(file).any? { |change| change =~ MODEL_CHANGES } + end + end end end end