diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml index ade96f48f8a..1b807c0c1f6 100644 --- a/.rubocop_todo/layout/line_length.yml +++ b/.rubocop_todo/layout/line_length.yml @@ -1948,7 +1948,6 @@ Layout/LineLength: - 'ee/spec/features/groups/security/compliance_dashboards_spec.rb' - 'ee/spec/features/groups/sso_spec.rb' - 'ee/spec/features/groups/usage_quotas_spec.rb' - - 'ee/spec/features/incidents/incident_details_spec.rb' - 'ee/spec/features/integrations/jira/jira_issues_list_spec.rb' - 'ee/spec/features/invites_spec.rb' - 'ee/spec/features/issues/filtered_search/filter_issues_weight_spec.rb' @@ -2790,8 +2789,6 @@ Layout/LineLength: - 'ee/spec/services/ee/groups/autocomplete_service_spec.rb' - 'ee/spec/services/ee/groups/deploy_tokens/create_service_spec.rb' - 'ee/spec/services/ee/groups/import_export/export_service_spec.rb' - - 'ee/spec/services/ee/incident_management/issuable_escalation_statuses/after_update_service_spec.rb' - - 'ee/spec/services/ee/incident_management/issuable_escalation_statuses/prepare_update_service_spec.rb' - 'ee/spec/services/ee/ip_restrictions/update_service_spec.rb' - 'ee/spec/services/ee/issuable/common_system_notes_service_spec.rb' - 'ee/spec/services/ee/issuable/destroy_service_spec.rb' diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml index a75e247c1ef..7becad56886 100644 --- a/.rubocop_todo/rspec/context_wording.yml +++ b/.rubocop_todo/rspec/context_wording.yml @@ -154,7 +154,6 @@ RSpec/ContextWording: - 'ee/spec/features/groups/wiki/user_views_wiki_empty_spec.rb' - 'ee/spec/features/groups_spec.rb' - 'ee/spec/features/ide/user_opens_ide_spec.rb' - - 'ee/spec/features/incidents/incident_details_spec.rb' - 'ee/spec/features/integrations/jira/jira_issues_list_spec.rb' - 'ee/spec/features/issues/epic_in_issue_sidebar_spec.rb' - 'ee/spec/features/issues/filtered_search/filter_issues_by_iteration_spec.rb' @@ -869,7 +868,6 @@ RSpec/ContextWording: - 'ee/spec/services/ee/ci/job_artifacts/destroy_batch_service_spec.rb' - 'ee/spec/services/ee/git/branch_push_service_spec.rb' - 'ee/spec/services/ee/groups/autocomplete_service_spec.rb' - - 'ee/spec/services/ee/incident_management/issuable_escalation_statuses/after_update_service_spec.rb' - 'ee/spec/services/ee/integrations/test/project_service_spec.rb' - 'ee/spec/services/ee/ip_restrictions/update_service_spec.rb' - 'ee/spec/services/ee/issuable/bulk_update_service_spec.rb' diff --git a/app/models/work_items/parent_link.rb b/app/models/work_items/parent_link.rb index 3c405dbce3b..fc907f323e4 100644 --- a/app/models/work_items/parent_link.rb +++ b/app/models/work_items/parent_link.rb @@ -5,6 +5,7 @@ module WorkItems self.table_name = 'work_item_parent_links' MAX_CHILDREN = 100 + PARENT_TYPES = [:issue, :incident].freeze belongs_to :work_item belongs_to :work_item_parent, class_name: 'WorkItem' @@ -21,15 +22,20 @@ module WorkItems return unless work_item unless work_item.task? - errors.add :work_item, _('Only Task can be assigned as a child in hierarchy.') + errors.add :work_item, _('only Task can be assigned as a child in hierarchy.') end end def validate_parent_type return unless work_item_parent - unless work_item_parent.issue? - errors.add :work_item_parent, _('Only Issue can be parent of Task.') + base_type = work_item_parent.work_item_type.base_type.to_sym + unless PARENT_TYPES.include?(base_type) + parent_names = WorkItems::Type::BASE_TYPES.slice(*WorkItems::ParentLink::PARENT_TYPES) + .values.map { |type| type[:name] } + + errors.add :work_item_parent, _('only %{parent_types} can be parent of Task.') % + { parent_types: parent_names.to_sentence } end end @@ -37,7 +43,7 @@ module WorkItems return if work_item.nil? || work_item_parent.nil? if work_item.resource_parent != work_item_parent.resource_parent - errors.add :work_item_parent, _('Parent must be in the same project as child.') + errors.add :work_item_parent, _('parent must be in the same project as child.') end end @@ -46,7 +52,7 @@ module WorkItems max = persisted? ? MAX_CHILDREN : MAX_CHILDREN - 1 if work_item_parent.child_links.count > max - errors.add :work_item_parent, _('Parent already has maximum number of children.') + errors.add :work_item_parent, _('parent already has maximum number of children.') end end end diff --git a/app/models/work_items/type.rb b/app/models/work_items/type.rb index c52565196a1..e38d0ae153a 100644 --- a/app/models/work_items/type.rb +++ b/app/models/work_items/type.rb @@ -22,7 +22,7 @@ module WorkItems WIDGETS_FOR_TYPE = { issue: [Widgets::Assignees, Widgets::Description, Widgets::Hierarchy, Widgets::Weight], - incident: [Widgets::Description], + incident: [Widgets::Description, Widgets::Hierarchy], test_case: [Widgets::Description], requirement: [Widgets::Description], task: [Widgets::Assignees, Widgets::Description, Widgets::Hierarchy, Widgets::Weight] diff --git a/app/models/work_items/widgets/hierarchy.rb b/app/models/work_items/widgets/hierarchy.rb index dadd341de83..e4367bc8ff1 100644 --- a/app/models/work_items/widgets/hierarchy.rb +++ b/app/models/work_items/widgets/hierarchy.rb @@ -4,13 +4,13 @@ module WorkItems module Widgets class Hierarchy < Base def parent - return unless Feature.enabled?(:work_items_hierarchy, work_item.project) + return unless Feature.enabled?(:work_items, work_item.project) work_item.work_item_parent end def children - return WorkItem.none unless Feature.enabled?(:work_items_hierarchy, work_item.project) + return WorkItem.none unless Feature.enabled?(:work_items, work_item.project) work_item.work_item_children end diff --git a/config/feature_flags/development/issue_email_participants.yml b/config/feature_flags/development/issue_email_participants.yml index 1459d2bc7f5..b5ebb9d8c13 100644 --- a/config/feature_flags/development/issue_email_participants.yml +++ b/config/feature_flags/development/issue_email_participants.yml @@ -1,7 +1,7 @@ --- name: issue_email_participants introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49264 -rollout_issue_url: +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350460 milestone: '13.8' type: development group: group::product planning diff --git a/config/feature_flags/development/skip_scheduling_mirrors_for_free.yml b/config/feature_flags/development/skip_scheduling_mirrors_for_free.yml new file mode 100644 index 00000000000..09f41fa9ff4 --- /dev/null +++ b/config/feature_flags/development/skip_scheduling_mirrors_for_free.yml @@ -0,0 +1,8 @@ +--- +name: skip_scheduling_mirrors_for_free +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/92377 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367712 +milestone: '15.2' +type: development +group: group::source code +default_enabled: false diff --git a/config/metrics/aggregates/common.yml b/config/metrics/aggregates/common.yml index 6396187a26a..a6585ddec23 100644 --- a/config/metrics/aggregates/common.yml +++ b/config/metrics/aggregates/common.yml @@ -59,6 +59,7 @@ events: - users_creating_work_items - users_updating_work_item_title + - users_updating_weight_estimate feature_flag: track_work_items_activity - name: xmau_project_management operator: OR @@ -67,6 +68,7 @@ events: - users_creating_work_items - users_updating_work_item_title + - users_updating_weight_estimate feature_flag: track_work_items_activity - name: users_work_items operator: OR @@ -75,4 +77,5 @@ events: - users_creating_work_items - users_updating_work_item_title + - users_updating_weight_estimate feature_flag: track_work_items_activity diff --git a/doc/administration/audit_event_streaming.md b/doc/administration/audit_event_streaming.md index 8a0bf0e1695..b0884395556 100644 --- a/doc/administration/audit_event_streaming.md +++ b/doc/administration/audit_event_streaming.md @@ -9,6 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332747) in GitLab 14.5 [with a flag](../administration/feature_flags.md) named `ff_external_audit_events_namespace`. Disabled by default. > - [Enabled on GitLab.com and by default on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/338939) in GitLab 14.7. > - [Feature flag `ff_external_audit_events_namespace`](https://gitlab.com/gitlab-org/gitlab/-/issues/349588) removed in GitLab 14.8. +> - [Subgroup events recording](https://gitlab.com/gitlab-org/gitlab/-/issues/366878) fixed in GitLab 15.2. Users can set an HTTP endpoint for a top-level group to receive all audit events about the group, its subgroups, and projects as structured JSON. diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md index a816e452844..08264170d52 100644 --- a/doc/ci/pipelines/index.md +++ b/doc/ci/pipelines/index.md @@ -40,7 +40,7 @@ A typical pipeline might consist of four stages, executed in the following order NOTE: If you have a [mirrored repository that GitLab pulls from](../../user/project/repository/mirror/pull.md), you may need to enable pipeline triggering in your project's -**Settings > Repository > Pull from a remote repository > Trigger pipelines for mirror updates**. +**Settings > Repository > Mirroring repositories > Trigger pipelines for mirror updates**. ## Types of pipelines diff --git a/doc/operations/incident_management/paging.md b/doc/operations/incident_management/paging.md index ef5f6c81383..3eeeb67bf51 100644 --- a/doc/operations/incident_management/paging.md +++ b/doc/operations/incident_management/paging.md @@ -61,4 +61,6 @@ the rule fires. You can respond to a page or stop incident escalations by [updating the incident's status](incidents.md#change-incident-status) or, if applicable, [unsetting the incident's escalation policy](incidents.md#change-escalation-policy). -To avoid duplicate pages, [incidents created from alerts](alerts.md#create-an-incident-from-an-alert) do not support independent escalation. +In GitLab 15.1 and earlier, [incidents created from alerts](alerts.md#create-an-incident-from-an-alert) +do not support independent escalation. In [GitLab 15.2 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/356057), +all incidents can be escalated independently. diff --git a/doc/user/application_security/policies/scan-result-policies.md b/doc/user/application_security/policies/scan-result-policies.md index d6f9465327b..3eee4957e2f 100644 --- a/doc/user/application_security/policies/scan-result-policies.md +++ b/doc/user/application_security/policies/scan-result-policies.md @@ -69,7 +69,7 @@ This rule enforces the defined actions based on the information provided. | Field | Type | Possible values | Description | |------------|------|-----------------|-------------| | `type` | `string` | `scan_finding` | The rule's type. | -| `branches` | `array` of `string` | `[]` or the branch's name | Protected branches for this rule to consider. | +| `branches` | `array` of `string` | `[]` or the branch's name | Applicable only to protected target branches. An empty array, `[]`, applies the rule to all protected target branches. | | `scanners` | `array` of `string` | `sast`, `secret_detection`, `dependency_scanning`, `container_scanning`, `dast`, `coverage_fuzzing`, `api_fuzzing` | The security scanners for this rule to consider. | | `vulnerabilities_allowed` | `integer` | Greater than or equal to zero | Number of vulnerabilities allowed before this rule is considered. | | `severity_levels` | `array` of `string` | `info`, `unknown`, `low`, `medium`, `high`, `critical`| The severity levels for this rule to consider. | diff --git a/doc/user/packages/generic_packages/index.md b/doc/user/packages/generic_packages/index.md index 22b792e443f..8d5fc73ad4e 100644 --- a/doc/user/packages/generic_packages/index.md +++ b/doc/user/packages/generic_packages/index.md @@ -209,3 +209,25 @@ upload: The [Write CI-CD Variables in Pipeline](https://gitlab.com/guided-explorations/cfg-data/write-ci-cd-variables-in-pipeline) project contains a working example you can use to create, upload, and download generic packages in GitLab CI/CD. It also demonstrates how to manage a semantic version for the generic package: storing it in a CI/CD variable, retrieving it, incrementing it, and writing it back to the CI/CD variable when tests for the download work correctly. + +## Troubleshooting + +### Internal Server error on large file uploads to S3 + +S3-compatible object storage [limits the size of a single PUT request to 5GB](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html). If the `aws_signature_version` is set to `2` in the [object storage connection settings](../../../administration/object_storage.md), attempting to publish a package file larger than the 5GB limit can result in a `HTTP 500: Internal Server Error` response. + +If you are receiving `HTTP 500: Internal Server Error` responses when publishing large files to S3, set the `aws_signature_version` to `4`: + +```ruby +# Consolidated Object Storage settings +gitlab_rails['object_store']['connection'] = { + # Other connection settings + `aws_signature_version` => '4' +} +# OR +# Storage-specific form settings +gitlab_rails['packages_object_store_connection'] = { + # Other connection settings + `aws_signature_version` => '4' +} +``` diff --git a/lib/gitlab/usage_data_counters/known_events/work_items.yml b/lib/gitlab/usage_data_counters/known_events/work_items.yml index 0c9c6026c46..5930e711aa2 100644 --- a/lib/gitlab/usage_data_counters/known_events/work_items.yml +++ b/lib/gitlab/usage_data_counters/known_events/work_items.yml @@ -9,3 +9,8 @@ redis_slot: users aggregation: weekly feature_flag: track_work_items_activity +- name: users_updating_weight_estimate + category: work_items + redis_slot: users + aggregation: weekly + feature_flag: track_work_items_activity diff --git a/lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb index 6f5300405c7..51bca8b51fe 100644 --- a/lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb +++ b/lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb @@ -26,3 +26,7 @@ module Gitlab end end end + +# rubocop:disable Layout/LineLength +Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter.prepend_mod_with('Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter') +# rubocop:enable Layout/LineLength diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a5917b76753..35b7cd01383 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -27101,18 +27101,12 @@ msgstr "" msgid "Only Issue ID or merge request ID is required" msgstr "" -msgid "Only Issue can be parent of Task." -msgstr "" - msgid "Only Project Members" msgstr "" msgid "Only SSH" msgstr "" -msgid "Only Task can be assigned as a child in hierarchy." -msgstr "" - msgid "Only accessible by %{membersPageLinkStart}project members%{membersPageLinkEnd}. Membership must be explicitly granted to each user." msgstr "" @@ -27880,18 +27874,12 @@ msgstr "" msgid "Parent" msgstr "" -msgid "Parent already has maximum number of children." -msgstr "" - msgid "Parent epic doesn't exist." msgstr "" msgid "Parent epic is not present." msgstr "" -msgid "Parent must be in the same project as child." -msgstr "" - msgid "Parsing error for param :embed_json. %{message}" msgstr "" @@ -46531,6 +46519,12 @@ msgstr "" msgid "on track" msgstr "" +msgid "only %{parent_types} can be parent of Task." +msgstr "" + +msgid "only Task can be assigned as a child in hierarchy." +msgstr "" + msgid "only available on top-level groups." msgstr "" @@ -46562,6 +46556,12 @@ msgid_plural "parents" msgstr[0] "" msgstr[1] "" +msgid "parent already has maximum number of children." +msgstr "" + +msgid "parent must be in the same project as child." +msgstr "" + msgid "password" msgstr "" diff --git a/package.json b/package.json index 25aa1f8a604..af8f6ca3b8d 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "dateformat": "^5.0.1", "deckar01-task_list": "^2.3.1", "diff": "^3.4.0", - "dompurify": "^2.3.8", + "dompurify": "^2.3.9", "dropzone": "^4.2.0", "editorconfig": "^0.15.3", "emoji-regex": "^10.0.0", diff --git a/spec/factories/work_items.rb b/spec/factories/work_items.rb index e80aa9cc008..81c9fb6ed87 100644 --- a/spec/factories/work_items.rb +++ b/spec/factories/work_items.rb @@ -14,5 +14,10 @@ FactoryBot.define do issue_type { :task } association :work_item_type, :default, :task end + + trait :incident do + issue_type { :incident } + association :work_item_type, :default, :incident + end end end diff --git a/spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb index 4561d898479..0264236f087 100644 --- a/spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb @@ -5,46 +5,6 @@ require 'spec_helper' RSpec.describe Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter, :clean_gitlab_redis_shared_state do let(:user) { build(:user, id: 1) } - shared_examples 'counter that does not track the event' do - it 'does not track the event' do - expect { 3.times { track_event } }.to not_change { - Gitlab::UsageDataCounters::HLLRedisCounter.unique_events( - event_names: event_name, - start_date: 2.weeks.ago, - end_date: 2.weeks.from_now - ) - } - end - end - - shared_examples 'work item unique counter' do - context 'when track_work_items_activity FF is enabled' do - it 'tracks a unique event only once' do - expect { 3.times { track_event } }.to change { - Gitlab::UsageDataCounters::HLLRedisCounter.unique_events( - event_names: event_name, - start_date: 2.weeks.ago, - end_date: 2.weeks.from_now - ) - }.by(1) - end - - context 'when author is nil' do - let(:user) { nil } - - it_behaves_like 'counter that does not track the event' - end - end - - context 'when track_work_items_activity FF is disabled' do - before do - stub_feature_flags(track_work_items_activity: false) - end - - it_behaves_like 'counter that does not track the event' - end - end - describe '.track_work_item_created_action' do subject(:track_event) { described_class.track_work_item_created_action(author: user) } diff --git a/spec/models/work_items/parent_link_spec.rb b/spec/models/work_items/parent_link_spec.rb index 9516baa7340..8abdb4e10b8 100644 --- a/spec/models/work_items/parent_link_spec.rb +++ b/spec/models/work_items/parent_link_spec.rb @@ -15,32 +15,37 @@ RSpec.describe WorkItems::ParentLink do describe 'hierarchy' do let_it_be(:project) { create(:project) } let_it_be(:issue) { build(:work_item, project: project) } + let_it_be(:incident) { build(:work_item, :incident, project: project) } let_it_be(:task1) { build(:work_item, :task, project: project) } let_it_be(:task2) { build(:work_item, :task, project: project) } - it 'is valid if not-task parent has task child' do + it 'is valid if issue parent has task child' do expect(build(:parent_link, work_item: task1, work_item_parent: issue)).to be_valid end + it 'is valid if incident parent has task child' do + expect(build(:parent_link, work_item: task1, work_item_parent: incident)).to be_valid + end + it 'is not valid if child is not task' do link = build(:parent_link, work_item: issue) expect(link).not_to be_valid - expect(link.errors[:work_item]).to include('Only Task can be assigned as a child in hierarchy.') + expect(link.errors[:work_item]).to include('only Task can be assigned as a child in hierarchy.') end it 'is not valid if parent is task' do link = build(:parent_link, work_item_parent: task1) expect(link).not_to be_valid - expect(link.errors[:work_item_parent]).to include('Only Issue can be parent of Task.') + expect(link.errors[:work_item_parent]).to include('only Issue and Incident can be parent of Task.') end it 'is not valid if parent is in other project' do link = build(:parent_link, work_item_parent: task1, work_item: build(:work_item)) expect(link).not_to be_valid - expect(link.errors[:work_item_parent]).to include('Parent must be in the same project as child.') + expect(link.errors[:work_item_parent]).to include('parent must be in the same project as child.') end context 'when parent already has maximum number of links' do @@ -54,7 +59,7 @@ RSpec.describe WorkItems::ParentLink do link2 = build(:parent_link, work_item_parent: issue, work_item: task2) expect(link2).not_to be_valid - expect(link2.errors[:work_item_parent]).to include('Parent already has maximum number of children.') + expect(link2.errors[:work_item_parent]).to include('parent already has maximum number of children.') end it 'existing link is still valid' do diff --git a/spec/models/work_items/widgets/hierarchy_spec.rb b/spec/models/work_items/widgets/hierarchy_spec.rb index 0141731529b..6d05953ecff 100644 --- a/spec/models/work_items/widgets/hierarchy_spec.rb +++ b/spec/models/work_items/widgets/hierarchy_spec.rb @@ -24,9 +24,9 @@ RSpec.describe WorkItems::Widgets::Hierarchy do it { is_expected.to eq parent_link.work_item_parent } - context 'when work_items_hierarchy flag is disabled' do + context 'when work_items flag is disabled' do before do - stub_feature_flags(work_items_hierarchy: false) + stub_feature_flags(work_items: false) end it { is_expected.to be_nil } @@ -41,9 +41,9 @@ RSpec.describe WorkItems::Widgets::Hierarchy do it { is_expected.to match_array([parent_link1.work_item, parent_link2.work_item]) } - context 'when work_items_hierarchy flag is disabled' do + context 'when work_items flag is disabled' do before do - stub_feature_flags(work_items_hierarchy: false) + stub_feature_flags(work_items: false) end it { is_expected.to be_empty } diff --git a/spec/requests/api/graphql/mutations/work_items/create_spec.rb b/spec/requests/api/graphql/mutations/work_items/create_spec.rb index c33dda67a25..3496ab38ee8 100644 --- a/spec/requests/api/graphql/mutations/work_items/create_spec.rb +++ b/spec/requests/api/graphql/mutations/work_items/create_spec.rb @@ -120,7 +120,8 @@ RSpec.describe 'Create a work item' do it 'returns error' do post_graphql_mutation(mutation, current_user: current_user) - expect(mutation_response['errors']).to contain_exactly(/cannot be added: Only Issue can be parent of Task./) + expect(mutation_response['errors']) + .to contain_exactly(/cannot be added: only Issue and Incident can be parent of Task./) expect(mutation_response['workItem']).to be_nil end end diff --git a/spec/requests/api/graphql/mutations/work_items/update_spec.rb b/spec/requests/api/graphql/mutations/work_items/update_spec.rb index e2c4386772c..b5f0eb7fbf6 100644 --- a/spec/requests/api/graphql/mutations/work_items/update_spec.rb +++ b/spec/requests/api/graphql/mutations/work_items/update_spec.rb @@ -170,7 +170,7 @@ RSpec.describe 'Update a work item' do let_it_be(:invalid_parent) { create(:work_item, :task, project: project) } context 'when parent work item type is invalid' do - let(:error) { "#{work_item.to_reference} cannot be added: Only Issue can be parent of Task." } + let(:error) { "#{work_item.to_reference} cannot be added: only Issue and Incident can be parent of Task." } let(:input) do { 'hierarchyWidget' => { 'parentId' => invalid_parent.to_global_id.to_s }, 'title' => 'new title' } end @@ -281,7 +281,7 @@ RSpec.describe 'Update a work item' do let(:input) { { 'hierarchyWidget' => { 'childrenIds' => children_ids } } } let(:error) do - "#{invalid_child.to_reference} cannot be added: Only Task can be assigned as a child in hierarchy." + "#{invalid_child.to_reference} cannot be added: only Task can be assigned as a child in hierarchy." end context 'when child work item type is invalid' do diff --git a/spec/services/work_items/create_and_link_service_spec.rb b/spec/services/work_items/create_and_link_service_spec.rb index 36038768d1a..81be15f9e2f 100644 --- a/spec/services/work_items/create_and_link_service_spec.rb +++ b/spec/services/work_items/create_and_link_service_spec.rb @@ -68,7 +68,7 @@ RSpec.describe WorkItems::CreateAndLinkService do end it 'returns a link creation error message' do - expect(service_result.errors).to contain_exactly(/Only Issue can be parent of Task./) + expect(service_result.errors).to contain_exactly(/only Issue and Incident can be parent of Task./) end end end diff --git a/spec/services/work_items/create_service_spec.rb b/spec/services/work_items/create_service_spec.rb index 0d3c5391a4f..7b44601bfdd 100644 --- a/spec/services/work_items/create_service_spec.rb +++ b/spec/services/work_items/create_service_spec.rb @@ -148,7 +148,7 @@ RSpec.describe WorkItems::CreateService do expect { service_result }.not_to change(WorkItem, :count) expect(service_result[:status]).to be(:error) - expect(service_result[:message]).to match(/Only Issue can be parent of Task./) + expect(service_result[:message]).to match(/only Issue and Incident can be parent of Task./) end end diff --git a/spec/services/work_items/parent_links/create_service_spec.rb b/spec/services/work_items/parent_links/create_service_spec.rb index 3e3d65a8615..7aa90d01a0b 100644 --- a/spec/services/work_items/parent_links/create_service_spec.rb +++ b/spec/services/work_items/parent_links/create_service_spec.rb @@ -102,8 +102,8 @@ RSpec.describe WorkItems::ParentLinks::CreateService do end it 'returns error status' do - error = "#{issue.to_reference} cannot be added: Only Task can be assigned as a child in hierarchy.. " \ - "#{other_project_task.to_reference} cannot be added: Parent must be in the same project as child." + error = "#{issue.to_reference} cannot be added: only Task can be assigned as a child in hierarchy.. " \ + "#{other_project_task.to_reference} cannot be added: parent must be in the same project as child." is_expected.to eq(service_error(error, http_status: 422)) end @@ -115,7 +115,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do let(:params) { { target_issuable: task1 } } it 'returns error status' do - error = "#{task1.to_reference} cannot be added: Only Issue can be parent of Task." + error = "#{task1.to_reference} cannot be added: only Issue and Incident can be parent of Task." is_expected.to eq(service_error(error, http_status: 422)) end @@ -129,7 +129,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do end it 'returns error status' do - error = "#{task2.to_reference} cannot be added: Parent already has maximum number of children." + error = "#{task2.to_reference} cannot be added: parent already has maximum number of children." is_expected.to eq(service_error(error, http_status: 422)) end diff --git a/spec/services/work_items/update_service_spec.rb b/spec/services/work_items/update_service_spec.rb index 25b8caba0e8..3423b92e35c 100644 --- a/spec/services/work_items/update_service_spec.rb +++ b/spec/services/work_items/update_service_spec.rb @@ -165,7 +165,7 @@ RSpec.describe WorkItems::UpdateService do it 'returns error status' do expect(subject[:status]).to be(:error) expect(subject[:message]) - .to match("#{child_work_item.to_reference} cannot be added: Only Task can be assigned as a child in hierarchy.") + .to match("#{child_work_item.to_reference} cannot be added: only Task can be assigned as a child in hierarchy.") end it 'does not update work item attributes' do diff --git a/spec/services/work_items/widgets/hierarchy_service/update_service_spec.rb b/spec/services/work_items/widgets/hierarchy_service/update_service_spec.rb index 528e20f95ad..c48e17431bf 100644 --- a/spec/services/work_items/widgets/hierarchy_service/update_service_spec.rb +++ b/spec/services/work_items/widgets/hierarchy_service/update_service_spec.rb @@ -85,7 +85,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do it_behaves_like 'raises a WidgetError' do let(:message) do - "#{child_issue.to_reference} cannot be added: Only Task can be assigned as a child in hierarchy." + "#{child_issue.to_reference} cannot be added: only Task can be assigned as a child in hierarchy." end end end @@ -149,7 +149,9 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do let(:params) {{ parent: parent_task } } it_behaves_like 'raises a WidgetError' do - let(:message) { "#{work_item.to_reference} cannot be added: Only Issue can be parent of Task." } + let(:message) do + "#{work_item.to_reference} cannot be added: only Issue and Incident can be parent of Task." + end end end end diff --git a/spec/support/shared_examples/usage_data_counters/work_item_activity_unique_counter_shared_examples.rb b/spec/support/shared_examples/usage_data_counters/work_item_activity_unique_counter_shared_examples.rb new file mode 100644 index 00000000000..4655585a092 --- /dev/null +++ b/spec/support/shared_examples/usage_data_counters/work_item_activity_unique_counter_shared_examples.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'counter that does not track the event' do + it 'does not track the event' do + expect { 3.times { track_event } }.to not_change { + Gitlab::UsageDataCounters::HLLRedisCounter.unique_events( + event_names: event_name, + start_date: 2.weeks.ago, + end_date: 2.weeks.from_now + ) + } + end +end + +RSpec.shared_examples 'work item unique counter' do + context 'when track_work_items_activity FF is enabled' do + it 'tracks a unique event only once' do + expect { 3.times { track_event } }.to change { + Gitlab::UsageDataCounters::HLLRedisCounter.unique_events( + event_names: event_name, + start_date: 2.weeks.ago, + end_date: 2.weeks.from_now + ) + }.by(1) + end + + context 'when author is nil' do + let(:user) { nil } + + it_behaves_like 'counter that does not track the event' + end + end + + context 'when track_work_items_activity FF is disabled' do + before do + stub_feature_flags(track_work_items_activity: false) + end + + it_behaves_like 'counter that does not track the event' + end +end diff --git a/workhorse/internal/badgateway/embed/gitlab-logo-500.png b/workhorse/internal/badgateway/embed/gitlab-logo-500.png new file mode 100644 index 00000000000..516f5bb27a1 Binary files /dev/null and b/workhorse/internal/badgateway/embed/gitlab-logo-500.png differ diff --git a/workhorse/internal/badgateway/roundtripper.go b/workhorse/internal/badgateway/roundtripper.go index 240a4ebc86b..cc982b092a7 100644 --- a/workhorse/internal/badgateway/roundtripper.go +++ b/workhorse/internal/badgateway/roundtripper.go @@ -2,6 +2,8 @@ package badgateway import ( "bytes" + _ "embed" + "encoding/base64" "fmt" "html/template" "io" @@ -12,6 +14,9 @@ import ( "gitlab.com/gitlab-org/gitlab/workhorse/internal/log" ) +//go:embed embed/gitlab-logo-500.png +var gitlabLogo []byte + // Error is a custom error for pretty Sentry 'issues' type sentryError struct{ error } @@ -68,9 +73,10 @@ func (t *roundTripper) RoundTrip(r *http.Request) (*http.Response, error) { func developmentModeResponse(err error) (body string, contentType string) { data := TemplateData{ - Time: time.Now().Format("15:04:05"), - Error: err.Error(), - ReloadSeconds: 5, + Time: time.Now().Format("15:04:05"), + Error: err.Error(), + ReloadSeconds: 5, + Base64EncodedGitLabLogo: base64.StdEncoding.EncodeToString(gitlabLogo), } buf := &bytes.Buffer{} @@ -82,28 +88,44 @@ func developmentModeResponse(err error) (body string, contentType string) { } type TemplateData struct { - Time string - Error string - ReloadSeconds int + Time string + Error string + ReloadSeconds int + Base64EncodedGitLabLogo string } var developmentErrorTemplate = template.Must(template.New("error502").Parse(` - + + + -502: GitLab is not responding - + Waiting for GitLab to boot -

502

-

GitLab is not responding. The error was:

+
+ GitLab -
{{.Error}}
+

Waiting for GitLab to boot

-

If you just started GDK it can take 60-300 seconds before GitLab has finished booting. This page will automatically reload every {{.ReloadSeconds}} seconds.

- +
{{.Error}}
+ +
+ +

It can take 60-180 seconds for GitLab to boot completely.

+

This page will automatically reload every {{.ReloadSeconds}} seconds.

+ +
+ + +
+ + + `))