diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue index 91f7c7dabf6..44b8282a8ab 100644 --- a/app/assets/javascripts/integrations/edit/components/integration_form.vue +++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue @@ -87,6 +87,7 @@ export default { }, helpHtmlConfig: { ADD_TAGS: ['use'], // to support icon SVGs + FORBID_ATTR: [], // This is trusted input so we can override the default config to allow data-* attributes }, }; diff --git a/app/assets/stylesheets/_jh/application_jh.scss b/app/assets/stylesheets/_jh/application_jh.scss new file mode 100644 index 00000000000..9d9918d5bbd --- /dev/null +++ b/app/assets/stylesheets/_jh/application_jh.scss @@ -0,0 +1,5 @@ +/* + This is a noop-file. In JH: + jh/app/assets/stylesheets/_jh/application_jh.scss + will take precedence over it and import more styles + */ diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 9ef1b58ed24..40228b93e01 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -24,6 +24,9 @@ // EE-only stylesheets @import 'application_ee'; +// JH-only stylesheets +@import 'application_jh'; + /* print styles */ @media print { @import 'print'; diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb index 88c709e3f53..0f40c9bfd2c 100644 --- a/app/controllers/groups/settings/ci_cd_controller.rb +++ b/app/controllers/groups/settings/ci_cd_controller.rb @@ -60,6 +60,7 @@ module Groups def define_variables define_ci_variables + define_view_variables end def define_ci_variables @@ -69,6 +70,10 @@ module Groups .map { |variable| variable.present(current_user: current_user) } end + def define_view_variables + @content_class = 'limit-container-width' unless fluid_layout + end + def authorize_admin_group! return render_404 unless can?(current_user, :admin_group, group) end diff --git a/app/models/concerns/time_trackable.rb b/app/models/concerns/time_trackable.rb index 89b42eec727..a638d62d79c 100644 --- a/app/models/concerns/time_trackable.rb +++ b/app/models/concerns/time_trackable.rb @@ -11,7 +11,7 @@ module TimeTrackable extend ActiveSupport::Concern included do - attr_reader :time_spent, :time_spent_user, :spent_at + attr_reader :time_spent, :time_spent_user, :spent_at, :summary alias_method :time_spent?, :time_spent @@ -29,6 +29,7 @@ module TimeTrackable @time_spent_note_id = options[:note_id] @time_spent_user = User.find(options[:user_id]) @spent_at = options[:spent_at] + @summary = options[:summary] @original_total_time_spent = nil return if @time_spent == 0 @@ -78,7 +79,8 @@ module TimeTrackable time_spent: time_spent, note_id: @time_spent_note_id, user: @time_spent_user, - spent_at: @spent_at + spent_at: @spent_at, + summary: @summary ) end # rubocop:enable Gitlab/ModuleWithInstanceVariables diff --git a/app/serializers/merge_request_poll_cached_widget_entity.rb b/app/serializers/merge_request_poll_cached_widget_entity.rb index 6ac43e02f3c..7fba52cbe17 100644 --- a/app/serializers/merge_request_poll_cached_widget_entity.rb +++ b/app/serializers/merge_request_poll_cached_widget_entity.rb @@ -50,11 +50,7 @@ class MergeRequestPollCachedWidgetEntity < IssuableEntity MergeRequests::PipelineEntity.represent(merge_request.actual_head_pipeline, options) end - expose :merge_pipeline, if: ->(mr, _) { - Feature.enabled?(:merge_request_cached_merge_pipeline_serializer, mr.project, default_enabled: :yaml) && - mr.merged? && - can?(request.current_user, :read_pipeline, mr.target_project) - } do |merge_request, options| + expose :merge_pipeline, if: ->(mr, _) { mr.merged? && can?(request.current_user, :read_pipeline, mr.target_project) } do |merge_request, options| MergeRequests::PipelineEntity.represent(merge_request.merge_pipeline, options) end diff --git a/app/serializers/merge_request_poll_widget_entity.rb b/app/serializers/merge_request_poll_widget_entity.rb index 3ce67d92af1..074bd2d18d7 100644 --- a/app/serializers/merge_request_poll_widget_entity.rb +++ b/app/serializers/merge_request_poll_widget_entity.rb @@ -19,14 +19,6 @@ class MergeRequestPollWidgetEntity < Grape::Entity # User entities expose :merge_user, using: UserEntity - expose :merge_pipeline, if: ->(mr, _) { - Feature.disabled?(:merge_request_cached_merge_pipeline_serializer, mr.project, default_enabled: :yaml) && - mr.merged? && - can?(request.current_user, :read_pipeline, mr.target_project) - } do |merge_request, options| - MergeRequests::PipelineEntity.represent(merge_request.merge_pipeline, options) - end - expose :default_merge_commit_message expose :mergeable do |merge_request, options| diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml index cddea17efbf..24048a8b328 100644 --- a/app/views/ci/runner/_how_to_setup_runner.html.haml +++ b/app/views/ci/runner/_how_to_setup_runner.html.haml @@ -1,7 +1,6 @@ - link = link_to _("Install GitLab Runner and ensure it's running."), 'https://docs.gitlab.com/runner/install/', target: '_blank' .gl-mb-3 - %h5= _("Set up a %{type} runner manually") % { type: type } - + %h5= _("Set up a %{type} Runner for a project") % { type: type } %ol %li = link.html_safe diff --git a/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml b/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml deleted file mode 100644 index 7140c0f4e7c..00000000000 --- a/app/views/ci/runner/_how_to_setup_runner_automatically.html.haml +++ /dev/null @@ -1,21 +0,0 @@ -%h5= _('Set up a %{type} runner automatically') % { type: type } - -%p - - link_to_help_page = link_to(_('Learn more.'), - help_page_path('user/project/clusters/index'), - target: '_blank', - rel: 'noopener noreferrer') - - = _('Register a runner on a Kubernetes cluster. %{link_to_help_page}').html_safe % { link_to_help_page: link_to_help_page } - -%ol - %li - = _('Click the button below.') - %li - = _('Select an existing Kubernetes cluster or create a new one.') - %li - = _('From the Kubernetes cluster details view, applications list, install GitLab Runner.') - -= link_to _('Install GitLab Runner on Kubernetes'), - clusters_path, - class: 'gl-button btn btn-info' diff --git a/app/views/clusters/clusters/_integrations.html.haml b/app/views/clusters/clusters/_integrations.html.haml index 96219fa9de5..f136091dad5 100644 --- a/app/views/clusters/clusters/_integrations.html.haml +++ b/app/views/clusters/clusters/_integrations.html.haml @@ -5,25 +5,23 @@ .settings-content#integrations-settings-section - if can?(current_user, :admin_cluster, @cluster) .sub-section.form-group - = form_for @prometheus_integration, as: :integration, namespace: :prometheus, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |prometheus_form| + = gitlab_ui_form_for @prometheus_integration, as: :integration, namespace: :prometheus, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |prometheus_form| = prometheus_form.hidden_field :application_type .form-group.gl-form-group - .gl-form-checkbox.custom-control.custom-checkbox - = prometheus_form.check_box :enabled, class: 'custom-control-input' - = prometheus_form.label :enabled, s_('ClusterIntegration|Enable Prometheus integration'), class: 'custom-control-label' - .form-text.text-gl-muted - = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics.') - = link_to _('More information.'), help_page_path("user/clusters/integrations", anchor: "prometheus-cluster-integration"), target: '_blank' + - help_text = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics.') + - help_link = link_to(_('More information.'), help_page_path("user/clusters/integrations", anchor: "prometheus-cluster-integration"), target: '_blank', rel: 'noopener noreferrer') + = prometheus_form.gitlab_ui_checkbox_component :enabled, + s_('ClusterIntegration|Enable Prometheus integration'), + help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link } = prometheus_form.submit _('Save changes'), class: 'btn gl-button btn-success' .sub-section.form-group - = form_for @elastic_stack_integration, as: :integration, namespace: :elastic_stack, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |elastic_stack_form| + = gitlab_ui_form_for @elastic_stack_integration, as: :integration, namespace: :elastic_stack, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |elastic_stack_form| = elastic_stack_form.hidden_field :application_type .form-group.gl-form-group - .gl-form-checkbox.custom-control.custom-checkbox - = elastic_stack_form.check_box :enabled, class: 'custom-control-input' - = elastic_stack_form.label :enabled, s_('ClusterIntegration|Enable Elastic Stack integration'), class: 'custom-control-label' - .form-text.text-gl-muted - = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Elasticsearch for pod logs.') - = link_to _('More information.'), help_page_path("user/clusters/integrations", anchor: "elastic-stack-cluster-integration"), target: '_blank' + - help_text = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Elasticsearch for pod logs.') + - help_link = link_to(_('More information.'), help_page_path("user/clusters/integrations", anchor: "elastic-stack-cluster-integration"), target: '_blank', rel: 'noopener noreferrer') + = elastic_stack_form.gitlab_ui_checkbox_component :enabled, + s_('ClusterIntegration|Enable Elastic Stack integration'), + help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link } = elastic_stack_form.submit _('Save changes'), class: 'btn gl-button btn-success' diff --git a/app/views/groups/runners/_group_runners.html.haml b/app/views/groups/runners/_group_runners.html.haml index 49e297ee13d..1cccce9f59a 100644 --- a/app/views/groups/runners/_group_runners.html.haml +++ b/app/views/groups/runners/_group_runners.html.haml @@ -3,17 +3,14 @@ %h4 = _('Group runners') -%p - = _('These runners are shared across projects in this group.') - = _('Group runners can be managed with the %{link}.').html_safe % { link: link } - -# Proper policies should be implemented per -# https://gitlab.com/gitlab-org/gitlab-foss/issues/45894 .bs-callout.help-callout + %p + = _('These runners are shared across projects in this group.') + = _('Group runners can be managed with the %{link}.').html_safe % { link: link } + - if can?(current_user, :admin_pipeline, @group) && valid_runner_registrars.include?('group') - = render partial: 'ci/runner/how_to_setup_runner_automatically', - locals: { type: 'group', - clusters_path: group_clusters_path(@group) } - if params[:ci_runner_templates] %hr = render partial: 'ci/runner/setup_runner_in_aws', diff --git a/app/views/groups/settings/_two_factor_auth.html.haml b/app/views/groups/settings/_two_factor_auth.html.haml index bd3b3283288..9e5eeee2e2a 100644 --- a/app/views/groups/settings/_two_factor_auth.html.haml +++ b/app/views/groups/settings/_two_factor_auth.html.haml @@ -7,17 +7,15 @@ %p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: ''.html_safe } .form-group - .gl-form-checkbox.custom-control.custom-checkbox - = f.check_box :require_two_factor_authentication, class: 'custom-control-input', data: { qa_selector: 'require_2fa_checkbox' } - = f.label :require_two_factor_authentication, class: 'custom-control-label' do - = _('Require all users in this group to setup two-factor authentication') + = f.gitlab_ui_checkbox_component :require_two_factor_authentication, + _('Require all users in this group to setup two-factor authentication'), + checkbox_options: { data: { qa_selector: 'require_2fa_checkbox' } } .form-group = f.label :two_factor_grace_period, _('Time before enforced'), class: 'label-bold' = f.text_field :two_factor_grace_period, class: 'form-control form-control-sm w-auto' .form-text.text-muted= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication') - unless group.has_parent? .form-group - .gl-form-checkbox.custom-control.custom-checkbox - = f.check_box :allow_mfa_for_subgroups, class: 'custom-control-input', checked: group.namespace_settings&.allow_mfa_for_subgroups - = f.label :allow_mfa_for_subgroups, class: 'custom-control-label' do - = _('Allow subgroups to set up their own two-factor authentication rules') + = f.gitlab_ui_checkbox_component :allow_mfa_for_subgroups, + _('Allow subgroups to set up their own two-factor authentication rules'), + checkbox_options: { checked: group.namespace_settings&.allow_mfa_for_subgroups } diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml index eb376ff7960..5e999b7afb3 100644 --- a/app/views/projects/runners/_specific_runners.html.haml +++ b/app/views/projects/runners/_specific_runners.html.haml @@ -4,10 +4,6 @@ .bs-callout.help-callout - if valid_runner_registrars.include?('project') = _('These runners are specific to this project.') - %hr - = render partial: 'ci/runner/how_to_setup_runner_automatically', - locals: { type: s_('Runners|specific'), - clusters_path: project_clusters_path(@project) } - if params[:ci_runner_templates] %hr = render partial: 'ci/runner/setup_runner_in_aws', diff --git a/config/application.rb b/config/application.rb index 6526be15cd4..ffdb4d1b4d7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -264,7 +264,9 @@ module Gitlab # Import path for EE specific SCSS entry point # In CE it will import a noop file, in EE a functioning file # Order is important, so that the ee file takes precedence: + config.assets.paths << "#{config.root}/jh/app/assets/stylesheets/_jh" if Gitlab.jh? config.assets.paths << "#{config.root}/ee/app/assets/stylesheets/_ee" if Gitlab.ee? + config.assets.paths << "#{config.root}/app/assets/stylesheets/_jh" config.assets.paths << "#{config.root}/app/assets/stylesheets/_ee" config.assets.paths << "#{config.root}/vendor/assets/javascripts/" diff --git a/config/feature_flags/development/merge_request_cached_merge_pipeline_serializer.yml b/config/feature_flags/development/merge_request_cached_merge_pipeline_serializer.yml deleted file mode 100644 index 506e59f001b..00000000000 --- a/config/feature_flags/development/merge_request_cached_merge_pipeline_serializer.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: merge_request_cached_merge_pipeline_serializer -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57827 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326317 -milestone: '13.11' -type: development -group: group::source code -default_enabled: false diff --git a/doc/api/issues.md b/doc/api/issues.md index 6de8912c1af..feec9b31747 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -1950,6 +1950,7 @@ POST /projects/:id/issues/:issue_iid/add_spent_time | `duration` | string | yes | The duration in human format. e.g: 3h30m | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user | | `issue_iid` | integer | yes | The internal ID of a project's issue | +| `summary` | string | no | A summary of how the time was spent | ```shell curl --request POST --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/5/issues/93/add_spent_time?duration=1h" diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index bc8c0397a3a..b90f0e70a02 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -2538,6 +2538,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/add_spent_time | `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. | | `merge_request_iid` | integer | yes | The internal ID of the merge request. | | `duration` | string | yes | The duration in human format, such as `3h30m` | +| `summary` | string | no | A summary of how the time was spent. | ```shell curl --request POST --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/5/merge_requests/93/add_spent_time?duration=1h" diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md index 9eb2405737e..3cbc8ba1862 100644 --- a/doc/user/application_security/dast/index.md +++ b/doc/user/application_security/dast/index.md @@ -54,28 +54,6 @@ results. On failure, the analyzer outputs an [`docker` executor](https://docs.gitlab.com/runner/executors/docker.html). - Target application deployed. For more details, read [Deployment options](#deployment-options). -### DAST job order - -When using the `DAST.gitlab-ci.yml` template, the `dast` stage is run last as shown in -the example below. To ensure DAST scans the latest code, deploy your application -in a stage before the `dast` stage. - -```yaml - stages: - - build - - test - - deploy - - dast -``` - -Be aware that if your pipeline is configured to deploy to the same webserver in -each run, running a pipeline while another is still running could cause a race condition -where one pipeline overwrites the code from another pipeline. The site to be scanned -should be excluded from changes for the duration of a DAST scan. -The only changes to the site should be from the DAST scanner. Be aware that any -changes that users, scheduled tasks, database changes, code changes, other pipelines, or other scanners make to -the site during a scan could lead to inaccurate results. - ### Deployment options Depending on the complexity of the target application, there are a few options as to how to deploy and configure @@ -143,6 +121,34 @@ services: # use services to link the container to the dast job alias: yourapp ``` +### DAST job order + +When using the `DAST.gitlab-ci.yml` template, the `dast` stage is run last as shown in +the example below. To ensure DAST scans the latest code, deploy your application +in a stage before the `dast` stage. + +```yaml + stages: + - build + - test + - deploy + - dast +``` + +Take care if your pipeline is configured to deploy to the same web server in each run. Running a +pipeline while another is still running could result in one pipeline overwriting the code from +another pipeline. The site to be scanned should be excluded from changes for the duration of a DAST +scan. The only changes to the site should be from the DAST scanner. + +Changes to the site during a scan from any of the following could lead to inaccurate results: + +- Users. +- Scheduled tasks. +- Database changes. +- Code changes. +- Other pipelines. +- Other scanners. + ## DAST run options You can use DAST to examine your web application: @@ -838,8 +844,8 @@ Chrome DevTools element selector tool is an effective way to find a selector. ![highlight](img/dast_auth_browser_scan_highlight.png) 1. Once highlighted, you can see the element's details, including attributes that would make a good candidate for a selector. -In this example, the `id="user_login"` appears to be a good candidate. You can use this as a selector as the DAST username field by setting -`DAST_USERNAME_FIELD: "id:user_login"`. +In this example, the `id="user_login"` appears to be a good candidate. You can use this as a selector as the DAST username field by setting +`DAST_USERNAME_FIELD: "id:user_login"`. ##### Choose the right selector diff --git a/lib/api/time_tracking_endpoints.rb b/lib/api/time_tracking_endpoints.rb index 969122d7906..b8323304957 100644 --- a/lib/api/time_tracking_endpoints.rb +++ b/lib/api/time_tracking_endpoints.rb @@ -88,6 +88,7 @@ module API update_params = { spend_time: { duration: Gitlab::TimeTrackingFormatter.parse(params.delete(:duration)), + summary: params.delete(:summary), user_id: current_user.id } } diff --git a/locale/gitlab.pot b/locale/gitlab.pot index abfcba5a429..1adb3cefe79 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1873,9 +1873,6 @@ msgstr "" msgid "Add GitLab to Slack" msgstr "" -msgid "Add Group Webhooks and GitLab Enterprise Edition." -msgstr "" - msgid "Add Jaeger URL" msgstr "" @@ -4622,9 +4619,6 @@ msgstr "" msgid "Audit Events" msgstr "" -msgid "Audit Events is a way to keep track of important events that happened in GitLab." -msgstr "" - msgid "AuditLogs|(removed)" msgstr "" @@ -6847,9 +6841,6 @@ msgstr "" msgid "Click %{link_to} to view the request." msgstr "" -msgid "Click the button below." -msgstr "" - msgid "Click the link below to confirm your email address (%{email})" msgstr "" @@ -11057,9 +11048,6 @@ msgstr "" msgid "Description template" msgstr "" -msgid "Description templates allow you to define context-specific templates for issue and merge request description fields for your project." -msgstr "" - msgid "Description:" msgstr "" @@ -14386,9 +14374,6 @@ msgstr "" msgid "From merge request merge until deploy to production" msgstr "" -msgid "From the Kubernetes cluster details view, applications list, install GitLab Runner." -msgstr "" - msgid "Full" msgstr "" @@ -16754,12 +16739,6 @@ msgstr "" msgid "Improve customer support with Service Desk" msgstr "" -msgid "Improve merge requests and customer support with GitLab Enterprise Edition." -msgstr "" - -msgid "Improve search with Advanced Search and GitLab Enterprise Edition." -msgstr "" - msgid "Improves Git cloning performance." msgstr "" @@ -17537,9 +17516,6 @@ msgstr "" msgid "Install GitLab Runner and ensure it's running." msgstr "" -msgid "Install GitLab Runner on Kubernetes" -msgstr "" - msgid "Install on clusters" msgstr "" @@ -26369,6 +26345,12 @@ msgstr "" msgid "Promotion is not supported." msgstr "" +msgid "Promotions|Add Group Webhooks and GitLab Enterprise Edition." +msgstr "" + +msgid "Promotions|Audit Events is a way to keep track of important events that happened in GitLab." +msgstr "" + msgid "Promotions|Burndown Charts are visual representations of the progress of completing a milestone. At a glance, you see the current state for the completion a given milestone. Without them, you would have to organize the data from the milestone and plot it yourself to have the same sense of progress." msgstr "" @@ -26387,6 +26369,9 @@ msgstr "" msgid "Promotions|Contact your Administrator to upgrade your license." msgstr "" +msgid "Promotions|Description templates allow you to define context-specific templates for issue and merge request description fields for your project." +msgstr "" + msgid "Promotions|Dismiss burndown charts promotion" msgstr "" @@ -26399,39 +26384,72 @@ msgstr "" msgid "Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition." msgstr "" +msgid "Promotions|Improve merge requests and customer support with GitLab Enterprise Edition." +msgstr "" + msgid "Promotions|Improve milestones with Burndown Charts." msgstr "" +msgid "Promotions|Improve search with Advanced Search and GitLab Enterprise Edition." +msgstr "" + msgid "Promotions|Learn more" msgstr "" +msgid "Promotions|Merge request approvals" +msgstr "" + msgid "Promotions|Not now, thanks!" msgstr "" msgid "Promotions|See the other features in the %{subscription_link_start}Premium plan%{subscription_link_end}" msgstr "" +msgid "Promotions|Set the number of necessary approvals and define a list of approvers needed for every merge request in a project." +msgstr "" + msgid "Promotions|Start GitLab Ultimate trial" msgstr "" +msgid "Promotions|The Advanced Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project." +msgstr "" + msgid "Promotions|This feature is locked." msgstr "" msgid "Promotions|Track activity with Contribution Analytics." msgstr "" +msgid "Promotions|Track your project with Audit Events." +msgstr "" + msgid "Promotions|Try it for free" msgstr "" msgid "Promotions|Upgrade plan" msgstr "" +msgid "Promotions|Upgrade your plan to activate Advanced Search." +msgstr "" + +msgid "Promotions|Upgrade your plan to activate Audit Events." +msgstr "" + msgid "Promotions|Upgrade your plan to activate Contribution Analytics." msgstr "" +msgid "Promotions|Upgrade your plan to activate Group Webhooks." +msgstr "" + +msgid "Promotions|Upgrade your plan to improve merge requests." +msgstr "" + msgid "Promotions|Upgrade your plan to improve milestones with Burndown Charts." msgstr "" +msgid "Promotions|Webhooks allow you to trigger a URL if, for example, new code is pushed or a new issue is created. You can configure webhooks to listen for specific events like pushes, issues or merge requests. Group webhooks will apply to all projects in a group, allowing you to standardize webhook functionality across your entire group." +msgstr "" + msgid "Promotions|Weight" msgstr "" @@ -26444,6 +26462,12 @@ msgstr "" msgid "Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members." msgstr "" +msgid "Promotions|description templates" +msgstr "" + +msgid "Promotions|to help your contributors communicate effectively!" +msgstr "" + msgid "Prompt users to upload SSH keys" msgstr "" @@ -27013,9 +27037,6 @@ msgstr "" msgid "Register WebAuthn Device" msgstr "" -msgid "Register a runner on a Kubernetes cluster. %{link_to_help_page}" -msgstr "" - msgid "Register as many runners as you want. You can register runners as separate users, on separate servers, and on your local machine. Runners are either:" msgstr "" @@ -29447,9 +29468,6 @@ msgstr "" msgid "Select an assignee" msgstr "" -msgid "Select an existing Kubernetes cluster or create a new one." -msgstr "" - msgid "Select an iteration" msgstr "" @@ -29909,9 +29927,6 @@ msgstr "" msgid "Set the milestone to %{milestone_reference}." msgstr "" -msgid "Set the number of necessary approvals and define a list of approvers needed for every merge request in a project." -msgstr "" - msgid "Set the timeout in seconds to send a secondary node status to the primary and IPs allowed for the secondary nodes." msgstr "" @@ -29927,7 +29942,7 @@ msgstr "" msgid "Set up Jira Integration" msgstr "" -msgid "Set up a %{type} runner automatically" +msgid "Set up a %{type} Runner for a project" msgstr "" msgid "Set up a %{type} runner manually" @@ -32476,9 +32491,6 @@ msgstr[1] "" msgid "The API key used by GitLab for accessing the Spam Check service endpoint" msgstr "" -msgid "The Advanced Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project." -msgstr "" - msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}." msgstr "" @@ -34552,9 +34564,6 @@ msgstr "" msgid "Track your GitLab projects with GitLab for Slack." msgstr "" -msgid "Track your project with Audit Events." -msgstr "" - msgid "Transfer" msgstr "" @@ -35259,18 +35268,6 @@ msgstr "" msgid "Upgrade your plan" msgstr "" -msgid "Upgrade your plan to activate Advanced Search." -msgstr "" - -msgid "Upgrade your plan to activate Audit Events." -msgstr "" - -msgid "Upgrade your plan to activate Group Webhooks." -msgstr "" - -msgid "Upgrade your plan to improve merge requests." -msgstr "" - msgid "Upload" msgstr "" @@ -36751,9 +36748,6 @@ msgstr "" msgid "Webhooks Help" msgstr "" -msgid "Webhooks allow you to trigger a URL if, for example, new code is pushed or a new issue is created. You can configure webhooks to listen for specific events like pushes, issues or merge requests. Group webhooks will apply to all projects in a group, allowing you to standardize webhook functionality across your entire group." -msgstr "" - msgid "Webhooks|Comments" msgstr "" @@ -39727,9 +39721,6 @@ msgstr "" msgid "time summary" msgstr "" -msgid "to help your contributors communicate effectively!" -msgstr "" - msgid "to join %{source_name}" msgstr "" diff --git a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb index 68afa64df6e..782b5570e4c 100644 --- a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb +++ b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb @@ -97,7 +97,9 @@ module QA group.add_member(user, Resource::Members::AccessLevel::MAINTAINER) end - after do + after do |example| + next if example.pending? + # save data for comparison after run finished save_json( "data", diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index b61a769185e..22de77f7cd0 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -16,10 +16,10 @@ RSpec.describe 'Runners' do project.add_maintainer(user) end - it 'user can see a button to install runners on kubernetes clusters' do + it 'user can see a link with instructions on how to install GitLab Runner' do visit project_runners_path(project) - expect(page).to have_link('Install GitLab Runner on Kubernetes', href: project_clusters_path(project)) + expect(page).to have_link('Install GitLab Runner and ensure it\'s running.', href: "https://docs.gitlab.com/runner/install/") end end @@ -343,12 +343,6 @@ RSpec.describe 'Runners' do expect(page).to have_content 'No runners found' end - - it 'user can see a link to install runners on kubernetes clusters' do - visit group_settings_ci_cd_path(group) - - expect(page).to have_link('Install GitLab Runner on Kubernetes', href: group_clusters_path(group)) - end end context 'group with a runner' do diff --git a/spec/frontend/integrations/edit/components/integration_form_spec.js b/spec/frontend/integrations/edit/components/integration_form_spec.js index cbce26762b1..ff602327592 100644 --- a/spec/frontend/integrations/edit/components/integration_form_spec.js +++ b/spec/frontend/integrations/edit/components/integration_form_spec.js @@ -278,6 +278,7 @@ describe('IntegrationForm', () => { + `); @@ -291,9 +292,14 @@ describe('IntegrationForm', () => { }); const helpHtml = wrapper.findByTestId(mockTestId); + const helpLink = helpHtml.find('a'); expect(helpHtml.isVisible()).toBe(true); expect(helpHtml.find('svg').isVisible()).toBe(true); + expect(helpLink.attributes()).toMatchObject({ + 'data-confirm': 'Are you sure?', + 'data-method': 'delete', + }); }); }); }); diff --git a/spec/serializers/merge_request_poll_cached_widget_entity_spec.rb b/spec/serializers/merge_request_poll_cached_widget_entity_spec.rb index 5845a868e53..5f4b734fcea 100644 --- a/spec/serializers/merge_request_poll_cached_widget_entity_spec.rb +++ b/spec/serializers/merge_request_poll_cached_widget_entity_spec.rb @@ -302,16 +302,6 @@ RSpec.describe MergeRequestPollCachedWidgetEntity do expect(subject[:merge_pipeline]).to be_nil end end - - context 'when merge_request_cached_merge_pipeline_serializer is disabled' do - before do - stub_feature_flags(merge_request_cached_merge_pipeline_serializer: false) - end - - it 'returns nil' do - expect(subject[:merge_pipeline]).to be_nil - end - end end end diff --git a/spec/serializers/merge_request_poll_widget_entity_spec.rb b/spec/serializers/merge_request_poll_widget_entity_spec.rb index 9a0e25516cb..3aebe16438c 100644 --- a/spec/serializers/merge_request_poll_widget_entity_spec.rb +++ b/spec/serializers/merge_request_poll_widget_entity_spec.rb @@ -22,54 +22,6 @@ RSpec.describe MergeRequestPollWidgetEntity do .to eq(resource.default_merge_commit_message(include_description: true)) end - describe 'merge_pipeline' do - before do - stub_feature_flags(merge_request_cached_merge_pipeline_serializer: false) - end - - it 'returns nil' do - expect(subject[:merge_pipeline]).to be_nil - end - - context 'when is merged' do - let_it_be(:resource) { create(:merged_merge_request, source_project: project, merge_commit_sha: project.commit.id) } - let_it_be(:pipeline) { create(:ci_empty_pipeline, project: project, ref: resource.target_branch, sha: resource.merge_commit_sha) } - - before do - project.add_maintainer(user) - end - - context 'when user cannot read pipelines on target project' do - before do - project.team.truncate - end - - it 'returns nil' do - expect(subject[:merge_pipeline]).to be_nil - end - end - - it 'returns merge_pipeline' do - pipeline_payload = - MergeRequests::PipelineEntity - .represent(pipeline, request: request) - .as_json - - expect(subject[:merge_pipeline]).to eq(pipeline_payload) - end - - context 'when merge_request_cached_merge_pipeline_serializer is enabled' do - before do - stub_feature_flags(merge_request_cached_merge_pipeline_serializer: true) - end - - it 'returns nil' do - expect(subject[:merge_pipeline]).to be_nil - end - end - end - end - describe 'new_blob_path' do context 'when user can push to project' do it 'returns path' do diff --git a/spec/services/merge_requests/add_spent_time_service_spec.rb b/spec/services/merge_requests/add_spent_time_service_spec.rb index db3380e9582..1e0b3e07f26 100644 --- a/spec/services/merge_requests/add_spent_time_service_spec.rb +++ b/spec/services/merge_requests/add_spent_time_service_spec.rb @@ -8,7 +8,7 @@ RSpec.describe MergeRequests::AddSpentTimeService do let_it_be_with_reload(:merge_request) { create(:merge_request, :simple, :unique_branches, source_project: project) } let(:duration) { 1500 } - let(:params) { { spend_time: { duration: duration, user_id: user.id } } } + let(:params) { { spend_time: { duration: duration, summary: 'summary', user_id: user.id } } } let(:service) { described_class.new(project: project, current_user: user, params: params) } describe '#execute' do @@ -16,13 +16,14 @@ RSpec.describe MergeRequests::AddSpentTimeService do project.add_developer(user) end - it 'creates a new timelog with the specified duration' do + it 'creates a new timelog with the specified duration and summary' do expect { service.execute(merge_request) }.to change { Timelog.count }.from(0).to(1) timelog = merge_request.timelogs.last expect(timelog).not_to be_nil expect(timelog.time_spent).to eq(1500) + expect(timelog.summary).to eq('summary') end it 'creates a system note with the time added' do diff --git a/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb b/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb index afc902dd184..104e91add8b 100644 --- a/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb @@ -128,17 +128,25 @@ RSpec.shared_examples 'time tracking endpoints' do |issuable_name| if issuable_name == 'merge_request' it 'calls update service with :use_specialized_service param' do - expect(::MergeRequests::UpdateService).to receive(:new).with(project: project, current_user: user, params: hash_including(use_specialized_service: true)) + expect(::MergeRequests::UpdateService).to receive(:new).with( + project: project, + current_user: user, + params: hash_including( + use_specialized_service: true, + spend_time: hash_including(duration: 7200, summary: 'summary'))) - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '2h' } + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '2h', summary: 'summary' } end end if issuable_name == 'issue' it 'calls update service without :use_specialized_service param' do - expect(::Issues::UpdateService).to receive(:new).with(project: project, current_user: user, params: hash_not_including(use_specialized_service: true)) + expect(::Issues::UpdateService).to receive(:new).with( + project: project, + current_user: user, + params: { spend_time: { duration: 3600, summary: 'summary', user_id: user.id } }) - post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '2h' } + post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '1h', summary: 'summary' } end end end diff --git a/storybook/config/webpack.config.js b/storybook/config/webpack.config.js index c67f79b55a0..4382ba43f21 100644 --- a/storybook/config/webpack.config.js +++ b/storybook/config/webpack.config.js @@ -5,6 +5,7 @@ const path = require('path'); const sass = require('node-sass'); // eslint-disable-line import/no-unresolved const { buildIncludePaths, resolveGlobUrl } = require('node-sass-magic-importer/dist/toolbox'); // eslint-disable-line import/no-unresolved const webpack = require('webpack'); +const IS_JH = require('../../config/helpers/is_jh_env'); const gitlabWebpackConfig = require('../../config/webpack.config'); const ROOT = path.resolve(__dirname, '../../'); @@ -13,11 +14,20 @@ const TRANSPARENT_1X1_PNG = const SASS_INCLUDE_PATHS = [ 'app/assets/stylesheets', 'app/assets/stylesheets/_ee', + 'app/assets/stylesheets/_jh', 'ee/app/assets/stylesheets', 'ee/app/assets/stylesheets/_ee', 'node_modules', ].map((p) => path.resolve(ROOT, p)); +if (IS_JH) { + SASS_INCLUDE_PATHS.push( + ...['jh/app/assets/stylesheets', 'jh/app/assets/stylesheets/_jh'].map((p) => + path.resolve(ROOT, p), + ), + ); +} + /** * Custom importer for node-sass, used when LibSass encounters the `@import` directive. * Doc source: https://github.com/sass/node-sass#importer--v200---experimental