diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-09 09:09:18 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-09 09:09:18 +0000 |
commit | 7a98d989740ec85982cdb6c1d57c8f24270e455e (patch) | |
tree | 7b0aca9f515ac61b346544afbec6b63ea3bf462c | |
parent | 0ac2fcc287b33c4f6940391c5632d5f90735eff9 (diff) | |
download | gitlab-ce-7a98d989740ec85982cdb6c1d57c8f24270e455e.tar.gz |
Add latest changes from gitlab-org/gitlab@master
16 files changed, 159 insertions, 30 deletions
diff --git a/.rubocop_todo/layout/hash_alignment.yml b/.rubocop_todo/layout/hash_alignment.yml index a612b545ac9..076b3adf7f5 100644 --- a/.rubocop_todo/layout/hash_alignment.yml +++ b/.rubocop_todo/layout/hash_alignment.yml @@ -1,5 +1,4 @@ --- -# Cop supports --auto-correct. Layout/HashAlignment: # Offense count: 630 # Temporarily disabled due to too many offenses @@ -40,17 +39,6 @@ Layout/HashAlignment: - 'app/models/wiki.rb' - 'app/models/work_items/type.rb' - 'ee/app/graphql/types/vulnerability_request_response_header_type.rb' - - 'ee/app/models/allowed_email_domain.rb' - - 'ee/app/models/ci/minutes/usage.rb' - - 'ee/app/models/ee/application_setting.rb' - - 'ee/app/models/elastic/reindexing_task.rb' - - 'ee/app/models/gitlab_subscriptions/features.rb' - - 'ee/app/models/gitlab_subscriptions/upcoming_reconciliation.rb' - - 'ee/app/models/historical_data.rb' - - 'ee/app/models/incident_management/escalation_rule.rb' - - 'ee/app/models/incident_management/oncall_rotation.rb' - - 'ee/app/models/scim_identity.rb' - - 'ee/app/models/status_page/project_setting.rb' - 'ee/app/serializers/ee/evidences/release_entity.rb' - 'ee/app/services/ci/external_pull_requests/process_github_event_service.rb' - 'ee/app/services/ci_cd/setup_project.rb' diff --git a/app/graphql/resolvers/group_milestones_resolver.rb b/app/graphql/resolvers/group_milestones_resolver.rb index 319ff9f68c4..9242be7f684 100644 --- a/app/graphql/resolvers/group_milestones_resolver.rb +++ b/app/graphql/resolvers/group_milestones_resolver.rb @@ -45,5 +45,9 @@ module Resolvers options: { include_subgroups: true } ).execute end + + def preloads + super.merge({ subgroup_milestone: :group }) + end end end diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb index d41b7c34302..6365738e869 100644 --- a/app/graphql/types/group_type.rb +++ b/app/graphql/types/group_type.rb @@ -85,6 +85,7 @@ module Types field :milestones, description: 'Milestones of the group.', + extras: [:lookahead], resolver: Resolvers::GroupMilestonesResolver field :boards, diff --git a/app/models/note.rb b/app/models/note.rb index 986a85acac6..1715f7cdc3b 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -23,6 +23,8 @@ class Note < ApplicationRecord include FromUnion include Sortable + ISSUE_TASK_SYSTEM_NOTE_PATTERN = /\A.*marked\sthe\stask.+as\s(completed|incomplete).*\z/.freeze + cache_markdown_field :note, pipeline: :note, issuable_reference_expansion_enabled: true redact_field :note @@ -685,6 +687,22 @@ class Note < ApplicationRecord Ability.users_that_can_read_internal_notes(users, resource_parent).pluck(:id) end + # Method necesary while we transition into the new format for task system notes + # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/369923 + def note + return super unless system? && for_issue? && super.match?(ISSUE_TASK_SYSTEM_NOTE_PATTERN) + + super.sub!('task', 'checklist item') + end + + # Method necesary while we transition into the new format for task system notes + # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/369923 + def note_html + return super unless system? && for_issue? && super.match?(ISSUE_TASK_SYSTEM_NOTE_PATTERN) + + super.sub!('task', 'checklist item') + end + private def system_note_viewable_by?(user) diff --git a/app/services/system_notes/issuables_service.rb b/app/services/system_notes/issuables_service.rb index 440ffd78855..d2c6e9890db 100644 --- a/app/services/system_notes/issuables_service.rb +++ b/app/services/system_notes/issuables_service.rb @@ -273,12 +273,12 @@ module SystemNotes # # Example Note text: # - # "marked the task Whatever as completed." + # "marked the checklist item Whatever as completed." # # Returns the created Note object def change_task_status(new_task) status_label = new_task.complete? ? Taskable::COMPLETED : Taskable::INCOMPLETE - body = "marked the task **#{new_task.source}** as #{status_label}" + body = "marked the checklist item **#{new_task.source}** as #{status_label}" issue_activity_counter.track_issue_description_changed_action(author: author) if noteable.is_a?(Issue) diff --git a/doc/development/documentation/site_architecture/deployment_process.md b/doc/development/documentation/site_architecture/deployment_process.md index 76ae144dbc0..5f6076f3195 100644 --- a/doc/development/documentation/site_architecture/deployment_process.md +++ b/doc/development/documentation/site_architecture/deployment_process.md @@ -142,6 +142,20 @@ graph LR B--"Unpacked documentation uploaded"-->C ``` +### Manually deploy to production + +GitLab Docs is deployed to production whenever the `Build docs.gitlab.com every 4 hours` scheduled pipeline runs. By +default, this pipeline runs every four hours. + +Maintainers can [manually](../../../ci/pipelines/schedules.md#run-manually) run this pipeline to force a deployment to +production: + +1. Go to the [scheduled pipelines](https://gitlab.com/gitlab-org/gitlab-docs/-/pipeline_schedules) for `gitlab-docs`. +1. Next to `Build docs.gitlab.com every 4 hours`, select **Play** (**{play}**). + +The updated documentation is available in production after the `pages` and `pages:deploy` jobs +complete in the new pipeline. + ## Docker files The [`dockerfiles` directory](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/dockerfiles/) contains all needed diff --git a/doc/operations/incident_management/img/timeline_events_v15_1.png b/doc/operations/incident_management/img/timeline_events_v15_1.png Binary files differindex 3241f35764c..67bc727bc22 100644 --- a/doc/operations/incident_management/img/timeline_events_v15_1.png +++ b/doc/operations/incident_management/img/timeline_events_v15_1.png diff --git a/doc/user/application_security/sast/img/sast_vulnerability_page_fp_detection_v15_2.png b/doc/user/application_security/sast/img/sast_vulnerability_page_fp_detection_v15_2.png Binary files differindex 253e914f1cd..2a3e6e7e45f 100644 --- a/doc/user/application_security/sast/img/sast_vulnerability_page_fp_detection_v15_2.png +++ b/doc/user/application_security/sast/img/sast_vulnerability_page_fp_detection_v15_2.png diff --git a/doc/user/img/completed_tasks_v15_3.png b/doc/user/img/completed_tasks_v15_3.png Binary files differindex 09174c688da..c1619e70839 100644 --- a/doc/user/img/completed_tasks_v15_3.png +++ b/doc/user/img/completed_tasks_v15_3.png diff --git a/spec/frontend/right_sidebar_spec.js b/spec/frontend/right_sidebar_spec.js index 5847842f5a6..3b220ba8351 100644 --- a/spec/frontend/right_sidebar_spec.js +++ b/spec/frontend/right_sidebar_spec.js @@ -70,7 +70,7 @@ describe('RightSidebar', () => { it('should not hide collapsed icons', () => { [].forEach.call(document.querySelectorAll('.sidebar-collapsed-icon'), (el) => { - expect(el.querySelector('.fa, svg').classList.contains('hidden')).toBeFalsy(); + expect(el.querySelector('.fa, svg').classList.contains('hidden')).toBe(false); }); }); }); diff --git a/spec/graphql/types/group_type_spec.rb b/spec/graphql/types/group_type_spec.rb index 69c7eaf111f..ab81db8fec0 100644 --- a/spec/graphql/types/group_type_spec.rb +++ b/spec/graphql/types/group_type_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe GitlabSchema.types['Group'] do + include GraphqlHelpers + specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Group) } specify { expect(described_class.graphql_name).to eq('Group') } @@ -56,4 +58,42 @@ RSpec.describe GitlabSchema.types['Group'] do it_behaves_like 'a GraphQL type with labels' do let(:labels_resolver_arguments) { [:search_term, :includeAncestorGroups, :includeDescendantGroups, :onlyGroupLabels] } end + + describe 'milestones' do + let(:user) { create(:user) } + let(:subgroup) { create(:group, parent: create(:group)) } + let(:query) do + %( + query { + group(fullPath: "#{subgroup.full_path}") { + milestones { + nodes { + id + title + projectMilestone + groupMilestone + subgroupMilestone + } + } + } + } + ) + end + + def clean_state_query + run_with_clean_state(query, context: { current_user: user }) + end + + it 'avoids N+1 queries' do + subgroup.add_reporter(user) + + create(:milestone, group: subgroup) + + control = ActiveRecord::QueryRecorder.new(skip_cached: false) { clean_state_query } + + create_list(:milestone, 2, group: subgroup) + + expect { clean_state_query }.not_to exceed_all_query_limit(control) + end + end end diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index b18adc98132..ca558848cb0 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -1792,4 +1792,68 @@ RSpec.describe Note do end end end + + shared_examples 'note that replaces task for checklist item in body text' do + subject { note.public_send(field_name) } + + context 'when note is not a system note' do + let(:note) { create(:note, note: original_note_body) } + + it { is_expected.to eq(unchanged_note_body) } + end + + context 'when note is a system note' do + context 'when note noteable_type is not Issue' do + let(:note) { create(:note, :system, :on_merge_request, note: original_note_body) } + + it { is_expected.to eq(unchanged_note_body) } + end + + context 'when note noteable_type is Issue' do + let(:note) { create(:note, :system, :on_issue, note: original_note_body) } + + it { is_expected.to eq(expected_text_replacement) } + end + end + end + + describe '#note' do + let(:field_name) { :note } + + it_behaves_like 'note that replaces task for checklist item in body text' do + let(:original_note_body) { 'marked the task **task 1** as completed' } + let(:unchanged_note_body) { original_note_body } + let(:expected_text_replacement) { 'marked the checklist item **task 1** as completed' } + end + + it_behaves_like 'note that replaces task for checklist item in body text' do + let(:original_note_body) { 'marked the task **task 1** as incomplete' } + let(:unchanged_note_body) { original_note_body } + let(:expected_text_replacement) { 'marked the checklist item **task 1** as incomplete' } + end + end + + describe '#note_html' do + let(:field_name) { :note_html } + + it_behaves_like 'note that replaces task for checklist item in body text' do + let(:original_note_body) { 'marked the task **task 1** as completed' } + let(:unchanged_note_body) { '<p data-sourcepos="1:1-1:48" dir="auto">marked the task <strong>task 1</strong> as completed</p>' } + let(:expected_text_replacement) { '<p data-sourcepos="1:1-1:48" dir="auto">marked the checklist item <strong>task 1</strong> as completed</p>' } + + before do + note.update_columns(note_html: unchanged_note_body) + end + end + + it_behaves_like 'note that replaces task for checklist item in body text' do + let(:original_note_body) { 'marked the task **task 1** as incomplete' } + let(:unchanged_note_body) { '<p data-sourcepos="1:1-1:48" dir="auto">marked the task <strong>task 1</strong> as incomplete</p>' } + let(:expected_text_replacement) { '<p data-sourcepos="1:1-1:48" dir="auto">marked the checklist item <strong>task 1</strong> as incomplete</p>' } + + before do + note.update_columns(note_html: unchanged_note_body) + end + end + end end diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 9ef969d802b..aef3608831c 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -849,8 +849,8 @@ RSpec.describe Issues::UpdateService, :mailer do end it 'creates system note about task status change' do - note1 = find_note('marked the task **Task 1** as completed') - note2 = find_note('marked the task **Task 2** as completed') + note1 = find_note('marked the checklist item **Task 1** as completed') + note2 = find_note('marked the checklist item **Task 2** as completed') expect(note1).not_to be_nil expect(note2).not_to be_nil @@ -867,8 +867,8 @@ RSpec.describe Issues::UpdateService, :mailer do end it 'creates system note about task status change' do - note1 = find_note('marked the task **Task 1** as incomplete') - note2 = find_note('marked the task **Task 2** as incomplete') + note1 = find_note('marked the checklist item **Task 1** as incomplete') + note2 = find_note('marked the checklist item **Task 2** as incomplete') expect(note1).not_to be_nil expect(note2).not_to be_nil @@ -885,7 +885,7 @@ RSpec.describe Issues::UpdateService, :mailer do end it 'does not create a system note for the task' do - task_note = find_note('marked the task **Task 2** as incomplete') + task_note = find_note('marked the checklist item **Task 2** as incomplete') description_notes = find_notes('description') expect(task_note).to be_nil @@ -900,7 +900,7 @@ RSpec.describe Issues::UpdateService, :mailer do end it 'does not create a system note referencing the position the old item' do - task_note = find_note('marked the task **Two** as incomplete') + task_note = find_note('marked the checklist item **Two** as incomplete') description_notes = find_notes('description') expect(task_note).to be_nil diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index a4cd9ed608b..b7fb48718d8 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -980,8 +980,8 @@ RSpec.describe MergeRequests::UpdateService, :mailer do end it 'creates system note about task status change' do - note1 = find_note('marked the task **Task 1** as completed') - note2 = find_note('marked the task **Task 2** as completed') + note1 = find_note('marked the checklist item **Task 1** as completed') + note2 = find_note('marked the checklist item **Task 2** as completed') expect(note1).not_to be_nil expect(note2).not_to be_nil @@ -998,8 +998,8 @@ RSpec.describe MergeRequests::UpdateService, :mailer do end it 'creates system note about task status change' do - note1 = find_note('marked the task **Task 1** as incomplete') - note2 = find_note('marked the task **Task 2** as incomplete') + note1 = find_note('marked the checklist item **Task 1** as incomplete') + note2 = find_note('marked the checklist item **Task 2** as incomplete') expect(note1).not_to be_nil expect(note2).not_to be_nil diff --git a/spec/services/system_notes/issuables_service_spec.rb b/spec/services/system_notes/issuables_service_spec.rb index 4bfedf5c2a2..70f6ce8926c 100644 --- a/spec/services/system_notes/issuables_service_spec.rb +++ b/spec/services/system_notes/issuables_service_spec.rb @@ -559,8 +559,8 @@ RSpec.describe ::SystemNotes::IssuablesService do let(:action) { 'task' } end - it "posts the 'marked the task as complete' system note" do - expect(subject.note).to eq("marked the task **task** as completed") + it "posts the 'marked the checklist item as complete' system note" do + expect(subject.note).to eq("marked the checklist item **task** as completed") end end diff --git a/spec/support/shared_examples/services/issuable_shared_examples.rb b/spec/support/shared_examples/services/issuable_shared_examples.rb index a50a386afe1..142d4ae8531 100644 --- a/spec/support/shared_examples/services/issuable_shared_examples.rb +++ b/spec/support/shared_examples/services/issuable_shared_examples.rb @@ -45,7 +45,7 @@ RSpec.shared_examples 'updating a single task' do end it 'creates system note about task status change' do - note1 = find_note('marked the task **Task 1** as completed') + note1 = find_note('marked the checklist item **Task 1** as completed') expect(note1).not_to be_nil @@ -61,7 +61,7 @@ RSpec.shared_examples 'updating a single task' do end it 'creates system note about task status change' do - note1 = find_note('marked the task **Task 2** as incomplete') + note1 = find_note('marked the checklist item **Task 2** as incomplete') expect(note1).not_to be_nil @@ -92,7 +92,7 @@ RSpec.shared_examples 'updating a single task' do end it 'creates system note about task status change' do - note1 = find_note('marked the task **Task 2** as incomplete') + note1 = find_note('marked the checklist item **Task 2** as incomplete') expect(note1).not_to be_nil |