diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-21 18:11:09 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-21 18:11:09 +0000 |
commit | 026689ee8276defd4376f60312d77cbc82b152fc (patch) | |
tree | ba38fe216d45b04d4bb48efb3cbbd380a7a2a5b5 | |
parent | 9c6578ed4e0bc92cd838ef96d978df54403e9609 (diff) | |
download | gitlab-ce-026689ee8276defd4376f60312d77cbc82b152fc.tar.gz |
Add latest changes from gitlab-org/gitlab@master
42 files changed, 768 insertions, 252 deletions
diff --git a/app/assets/javascripts/content_editor/services/create_editor.js b/app/assets/javascripts/content_editor/services/create_editor.js index f46129db389..06b8b2b4c45 100644 --- a/app/assets/javascripts/content_editor/services/create_editor.js +++ b/app/assets/javascripts/content_editor/services/create_editor.js @@ -12,6 +12,7 @@ import { BulletList, OrderedList, ListItem, + HardBreak, } from 'tiptap-extensions'; import { PROVIDE_SERIALIZER_OR_RENDERER_ERROR } from '../constants'; import CodeBlockHighlight from '../extensions/code_block_highlight'; @@ -36,6 +37,7 @@ const createEditor = async ({ content, renderMarkdown, serializer: customSeriali new ListItem(), new OrderedList(), new CodeBlockHighlight(), + new HardBreak(), ], editorProps: { attributes: { diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue index 47505093140..a3440d612ca 100644 --- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue @@ -2,6 +2,7 @@ import { reportToSentry } from '../../utils'; import LinkedGraphWrapper from '../graph_shared/linked_graph_wrapper.vue'; import LinksLayer from '../graph_shared/links_layer.vue'; +import { generateColumnsFromLayersListMemoized } from '../parsing_utils'; import { DOWNSTREAM, MAIN, UPSTREAM, ONE_COL_WIDTH, STAGE_VIEW } from './constants'; import LinkedPipelinesColumn from './linked_pipelines_column.vue'; import StageColumnComponent from './stage_column_component.vue'; @@ -78,7 +79,9 @@ export default { return this.hasDownstreamPipelines ? this.pipeline.downstream : []; }, layout() { - return this.isStageView ? this.pipeline.stages : this.generateColumnsFromLayersList(); + return this.isStageView + ? this.pipeline.stages + : generateColumnsFromLayersListMemoized(this.pipeline, this.pipelineLayers); }, hasDownstreamPipelines() { return Boolean(this.pipeline?.downstream?.length > 0); @@ -124,26 +127,6 @@ export default { this.getMeasurements(); }, methods: { - generateColumnsFromLayersList() { - return this.pipelineLayers.map((layers, idx) => { - /* - look up the groups in each layer, - then add each set of layer groups to a stage-like object - */ - - const groups = layers.map((id) => { - const { stageIdx, groupIdx } = this.pipeline.stagesLookup[id]; - return this.pipeline.stages?.[stageIdx]?.groups?.[groupIdx]; - }); - - return { - name: '', - id: `layer-${idx}`, - status: { action: null }, - groups: groups.filter(Boolean), - }; - }); - }, getMeasurements() { this.measurements = { width: this.$refs[this.containerId].scrollWidth, diff --git a/app/assets/javascripts/pipelines/components/parsing_utils.js b/app/assets/javascripts/pipelines/components/parsing_utils.js index f5ab869633b..9d886e0e379 100644 --- a/app/assets/javascripts/pipelines/components/parsing_utils.js +++ b/app/assets/javascripts/pipelines/components/parsing_utils.js @@ -1,4 +1,4 @@ -import { uniqWith, isEqual } from 'lodash'; +import { isEqual, memoize, uniqWith } from 'lodash'; import { createSankey } from './dag/drawing_utils'; /* @@ -170,3 +170,26 @@ export const listByLayers = ({ stages }) => { return acc; }, []); }; + +export const generateColumnsFromLayersListBare = ({ stages, stagesLookup }, pipelineLayers) => { + return pipelineLayers.map((layers, idx) => { + /* + Look up the groups in each layer, + then add each set of layer groups to a stage-like object. + */ + + const groups = layers.map((id) => { + const { stageIdx, groupIdx } = stagesLookup[id]; + return stages[stageIdx]?.groups?.[groupIdx]; + }); + + return { + name: '', + id: `layer-${idx}`, + status: { action: null }, + groups: groups.filter(Boolean), + }; + }); +}; + +export const generateColumnsFromLayersListMemoized = memoize(generateColumnsFromLayersListBare); diff --git a/app/assets/stylesheets/themes/_dark.scss b/app/assets/stylesheets/themes/_dark.scss index 11b4bde74a6..a3c6940585e 100644 --- a/app/assets/stylesheets/themes/_dark.scss +++ b/app/assets/stylesheets/themes/_dark.scss @@ -232,9 +232,7 @@ $well-inner-border: $gray-200; } // white-ish text for light labels -// and for scoped label value (the right section) -.gl-label-text-light.gl-label-text-light, -.gl-label-text-dark + .gl-label-text-dark { +.gl-label-text-light.gl-label-text-light { color: $gray-900; } diff --git a/app/models/project_services/custom_issue_tracker_service.rb b/app/models/project_services/custom_issue_tracker_service.rb index aab8661ec55..b510df13ecb 100644 --- a/app/models/project_services/custom_issue_tracker_service.rb +++ b/app/models/project_services/custom_issue_tracker_service.rb @@ -1,25 +1,23 @@ # frozen_string_literal: true class CustomIssueTrackerService < IssueTrackerService + include ActionView::Helpers::UrlHelper validates :project_url, :issues_url, :new_issue_url, presence: true, public_url: true, if: :activated? def title - 'Custom Issue Tracker' + s_('IssueTracker|Custom issue tracker') end def description - s_('IssueTracker|Custom issue tracker') + s_('IssueTracker|Use a custom issue tracker.') end - def self.to_param - 'custom_issue_tracker' + def help + docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/custom_issue_tracker'), target: '_blank', rel: 'noopener noreferrer' + s_('IssueTracker|Use a custom issue tracker that is not in the integration list. %{docs_link}').html_safe % { docs_link: docs_link.html_safe } end - def fields - [ - { type: 'text', name: 'project_url', title: _('Project URL'), required: true }, - { type: 'text', name: 'issues_url', title: s_('ProjectService|Issue URL'), required: true }, - { type: 'text', name: 'new_issue_url', title: s_('ProjectService|New issue URL'), required: true } - ] + def self.to_param + 'custom_issue_tracker' end end diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb index 2bb9a7e7254..c7358e3b9d4 100644 --- a/app/serializers/environment_serializer.rb +++ b/app/serializers/environment_serializer.rb @@ -23,6 +23,8 @@ class EnvironmentSerializer < BaseSerializer latest: super(item.latest, opts) } end else + resource = @paginator.paginate(resource) if paginated? + super(batch_load(resource), opts) end end @@ -52,7 +54,7 @@ class EnvironmentSerializer < BaseSerializer def batch_load(resource) resource = resource.preload(environment_associations) - resource.all.tap do |environments| + resource.all.to_a.tap do |environments| environments.each do |environment| # Batch loading the commits of the deployments environment.last_deployment&.commit&.try(:lazy_author) diff --git a/app/views/admin/application_settings/_plantuml.html.haml b/app/views/admin/application_settings/_plantuml.html.haml index d57ae94b084..632aeec6ce3 100644 --- a/app/views/admin/application_settings/_plantuml.html.haml +++ b/app/views/admin/application_settings/_plantuml.html.haml @@ -17,7 +17,7 @@ = f.check_box :plantuml_enabled, class: 'form-check-input' = f.label :plantuml_enabled, _('Enable PlantUML'), class: 'form-check-label' .form-group - = f.label :plantuml_url, 'PlantUML URL', class: 'label-bold' + = f.label :plantuml_url, _('PlantUML URL'), class: 'label-bold' = f.text_field :plantuml_url, class: 'form-control gl-form-input', placeholder: 'http://your-plantuml-instance:8080' .form-text.text-muted Allow rendering of diff --git a/app/views/groups/milestones/new.html.haml b/app/views/groups/milestones/new.html.haml index 2c93b0e4efd..0d4565706d4 100644 --- a/app/views/groups/milestones/new.html.haml +++ b/app/views/groups/milestones/new.html.haml @@ -3,7 +3,7 @@ - page_title _("Milestones"), @milestone.name, _("Milestones") %h3.page-title - New Milestone + = _("New Milestone") %hr diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index c111714f552..b25f651aa64 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -9,7 +9,7 @@ = button_tag class: 'toggle-mobile-nav', type: 'button' do %span.sr-only= _("Open sidebar") = sprite_icon('hamburger', size: 18) - .breadcrumbs-links{ data: { testid: 'breadcrumb-links', qa_selector: 'breadcrumb_links_content' } } + .breadcrumbs-links.overflow-auto{ data: { testid: 'breadcrumb-links', qa_selector: 'breadcrumb_links_content' } } %ul.list-unstyled.breadcrumbs-list.js-breadcrumbs-list - unless hide_top_links = header_title diff --git a/changelogs/unreleased/25301-breadcrumbs-list-overflow-on-compare-with-sha1-on-mobile.yml b/changelogs/unreleased/25301-breadcrumbs-list-overflow-on-compare-with-sha1-on-mobile.yml new file mode 100644 index 00000000000..6677a464768 --- /dev/null +++ b/changelogs/unreleased/25301-breadcrumbs-list-overflow-on-compare-with-sha1-on-mobile.yml @@ -0,0 +1,5 @@ +--- +title: Fix overflow in breadcrumbs list mainly on mobile +merge_request: 59552 +author: Takuya Noguchi +type: other diff --git a/changelogs/unreleased/325179-dark-mode-light-colored-labels-are-hard-to-read.yml b/changelogs/unreleased/325179-dark-mode-light-colored-labels-are-hard-to-read.yml new file mode 100644 index 00000000000..644b2ca4db6 --- /dev/null +++ b/changelogs/unreleased/325179-dark-mode-light-colored-labels-are-hard-to-read.yml @@ -0,0 +1,5 @@ +--- +title: Fix light label text color in dark mode +merge_request: 59088 +author: +type: fixed diff --git a/changelogs/unreleased/Externalise-strings-in-_plantuml-html-haml.yml b/changelogs/unreleased/Externalise-strings-in-_plantuml-html-haml.yml new file mode 100644 index 00000000000..4cba027b580 --- /dev/null +++ b/changelogs/unreleased/Externalise-strings-in-_plantuml-html-haml.yml @@ -0,0 +1,5 @@ +--- +title: Externalise strings in application_settings/_plantuml.html.haml +merge_request: 58023 +author: nuwe1 +type: other diff --git a/changelogs/unreleased/Externalize-strings-in-milestones-new-html-haml.yml b/changelogs/unreleased/Externalize-strings-in-milestones-new-html-haml.yml new file mode 100644 index 00000000000..f3169924e1b --- /dev/null +++ b/changelogs/unreleased/Externalize-strings-in-milestones-new-html-haml.yml @@ -0,0 +1,5 @@ +--- +title: Externalize strings in milestones/new.html.haml +merge_request: 58311 +author: nuwe1 +type: other diff --git a/changelogs/unreleased/fix-paginator-for-environment-serializer.yml b/changelogs/unreleased/fix-paginator-for-environment-serializer.yml new file mode 100644 index 00000000000..854480d0f79 --- /dev/null +++ b/changelogs/unreleased/fix-paginator-for-environment-serializer.yml @@ -0,0 +1,5 @@ +--- +title: Fix paginator of Environment Serializer +merge_request: 59751 +author: +type: fixed diff --git a/changelogs/unreleased/msj-custom-issue-tracker-okr.yml b/changelogs/unreleased/msj-custom-issue-tracker-okr.yml new file mode 100644 index 00000000000..74025864e02 --- /dev/null +++ b/changelogs/unreleased/msj-custom-issue-tracker-okr.yml @@ -0,0 +1,5 @@ +--- +title: Review and revise custom issue tracker UI text +merge_request: 59277 +author: +type: other diff --git a/doc/administration/index.md b/doc/administration/index.md index a7d81ca1543..a3714d10bf2 100644 --- a/doc/administration/index.md +++ b/doc/administration/index.md @@ -139,7 +139,7 @@ Learn how to install, configure, update, and maintain your GitLab instance. - [Postfix for incoming email](reply_by_email_postfix_setup.md): Set up a basic Postfix mail server with IMAP authentication on Ubuntu for incoming emails. -- [Abuse reports](../user/admin_area/abuse_reports.md): View and resolve abuse reports from your users. +- [Abuse reports](../user/admin_area/review_abuse_reports.md): View and resolve abuse reports from your users. - [Credentials Inventory](../user/admin_area/credentials_inventory.md): With Credentials inventory, GitLab administrators can keep track of the credentials used by their users in their GitLab self-managed instance. ## Project settings diff --git a/doc/api/settings.md b/doc/api/settings.md index 6322f14442c..bdf47fafb7e 100644 --- a/doc/api/settings.md +++ b/doc/api/settings.md @@ -217,8 +217,8 @@ listed in the descriptions of the relevant settings. | Attribute | Type | Required | Description | |------------------------------------------|------------------|:------------------------------------:|-------------| | `admin_mode` | boolean | no | Require admins to enable Admin Mode by re-authenticating for administrative tasks. | -| `admin_notification_email` | string | no | Deprecated: Use `abuse_notification_email` instead. If set, [abuse reports](../user/admin_area/abuse_reports.md) are sent to this address. Abuse reports are always available in the Admin Area. | -| `abuse_notification_email` | string | no | If set, [abuse reports](../user/admin_area/abuse_reports.md) are sent to this address. Abuse reports are always available in the Admin Area. | +| `admin_notification_email` | string | no | Deprecated: Use `abuse_notification_email` instead. If set, [abuse reports](../user/admin_area/review_abuse_reports.md) are sent to this address. Abuse reports are always available in the Admin Area. | +| `abuse_notification_email` | string | no | If set, [abuse reports](../user/admin_area/review_abuse_reports.md) are sent to this address. Abuse reports are always available in the Admin Area. | | `after_sign_out_path` | string | no | Where to redirect users after logout. | | `after_sign_up_text` | string | no | Text shown to the user after signing up | | `akismet_api_key` | string | required by: `akismet_enabled` | API key for Akismet spam protection. | diff --git a/doc/user/abuse_reports.md b/doc/user/abuse_reports.md index e2f2038f240..66b7c3c6ac7 100644 --- a/doc/user/abuse_reports.md +++ b/doc/user/abuse_reports.md @@ -1,68 +1,8 @@ --- -stage: none -group: unassigned -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +redirect_to: 'report_abuse.md' --- -# Abuse reports **(FREE)** +This file was moved to [another location](report_abuse.md). -You can report abuse from other GitLab users to GitLab administrators. - -A GitLab administrator [can then choose](admin_area/abuse_reports.md) to: - -- Remove the user, which deletes them from the instance. -- Block the user, which denies them access to the instance. -- Or remove the report, which retains the user's access to the instance. - -You can report a user through their: - -- [Profile](#reporting-abuse-through-a-users-profile) -- [Comments](#reporting-abuse-through-a-users-comment) -- [Issues and Merge requests](#reporting-abuse-through-a-users-issue-or-merge-request) - -## Reporting abuse through a user's profile - -To report abuse from a user's profile page: - -1. Click on the exclamation point report abuse button at the top right of the - user's profile. -1. Complete an abuse report. -1. Click the **Send report** button. - -## Reporting abuse through a user's comment - -To report abuse from a user's comment: - -1. Click on the vertical ellipsis (⋮) more actions button to open the dropdown. -1. Select **Report as abuse**. -1. Complete an abuse report. -1. Click the **Send report** button. - -NOTE: -A URL to the reported user's comment is pre-filled in the abuse report's -**Message** field. - -## Reporting abuse through a user's issue or merge request - -The **Report abuse** button is displayed at the top right of the issue or merge request: - -- When **Report abuse** is selected from the menu that appears when the - **Close issue** or **Close merge request** button is clicked, for users that - have permission to close the issue or merge request. -- When viewing the issue or merge request, for users that don't have permission - to close the issue or merge request. - -With the **Report abuse** button displayed, to submit an abuse report: - -1. Click the **Report abuse** button. -1. Submit an abuse report. -1. Click the **Send report** button. - -NOTE: -A URL to the reported user's issue or merge request is pre-filled -in the abuse report's **Message** field. - -## Managing abuse reports - -Admins are able to view and resolve abuse reports. -For more information, see [abuse reports administration documentation](admin_area/abuse_reports.md). +<!-- This redirect file can be deleted after <2021-07-21>. --> +<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page --> diff --git a/doc/user/admin_area/abuse_reports.md b/doc/user/admin_area/abuse_reports.md index 85ad0667322..5424d4d2cb4 100644 --- a/doc/user/admin_area/abuse_reports.md +++ b/doc/user/admin_area/abuse_reports.md @@ -1,90 +1,8 @@ --- -stage: Manage -group: Access -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments -type: reference, howto +redirect_to: 'review_abuse_reports.md' --- -# Abuse reports **(FREE SELF)** +This file was moved to [another location](review_abuse_reports.md). -View and resolve abuse reports from GitLab users. - -GitLab administrators can view and [resolve](#resolving-abuse-reports) abuse -reports in the Admin Area. - -## Receiving notifications of abuse reports - -To receive notifications of new abuse reports by e-mail, follow these steps: - -1. Select **Admin Area > Settings > Reporting**. -1. Expand the **Abuse reports** section. -1. Provide an email address. - -The notification email address can also be set and retrieved -[using the API](../../api/settings.md#list-of-settings-that-can-be-accessed-via-api-calls). - -## Reporting abuse - -To find out more about reporting abuse, see [abuse reports user -documentation](../abuse_reports.md). - -## Resolving abuse reports - -To access abuse reports, go to **Admin Area > Abuse Reports**. - -There are 3 ways to resolve an abuse report, with a button for each method: - -- Remove user & report. This: - - [Deletes the reported user](../profile/account/delete_account.md) from the - instance. - - Removes the abuse report from the list. -- [Block user](#blocking-users). -- Remove report. This: - - Removes the abuse report from the list. - - Removes access restrictions for the reported user. - -The following is an example of the **Abuse Reports** page: - -![abuse-reports-page-image](img/abuse_reports_page_v13_11.png) - -### Blocking users - -A blocked user cannot log in or access any repositories, but all of their data -remains. - -Blocking a user: - -- Leaves them in the abuse report list. -- Changes the **Block user** button to a disabled **Already blocked** button. - -The user is notified with the following message: - -```plaintext -Your account has been blocked. If you believe this is in error, contact a staff member. -``` - -After blocking, you can still either: - -- Remove the user and report if necessary. -- Remove the report. - -The following is an example of a blocked user listed on the **Abuse Reports** -page: - -![abuse-report-blocked-user-image](img/abuse_report_blocked_user.png) - -NOTE: -Users can be [blocked](../../api/users.md#block-user) and -[unblocked](../../api/users.md#unblock-user) using the GitLab API. - -<!-- ## Troubleshooting - -Include any troubleshooting steps that you can foresee. If you know beforehand what issues -one might have when setting this up, or when something is changed, or on upgrading, it's -important to describe those, too. Think of things that may go wrong and include them here. -This is important to minimize requests for support, and to avoid doc comments with -questions that you know someone might ask. - -Each scenario can be a third-level heading, e.g. `### Getting error message X`. -If you have none to add when creating a doc, leave this section in place -but commented out to help encourage others to add to it in the future. --> +<!-- This redirect file can be deleted after <2021-07-21>. --> +<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page --> diff --git a/doc/user/admin_area/blocking_unblocking_users.md b/doc/user/admin_area/blocking_unblocking_users.md index 1dba9e5adda..14a5b5085cb 100644 --- a/doc/user/admin_area/blocking_unblocking_users.md +++ b/doc/user/admin_area/blocking_unblocking_users.md @@ -14,7 +14,7 @@ GitLab administrators block and unblock users. In order to completely prevent access of a user to the GitLab instance, administrators can choose to block the user. -Users can be blocked [via an abuse report](abuse_reports.md#blocking-users), +Users can be blocked [via an abuse report](review_abuse_reports.md#blocking-users), or directly from the Admin Area. To do this: 1. Navigate to **Admin Area > Overview > Users**. diff --git a/doc/user/admin_area/broadcast_messages.md b/doc/user/admin_area/broadcast_messages.md index 6f6aed68620..8cb2f797b2e 100644 --- a/doc/user/admin_area/broadcast_messages.md +++ b/doc/user/admin_area/broadcast_messages.md @@ -66,11 +66,16 @@ To add a broadcast message: 1. Navigate to the **Admin Area > Messages** page. 1. Add the text for the message to the **Message** field. Markdown and emoji are supported. 1. Select one of the suggested background colors, or add the hex code of a different color. The default color is orange. -1. If required, add a **Target Path** to only show the broadcast message on URLs matching that path. You can use the wildcard character `*` to match multiple URLs, for example `/users/*/issues`. +1. If required, add a **Target Path** to only show the broadcast message on URLs matching that path. You can use the wildcard character `*` to match multiple URLs, for example `mygroup/myproject*`. 1. Select a date for the message to start and end. 1. Click the **Add broadcast message** button. NOTE: +When scoping messages, you can't use preceding or trailing slashes. For example, +instead of `/mygroup/myproject/`, you must use `mygroup/myproject`. A fix is +[planned for GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59482). + +NOTE: The **Background color** field expects the value to be a hexadecimal code because the form uses the [color_field](https://api.rubyonrails.org/v6.0.3.4/classes/ActionView/Helpers/FormHelper.html#method-i-color_field) helper method, which generates the proper HTML to render. diff --git a/doc/user/admin_area/index.md b/doc/user/admin_area/index.md index 08fcd4674dc..01926f28937 100644 --- a/doc/user/admin_area/index.md +++ b/doc/user/admin_area/index.md @@ -28,7 +28,7 @@ The Admin Area is made up of the following sections: | **{messages}** Messages | Send and manage [broadcast messages](broadcast_messages.md) for your users. | | **{hook}** System Hooks | Configure [system hooks](../../system_hooks/system_hooks.md) for many events. | | **{applications}** Applications | Create system [OAuth applications](../../integration/oauth_provider.md) for integrations with other services. | -| **{slight-frown}** Abuse Reports | Manage [abuse reports](abuse_reports.md) submitted by your users. | +| **{slight-frown}** Abuse Reports | Manage [abuse reports](review_abuse_reports.md) submitted by your users. | | **{license}** License | Upload, display, and remove [licenses](license.md). | | **{cloud-gear}** Kubernetes | Create and manage instance-level [Kubernetes clusters](../instance/clusters/index.md). | | **{push-rules}** Push rules | Configure pre-defined Git [push rules](../../push_rules/push_rules.md) for projects. Also, configure [merge requests approvers rules](merge_requests_approvals.md). | diff --git a/doc/user/admin_area/review_abuse_reports.md b/doc/user/admin_area/review_abuse_reports.md new file mode 100644 index 00000000000..12a3111c6f3 --- /dev/null +++ b/doc/user/admin_area/review_abuse_reports.md @@ -0,0 +1,90 @@ +--- +stage: Manage +group: Access +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +type: reference, howto +--- + +# Review abuse reports **(FREE SELF)** + +View and resolve abuse reports from GitLab users. + +GitLab administrators can view and [resolve](#resolving-abuse-reports) abuse +reports in the Admin Area. + +## Receiving notifications of abuse reports + +To receive notifications of new abuse reports by e-mail, follow these steps: + +1. Select **Admin Area > Settings > Reporting**. +1. Expand the **Abuse reports** section. +1. Provide an email address. + +The notification email address can also be set and retrieved +[using the API](../../api/settings.md#list-of-settings-that-can-be-accessed-via-api-calls). + +## Reporting abuse + +To find out more about reporting abuse, see [abuse reports user +documentation](../report_abuse.md). + +## Resolving abuse reports + +To access abuse reports, go to **Admin Area > Abuse Reports**. + +There are 3 ways to resolve an abuse report, with a button for each method: + +- Remove user & report. This: + - [Deletes the reported user](../profile/account/delete_account.md) from the + instance. + - Removes the abuse report from the list. +- [Block user](#blocking-users). +- Remove report. This: + - Removes the abuse report from the list. + - Removes access restrictions for the reported user. + +The following is an example of the **Abuse Reports** page: + +![abuse-reports-page-image](img/abuse_reports_page_v13_11.png) + +### Blocking users + +A blocked user cannot log in or access any repositories, but all of their data +remains. + +Blocking a user: + +- Leaves them in the abuse report list. +- Changes the **Block user** button to a disabled **Already blocked** button. + +The user is notified with the following message: + +```plaintext +Your account has been blocked. If you believe this is in error, contact a staff member. +``` + +After blocking, you can still either: + +- Remove the user and report if necessary. +- Remove the report. + +The following is an example of a blocked user listed on the **Abuse Reports** +page: + +![abuse-report-blocked-user-image](img/abuse_report_blocked_user.png) + +NOTE: +Users can be [blocked](../../api/users.md#block-user) and +[unblocked](../../api/users.md#unblock-user) using the GitLab API. + +<!-- ## Troubleshooting + +Include any troubleshooting steps that you can foresee. If you know beforehand what issues +one might have when setting this up, or when something is changed, or on upgrading, it's +important to describe those, too. Think of things that may go wrong and include them here. +This is important to minimize requests for support, and to avoid doc comments with +questions that you know someone might ask. + +Each scenario can be a third-level heading, e.g. `### Getting error message X`. +If you have none to add when creating a doc, leave this section in place +but commented out to help encourage others to add to it in the future. --> diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md index f924a71caf3..023c4548d73 100644 --- a/doc/user/admin_area/settings/index.md +++ b/doc/user/admin_area/settings/index.md @@ -72,7 +72,7 @@ Access the default page for admin area settings by navigating to **Admin Area > | Option | Description | | ------ | ----------- | | [Spam and Anti-bot Protection](../../../integration/recaptcha.md) | Enable reCAPTCHA or Akismet and set IP limits. For reCAPTCHA, we currently only support [v2](https://developers.google.com/recaptcha/docs/versions). | -| [Abuse reports](../abuse_reports.md) | Set notification email for abuse reports. | +| [Abuse reports](../review_abuse_reports.md) | Set notification email for abuse reports. | ## Metrics and profiling diff --git a/doc/user/index.md b/doc/user/index.md index 872dbd09c7d..49bf325b0d3 100644 --- a/doc/user/index.md +++ b/doc/user/index.md @@ -119,7 +119,7 @@ to enjoy the best of GitLab. user type (guest, reporter, developer, maintainer, owner). - [Feature highlight](feature_highlight.md): Learn more about the little blue dots around the app that explain certain features. -- [Abuse reports](abuse_reports.md): Report abuse from users to GitLab administrators. +- [Abuse reports](report_abuse.md): Report abuse from users to GitLab administrators. ## Groups diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md index a33b6742d61..e21ebb25354 100644 --- a/doc/user/profile/account/delete_account.md +++ b/doc/user/profile/account/delete_account.md @@ -72,7 +72,7 @@ merge requests, notes/comments, and more. Consider [blocking a user](../../admin_area/blocking_unblocking_users.md) or using the **Delete user** option instead. -When a user is deleted from an [abuse report](../../admin_area/abuse_reports.md) +When a user is deleted from an [abuse report](../../admin_area/review_abuse_reports.md) or spam log, these associated records are not ghosted and will be removed, along with any groups the user is a sole owner of. Administrators can also request this behavior when diff --git a/doc/user/project/integrations/custom_issue_tracker.md b/doc/user/project/integrations/custom_issue_tracker.md index 9cc4e980212..19beafd6663 100644 --- a/doc/user/project/integrations/custom_issue_tracker.md +++ b/doc/user/project/integrations/custom_issue_tracker.md @@ -4,35 +4,43 @@ group: Ecosystem info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- -# Custom Issue Tracker service **(FREE)** +# Custom issue tracker service **(FREE)** -To enable the Custom Issue Tracker integration in a project: +Use a custom issue tracker that is not in the integration list. -1. Go to **Settings > Integrations**. -1. Click **Custom Issue Tracker** -1. Fill in the tracker's details, such as title, description, and URLs. - You can edit these fields later as well. +To enable a custom issue tracker in a project: - These are some of the required fields: +1. Go to the [Integrations page](overview.md#accessing-integrations). +1. Select **Custom issue tracker**. +1. Select the checkbox under **Enable integration**. +1. Fill in the required fields: - | Field | Description | - | --------------- | ----------- | - | **Project URL** | The URL to the project in the custom issue tracker. | - | **Issues URL** | The URL to the issue in the issue tracker project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. For example, `https://customissuetracker.com/project-name/:id`. | - | **New issue URL** | Currently unused. Planned to be changed in a future release. | + - **Project URL**: The URL to view all the issues in the custom issue tracker. + - **Issue URL**: The URL to view an issue in the custom issue tracker. The URL must contain `:id`. + GitLab replaces `:id` with the issue number (for example, + `https://customissuetracker.com/project-name/:id`, which becomes `https://customissuetracker.com/project-name/123`). + - **New issue URL**: + <!-- The line below was originally added in January 2018: https://gitlab.com/gitlab-org/gitlab/-/commit/778b231f3a5dd42ebe195d4719a26bf675093350 --> + **This URL is not used and removal is planned in a future release.** + Enter any URL here. + For more information, see [issue 327503](https://gitlab.com/gitlab-org/gitlab/-/issues/327503). -1. Click **Test settings and save changes**. +1. Select **Save changes** or optionally select **Test settings**. -After you configure and enable the Custom Issue Tracker service, you see a link on the GitLab -project pages that takes you to that custom issue tracker. +After you configure and enable the custom issue tracker service, a link appears on the GitLab +project pages. This link takes you to the custom issue tracker. -## Referencing issues +## Reference issues in a custom issue tracker -Issues are referenced with `<ANYTHING>-<ID>` (for example, `PROJECT-143`), where `<ANYTHING>` can be any string in CAPS, and `<ID>` -is a number used in the target project of the custom integration. +You can reference issues in a custom issue tracker using: -`<ANYTHING>` is a placeholder to differentiate against GitLab issues, which are referenced with `#<ID>`. You can use a project name or project key to replace it for example. +- `#<ID>`, where `<ID>` is a number (for example, `#143`). +- `<PROJECT>-<ID>` (for example `API_32-143`) where: + - `<PROJECT>` starts with a capital letter, followed by capital letters, numbers, or underscores. + - `<ID>` is a number. -When building the hyperlink, the `<ANYTHING>` part is ignored, and links always point to the address -specified in `issues_url`, so in the example above, `PROJECT-143` would refer to -`https://customissuetracker.com/project-name/143`. +The `<PROJECT>` part is ignored in links, which always point to the address specified in **Issue URL**. + +We suggest using the longer format (`<PROJECT>-<ID>`) if you have both internal and external issue +trackers enabled. If you use the shorter format, and an issue with the same ID exists in the +internal issue tracker, the internal issue is linked. diff --git a/doc/user/project/issues/issue_data_and_actions.md b/doc/user/project/issues/issue_data_and_actions.md index 2963555869c..4c0ec706c83 100644 --- a/doc/user/project/issues/issue_data_and_actions.md +++ b/doc/user/project/issues/issue_data_and_actions.md @@ -67,7 +67,7 @@ To access additional actions, select the vertical ellipsis - To create a new issue in the same project, select **New issue** in the dropdown menu. -- If you are not the issue author, you can [submit an abuse report](../../abuse_reports.md). +- If you are not the issue author, you can [submit an abuse report](../../report_abuse.md). Select **Report abuse** in the dropdown menu. ### To Do diff --git a/doc/user/report_abuse.md b/doc/user/report_abuse.md new file mode 100644 index 00000000000..2b585315326 --- /dev/null +++ b/doc/user/report_abuse.md @@ -0,0 +1,68 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# Report abuse **(FREE)** + +You can report abuse from other GitLab users to GitLab administrators. + +A GitLab administrator [can then choose](admin_area/review_abuse_reports.md) to: + +- Remove the user, which deletes them from the instance. +- Block the user, which denies them access to the instance. +- Or remove the report, which retains the user's access to the instance. + +You can report a user through their: + +- [Profile](#reporting-abuse-through-a-users-profile) +- [Comments](#reporting-abuse-through-a-users-comment) +- [Issues and Merge requests](#reporting-abuse-through-a-users-issue-or-merge-request) + +## Reporting abuse through a user's profile + +To report abuse from a user's profile page: + +1. Click on the exclamation point report abuse button at the top right of the + user's profile. +1. Complete an abuse report. +1. Click the **Send report** button. + +## Reporting abuse through a user's comment + +To report abuse from a user's comment: + +1. Click on the vertical ellipsis (⋮) more actions button to open the dropdown. +1. Select **Report as abuse**. +1. Complete an abuse report. +1. Click the **Send report** button. + +NOTE: +A URL to the reported user's comment is pre-filled in the abuse report's +**Message** field. + +## Reporting abuse through a user's issue or merge request + +The **Report abuse** button is displayed at the top right of the issue or merge request: + +- When **Report abuse** is selected from the menu that appears when the + **Close issue** or **Close merge request** button is clicked, for users that + have permission to close the issue or merge request. +- When viewing the issue or merge request, for users that don't have permission + to close the issue or merge request. + +With the **Report abuse** button displayed, to submit an abuse report: + +1. Click the **Report abuse** button. +1. Submit an abuse report. +1. Click the **Send report** button. + +NOTE: +A URL to the reported user's issue or merge request is pre-filled +in the abuse report's **Message** field. + +## Managing abuse reports + +Admins are able to view and resolve abuse reports. +For more information, see [abuse reports administration documentation](admin_area/review_abuse_reports.md). diff --git a/locale/gitlab.pot b/locale/gitlab.pot index cd4c8a7a09e..398bfcb3ec0 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6668,6 +6668,12 @@ msgstr "" msgid "CloudLicense|Billable users" msgstr "" +msgid "CloudLicense|Buy subscription" +msgstr "" + +msgid "CloudLicense|Free trial" +msgstr "" + msgid "CloudLicense|I agree that my use of the GitLab Software is subject to the Subscription Agreement located at the %{linkStart}Terms of Service%{linkEnd}, unless otherwise agreed to in writing with GitLab." msgstr "" @@ -6680,6 +6686,15 @@ msgstr "" msgid "CloudLicense|Paste your activation code" msgstr "" +msgid "CloudLicense|Ready to get started? A GitLab plan is ideal for scaling organizations and for multi team usage." +msgstr "" + +msgid "CloudLicense|Start free trial" +msgstr "" + +msgid "CloudLicense|Subscription" +msgstr "" + msgid "CloudLicense|This is the highest peak of users on your installation since the license started." msgstr "" @@ -6695,6 +6710,9 @@ msgstr "" msgid "CloudLicense|Users with a Guest role or those who don't belong to a Project or Group will not use a seat from your license." msgstr "" +msgid "CloudLicense|You can start a free trial of GitLab Ultimate without any obligation or payment details." +msgstr "" + msgid "CloudLicense|You'll be charged for %{trueUpLinkStart}users over license%{trueUpLinkEnd} on a quarterly or annual basis, depending on the terms of your agreement." msgstr "" @@ -17866,6 +17884,12 @@ msgstr "" msgid "IssueTracker|Use Redmine as the issue tracker. %{docs_link}" msgstr "" +msgid "IssueTracker|Use a custom issue tracker that is not in the integration list. %{docs_link}" +msgstr "" + +msgid "IssueTracker|Use a custom issue tracker." +msgstr "" + msgid "IssueTracker|YouTrack issue tracker" msgstr "" @@ -23678,6 +23702,9 @@ msgstr "" msgid "PlantUML" msgstr "" +msgid "PlantUML URL" +msgstr "" + msgid "Play" msgstr "" @@ -31932,9 +31959,6 @@ msgstr "" msgid "There was an error when subscribing to this label." msgstr "" -msgid "There was an error when trying to sync your license. Please verify that your instance is using an active license key." -msgstr "" - msgid "There was an error when unsubscribing from this label." msgstr "" @@ -36564,9 +36588,6 @@ msgstr "" msgid "Your license is valid from" msgstr "" -msgid "Your license was successfully synced." -msgstr "" - msgid "Your license will be included in your GitLab backup and will survive upgrades, so in normal usage you should never need to re-upload your %{code_open}.gitlab-license%{code_close} file." msgstr "" diff --git a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb index c0d84d82e51..3db5b9671d9 100644 --- a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb @@ -21,33 +21,24 @@ module QA end let(:another_project) do - Resource::Project.fabricate_via_api! do |project| - project.name = 'nuget-package-install-project' - project.template_name = 'dotnetcore' + Resource::Project.fabricate_via_api! do |another_project| + another_project.name = 'nuget-package-install-project' + another_project.template_name = 'dotnetcore' + another_project.group = project.group end end let!(:runner) do Resource::Runner.fabricate! do |runner| runner.name = "qa-runner-#{Time.now.to_i}" - runner.tags = ["runner-for-#{project.name}"] - runner.executor = :docker - runner.project = project - end - end - - let!(:another_runner) do - Resource::Runner.fabricate! do |runner| - runner.name = "qa-runner-#{Time.now.to_i}" - runner.tags = ["runner-for-#{another_project.name}"] + runner.tags = ["runner-for-#{project.group.sandbox.name}"] runner.executor = :docker - runner.project = another_project + runner.token = project.group.sandbox.runners_token end end after do runner.remove_via_api! - another_runner.remove_via_api! package.remove_via_api! end @@ -78,7 +69,7 @@ module QA only: - "#{project.default_branch}" tags: - - "runner-for-#{project.name}" + - "runner-for-#{project.group.sandbox.name}" YAML } ] @@ -137,7 +128,7 @@ module QA only: - "#{another_project.default_branch}" tags: - - "runner-for-#{another_project.name}" + - "runner-for-#{project.group.sandbox.name}" YAML } ] diff --git a/scripts/regenerate-schema b/scripts/regenerate-schema index 65c73a8116a..485bb2d5505 100755 --- a/scripts/regenerate-schema +++ b/scripts/regenerate-schema @@ -194,7 +194,7 @@ class SchemaRegenerator # Get source ref from CI environment variable, or read the +TARGET+ # environment+ variable, or default to +HEAD+. def target_branch - ENV['CI_MERGE_REQUEST_TARGET_BRANCH_NAME'] || ENV['TARGET'] || 'master' + ENV['CI_MERGE_REQUEST_TARGET_BRANCH_NAME'] || ENV['TARGET'] || ENV['CI_DEFAULT_BRANCH'] || 'master' end ## diff --git a/scripts/review_apps/review-apps.sh b/scripts/review_apps/review-apps.sh index 88be78c7615..79f156b5795 100755 --- a/scripts/review_apps/review-apps.sh +++ b/scripts/review_apps/review-apps.sh @@ -310,7 +310,7 @@ function parse_gitaly_image_tag() { function deploy() { local namespace="${KUBE_NAMESPACE}" local release="${CI_ENVIRONMENT_SLUG}" - local base_config_file_ref="master" + local base_config_file_ref="${CI_DEFAULT_BRANCH}" if [[ "$(base_config_changed)" == "true" ]]; then base_config_file_ref="${CI_COMMIT_SHA}"; fi local base_config_file="https://gitlab.com/gitlab-org/gitlab/raw/${base_config_file_ref}/scripts/review_apps/base-config.yaml" diff --git a/scripts/rspec_helpers.sh b/scripts/rspec_helpers.sh index e23231e429b..0b109ba0fb3 100644 --- a/scripts/rspec_helpers.sh +++ b/scripts/rspec_helpers.sh @@ -7,7 +7,7 @@ function retrieve_tests_metadata() { local test_metadata_job_id # Ruby - test_metadata_job_id=$(scripts/api/get_job_id.rb --project "${project_path}" -q "status=success" -q "ref=master" -q "username=gitlab-bot" -Q "scope=success" --job-name "update-tests-metadata") + test_metadata_job_id=$(scripts/api/get_job_id.rb --project "${project_path}" -q "status=success" -q "ref=${CI_DEFAULT_BRANCH}" -q "username=gitlab-bot" -Q "scope=success" --job-name "update-tests-metadata") if [[ ! -f "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" ]]; then scripts/api/download_job_artifact.rb --project "${project_path}" --job-id "${test_metadata_job_id}" --artifact-path "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" @@ -42,7 +42,7 @@ function retrieve_tests_mapping() { local project_path="gitlab-org/gitlab" local test_metadata_with_mapping_job_id - test_metadata_with_mapping_job_id=$(scripts/api/get_job_id.rb --project "${project_path}" -q "status=success" -q "ref=master" -q "username=gitlab-bot" -Q "scope=success" --job-name "update-tests-metadata" --artifact-path "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz") + test_metadata_with_mapping_job_id=$(scripts/api/get_job_id.rb --project "${project_path}" -q "status=success" -q "ref=${CI_DEFAULT_BRANCH}" -q "username=gitlab-bot" -Q "scope=success" --job-name "update-tests-metadata" --artifact-path "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz") if [[ ! -f "${RSPEC_PACKED_TESTS_MAPPING_PATH}" ]]; then (scripts/api/download_job_artifact.rb --project "${project_path}" --job-id "${test_metadata_with_mapping_job_id}" --artifact-path "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" && gzip -d "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz") || echo "{}" > "${RSPEC_PACKED_TESTS_MAPPING_PATH}" diff --git a/scripts/validate_migration_schema b/scripts/validate_migration_schema index 0b909f7ac77..f9b2f0677b7 100755 --- a/scripts/validate_migration_schema +++ b/scripts/validate_migration_schema @@ -72,7 +72,7 @@ class MigrationSchemaValidator end def target_branch - ENV['CI_MERGE_REQUEST_TARGET_BRANCH_NAME'] || ENV['TARGET'] || 'master' + ENV['CI_MERGE_REQUEST_TARGET_BRANCH_NAME'] || ENV['TARGET'] || ENV['CI_DEFAULT_BRANCH'] || 'master' end def source_ref diff --git a/spec/features/projects/services/user_activates_issue_tracker_spec.rb b/spec/features/projects/services/user_activates_issue_tracker_spec.rb index 1aec8883395..019d50a497b 100644 --- a/spec/features/projects/services/user_activates_issue_tracker_spec.rb +++ b/spec/features/projects/services/user_activates_issue_tracker_spec.rb @@ -87,6 +87,6 @@ RSpec.describe 'User activates issue tracker', :js do it_behaves_like 'external issue tracker activation', tracker: 'Redmine' it_behaves_like 'external issue tracker activation', tracker: 'YouTrack', skip_new_issue_url: true it_behaves_like 'external issue tracker activation', tracker: 'Bugzilla' - it_behaves_like 'external issue tracker activation', tracker: 'Custom Issue Tracker' + it_behaves_like 'external issue tracker activation', tracker: 'Custom issue tracker' it_behaves_like 'external issue tracker activation', tracker: 'EWM', skip_test: true end diff --git a/spec/frontend/fixtures/api_markdown.yml b/spec/frontend/fixtures/api_markdown.yml index a83d5374e2c..a1ea2806879 100644 --- a/spec/frontend/fixtures/api_markdown.yml +++ b/spec/frontend/fixtures/api_markdown.yml @@ -48,3 +48,7 @@ 3. list item 3 - name: image markdown: '![alt text](https://gitlab.com/logo.png)' +- name: hard_break + markdown: |- + This is a line after a\ + hard break diff --git a/spec/frontend/pipelines/__snapshots__/parsing_utils_spec.js.snap b/spec/frontend/pipelines/__snapshots__/parsing_utils_spec.js.snap new file mode 100644 index 00000000000..60625d301c0 --- /dev/null +++ b/spec/frontend/pipelines/__snapshots__/parsing_utils_spec.js.snap @@ -0,0 +1,373 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DAG visualization parsing utilities generateColumnsFromLayersList matches the snapshot 1`] = ` +Array [ + Object { + "groups": Array [ + Object { + "__typename": "CiGroup", + "jobs": Array [ + Object { + "__typename": "CiJob", + "name": "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", + "needs": Array [], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": Object { + "__typename": "StatusAction", + "buttonTitle": "Retry this job", + "icon": "retry", + "path": "/root/abcd-dag/-/jobs/1482/retry", + "title": "Retry", + }, + "detailsPath": "/root/abcd-dag/-/jobs/1482", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": "passed", + }, + }, + ], + "name": "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", + "size": 1, + "stageName": "build", + "status": Object { + "__typename": "DetailedStatus", + "group": "success", + "icon": "status_success", + "label": "passed", + }, + }, + Object { + "__typename": "CiGroup", + "jobs": Array [ + Object { + "__typename": "CiJob", + "name": "build_b", + "needs": Array [], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": Object { + "__typename": "StatusAction", + "buttonTitle": "Retry this job", + "icon": "retry", + "path": "/root/abcd-dag/-/jobs/1515/retry", + "title": "Retry", + }, + "detailsPath": "/root/abcd-dag/-/jobs/1515", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": "passed", + }, + }, + ], + "name": "build_b", + "size": 1, + "stageName": "build", + "status": Object { + "__typename": "DetailedStatus", + "group": "success", + "icon": "status_success", + "label": "passed", + }, + }, + Object { + "__typename": "CiGroup", + "jobs": Array [ + Object { + "__typename": "CiJob", + "name": "build_c", + "needs": Array [], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": Object { + "__typename": "StatusAction", + "buttonTitle": "Retry this job", + "icon": "retry", + "path": "/root/abcd-dag/-/jobs/1484/retry", + "title": "Retry", + }, + "detailsPath": "/root/abcd-dag/-/jobs/1484", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": "passed", + }, + }, + ], + "name": "build_c", + "size": 1, + "stageName": "build", + "status": Object { + "__typename": "DetailedStatus", + "group": "success", + "icon": "status_success", + "label": "passed", + }, + }, + Object { + "__typename": "CiGroup", + "jobs": Array [ + Object { + "__typename": "CiJob", + "name": "build_d 1/3", + "needs": Array [], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": Object { + "__typename": "StatusAction", + "buttonTitle": "Retry this job", + "icon": "retry", + "path": "/root/abcd-dag/-/jobs/1485/retry", + "title": "Retry", + }, + "detailsPath": "/root/abcd-dag/-/jobs/1485", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": "passed", + }, + }, + Object { + "__typename": "CiJob", + "name": "build_d 2/3", + "needs": Array [], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": Object { + "__typename": "StatusAction", + "buttonTitle": "Retry this job", + "icon": "retry", + "path": "/root/abcd-dag/-/jobs/1486/retry", + "title": "Retry", + }, + "detailsPath": "/root/abcd-dag/-/jobs/1486", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": "passed", + }, + }, + Object { + "__typename": "CiJob", + "name": "build_d 3/3", + "needs": Array [], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": Object { + "__typename": "StatusAction", + "buttonTitle": "Retry this job", + "icon": "retry", + "path": "/root/abcd-dag/-/jobs/1487/retry", + "title": "Retry", + }, + "detailsPath": "/root/abcd-dag/-/jobs/1487", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": "passed", + }, + }, + ], + "name": "build_d", + "size": 3, + "stageName": "build", + "status": Object { + "__typename": "DetailedStatus", + "group": "success", + "icon": "status_success", + "label": "passed", + }, + }, + Object { + "__typename": "CiGroup", + "jobs": Array [ + Object { + "__typename": "CiJob", + "name": "test_c", + "needs": Array [], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": null, + "detailsPath": "/root/kinder-pipe/-/pipelines/154", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": null, + }, + }, + ], + "name": "test_c", + "size": 1, + "stageName": "test", + "status": Object { + "__typename": "DetailedStatus", + "group": "success", + "icon": "status_success", + "label": null, + }, + }, + ], + "id": "layer-0", + "name": "", + "status": Object { + "action": null, + }, + }, + Object { + "groups": Array [ + Object { + "__typename": "CiGroup", + "jobs": Array [ + Object { + "__typename": "CiJob", + "name": "test_a", + "needs": Array [ + "build_c", + "build_b", + "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", + ], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": Object { + "__typename": "StatusAction", + "buttonTitle": "Retry this job", + "icon": "retry", + "path": "/root/abcd-dag/-/jobs/1514/retry", + "title": "Retry", + }, + "detailsPath": "/root/abcd-dag/-/jobs/1514", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": "passed", + }, + }, + ], + "name": "test_a", + "size": 1, + "stageName": "test", + "status": Object { + "__typename": "DetailedStatus", + "group": "success", + "icon": "status_success", + "label": "passed", + }, + }, + Object { + "__typename": "CiGroup", + "jobs": Array [ + Object { + "__typename": "CiJob", + "name": "test_b 1/2", + "needs": Array [ + "build_d 3/3", + "build_d 2/3", + "build_d 1/3", + "build_b", + "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", + ], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": Object { + "__typename": "StatusAction", + "buttonTitle": "Retry this job", + "icon": "retry", + "path": "/root/abcd-dag/-/jobs/1489/retry", + "title": "Retry", + }, + "detailsPath": "/root/abcd-dag/-/jobs/1489", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": "passed", + }, + }, + Object { + "__typename": "CiJob", + "name": "test_b 2/2", + "needs": Array [ + "build_d 3/3", + "build_d 2/3", + "build_d 1/3", + "build_b", + "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", + ], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": Object { + "__typename": "StatusAction", + "buttonTitle": "Retry this job", + "icon": "retry", + "path": "/root/abcd-dag/-/jobs/1490/retry", + "title": "Retry", + }, + "detailsPath": "/root/abcd-dag/-/jobs/1490", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": "passed", + }, + }, + ], + "name": "test_b", + "size": 2, + "stageName": "test", + "status": Object { + "__typename": "DetailedStatus", + "group": "success", + "icon": "status_success", + "label": "passed", + }, + }, + Object { + "__typename": "CiGroup", + "jobs": Array [ + Object { + "__typename": "CiJob", + "name": "test_d", + "needs": Array [ + "build_b", + ], + "scheduledAt": null, + "status": Object { + "__typename": "DetailedStatus", + "action": null, + "detailsPath": "/root/abcd-dag/-/pipelines/153", + "group": "success", + "hasDetails": true, + "icon": "status_success", + "tooltip": null, + }, + }, + ], + "name": "test_d", + "size": 1, + "stageName": "test", + "status": Object { + "__typename": "DetailedStatus", + "group": "success", + "icon": "status_success", + "label": null, + }, + }, + ], + "id": "layer-1", + "name": "", + "status": Object { + "action": null, + }, + }, +] +`; diff --git a/spec/frontend/pipelines/components/dag/parsing_utils_spec.js b/spec/frontend/pipelines/parsing_utils_spec.js index 84ff83883b7..96748ae9e5c 100644 --- a/spec/frontend/pipelines/components/dag/parsing_utils_spec.js +++ b/spec/frontend/pipelines/parsing_utils_spec.js @@ -3,12 +3,15 @@ import { createNodeDict, makeLinksFromNodes, filterByAncestors, + generateColumnsFromLayersListBare, + listByLayers, parseData, removeOrphanNodes, getMaxNodes, } from '~/pipelines/components/parsing_utils'; -import { mockParsedGraphQLNodes } from './mock_data'; +import { mockParsedGraphQLNodes } from './components/dag/mock_data'; +import { generateResponse, mockPipelineResponse } from './graph/mock_data'; describe('DAG visualization parsing utilities', () => { const nodeDict = createNodeDict(mockParsedGraphQLNodes); @@ -108,4 +111,45 @@ describe('DAG visualization parsing utilities', () => { expect(getMaxNodes(layerNodes)).toBe(3); }); }); + + describe('generateColumnsFromLayersList', () => { + const pipeline = generateResponse(mockPipelineResponse, 'root/fungi-xoxo'); + const layers = listByLayers(pipeline); + const columns = generateColumnsFromLayersListBare(pipeline, layers); + + it('returns stage-like objects with default name, id, and status', () => { + columns.forEach((col, idx) => { + expect(col).toMatchObject({ + name: '', + status: { action: null }, + id: `layer-${idx}`, + }); + }); + }); + + it('creates groups that match the list created in listByLayers', () => { + columns.forEach((col, idx) => { + const groupNames = col.groups.map(({ name }) => name); + expect(groupNames).toEqual(layers[idx]); + }); + }); + + it('looks up the correct group object', () => { + columns.forEach((col) => { + col.groups.forEach((group) => { + const groupStage = pipeline.stages.find((el) => el.name === group.stageName); + const groupObject = groupStage.groups.find((el) => el.name === group.name); + expect(group).toBe(groupObject); + }); + }); + }); + + /* + Just as a fallback in case multiple functions change, so tests pass + but the implementation moves away from case. + */ + it('matches the snapshot', () => { + expect(columns).toMatchSnapshot(); + }); + }); }); diff --git a/spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb b/spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb index 00146335ef7..9d7ae6bcb3d 100644 --- a/spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb +++ b/spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb @@ -20,9 +20,27 @@ RSpec.shared_examples 'avoid N+1 on environments serialization' do expect { serialize(grouping: false) }.not_to exceed_query_limit(control.count) end - def serialize(grouping:) + it 'does not preload for environments that does not exist in the page', :request_store do + create_environment_with_associations(project) + + first_page_query = ActiveRecord::QueryRecorder.new do + serialize(grouping: false, query: { page: 1, per_page: 1 } ) + end + + second_page_query = ActiveRecord::QueryRecorder.new do + serialize(grouping: false, query: { page: 2, per_page: 1 } ) + end + + expect(second_page_query.count).to be < first_page_query.count + end + + def serialize(grouping:, query: nil) + query ||= { page: 1, per_page: 1 } + request = double(url: "#{Gitlab.config.gitlab.url}:8080/api/v4/projects?#{query.to_query}", query_parameters: query) + EnvironmentSerializer.new(current_user: user, project: project).yield_self do |serializer| serializer.within_folders if grouping + serializer.with_pagination(request, spy('response')) serializer.represent(Environment.where(project: project)) end end 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 |