diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-24 15:08:44 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-24 15:08:44 +0000 |
commit | 120f4aaedc8fe830a3f572491d240d8ee6addefb (patch) | |
tree | a2138baa55dfa67d292fb1a83ce686ee7f5d10a5 | |
parent | 729e3765d5feb762df1ccfbc228a8dd4662aa3f9 (diff) | |
download | gitlab-ce-120f4aaedc8fe830a3f572491d240d8ee6addefb.tar.gz |
Add latest changes from gitlab-org/gitlab@master
47 files changed, 317 insertions, 68 deletions
diff --git a/app/assets/javascripts/pages/admin/application_settings/integrations/index.js b/app/assets/javascripts/pages/admin/application_settings/integrations/index.js new file mode 100644 index 00000000000..2e61eedd185 --- /dev/null +++ b/app/assets/javascripts/pages/admin/application_settings/integrations/index.js @@ -0,0 +1,6 @@ +import PersistentUserCallout from '~/persistent_user_callout'; + +document.addEventListener('DOMContentLoaded', () => { + const callout = document.querySelector('.js-admin-integrations-moved'); + PersistentUserCallout.factory(callout); +}); diff --git a/app/assets/javascripts/pages/projects/snippets/show/index.js b/app/assets/javascripts/pages/projects/snippets/show/index.js index d8fbb851ffb..e49d46ea97b 100644 --- a/app/assets/javascripts/pages/projects/snippets/show/index.js +++ b/app/assets/javascripts/pages/projects/snippets/show/index.js @@ -3,7 +3,7 @@ import ZenMode from '~/zen_mode'; import LineHighlighter from '~/line_highlighter'; import BlobViewer from '~/blob/viewer'; import snippetEmbed from '~/snippet/snippet_embed'; -import initSnippetsApp from '~/snippets'; +import { SnippetShowInit } from '~/snippets'; document.addEventListener('DOMContentLoaded', () => { if (!gon.features.snippetsVue) { @@ -13,7 +13,7 @@ document.addEventListener('DOMContentLoaded', () => { new ZenMode(); // eslint-disable-line no-new snippetEmbed(); } else { - initSnippetsApp(); + SnippetShowInit(); initNotes(); } }); diff --git a/app/assets/javascripts/pages/snippets/show/index.js b/app/assets/javascripts/pages/snippets/show/index.js index 3bc9d4f957f..9a463b4762b 100644 --- a/app/assets/javascripts/pages/snippets/show/index.js +++ b/app/assets/javascripts/pages/snippets/show/index.js @@ -3,7 +3,7 @@ import BlobViewer from '~/blob/viewer'; import ZenMode from '~/zen_mode'; import initNotes from '~/init_notes'; import snippetEmbed from '~/snippet/snippet_embed'; -import initSnippetsApp from '~/snippets'; +import { SnippetShowInit } from '~/snippets'; document.addEventListener('DOMContentLoaded', () => { if (!gon.features.snippetsVue) { @@ -13,7 +13,7 @@ document.addEventListener('DOMContentLoaded', () => { new ZenMode(); // eslint-disable-line no-new snippetEmbed(); } else { - initSnippetsApp(); + SnippetShowInit(); initNotes(); } }); diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue index 0c9d242f509..6c977b841af 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue @@ -58,7 +58,11 @@ export default { </script> <template> <div class="table-section section-10 d-none d-sm-none d-md-block pipeline-tags"> - <gl-link :href="pipeline.path" class="js-pipeline-url-link js-onboarding-pipeline-item"> + <gl-link + :href="pipeline.path" + class="js-pipeline-url-link js-onboarding-pipeline-item" + data-qa-selector="pipeline_url_link" + > <span class="pipeline-id">#{{ pipeline.id }}</span> </gl-link> <div class="label-container"> diff --git a/app/assets/javascripts/snippets/components/app.vue b/app/assets/javascripts/snippets/components/show.vue index e98f56d87f5..e98f56d87f5 100644 --- a/app/assets/javascripts/snippets/components/app.vue +++ b/app/assets/javascripts/snippets/components/show.vue diff --git a/app/assets/javascripts/snippets/index.js b/app/assets/javascripts/snippets/index.js index 654856f8d14..b826110117c 100644 --- a/app/assets/javascripts/snippets/index.js +++ b/app/assets/javascripts/snippets/index.js @@ -3,19 +3,16 @@ import Translate from '~/vue_shared/translate'; import VueApollo from 'vue-apollo'; import createDefaultClient from '~/lib/graphql'; -import SnippetsApp from './components/app.vue'; +import SnippetsApp from './components/show.vue'; Vue.use(VueApollo); Vue.use(Translate); -export default () => { - const el = document.getElementById('js-snippet-view'); - +function appFactory(el, Component) { if (!el) { return false; } - const { snippetGid } = el.dataset; const apolloProvider = new VueApollo({ defaultClient: createDefaultClient(), }); @@ -24,11 +21,17 @@ export default () => { el, apolloProvider, render(createElement) { - return createElement(SnippetsApp, { + return createElement(Component, { props: { - snippetGid, + ...el.dataset, }, }); }, }); +} + +export const SnippetShowInit = () => { + appFactory(document.getElementById('js-snippet-view'), SnippetsApp); }; + +export default () => {}; diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss index 1eff21401a2..00d738a50be 100644 --- a/app/assets/stylesheets/utilities.scss +++ b/app/assets/stylesheets/utilities.scss @@ -81,3 +81,8 @@ .gl-text-green-700 { @include gl-text-green-700; } .gl-align-items-center { @include gl-align-items-center; } +.d-sm-table-column { + @include media-breakpoint-up(sm) { + display: table-column !important; + } +} diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 2192bcc96ee..ef6af01eff6 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -27,6 +27,16 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController define_method(action) { perform_update if submitted? } end + def integrations + if Feature.enabled?(:instance_level_integrations) + # TODO: Update this with actual integrations + # To be fixed with https://gitlab.com/gitlab-org/gitlab/-/issues/199388 + @integrations = [] + end + + perform_update if submitted? + end + def update perform_update end diff --git a/app/helpers/broadcast_messages_helper.rb b/app/helpers/broadcast_messages_helper.rb index 73c68dd9e18..0c32b48a85a 100644 --- a/app/helpers/broadcast_messages_helper.rb +++ b/app/helpers/broadcast_messages_helper.rb @@ -48,7 +48,7 @@ module BroadcastMessagesHelper def render_broadcast_message(broadcast_message) if Feature.enabled?(:broadcast_message_placeholders) - Banzai.render_and_post_process(broadcast_message.message, { + Banzai.render_field_and_post_process(broadcast_message, :message, { current_user: current_user, skip_project_check: true, broadcast_message_placeholders: true diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb index caef6dba212..d2336de7193 100644 --- a/app/helpers/services_helper.rb +++ b/app/helpers/services_helper.rb @@ -62,6 +62,10 @@ module ServicesHelper !current_controller?("admin/services") && service.deprecated? end + def edit_integration_path(integration) + edit_admin_application_settings_integration_path(integration) + end + extend self end diff --git a/app/helpers/user_callouts_helper.rb b/app/helpers/user_callouts_helper.rb index 841599abe81..34c8ce51df0 100644 --- a/app/helpers/user_callouts_helper.rb +++ b/app/helpers/user_callouts_helper.rb @@ -1,12 +1,17 @@ # frozen_string_literal: true module UserCalloutsHelper + ADMIN_INTEGRATIONS_MOVED = 'admin_integrations_moved' GKE_CLUSTER_INTEGRATION = 'gke_cluster_integration' GCP_SIGNUP_OFFER = 'gcp_signup_offer' SUGGEST_POPOVER_DISMISSED = 'suggest_popover_dismissed' TABS_POSITION_HIGHLIGHT = 'tabs_position_highlight' WEBHOOKS_MOVED = 'webhooks_moved' + def show_admin_integrations_moved? + !user_dismissed?(ADMIN_INTEGRATIONS_MOVED) + end + def show_gke_cluster_integration_callout?(project) can?(current_user, :create_cluster, project) && !user_dismissed?(GKE_CLUSTER_INTEGRATION) diff --git a/app/models/concerns/optionally_search.rb b/app/models/concerns/optionally_search.rb index 06f8c3dc1cb..9d43c61eb57 100644 --- a/app/models/concerns/optionally_search.rb +++ b/app/models/concerns/optionally_search.rb @@ -4,7 +4,7 @@ module OptionallySearch extend ActiveSupport::Concern class_methods do - def search(*) + def search(query, **options) raise( NotImplementedError, 'Your model must implement the "search" class method' diff --git a/app/models/label.rb b/app/models/label.rb index 106d26685d4..d9c5fe0bb39 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -138,7 +138,7 @@ class Label < ApplicationRecord # query - The search query as a String. # # Returns an ActiveRecord::Relation. - def self.search(query) + def self.search(query, **options) fuzzy_search(query, [:title, :description]) end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 2deece8c7cd..260ba9ea4a5 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -274,7 +274,7 @@ class Namespace < ApplicationRecord end def has_parent? - parent_id.present? || parent.present? + parent.present? end def root_ancestor diff --git a/app/models/project_services/discord_service.rb b/app/models/project_services/discord_service.rb index ff1a9552a6c..294b286f073 100644 --- a/app/models/project_services/discord_service.rb +++ b/app/models/project_services/discord_service.rb @@ -3,6 +3,8 @@ require "discordrb/webhooks" class DiscordService < ChatNotificationService + ATTACHMENT_REGEX = /: (?<entry>.*?)\n - (?<name>.*)\n*/.freeze + def title s_("DiscordService|Discord Notifications") end @@ -52,7 +54,10 @@ class DiscordService < ChatNotificationService client = Discordrb::Webhooks::Client.new(url: webhook) client.execute do |builder| - builder.content = message.pretext + builder.add_embed do |embed| + embed.author = Discordrb::Webhooks::EmbedAuthor.new(name: message.user_name, icon_url: message.user_avatar) + embed.description = (message.pretext + "\n" + Array.wrap(message.attachments).join("\n")).gsub(ATTACHMENT_REGEX, " \\k<entry> - \\k<name>\n") + end end end diff --git a/app/models/user.rb b/app/models/user.rb index 4f484657f13..090d033f80c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -511,7 +511,7 @@ class User < ApplicationRecord # query - The search query as a String # # Returns an ActiveRecord::Relation. - def search(query) + def search(query, **options) query = query&.delete_prefix('@') return none if query.blank? diff --git a/app/models/user_callout_enums.rb b/app/models/user_callout_enums.rb index 625cbb4fe5f..0a3f597ae27 100644 --- a/app/models/user_callout_enums.rb +++ b/app/models/user_callout_enums.rb @@ -16,7 +16,8 @@ module UserCalloutEnums cluster_security_warning: 3, suggest_popover_dismissed: 9, tabs_position_highlight: 10, - webhooks_moved: 13 + webhooks_moved: 13, + admin_integrations_moved: 15 } end end diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml index 94048060767..1a029996aaf 100644 --- a/app/views/admin/application_settings/general.html.haml +++ b/app/views/admin/application_settings/general.html.haml @@ -103,3 +103,12 @@ = s_('IDE|Allow live previews of JavaScript projects in the Web IDE using CodeSandbox client side evaluation.') = f.submit _('Save changes'), class: "btn btn-success" + +- if Feature.enabled?(:instance_level_integrations) + = render_if_exists 'admin/application_settings/elasticsearch_form' + = render 'admin/application_settings/plantuml' + = render 'admin/application_settings/sourcegraph' + = render_if_exists 'admin/application_settings/slack' + = render 'admin/application_settings/third_party_offers' + = render 'admin/application_settings/snowplow' + = render 'admin/application_settings/eks' diff --git a/app/views/admin/application_settings/integrations.html.haml b/app/views/admin/application_settings/integrations.html.haml index c6318c9bb2f..14df0599583 100644 --- a/app/views/admin/application_settings/integrations.html.haml +++ b/app/views/admin/application_settings/integrations.html.haml @@ -1,12 +1,30 @@ -- breadcrumb_title _("Integrations") -- page_title _("Integrations") -- @content_class = "limit-container-width" unless fluid_layout +- breadcrumb_title _('Integrations') +- page_title _('Integrations') +- @content_class = 'limit-container-width' unless fluid_layout -= render_if_exists 'admin/application_settings/elasticsearch_form' -= render 'admin/application_settings/plantuml' -= render 'admin/application_settings/sourcegraph' -= render_if_exists 'admin/application_settings/slack' -= render 'admin/application_settings/third_party_offers' -= render 'admin/application_settings/snowplow' -= render 'admin/application_settings/eks' +- if Feature.enabled?(:instance_level_integrations) + - if show_admin_integrations_moved? + .gl-alert.gl-alert-info.js-admin-integrations-moved.mt-3{ role: 'alert', data: { feature_id: UserCalloutsHelper::ADMIN_INTEGRATIONS_MOVED, dismiss_endpoint: user_callouts_path } } + = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') } + = sprite_icon('close', size: 16, css_class: 'gl-icon') + .gl-alert-body + %h4.gl-alert-title= s_('AdminSettings|Some settings have moved') + = s_('AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General.') + .gl-alert-actions + = link_to s_('AdminSettings|Go to General Settings'), admin_application_settings_path, class: 'btn gl-alert-action btn-info new-gl-button' + %h4= s_('AdminSettings|Apply integration settings to all Projects') + %p + = s_('AdminSettings|Integrations configured here will automatically apply to all projects on this instance.') + = link_to _('Learn more'), '#' + = render 'projects/services/integrations' + +- else + = render_if_exists 'admin/application_settings/elasticsearch_form' + = render 'admin/application_settings/plantuml' + = render 'admin/application_settings/sourcegraph' + = render_if_exists 'admin/application_settings/slack' + = render 'admin/application_settings/third_party_offers' + = render 'admin/application_settings/snowplow' + = render 'admin/application_settings/eks' diff --git a/app/views/admin/integrations/edit.html.haml b/app/views/admin/integrations/edit.html.haml index dea0f524f03..b19d00d7a16 100644 --- a/app/views/admin/integrations/edit.html.haml +++ b/app/views/admin/integrations/edit.html.haml @@ -1,4 +1,4 @@ -- add_to_breadcrumbs _('Integrations'), admin_application_settings_integration_path +- add_to_breadcrumbs _('Integrations'), integrations_admin_application_settings_path - breadcrumb_title @service.title - page_title @service.title, _('Integrations') diff --git a/app/views/projects/services/_integrations.html.haml b/app/views/projects/services/_integrations.html.haml new file mode 100644 index 00000000000..e51585e55a4 --- /dev/null +++ b/app/views/projects/services/_integrations.html.haml @@ -0,0 +1,26 @@ +%table.table.b-table.gl-table.mt-3{ role: 'table', 'aria-busy': false, 'aria-colcount': 4 } + %colgroup + %col + %col + %col.d-none.d-sm-table-column + %col{ width: 120 } + %thead{ role: 'rowgroup' } + %tr{ role: 'row' } + %th{ role: 'columnheader', scope: 'col', 'aria-colindex': 1 } + %th{ role: 'columnheader', scope: 'col', 'aria-colindex': 2 }= _('Integration') + %th.d-none.d-sm-block{ role: 'columnheader', scope: 'col', 'aria-colindex': 3 }= _('Description') + %th{ role: 'columnheader', scope: 'col', 'aria-colindex': 4 }= _('Last updated') + + %tbody{ role: 'rowgroup' } + - @integrations&.each do |integration| + %tr{ role: 'row' } + %td{ role: 'cell', 'aria-colindex': 1 } + = boolean_to_icon integration.activated? + %td{ role: 'cell', 'aria-colindex': 2 } + = link_to edit_integration_path(integration) do + %strong= integration.title + %td.d-none.d-sm-block{ role: 'cell', 'aria-colindex': 3 } + = integration.description + %td{ role: 'cell', 'aria-colindex': 4 } + - if integration.updated_at.present? + = time_ago_with_tooltip integration.updated_at diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index cae4bb73e04..c101759ff9b 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -928,7 +928,7 @@ :weight: 2 :idempotent: true - :name: background_migration - :feature_category: :not_owned + :feature_category: :database :has_external_dependencies: :urgency: :low :resource_boundary: :unknown diff --git a/app/workers/background_migration_worker.rb b/app/workers/background_migration_worker.rb index 231c2bcd83b..f5fd73156b3 100644 --- a/app/workers/background_migration_worker.rb +++ b/app/workers/background_migration_worker.rb @@ -3,7 +3,7 @@ class BackgroundMigrationWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker - feature_category_not_owned! + feature_category :database # The minimum amount of time between processing two jobs of the same migration # class. diff --git a/changelogs/unreleased/208923-enable-batch-counting-for-some-individual-queries-6.yml b/changelogs/unreleased/208923-enable-batch-counting-for-some-individual-queries-6.yml new file mode 100644 index 00000000000..a4fe7f430c5 --- /dev/null +++ b/changelogs/unreleased/208923-enable-batch-counting-for-some-individual-queries-6.yml @@ -0,0 +1,5 @@ +--- +title: Optimize usage ping queries by using batch counting +merge_request: 27455 +author: +type: performance diff --git a/changelogs/unreleased/26978-discord-messages.yml b/changelogs/unreleased/26978-discord-messages.yml new file mode 100644 index 00000000000..502e28286fe --- /dev/null +++ b/changelogs/unreleased/26978-discord-messages.yml @@ -0,0 +1,5 @@ +--- +title: Update discord notifications to be a single embed and include log messages +merge_request: 27812 +author: Sam Bingner +type: fixed diff --git a/changelogs/unreleased/replace-cve-with-id.yml b/changelogs/unreleased/replace-cve-with-id.yml new file mode 100644 index 00000000000..9b2e01d22ec --- /dev/null +++ b/changelogs/unreleased/replace-cve-with-id.yml @@ -0,0 +1,5 @@ +--- +title: Use id instead of cve where possible when parsing remediations +merge_request: 27815 +author: +type: other diff --git a/config/feature_categories.yml b/config/feature_categories.yml index 7e3746baec5..b40bbdd9658 100644 --- a/config/feature_categories.yml +++ b/config/feature_categories.yml @@ -9,6 +9,7 @@ --- - accessibility_testing - analysis +- api - attack_emulation - audit_events - audit_reports @@ -24,14 +25,16 @@ - code_analytics - code_quality - code_review +- code_testing - collection - compliance_management +- container_behavior_analytics - container_network_security - container_registry - container_scanning - continuous_delivery - continuous_integration -- ddos_protection +- database - dependency_firewall - dependency_proxy - dependency_scanning @@ -43,8 +46,8 @@ - epics - error_tracking - feature_flags -- frontend_foundation -- fuzzing +- foundations +- fuzz-testing - gdk - geo_replication - git_lfs @@ -72,6 +75,7 @@ - load_testing - logging - malware_scanning +- merge_trains - metrics - omnibus_package - package_registry @@ -87,8 +91,6 @@ - roadmaps - runbooks - runner -- runtime_application_self_protection -- sdk - secret_detection - secrets_management - serverless @@ -100,10 +102,8 @@ - status_page - subgroups - templates -- threat_detection - time_tracking - tracing -- unit_testing - usability_testing - users - value_stream_management diff --git a/lib/banzai.rb b/lib/banzai.rb index 1eb41ff7133..f183d409704 100644 --- a/lib/banzai.rb +++ b/lib/banzai.rb @@ -8,6 +8,10 @@ module Banzai post_process(render(text, context), context) end + def self.render_field_and_post_process(object, field, context = {}) + post_process(render_field(object, field, context), context) + end + def self.render(text, context = {}) Renderer.render(text, context) end diff --git a/lib/gitlab/ci/pipeline/chain/validate/external.rb b/lib/gitlab/ci/pipeline/chain/validate/external.rb index 44dc333a6a1..24628338dd2 100644 --- a/lib/gitlab/ci/pipeline/chain/validate/external.rb +++ b/lib/gitlab/ci/pipeline/chain/validate/external.rb @@ -13,7 +13,12 @@ module Gitlab VALIDATION_REQUEST_TIMEOUT = 5 def perform! - error('External validation failed', drop_reason: :external_validation_failure) unless validate_external + pipeline_authorized = validate_external + + log_message = pipeline_authorized ? 'authorized' : 'not authorized' + Gitlab::AppLogger.info(message: "Pipeline #{log_message}", project_id: @pipeline.project.id, user_id: @pipeline.user.id) + + error('External validation failed', drop_reason: :external_validation_failure) unless pipeline_authorized end def break? diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 4457dffd603..384f7d159fd 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -218,9 +218,9 @@ module Gitlab results[:projects_jira_server_active] += counts[:server].count if counts[:server] results[:projects_jira_cloud_active] += counts[:cloud].count if counts[:cloud] if results[:projects_jira_active] == -1 - results[:projects_jira_active] = count(services, batch: false) + results[:projects_jira_active] = services.size else - results[:projects_jira_active] += count(services, batch: false) + results[:projects_jira_active] += services.size end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index cb8ba1baab7..e1cff49bee2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1346,15 +1346,27 @@ msgstr "" msgid "AdminProjects|Delete project" msgstr "" +msgid "AdminSettings|Apply integration settings to all Projects" +msgstr "" + msgid "AdminSettings|Auto DevOps domain" msgstr "" +msgid "AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General." +msgstr "" + msgid "AdminSettings|Enable shared runners for new projects" msgstr "" msgid "AdminSettings|Environment variables are protected by default" msgstr "" +msgid "AdminSettings|Go to General Settings" +msgstr "" + +msgid "AdminSettings|Integrations configured here will automatically apply to all projects on this instance." +msgstr "" + msgid "AdminSettings|No required pipeline" msgstr "" @@ -1370,6 +1382,9 @@ msgstr "" msgid "AdminSettings|Set an instance-wide auto included %{link_start}pipeline configuration%{link_end}. This pipeline configuration will be run after the project's own configuration." msgstr "" +msgid "AdminSettings|Some settings have moved" +msgstr "" + msgid "AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages." msgstr "" @@ -8458,6 +8473,9 @@ msgstr "" msgid "Failed to load errors from Sentry. Error message: %{errorMessage}" msgstr "" +msgid "Failed to load group activity metrics. Please try again." +msgstr "" + msgid "Failed to load groups & users." msgstr "" @@ -10015,6 +10033,15 @@ msgstr "" msgid "Group: %{name}" msgstr "" +msgid "GroupActivyMetrics|Issues created" +msgstr "" + +msgid "GroupActivyMetrics|Merge Requests created" +msgstr "" + +msgid "GroupActivyMetrics|Recent activity (last 90 days)" +msgstr "" + msgid "GroupRoadmap|%{dateWord} – No end date" msgstr "" @@ -10943,6 +10970,9 @@ msgstr "" msgid "Instance license" msgstr "" +msgid "Integration" +msgstr "" + msgid "Integration Settings" msgstr "" @@ -478,7 +478,7 @@ module QA autoload :Configure, 'qa/vendor/jenkins/page/configure' autoload :NewCredentials, 'qa/vendor/jenkins/page/new_credentials' autoload :NewJob, 'qa/vendor/jenkins/page/new_job' - autoload :Job, 'qa/vendor/jenkins/page/job' + autoload :LastJobConsole, 'qa/vendor/jenkins/page/last_job_console' autoload :ConfigureJob, 'qa/vendor/jenkins/page/configure_job' end end diff --git a/qa/qa/page/project/pipeline/index.rb b/qa/qa/page/project/pipeline/index.rb index f018e4bf018..f9332e0a853 100644 --- a/qa/qa/page/project/pipeline/index.rb +++ b/qa/qa/page/project/pipeline/index.rb @@ -4,7 +4,7 @@ module QA::Page module Project::Pipeline class Index < QA::Page::Base view 'app/assets/javascripts/pipelines/components/pipeline_url.vue' do - element :pipeline_link, 'class="js-pipeline-url-link' # rubocop:disable QA/ElementWithPattern + element :pipeline_url_link end view 'app/assets/javascripts/pipelines/components/pipelines_table_row.vue' do @@ -13,9 +13,7 @@ module QA::Page end def click_on_latest_pipeline - css = '.js-pipeline-url-link' - - first(css, wait: 60).click + all_elements(:pipeline_url_link, minimum: 1, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).first.click end def wait_for_latest_pipeline_success diff --git a/qa/qa/vendor/jenkins/page/configure_job.rb b/qa/qa/vendor/jenkins/page/configure_job.rb index ab16e895fa9..56a2602a003 100644 --- a/qa/qa/vendor/jenkins/page/configure_job.rb +++ b/qa/qa/vendor/jenkins/page/configure_job.rb @@ -18,6 +18,7 @@ module QA click_build_when_change_is_pushed_to_gitlab set_publish_status_to_gitlab click_save + wait_for_configuration_to_save end private @@ -55,6 +56,12 @@ module QA def select_publish_build_status_to_gitlab click_link "Publish build status to GitLab" end + + def wait_for_configuration_to_save + QA::Support::Waiter.wait_until(sleep_interval: 1.0) do + !page.current_url.include?(@path) + end + end end end end diff --git a/qa/qa/vendor/jenkins/page/job.rb b/qa/qa/vendor/jenkins/page/last_job_console.rb index 498ce6041b8..4c511a8c1f8 100644 --- a/qa/qa/vendor/jenkins/page/job.rb +++ b/qa/qa/vendor/jenkins/page/last_job_console.rb @@ -6,15 +6,19 @@ module QA module Vendor module Jenkins module Page - class Job < Page::Base + class LastJobConsole < Page::Base attr_accessor :job_name def path - "/job/#{@job_name}" + "/job/#{@job_name}/lastBuild/console" end def has_successful_build? - page.has_text?("Last successful build") + page.has_text?('Finished: SUCCESS') + end + + def no_failed_status_update? + page.has_no_text?('Failed to update Gitlab commit status') end end end diff --git a/spec/factories/application_settings.rb b/spec/factories/application_settings.rb index d4571b9861d..8ac003d0a98 100644 --- a/spec/factories/application_settings.rb +++ b/spec/factories/application_settings.rb @@ -3,5 +3,6 @@ FactoryBot.define do factory :application_setting do default_projects_limit { 42 } + import_sources { [] } end end diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 9b275a8897b..743aa0ed60e 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -194,12 +194,6 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc expect(page).to have_content "Application settings saved successfully" expect(current_settings.terminal_max_session_time).to eq(15) end - end - - context 'Integrations page' do - before do - visit integrations_admin_application_settings_path - end it 'Enable hiding third party offers' do page.within('.as-third-party-offers') do @@ -241,6 +235,25 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc end end + context 'Integration page', :js do + before do + visit integrations_admin_application_settings_path + end + + it 'allows user to dismiss deprecation notice' do + expect(page).to have_content('Some settings have moved') + + click_button 'Dismiss' + wait_for_requests + + expect(page).not_to have_content('Some settings have moved') + + visit integrations_admin_application_settings_path + + expect(page).not_to have_content('Some settings have moved') + end + end + context 'CI/CD page' do it 'Change CI/CD settings' do visit ci_cd_admin_application_settings_path diff --git a/spec/features/broadcast_messages_spec.rb b/spec/features/broadcast_messages_spec.rb index 809e53ed7f7..41e8e969610 100644 --- a/spec/features/broadcast_messages_spec.rb +++ b/spec/features/broadcast_messages_spec.rb @@ -68,4 +68,16 @@ describe 'Broadcast Messages' do expect(page).to have_content "Hi #{user.name}" end + + it 'renders broadcast message with placeholders and styled links' do + create(:broadcast_message, broadcast_type: 'notification', message: "Hi {{name}} <a href='gitlab.com' style='color: purple'>click</a>") + + user = create(:user) + sign_in(user) + + visit root_path + + expected_html = "<p>Hi #{user.name} <a href=\"gitlab.com\" style=\"color: purple\">click</a></p>" + expect(page.body).to include(expected_html) + end end diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index df786cf0818..15045023cf8 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -208,7 +208,7 @@ describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) - visit integrations_admin_application_settings_path + visit general_admin_application_settings_path end it 'user does not see the offer' do diff --git a/spec/frontend/snippets/components/app_spec.js b/spec/frontend/snippets/components/show_spec.js index a683ed9aaba..33608df8cf2 100644 --- a/spec/frontend/snippets/components/app_spec.js +++ b/spec/frontend/snippets/components/show_spec.js @@ -1,4 +1,4 @@ -import SnippetApp from '~/snippets/components/app.vue'; +import SnippetApp from '~/snippets/components/show.vue'; import SnippetHeader from '~/snippets/components/snippet_header.vue'; import SnippetTitle from '~/snippets/components/snippet_title.vue'; import SnippetBlob from '~/snippets/components/snippet_blob_view.vue'; diff --git a/spec/helpers/user_callouts_helper_spec.rb b/spec/helpers/user_callouts_helper_spec.rb index 547bf693e94..b123b11d278 100644 --- a/spec/helpers/user_callouts_helper_spec.rb +++ b/spec/helpers/user_callouts_helper_spec.rb @@ -47,6 +47,26 @@ describe UserCalloutsHelper do end end + describe '.show_admin_integrations_moved?' do + subject { helper.show_admin_integrations_moved? } + + context 'when user has not dismissed' do + before do + allow(helper).to receive(:user_dismissed?).with(described_class::ADMIN_INTEGRATIONS_MOVED) { false } + end + + it { is_expected.to be true } + end + + context 'when user dismissed' do + before do + allow(helper).to receive(:user_dismissed?).with(described_class::ADMIN_INTEGRATIONS_MOVED) { true } + end + + it { is_expected.to be false } + end + end + describe '.render_flash_user_callout' do it 'renders the flash_user_callout partial' do expect(helper).to receive(:render) diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb index f2a0b93ef28..9a2cf014007 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb @@ -67,6 +67,12 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::External do expect(step.break?).to be false end + + it 'logs the authorization' do + expect(Gitlab::AppLogger).to receive(:info).with(message: 'Pipeline authorized', project_id: project.id, user_id: user.id) + + perform! + end end context 'when validation return false' do @@ -86,6 +92,12 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::External do expect(step.break?).to be true end + + it 'logs the authorization' do + expect(Gitlab::AppLogger).to receive(:info).with(message: 'Pipeline not authorized', project_id: project.id, user_id: user.id) + + perform! + end end end diff --git a/spec/models/concerns/optionally_search_spec.rb b/spec/models/concerns/optionally_search_spec.rb index 71cf536db89..e1eb4cf8cd2 100644 --- a/spec/models/concerns/optionally_search_spec.rb +++ b/spec/models/concerns/optionally_search_spec.rb @@ -3,28 +3,39 @@ require 'spec_helper' describe OptionallySearch do - let(:model) do - Class.new(ActiveRecord::Base) do - self.table_name = 'users' - - include OptionallySearch + describe '.search' do + let(:model) do + Class.new do + include OptionallySearch + end end - end - describe '.search' do it 'raises NotImplementedError' do expect { model.search('foo') }.to raise_error(NotImplementedError) end end describe '.optionally_search' do + let(:model) do + Class.new(ActiveRecord::Base) do + self.table_name = 'users' + + include OptionallySearch + + def self.search(query, **options) + [query, options] + end + end + end + context 'when a query is given' do it 'delegates to the search method' do expect(model) .to receive(:search) .with('foo', {}) + .and_call_original - model.optionally_search('foo') + expect(model.optionally_search('foo')).to eq(['foo', {}]) end end @@ -33,8 +44,9 @@ describe OptionallySearch do expect(model) .to receive(:search) .with('foo', some_option: true) + .and_call_original - model.optionally_search('foo', some_option: true) + expect(model.optionally_search('foo', some_option: true)).to eq(['foo', { some_option: true }]) end end diff --git a/spec/models/project_services/discord_service_spec.rb b/spec/models/project_services/discord_service_spec.rb index 96ac532dcd1..b5a54676dd7 100644 --- a/spec/models/project_services/discord_service_spec.rb +++ b/spec/models/project_services/discord_service_spec.rb @@ -31,6 +31,24 @@ describe DiscordService do WebMock.stub_request(:post, webhook_url) end + it 'uses the right embed parameters' do + builder = Discordrb::Webhooks::Builder.new + + allow_next_instance_of(Discordrb::Webhooks::Client) do |client| + allow(client).to receive(:execute).and_yield(builder) + end + + subject.execute(sample_data) + + expect(builder.to_json_hash[:embeds].first).to include( + description: start_with("#{user.name} pushed to branch [master](http://localhost/#{project.namespace.path}/#{project.path}/commits/master) of"), + author: hash_including( + icon_url: start_with('https://www.gravatar.com/avatar/'), + name: user.name + ) + ) + end + context 'DNS rebind to local address' do before do stub_dns(webhook_url, ip_address: '192.168.2.120') diff --git a/spec/views/admin/application_settings/integrations.html.haml_spec.rb b/spec/views/admin/application_settings/general.html.haml_spec.rb index 392d43ef2d4..e6a0307afd9 100644 --- a/spec/views/admin/application_settings/integrations.html.haml_spec.rb +++ b/spec/views/admin/application_settings/general.html.haml_spec.rb @@ -2,8 +2,9 @@ require 'spec_helper' -describe 'admin/application_settings/integrations.html.haml' do +describe 'admin/application_settings/general.html.haml' do let(:app_settings) { build(:application_setting) } + let(:user) { create(:admin) } describe 'sourcegraph integration' do let(:sourcegraph_flag) { true } @@ -11,6 +12,7 @@ describe 'admin/application_settings/integrations.html.haml' do before do assign(:application_setting, app_settings) allow(Gitlab::Sourcegraph).to receive(:feature_available?).and_return(sourcegraph_flag) + allow(view).to receive(:current_user).and_return(user) end context 'when sourcegraph feature is enabled' do diff --git a/vendor/gitignore/C++.gitignore b/vendor/gitignore/C++.gitignore index 259148fa18f..259148fa18f 100755..100644 --- a/vendor/gitignore/C++.gitignore +++ b/vendor/gitignore/C++.gitignore diff --git a/vendor/gitignore/Java.gitignore b/vendor/gitignore/Java.gitignore index a1c2a238a96..a1c2a238a96 100755..100644 --- a/vendor/gitignore/Java.gitignore +++ b/vendor/gitignore/Java.gitignore |