diff --git a/.rubocop_todo/style/open_struct_use.yml b/.rubocop_todo/style/open_struct_use.yml index 47d272def01..e6af3b7bf24 100644 --- a/.rubocop_todo/style/open_struct_use.yml +++ b/.rubocop_todo/style/open_struct_use.yml @@ -17,7 +17,5 @@ Style/OpenStructUse: - spec/helpers/profiles_helper_spec.rb - spec/lib/gitlab/gitaly_client/blobs_stitcher_spec.rb - spec/lib/gitlab/gitaly_client/diff_stitcher_spec.rb - - spec/lib/gitlab/legacy_github_import/project_creator_spec.rb - - spec/lib/gitlab/quick_actions/command_definition_spec.rb - spec/services/system_note_service_spec.rb - spec/support/helpers/repo_helpers.rb diff --git a/app/assets/javascripts/groups/components/item_stats.vue b/app/assets/javascripts/groups/components/item_stats.vue index 00d597a0ccd..2aa812250a0 100644 --- a/app/assets/javascripts/groups/components/item_stats.vue +++ b/app/assets/javascripts/groups/components/item_stats.vue @@ -55,7 +55,7 @@ export default { :title="__('Subgroups')" :value="item.subgroupCount" css-class="number-subgroups gl-ml-5" - icon-name="group" + icon-name="subgroup" data-testid="subgroups-count" />
-
+
'support_help_block' diff --git a/app/views/admin/application_settings/_kroki.html.haml b/app/views/admin/application_settings/_kroki.html.haml index b22eef83876..61469d87656 100644 --- a/app/views/admin/application_settings/_kroki.html.haml +++ b/app/views/admin/application_settings/_kroki.html.haml @@ -9,14 +9,13 @@ = _('Users can render diagrams in AsciiDoc, Markdown, reStructuredText, and Textile documents using Kroki.') = link_to _('Learn more.'), help_page_path('administration/integration/kroki.md'), target: '_blank', rel: 'noopener noreferrer' .settings-content - = form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-kroki-settings'), html: { class: 'fieldset-form', id: 'kroki-settings' } do |f| + = gitlab_ui_form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-kroki-settings'), html: { class: 'fieldset-form', id: 'kroki-settings' } do |f| = form_errors(@application_setting) if expanded %fieldset .form-group - .form-check - = f.check_box :kroki_enabled, class: 'form-check-input' - = f.label :kroki_enabled, _('Enable Kroki'), class: 'form-check-label' + = f.gitlab_ui_checkbox_component :kroki_enabled, + _('Enable Kroki') .form-group = f.label :kroki_url, 'Kroki URL', class: 'label-bold' = f.text_field :kroki_url, class: 'form-control gl-form-input', placeholder: 'http://your-kroki-instance:8000' @@ -30,9 +29,7 @@ - container_link_url = 'https://docs.kroki.io/kroki/setup/install/#images' - container_link_start = ''.html_safe % { url: container_link_url } = html_escape(_('To use the additional formats, you must start the required %{container_link_start}companion containers%{container_link_end}.')) % { container_link_start: container_link_start, container_link_end: ''.html_safe } - - kroki_available_formats.each do |format| - .form-check - = f.check_box format[:name], class: 'form-check-input' - = f.label format[:name], format[:label], class: 'form-check-label' + - kroki_available_formats.each do |format| + = f.gitlab_ui_checkbox_component format[:name], format[:label] = f.submit _('Save changes'), class: "btn gl-button btn-confirm" diff --git a/app/views/admin/application_settings/_mailgun.html.haml b/app/views/admin/application_settings/_mailgun.html.haml index ad9e84ffdab..7afb35bc9cb 100644 --- a/app/views/admin/application_settings/_mailgun.html.haml +++ b/app/views/admin/application_settings/_mailgun.html.haml @@ -8,14 +8,13 @@ %p = _('Configure the %{link} integration.').html_safe % { link: link_to(_('Mailgun events'), 'https://documentation.mailgun.com/en/latest/user_manual.html#webhooks', target: '_blank', rel: 'noopener noreferrer') } .settings-content - = form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-mailgun-settings'), html: { class: 'fieldset-form', id: 'mailgun-settings' } do |f| + = gitlab_ui_form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-mailgun-settings'), html: { class: 'fieldset-form', id: 'mailgun-settings' } do |f| = form_errors(@application_setting) if expanded %fieldset .form-group - .form-check - = f.check_box :mailgun_events_enabled, class: 'form-check-input' - = f.label :mailgun_events_enabled, _('Enable Mailgun event receiver'), class: 'form-check-label' + = f.gitlab_ui_checkbox_component :mailgun_events_enabled, + _('Enable Mailgun event receiver') .form-group = f.label :mailgun_signing_key, _('Mailgun HTTP webhook signing key'), class: 'label-light' = f.text_field :mailgun_signing_key, class: 'form-control gl-form-input' diff --git a/app/views/admin/application_settings/_plantuml.html.haml b/app/views/admin/application_settings/_plantuml.html.haml index 39de15dc38d..42914652655 100644 --- a/app/views/admin/application_settings/_plantuml.html.haml +++ b/app/views/admin/application_settings/_plantuml.html.haml @@ -9,14 +9,13 @@ = _('Render diagrams in your documents using PlantUML.') = link_to _('Learn more.'), help_page_path('administration/integration/plantuml.md'), target: '_blank', rel: 'noopener noreferrer' .settings-content - = form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-plantuml-settings'), html: { class: 'fieldset-form', id: 'plantuml-settings' } do |f| + = gitlab_ui_form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-plantuml-settings'), html: { class: 'fieldset-form', id: 'plantuml-settings' } do |f| = form_errors(@application_setting) if expanded %fieldset .form-group - .form-check - = f.check_box :plantuml_enabled, class: 'form-check-input' - = f.label :plantuml_enabled, _('Enable PlantUML'), class: 'form-check-label' + = f.gitlab_ui_checkbox_component :plantuml_enabled, + _('Enable PlantUML') .form-group = 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' diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index ddd3b4c2d1c..3fb48f3d3e3 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -8,7 +8,7 @@ - Gitlab::Themes.each do |theme| = stylesheet_link_tag "themes/#{theme.css_filename}" if theme.css_filename -= form_for @user, url: profile_preferences_path, remote: true, method: :put, html: { id: "profile-preferences-form" } do |f| += gitlab_ui_form_for @user, url: profile_preferences_path, remote: true, method: :put, html: { id: "profile-preferences-form" } do |f| .row.gl-mt-3.js-preferences-form.js-search-settings-section .col-lg-4.application-theme#navigation-theme %h4.gl-mt-0 @@ -87,27 +87,19 @@ = f.select :project_view, project_view_choices, {}, class: 'select2' .form-text.text-muted = s_('Preferences|Choose what content you want to see on a project’s overview page.') - .form-group.form-check - = f.check_box :render_whitespace_in_code, class: 'form-check-input' - = f.label :render_whitespace_in_code, class: 'form-check-label' do - = s_('Preferences|Render whitespace characters in the Web IDE') - .form-group.form-check - = f.check_box :show_whitespace_in_diffs, class: 'form-check-input' - = f.label :show_whitespace_in_diffs, class: 'form-check-label' do - = s_('Preferences|Show whitespace changes in diffs') - .form-group.form-check - = f.check_box :view_diffs_file_by_file, class: 'form-check-input' - = f.label :view_diffs_file_by_file, class: 'form-check-label' do - = s_("Preferences|Show one file at a time on merge request's Changes tab") - .form-text.text-muted - = s_("Preferences|Instead of all the files changed, show only one file at a time. To switch between files, use the file browser.") - .form-group.form-check - = f.check_box :markdown_surround_selection, class: 'form-check-input' - = f.label :markdown_surround_selection, class: 'form-check-label' do - = s_('Preferences|Surround text selection when typing quotes or brackets') - .form-text.text-muted - - supported_characters = %w(" ' ` \( [ { < * _).map {|char| "#{char}" }.join(', ') - = sprintf(s_( "Preferences|When you type in a description or comment box, selected text is surrounded by the corresponding character after typing one of the following characters: %{supported_characters}."), { supported_characters: supported_characters }).html_safe + .form-group + = f.gitlab_ui_checkbox_component :render_whitespace_in_code, s_('Preferences|Render whitespace characters in the Web IDE') + .form-group + = f.gitlab_ui_checkbox_component :show_whitespace_in_diffs, s_('Preferences|Show whitespace changes in diffs') + .form-group + = f.gitlab_ui_checkbox_component :view_diffs_file_by_file, + s_("Preferences|Show one file at a time on merge request's Changes tab"), + help_text: s_("Preferences|Instead of all the files changed, show only one file at a time. To switch between files, use the file browser.") + .form-group + - supported_characters = %w(" ' ` ( [ { < * _).map {|char| "#{char}" }.join(', ') + = f.gitlab_ui_checkbox_component :markdown_surround_selection, + s_('Preferences|Surround text selection when typing quotes or brackets'), + help_text: sprintf(s_( "Preferences|When you type in a description or comment box, selected text is surrounded by the corresponding character after typing one of the following characters: %{supported_characters}."), { supported_characters: supported_characters }).html_safe .form-group = f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold' @@ -151,16 +143,12 @@ = succeed '.' do = link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'time-preferences'), target: '_blank', rel: 'noopener noreferrer' .col-lg-8 - .form-group.form-check - = f.check_box :time_display_relative, class: 'form-check-input' - = f.label :time_display_relative, class: 'form-check-label' do - = s_('Preferences|Use relative times') - .form-text.text-muted - = s_('Preferences|For example: 30 minutes ago.') + .form-group + = f.gitlab_ui_checkbox_component :time_display_relative, + s_('Preferences|Use relative times'), + help_text: s_('Preferences|For example: 30 minutes ago.') - if Feature.enabled?(:user_time_settings) - .form-group.form-check - = f.check_box :time_format_in_24h, class: 'form-check-input' - = f.label :time_format_in_24h, class: 'form-check-label' do - = s_('Preferences|Display time in 24-hour format') + .form-group + = f.gitlab_ui_checkbox_component :time_format_in_24h, s_('Preferences|Display time in 24-hour format') #js-profile-preferences-app{ data: data_attributes } diff --git a/doc/administration/geo/replication/geo_validation_tests.md b/doc/administration/geo/replication/geo_validation_tests.md index 70b3eaf5fea..e4432c41ff1 100644 --- a/doc/administration/geo/replication/geo_validation_tests.md +++ b/doc/administration/geo/replication/geo_validation_tests.md @@ -208,4 +208,16 @@ The following are additional validation tests we performed. - Description: Tested the average time it takes for a single image to replicate from the primary object storage location to the secondary when using Azure based object storage replication and [GitLab based object storage replication](object_storage.md#enabling-gitlab-managed-object-storage-replication). This was tested by uploading a 1mb image to a project on the primary site every second for 60 seconds. The time was then measured until a image was available on the secondary site. This was achieved using a [Ruby Script](https://gitlab.com/gitlab-org/quality/geo-replication-tester). - Outcome: When using Azure based replication the average time for an image to replicate from the primary object storage to the secondary was recorded as 40 seconds, the longest replication time was 70 seconds and the quickest was 11 seconds. When using GitLab based replication the average time for replication to complete was 5 seconds, the longest replication time was 10 seconds and the quickest was 3 seconds. - Follow up issue: - - [Test and validate object storage replication performance on reference architectures](https://gitlab.com/gitlab-org/gitlab/-/issues/347314) + - [Validate Cross Region Object storage replication using Azure based object storage](https://gitlab.com/gitlab-org/gitlab/-/issues/358154) + +### April 2022 + +[Validate Object storage replication using AWS based object storage](https://gitlab.com/gitlab-org/gitlab/-/issues/351463): + +- Description: Tested the average time it takes for a single image to replicate from the primary object storage location to the secondary when using AWS based object storage replication and [GitLab based object storage replication](object_storage.md#enabling-gitlab-managed-object-storage-replication). This was tested by uploading a 1mb image to a project on the primary site every second for 60 seconds. The time was then measured until a image was available on the secondary site. This was achieved using a [Ruby Script](https://gitlab.com/gitlab-org/quality/geo-replication-tester). +- Outcome: When using AWS managed replication the average time for an image to replicate between sites is about 49 seconds, this is true for when sites are located within the same region and when they are further apart (Europe to America). When using Geo managed replication within the same region the average time for replication took just 5 seconds, however when replicating cross region the average time rose to 33 seconds. + +[Validate Object storage replication using GCP based object storage](https://gitlab.com/gitlab-org/gitlab/-/issues/351464): + +- Description: Tested the average time it takes for a single image to replicate from the primary object storage location to the secondary when using GCP based object storage replication and [GitLab based object storage replication](object_storage.md#enabling-gitlab-managed-object-storage-replication). This was tested by uploading a 1mb image to a project on the primary site every second for 60 seconds. The time was then measured until a image was available on the secondary site. This was achieved using a [Ruby Script](https://gitlab.com/gitlab-org/quality/geo-replication-tester). +- Outcome: GCP handles replication differently than other Cloud Providers. In GCP, the process is to a create single bucket that is either multi, dual or single region based. This means that the bucket will automatically store replicas in a region based on the option chosen. Even when using multi region, this will still only replicate within a single continent, the options being America, Europe, or Asia. At current there doesn't seem to be any way to replicate objects between continents using GCP based replication. For Geo managed replication the average time when replicating within the same region was 6 seconds, and when replicating cross region this rose to just 9 seconds. diff --git a/doc/install/aws/manual_install_aws.md b/doc/install/aws/manual_install_aws.md index b0e71cbc77e..8b827d05b57 100644 --- a/doc/install/aws/manual_install_aws.md +++ b/doc/install/aws/manual_install_aws.md @@ -299,8 +299,8 @@ The steps for doing this vary depending on which registrar you use and is beyond ## PostgreSQL with RDS -For our database server we will use Amazon RDS which offers Multi AZ -for redundancy. First we'll create a security group and subnet group, then we'll +For our database server we will use Amazon RDS for PostgreSQL which offers Multi AZ +for redundancy (Aurora is **not** supported). First we'll create a security group and subnet group, then we'll create the actual RDS instance. ### RDS Security Group diff --git a/lib/container_registry/migration.rb b/lib/container_registry/migration.rb index b2c2ca3716a..005ef880034 100644 --- a/lib/container_registry/migration.rb +++ b/lib/container_registry/migration.rb @@ -39,9 +39,9 @@ module ContainerRegistry def self.enqueue_waiting_time return 0 if Feature.enabled?(:container_registry_migration_phase2_enqueue_speed_fast) - return 6.hours if Feature.enabled?(:container_registry_migration_phase2_enqueue_speed_slow) + return 165.minutes if Feature.enabled?(:container_registry_migration_phase2_enqueue_speed_slow) - 1.hour + 45.minutes end def self.capacity diff --git a/lib/sidebars/groups/menus/group_information_menu.rb b/lib/sidebars/groups/menus/group_information_menu.rb index 9656811455e..3ce99e14a04 100644 --- a/lib/sidebars/groups/menus/group_information_menu.rb +++ b/lib/sidebars/groups/menus/group_information_menu.rb @@ -20,7 +20,7 @@ module Sidebars override :sprite_icon def sprite_icon - 'group' + context.group.subgroup? ? 'subgroup' : 'group' end override :active_routes diff --git a/qa/qa/page/project/pipeline/new.rb b/qa/qa/page/project/pipeline/new.rb index 644a21b46e9..96a48e6240a 100644 --- a/qa/qa/page/project/pipeline/new.rb +++ b/qa/qa/page/project/pipeline/new.rb @@ -7,10 +7,20 @@ module QA class New < QA::Page::Base view 'app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue' do element :run_pipeline_button, required: true + element :ci_variable_row_container + element :ci_variable_key_field + element :ci_variable_value_field end def click_run_pipeline_button - click_element :run_pipeline_button + click_element(:run_pipeline_button, Page::Project::Pipeline::Show) + end + + def add_variable(key, value, row_index: 0) + within_element_by_index(:ci_variable_row_container, row_index) do + fill_element(:ci_variable_key_field, key) + fill_element(:ci_variable_value_field, value) + end end end end diff --git a/qa/qa/page/project/pipeline/show.rb b/qa/qa/page/project/pipeline/show.rb index 318d7633a6e..f499b748fb4 100644 --- a/qa/qa/page/project/pipeline/show.rb +++ b/qa/qa/page/project/pipeline/show.rb @@ -8,7 +8,7 @@ module QA include Component::CiBadgeLink view 'app/assets/javascripts/vue_shared/components/header_ci_component.vue' do - element :pipeline_header + element :pipeline_header, required: true end view 'app/assets/javascripts/pipelines/components/graph/graph_component.vue' do @@ -16,8 +16,8 @@ module QA end view 'app/assets/javascripts/pipelines/components/graph/job_item.vue' do - element :job_item_container - element :job_link + element :job_item_container, required: true + element :job_link, required: true element :job_action_button end diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_inheritable_when_forward_pipeline_variables_true_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_inheritable_when_forward_pipeline_variables_true_spec.rb new file mode 100644 index 00000000000..dd370b2e8b2 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_inheritable_when_forward_pipeline_variables_true_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module QA + # Running with FF :ci_trigger_forward_variables + RSpec.describe 'Verify', :runner do + describe 'UI defined variable' do + include_context 'variable inheritance test prep' + + before do + add_ci_file(downstream1_project, [downstream1_ci_file]) + add_ci_file(upstream_project, [upstream_ci_file, upstream_child1_ci_file]) + + start_pipeline_with_variable + Page::Project::Pipeline::Show.perform do |show| + Support::Waiter.wait_until { show.passed? } + end + end + + it( + 'is inheritable when forward:pipeline_variables is true', + :aggregate_failures, + test_case: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358197' + ) do + visit_job_page('child1', 'child1_job') + verify_job_log_shows_variable_value + + page.go_back + + visit_job_page('downstream1', 'downstream1_job') + verify_job_log_shows_variable_value + end + + def upstream_ci_file + { + file_path: '.gitlab-ci.yml', + content: <<~YAML + stages: + - test + - deploy + + child1_trigger: + stage: test + trigger: + include: .child1-ci.yml + forward: + pipeline_variables: true + + downstream1_trigger: + stage: deploy + trigger: + project: #{downstream1_project.full_path} + forward: + pipeline_variables: true + YAML + } + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_non_inheritable_when_forward_pipeline_variables_false_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_non_inheritable_when_forward_pipeline_variables_false_spec.rb new file mode 100644 index 00000000000..156d744398c --- /dev/null +++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_non_inheritable_when_forward_pipeline_variables_false_spec.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +module QA + # Running with FF :ci_trigger_forward_variables + RSpec.describe 'Verify', :runner do + describe 'UI defined variable' do + include_context 'variable inheritance test prep' + + before do + add_ci_file(downstream1_project, [downstream1_ci_file]) + add_ci_file(downstream2_project, [downstream2_ci_file]) + add_ci_file(upstream_project, [upstream_ci_file, upstream_child1_ci_file, upstream_child2_ci_file]) + + start_pipeline_with_variable + Page::Project::Pipeline::Show.perform do |show| + Support::Waiter.wait_until { show.passed? } + end + end + + it( + 'is not inheritable when forward:pipeline_variables is false', + :aggregate_failures, + test_case: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358199' + ) do + visit_job_page('child1', 'child1_job') + verify_job_log_does_not_show_variable_value + + page.go_back + + visit_job_page('downstream1', 'downstream1_job') + verify_job_log_does_not_show_variable_value + end + + it( + 'is not inheritable by default', + :aggregate_failures, + test_case: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358200' + ) do + visit_job_page('child2', 'child2_job') + verify_job_log_does_not_show_variable_value + + page.go_back + + visit_job_page('downstream2', 'downstream2_job') + verify_job_log_does_not_show_variable_value + end + + def upstream_ci_file + { + file_path: '.gitlab-ci.yml', + content: <<~YAML + stages: + - test + - deploy + + child1_trigger: + stage: test + trigger: + include: .child1-ci.yml + forward: + pipeline_variables: false + + # default behavior + child2_trigger: + stage: test + trigger: + include: .child2-ci.yml + + downstream1_trigger: + stage: deploy + trigger: + project: #{downstream1_project.full_path} + forward: + pipeline_variables: false + + # default behavior + downstream2_trigger: + stage: deploy + trigger: + project: #{downstream2_project.full_path} + YAML + } + end + end + end +end diff --git a/qa/spec/support/shared_contexts/variable_inheritance_shared_context.rb b/qa/spec/support/shared_contexts/variable_inheritance_shared_context.rb new file mode 100644 index 00000000000..7e6b69d1099 --- /dev/null +++ b/qa/spec/support/shared_contexts/variable_inheritance_shared_context.rb @@ -0,0 +1,156 @@ +# frozen_string_literal: true + +module QA + # TODO: + # Remove FF :ci_trigger_forward_variables + # when https://gitlab.com/gitlab-org/gitlab/-/issues/355572 is closed + RSpec.shared_context 'variable inheritance test prep', feature_flag: { + name: 'ci_trigger_forward_variables', + scope: :global + } do + let(:random_string) { Faker::Alphanumeric.alphanumeric(number: 8) } + + let(:group) do + Resource::Group.fabricate_via_api! do |group| + group.path = "group-for-variable-inheritance-#{random_string}" + end + end + + let(:upstream_project) do + Resource::Project.fabricate_via_api! do |project| + project.group = group + project.name = 'upstream-variable-inheritance' + project.description = 'Project for pipeline with variable defined via UI - Upstream' + end + end + + let(:downstream1_project) do + Resource::Project.fabricate_via_api! do |project| + project.group = group + project.name = 'downstream1-variable-inheritance' + project.description = 'Project for pipeline with variable defined via UI - Downstream' + end + end + + let(:downstream2_project) do + Resource::Project.fabricate_via_api! do |project| + project.group = group + project.name = 'downstream2-variable-inheritance' + project.description = 'Project for pipeline with variable defined via UI - Downstream' + end + end + + let!(:runner) do + Resource::Runner.fabricate! do |runner| + runner.token = group.reload!.runners_token + runner.name = random_string + runner.tags = [random_string] + end + end + + before do + Runtime::Feature.enable(:ci_trigger_forward_variables) + Flow::Login.sign_in + end + + after do + runner.remove_via_api! + Runtime::Feature.disable(:ci_trigger_forward_variables) + end + + def start_pipeline_with_variable + upstream_project.visit! + Flow::Pipeline.wait_for_latest_pipeline + Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button) + Page::Project::Pipeline::New.perform do |new| + new.add_variable('TEST_VAR', 'This is great!') + new.click_run_pipeline_button + end + end + + def add_ci_file(project, files) + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = project + commit.commit_message = 'Add CI config file' + commit.add_files(files) + end + end + + def visit_job_page(pipeline_title, job_name) + Page::Project::Pipeline::Show.perform do |show| + show.expand_child_pipeline(title: pipeline_title) + show.click_job(job_name) + end + end + + def verify_job_log_shows_variable_value + Page::Project::Job::Show.perform do |show| + show.wait_until { show.successful? } + expect(show.output).to have_content('This is great!') + end + end + + def verify_job_log_does_not_show_variable_value + Page::Project::Job::Show.perform do |show| + show.wait_until { show.successful? } + expect(show.output).to have_no_content('This is great!') + end + end + + def upstream_child1_ci_file + { + file_path: '.child1-ci.yml', + content: <<~YAML + child1_job: + stage: test + tags: ["#{random_string}"] + script: + - echo $TEST_VAR + - echo Done! + YAML + } + end + + def upstream_child2_ci_file + { + file_path: '.child2-ci.yml', + content: <<~YAML + child2_job: + stage: test + tags: ["#{random_string}"] + script: + - echo $TEST_VAR + - echo Done! + YAML + } + end + + def downstream1_ci_file + { + file_path: '.gitlab-ci.yml', + content: <<~YAML + downstream1_job: + stage: deploy + tags: ["#{random_string}"] + script: + - echo $TEST_VAR + - echo Done! + YAML + } + end + + def downstream2_ci_file + { + file_path: '.gitlab-ci.yml', + content: <<~YAML + downstream2_job: + stage: deploy + tags: ["#{random_string}"] + script: + - echo $TEST_VAR + - echo Done! + YAML + } + end + end +end diff --git a/spec/frontend/groups/components/item_type_icon_spec.js b/spec/frontend/groups/components/item_type_icon_spec.js index fcfb4c848c6..f3652f1a410 100644 --- a/spec/frontend/groups/components/item_type_icon_spec.js +++ b/spec/frontend/groups/components/item_type_icon_spec.js @@ -34,7 +34,7 @@ describe('ItemTypeIcon', () => { it.each` type | icon - ${ITEM_TYPE.GROUP} | ${'group'} + ${ITEM_TYPE.GROUP} | ${'subgroup'} ${ITEM_TYPE.PROJECT} | ${'project'} `('shows "$icon" icon when `itemType` is "$type"', ({ type, icon }) => { createComponent({ diff --git a/spec/frontend/profile/preferences/components/integration_view_spec.js b/spec/frontend/profile/preferences/components/integration_view_spec.js index 6ab0c70298c..92c53b8c91b 100644 --- a/spec/frontend/profile/preferences/components/integration_view_spec.js +++ b/spec/frontend/profile/preferences/components/integration_view_spec.js @@ -1,5 +1,5 @@ -import { GlFormText } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; +import { GlFormGroup } from '@gitlab/ui'; +import { mountExtended } from 'helpers/vue_test_utils_helper'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import IntegrationView from '~/profile/preferences/components/integration_view.vue'; @@ -21,7 +21,7 @@ describe('IntegrationView component', () => { function createComponent(options = {}) { const { props = {}, provide = {} } = options; - return shallowMount(IntegrationView, { + return mountExtended(IntegrationView, { provide: { userFields, ...provide, @@ -33,28 +33,20 @@ describe('IntegrationView component', () => { }); } - function findCheckbox() { - return wrapper.find('[data-testid="profile-preferences-integration-checkbox"]'); - } - function findFormGroup() { - return wrapper.find('[data-testid="profile-preferences-integration-form-group"]'); - } - function findHiddenField() { - return wrapper.find('[data-testid="profile-preferences-integration-hidden-field"]'); - } - function findFormGroupLabel() { - return wrapper.find('[data-testid="profile-preferences-integration-form-group"] label'); - } + const findCheckbox = () => wrapper.findByLabelText(new RegExp(defaultProps.config.label)); + const findFormGroup = () => wrapper.findComponent(GlFormGroup); + const findHiddenField = () => + wrapper.findByTestId('profile-preferences-integration-hidden-field'); afterEach(() => { wrapper.destroy(); wrapper = null; }); - it('should render the title correctly', () => { + it('should render the form group legend correctly', () => { wrapper = createComponent(); - expect(wrapper.find('label.label-bold').text()).toBe('Foo'); + expect(wrapper.findByText(defaultProps.config.title).exists()).toBe(true); }); it('should render the form correctly', () => { @@ -106,13 +98,6 @@ describe('IntegrationView component', () => { it('should render the help text', () => { wrapper = createComponent(); - expect(wrapper.find(GlFormText).exists()).toBe(true); expect(wrapper.find(IntegrationHelpText).exists()).toBe(true); }); - - it('should render the label correctly', () => { - wrapper = createComponent(); - - expect(findFormGroupLabel().text()).toBe('Enable foo'); - }); }); diff --git a/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap b/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap index b8f9951bbfc..26a3b27d958 100644 --- a/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap +++ b/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap @@ -36,7 +36,7 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` modalclass="" modalid="fakeUniqueId" ok-variant="danger" - size="sm" + size="md" title-class="gl-text-red-500" titletag="h4" > diff --git a/spec/helpers/button_helper_spec.rb b/spec/helpers/button_helper_spec.rb index 851e13d908f..a7f65aa3134 100644 --- a/spec/helpers/button_helper_spec.rb +++ b/spec/helpers/button_helper_spec.rb @@ -164,7 +164,7 @@ RSpec.describe ButtonHelper do context 'with default options' do context 'when no `text` attribute is not provided' do it 'shows copy to clipboard button with default configuration and no text set to copy' do - expect(element.attr('class')).to eq('btn btn-clipboard btn-transparent') + expect(element.attr('class')).to eq('btn btn-clipboard gl-button btn-default-tertiary btn-icon btn-sm') expect(element.attr('type')).to eq('button') expect(element.attr('aria-label')).to eq('Copy') expect(element.attr('aria-live')).to eq('polite') diff --git a/spec/lib/container_registry/migration_spec.rb b/spec/lib/container_registry/migration_spec.rb index 8596a1b7bc4..6c0fc94e27f 100644 --- a/spec/lib/container_registry/migration_spec.rb +++ b/spec/lib/container_registry/migration_spec.rb @@ -37,8 +37,8 @@ RSpec.describe ContainerRegistry::Migration do subject { described_class.enqueue_waiting_time } where(:slow_enabled, :fast_enabled, :expected_result) do - false | false | 1.hour - true | false | 6.hours + false | false | 45.minutes + true | false | 165.minutes false | true | 0 true | true | 0 end diff --git a/spec/lib/gitlab/legacy_github_import/project_creator_spec.rb b/spec/lib/gitlab/legacy_github_import/project_creator_spec.rb index 02cc2eba4da..68f1c214cef 100644 --- a/spec/lib/gitlab/legacy_github_import/project_creator_spec.rb +++ b/spec/lib/gitlab/legacy_github_import/project_creator_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Gitlab::LegacyGithubImport::ProjectCreator do let(:namespace) { create(:group) } let(:repo) do - OpenStruct.new( + ActiveSupport::InheritableOptions.new( login: 'vim', name: 'vim', full_name: 'asd/vim', @@ -21,7 +21,7 @@ RSpec.describe Gitlab::LegacyGithubImport::ProjectCreator do namespace.add_owner(user) expect_next_instance_of(Project) do |project| - expect(project).to receive(:add_import_job) + allow(project).to receive(:add_import_job) end end diff --git a/spec/lib/gitlab/quick_actions/command_definition_spec.rb b/spec/lib/gitlab/quick_actions/command_definition_spec.rb index 73629ce3da2..8362c07baca 100644 --- a/spec/lib/gitlab/quick_actions/command_definition_spec.rb +++ b/spec/lib/gitlab/quick_actions/command_definition_spec.rb @@ -26,7 +26,7 @@ RSpec.describe Gitlab::QuickActions::CommandDefinition do describe "#noop?" do context "when the command has an action block" do before do - subject.action_block = proc { } + subject.action_block = proc {} end it "returns false" do @@ -42,7 +42,7 @@ RSpec.describe Gitlab::QuickActions::CommandDefinition do end describe "#available?" do - let(:opts) { OpenStruct.new(go: false) } + let(:opts) { ActiveSupport::InheritableOptions.new(go: false) } context "when the command has a condition block" do before do @@ -104,7 +104,8 @@ RSpec.describe Gitlab::QuickActions::CommandDefinition do end describe "#execute" do - let(:context) { OpenStruct.new(run: false, commands_executed_count: nil) } + let(:fake_context) { Struct.new(:run, :commands_executed_count, :received_arg) } + let(:context) { fake_context.new(false, nil, nil) } context "when the command is a noop" do it "doesn't execute the command" do diff --git a/spec/lib/sidebars/groups/menus/group_information_menu_spec.rb b/spec/lib/sidebars/groups/menus/group_information_menu_spec.rb index b68af6fb8ab..5f67ee11970 100644 --- a/spec/lib/sidebars/groups/menus/group_information_menu_spec.rb +++ b/spec/lib/sidebars/groups/menus/group_information_menu_spec.rb @@ -28,6 +28,20 @@ RSpec.describe Sidebars::Groups::Menus::GroupInformationMenu do end end + describe '#sprite_icon' do + subject { described_class.new(context).sprite_icon } + + context 'when group is a root group' do + specify { is_expected.to eq 'group'} + end + + context 'when group is a child group' do + let(:group) { build(:group, parent: root_group) } + + specify { is_expected.to eq 'subgroup'} + end + end + describe 'Menu Items' do subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } } diff --git a/spec/workers/container_registry/migration/enqueuer_worker_spec.rb b/spec/workers/container_registry/migration/enqueuer_worker_spec.rb index 8ad605eed3a..81fa28dc603 100644 --- a/spec/workers/container_registry/migration/enqueuer_worker_spec.rb +++ b/spec/workers/container_registry/migration/enqueuer_worker_spec.rb @@ -141,20 +141,20 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures with_them do before do - allow(ContainerRegistry::Migration).to receive(:enqueue_waiting_time).and_return(1.hour) + allow(ContainerRegistry::Migration).to receive(:enqueue_waiting_time).and_return(45.minutes) create(:container_repository, state, timestamp => 1.minute.ago) end it_behaves_like 'no action' do before do - expect_log_extra_metadata(waiting_time_passed: false, current_waiting_time_setting: 1.hour) + expect_log_extra_metadata(waiting_time_passed: false, current_waiting_time_setting: 45.minutes) end end end context 'when last completed repository has nil timestamps' do before do - allow(ContainerRegistry::Migration).to receive(:enqueue_waiting_time).and_return(1.hour) + allow(ContainerRegistry::Migration).to receive(:enqueue_waiting_time).and_return(45.minutes) create(:container_repository, migration_state: 'import_done') end