diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-10 09:09:49 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-10 09:09:49 +0000 |
commit | 14b71b2795e7765989101241ee89d7bfa55bd838 (patch) | |
tree | 55289a166041cb93deea0457d69c6d00d82d54d4 | |
parent | 991caa14edb67f7fd575e981e4755cfc743bac31 (diff) | |
download | gitlab-ce-14b71b2795e7765989101241ee89d7bfa55bd838.tar.gz |
Add latest changes from gitlab-org/gitlab@master
28 files changed, 289 insertions, 49 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 37575989f69..d12971a14f9 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -3bf6396fafab29ebbb984a77be0405d7ff5510fd +7144bcd52a6b8c745bf90af812a78426384ac535 diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue index db55fd96ad0..d03de91ea07 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue +++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue @@ -19,6 +19,7 @@ import getPipelineSchedulesQuery from '../graphql/queries/get_pipeline_schedules import PipelineSchedulesTable from './table/pipeline_schedules_table.vue'; import TakeOwnershipModal from './take_ownership_modal.vue'; import DeletePipelineScheduleModal from './delete_pipeline_schedule_modal.vue'; +import PipelineScheduleEmptyState from './pipeline_schedules_empty_state.vue'; export default { i18n: { @@ -48,6 +49,7 @@ export default { GlLink, PipelineSchedulesTable, TakeOwnershipModal, + PipelineScheduleEmptyState, }, inject: { fullPath: { @@ -249,6 +251,7 @@ export default { </gl-alert> <gl-tabs + v-if="isLoading || count > 0" sync-active-tab-with-query-params query-param-name="scope" nav-class="gl-flex-grow-1 gl-align-items-center" @@ -289,6 +292,8 @@ export default { </template> </gl-tabs> + <pipeline-schedule-empty-state v-else-if="!isLoading && count === 0" /> + <take-ownership-modal :visible="showTakeOwnershipModal" @takeOwnership="takeOwnership" diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_empty_state.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_empty_state.vue new file mode 100644 index 00000000000..f633ba053ee --- /dev/null +++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules_empty_state.vue @@ -0,0 +1,63 @@ +<script> +import scheduleSvg from '@gitlab/svgs/dist/illustrations/schedule-md.svg'; +import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui'; +import { helpPagePath } from '~/helpers/help_page_helper'; +import { s__ } from '~/locale'; + +export default { + i18n: { + pipelineSchedules: s__('PipelineSchedules|Pipeline schedules'), + description: s__( + 'PipelineSchedules|A scheduled pipeline starts automatically at regular intervals, like daily or weekly. The pipeline: ', + ), + learnMore: s__( + 'PipelineSchedules|Learn more in the %{linkStart}scheduled pipelines documentation.%{linkEnd}', + ), + listElements: [ + s__('PipelineSchedules|Runs for a specific branch or tag.'), + s__('PipelineSchedules|Can have custom CI/CD variables.'), + s__('PipelineSchedules|Runs with the same project permissions as the schedule owner.'), + ], + createNew: s__('PipelineSchedules|Create a new pipeline schedule'), + }, + components: { + GlEmptyState, + GlLink, + GlSprintf, + }, + computed: { + scheduleSvgPath() { + return `data:image/svg+xml;utf8,${encodeURIComponent(scheduleSvg)}`; + }, + schedulesHelpPath() { + return helpPagePath('ci/pipelines/schedules'); + }, + }, +}; +</script> +<template> + <gl-empty-state + :svg-path="scheduleSvgPath" + :primary-button-text="$options.i18n.createNew" + primary-button-link="#" + > + <template #title> + <h3> + {{ $options.i18n.pipelineSchedules }} + </h3> + </template> + <template #description> + <p class="gl-mb-0">{{ $options.i18n.description }}</p> + <ul class="gl-list-style-position-inside" data-testid="pipeline-schedules-characteristics"> + <li v-for="(el, index) in $options.i18n.listElements" :key="index">{{ el }}</li> + </ul> + <p> + <gl-sprintf :message="$options.i18n.learnMore"> + <template #link="{ content }"> + <gl-link :href="schedulesHelpPath" target="_blank">{{ content }}</gl-link> + </template> + </gl-sprintf> + </p> + </template> + </gl-empty-state> +</template> diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js b/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js index 27610df482d..4bdbb70d942 100644 --- a/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js +++ b/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js @@ -67,10 +67,9 @@ function initTakeownershipModal() { }); } -initPipelineSchedulesCallout(); - if (gon.features?.pipelineSchedulesVue) { initPipelineSchedulesApp(); } else { + initPipelineSchedulesCallout(); initTakeownershipModal(); } diff --git a/app/services/design_management/save_designs_service.rb b/app/services/design_management/save_designs_service.rb index 64537293e65..ea5675c6ddd 100644 --- a/app/services/design_management/save_designs_service.rb +++ b/app/services/design_management/save_designs_service.rb @@ -113,7 +113,7 @@ module DesignManagement def file_content(file, full_path) transformer = ::Lfs::FileTransformer.new(project, repository, target_branch) - transformer.new_file(full_path, file.to_io).content + transformer.new_file(full_path, file.to_io, detect_content_type: Feature.enabled?(:design_management_allow_dangerous_images, project)).content end # Returns the latest blobs for the designs as a Hash of `{ Design => Blob }` diff --git a/app/services/lfs/file_transformer.rb b/app/services/lfs/file_transformer.rb index 69d33e1c873..a02fce552cf 100644 --- a/app/services/lfs/file_transformer.rb +++ b/app/services/lfs/file_transformer.rb @@ -29,11 +29,11 @@ module Lfs @branch_name = branch_name end - def new_file(file_path, file_content, encoding: nil) + def new_file(file_path, file_content, encoding: nil, detect_content_type: false) if project.lfs_enabled? && lfs_file?(file_path) file_content = parse_file_content(file_content, encoding: encoding) lfs_pointer_file = Gitlab::Git::LfsPointerFile.new(file_content) - lfs_object = create_lfs_object!(lfs_pointer_file, file_content) + lfs_object = create_lfs_object!(lfs_pointer_file, file_content, detect_content_type) link_lfs_object!(lfs_object) @@ -63,9 +63,17 @@ module Lfs end # rubocop: disable CodeReuse/ActiveRecord - def create_lfs_object!(lfs_pointer_file, file_content) + def create_lfs_object!(lfs_pointer_file, file_content, detect_content_type) LfsObject.find_or_create_by(oid: lfs_pointer_file.sha256, size: lfs_pointer_file.size) do |lfs_object| - lfs_object.file = CarrierWaveStringFile.new(file_content) + lfs_object.file = if detect_content_type && (content_type = Gitlab::Utils::MimeType.from_string(file_content)) + CarrierWaveStringFile.new_file( + file_content: file_content, + filename: '', + content_type: content_type + ) + else + CarrierWaveStringFile.new(file_content) + end end end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/workers/projects/refresh_build_artifacts_size_statistics_worker.rb b/app/workers/projects/refresh_build_artifacts_size_statistics_worker.rb index 705bf0534f7..ec23bde5898 100644 --- a/app/workers/projects/refresh_build_artifacts_size_statistics_worker.rb +++ b/app/workers/projects/refresh_build_artifacts_size_statistics_worker.rb @@ -11,6 +11,10 @@ module Projects idempotent! + MAX_RUNNING_LOW = 1 + MAX_RUNNING_MEDIUM = 3 + MAX_RUNNING_HIGH = 5 + def perform_work(*args) refresh = Projects::RefreshBuildArtifactsSizeStatisticsService.new.execute return unless refresh @@ -33,8 +37,12 @@ module Projects end def max_running_jobs - if ::Feature.enabled?(:projects_build_artifacts_size_refresh, type: :ops) - 10 + if ::Feature.enabled?(:projects_build_artifacts_size_refresh_high, type: :ops) + MAX_RUNNING_HIGH + elsif ::Feature.enabled?(:projects_build_artifacts_size_refresh_medium, type: :ops) + MAX_RUNNING_MEDIUM + elsif ::Feature.enabled?(:projects_build_artifacts_size_refresh, type: :ops) + MAX_RUNNING_LOW else 0 end diff --git a/config/feature_flags/ops/projects_build_artifacts_size_refresh_high.yml b/config/feature_flags/ops/projects_build_artifacts_size_refresh_high.yml new file mode 100644 index 00000000000..d16ee72ab71 --- /dev/null +++ b/config/feature_flags/ops/projects_build_artifacts_size_refresh_high.yml @@ -0,0 +1,8 @@ +--- +name: projects_build_artifacts_size_refresh_high +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84701 +rollout_issue_url: +milestone: '15.8' +type: ops +group: group::pipeline insights +default_enabled: false diff --git a/config/feature_flags/ops/projects_build_artifacts_size_refresh_medium.yml b/config/feature_flags/ops/projects_build_artifacts_size_refresh_medium.yml new file mode 100644 index 00000000000..73bfd16ec94 --- /dev/null +++ b/config/feature_flags/ops/projects_build_artifacts_size_refresh_medium.yml @@ -0,0 +1,8 @@ +--- +name: projects_build_artifacts_size_refresh_medium +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84701 +rollout_issue_url: +milestone: '15.8' +type: ops +group: group::pipeline insights +default_enabled: false diff --git a/doc/architecture/blueprints/secret_detection/index.md b/doc/architecture/blueprints/secret_detection/index.md index ac99b7cc390..26551367a7c 100644 --- a/doc/architecture/blueprints/secret_detection/index.md +++ b/doc/architecture/blueprints/secret_detection/index.md @@ -1,6 +1,6 @@ --- status: proposed -creation-date: 2022-11-25 +creation-date: "2022-11-25" authors: [ "@theoretick" ] coach: "@DylanGriffith" approvers: [ "@connorgilbert", "@amarpatel" ] diff --git a/doc/operations/feature_flags.md b/doc/operations/feature_flags.md index fff2c8ffbf7..156f496f4cb 100644 --- a/doc/operations/feature_flags.md +++ b/doc/operations/feature_flags.md @@ -395,6 +395,9 @@ docker run \ | `UNLEASH_APP_NAME` | The name of the environment the application runs in. For more details, read [Get access credentials](#get-access-credentials). | | `UNLEASH_API_TOKEN` | Required to start the Unleash Proxy, but not used to connect to GitLab. Can be set to any value. | +There is a limitation when using the Unleash Proxy where each proxy instance can request flags only for the environment named in `UNLEASH_APP_NAME`. The Proxy sends +this to GitLab on behalf of the client, which means the client can't override it. + ## Feature flag related issues **(PREMIUM)** > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36617) in GitLab 13.2. diff --git a/doc/user/todos.md b/doc/user/todos.md index 4102d31cfc4..221e89d658c 100644 --- a/doc/user/todos.md +++ b/doc/user/todos.md @@ -50,6 +50,8 @@ A to-do item is added to your To-Do List when: merge request is removed from a [merge train](../ci/pipelines/merge_trains.md), and you're the user that added it. +- [In GitLab 15.8](https://gitlab.com/gitlab-org/gitlab/-/issues/374725) and later, + a member access request is raised for a group or project you're an owner of. When several actions occur for the same user on the same object, GitLab displays the first action as a single to-do item. diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 8067daa34cd..a68f4f127eb 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -30504,6 +30504,9 @@ msgstr "" msgid "PipelineScheduleIntervalPattern|Custom (%{linkStart}Learn more.%{linkEnd})" msgstr "" +msgid "PipelineSchedules|A scheduled pipeline starts automatically at regular intervals, like daily or weekly. The pipeline: " +msgstr "" + msgid "PipelineSchedules|Activated" msgstr "" @@ -30516,6 +30519,12 @@ msgstr "" msgid "PipelineSchedules|Are you sure you want to delete this pipeline schedule?" msgstr "" +msgid "PipelineSchedules|Can have custom CI/CD variables." +msgstr "" + +msgid "PipelineSchedules|Create a new pipeline schedule" +msgstr "" + msgid "PipelineSchedules|Cron timezone" msgstr "" @@ -30537,6 +30546,9 @@ msgstr "" msgid "PipelineSchedules|Last Pipeline" msgstr "" +msgid "PipelineSchedules|Learn more in the %{linkStart}scheduled pipelines documentation.%{linkEnd}" +msgstr "" + msgid "PipelineSchedules|New schedule" msgstr "" @@ -30555,12 +30567,21 @@ msgstr "" msgid "PipelineSchedules|Pipeline schedule successfully deleted." msgstr "" +msgid "PipelineSchedules|Pipeline schedules" +msgstr "" + msgid "PipelineSchedules|Provide a short description for this pipeline" msgstr "" msgid "PipelineSchedules|Run pipeline schedule" msgstr "" +msgid "PipelineSchedules|Runs for a specific branch or tag." +msgstr "" + +msgid "PipelineSchedules|Runs with the same project permissions as the schedule owner." +msgstr "" + msgid "PipelineSchedules|Save pipeline schedule" msgstr "" diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb index 93f804f1e39..c09f24ac265 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :project }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do describe 'Web IDE file templates' do include Runtime::Fixtures @@ -11,11 +11,11 @@ module QA project.description = 'Add file templates via the Web IDE' project.initialize_with_readme = true end - Runtime::Feature.disable(:vscode_web_ide, project: @project) + Runtime::Feature.disable(:vscode_web_ide) end after(:all) do - Runtime::Feature.enable(:vscode_web_ide, project: @project) + Runtime::Feature.enable(:vscode_web_ide) end templates = [ diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb index a001dee891a..dcaaa395a6f 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :project }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do describe 'Add a directory in Web IDE' do let(:project) do Resource::Project.fabricate_via_api! do |project| @@ -11,13 +11,13 @@ module QA end before do - Runtime::Feature.disable(:vscode_web_ide, project: project) + Runtime::Feature.disable(:vscode_web_ide) Flow::Login.sign_in project.visit! end after do - Runtime::Feature.enable(:vscode_web_ide, project: project) + Runtime::Feature.enable(:vscode_web_ide) end context 'when a directory with the same name already exists' do diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb index cb0da601a88..5be2dd7cff5 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :project }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do describe 'First file using Web IDE' do let(:project) do Resource::Project.fabricate_via_api! do |project| @@ -13,12 +13,12 @@ module QA let(:file_name) { 'the very first file.txt' } before do - Runtime::Feature.disable(:vscode_web_ide, project: project) + Runtime::Feature.disable(:vscode_web_ide) Flow::Login.sign_in end after do - Runtime::Feature.enable(:vscode_web_ide, project: project) + Runtime::Feature.enable(:vscode_web_ide) end it "creates the first file in an empty project via Web IDE", testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347803' do diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb index 2007fe4a667..87492e35bdf 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :project }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do describe 'Link to line in Web IDE' do let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) } let(:project) do @@ -11,12 +11,12 @@ module QA end before do - Runtime::Feature.disable(:vscode_web_ide, project: project) + Runtime::Feature.disable(:vscode_web_ide) Flow::Login.sign_in end after do - Runtime::Feature.enable(:vscode_web_ide, project: project) + Runtime::Feature.enable(:vscode_web_ide) project.remove_via_api! end diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb index dc9f68c5c73..7195dd5c970 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :project }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do describe 'Open a fork in Web IDE', skip: { issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/351696", @@ -15,11 +15,11 @@ module QA end before do - Runtime::Feature.disable(:vscode_web_ide, project: parent_project) + Runtime::Feature.disable(:vscode_web_ide) end after do - Runtime::Feature.enable(:vscode_web_ide, project: parent_project) + Runtime::Feature.enable(:vscode_web_ide) end context 'when a user does not have permissions to commit to the project' do diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb index 039d25477bf..183aea58276 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :project }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do describe 'Open Web IDE from Diff Tab' do files = [ { @@ -44,13 +44,13 @@ module QA end before do - Runtime::Feature.disable(:vscode_web_ide, project: project) + Runtime::Feature.disable(:vscode_web_ide) Flow::Login.sign_in merge_request.visit! end after do - Runtime::Feature.enable(:vscode_web_ide, project: project) + Runtime::Feature.enable(:vscode_web_ide) end it 'opens and edits a multi-file merge request in Web IDE from Diff Tab', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347724' do diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb index fe0060e9bbc..a082204803b 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :project }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do describe 'Review a merge request in Web IDE' do let(:new_file) { 'awesome_new_file.txt' } let(:original_text) { 'Text' } @@ -23,13 +23,13 @@ module QA end before do - Runtime::Feature.disable(:vscode_web_ide, project: project) + Runtime::Feature.disable(:vscode_web_ide) Flow::Login.sign_in merge_request.visit! end after do - Runtime::Feature.enable(:vscode_web_ide, project: project) + Runtime::Feature.enable(:vscode_web_ide) end it 'opens and edits a merge request in Web IDE', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347786' do diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb index 3cd14ecd799..fb09fb25b2f 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create', :skip_live_env, except: { job: 'review-qa-*' }, - feature_flag: { name: 'vscode_web_ide', scope: :project }, + feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do describe 'Git Server Hooks' do let(:file_path) { File.absolute_path(File.join('qa', 'fixtures', 'web_ide', 'README.md')) } @@ -16,13 +16,13 @@ module QA end before do - Runtime::Feature.disable(:vscode_web_ide, project: project) + Runtime::Feature.disable(:vscode_web_ide) Flow::Login.sign_in project.visit! end after do - Runtime::Feature.enable(:vscode_web_ide, project: project) + Runtime::Feature.enable(:vscode_web_ide) end context 'Custom error messages' do diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb index c6e283f67e0..7e9596751cf 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :project }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do describe 'Upload a file in Web IDE' do let(:file_path) { File.absolute_path(File.join('qa', 'fixtures', 'web_ide', file_name)) } @@ -13,7 +13,7 @@ module QA end before do - Runtime::Feature.disable(:vscode_web_ide, project: project) + Runtime::Feature.disable(:vscode_web_ide) Flow::Login.sign_in project.visit! @@ -21,7 +21,7 @@ module QA end after do - Runtime::Feature.enable(:vscode_web_ide, project: project) + Runtime::Feature.enable(:vscode_web_ide) end context 'when a file with the same name already exists' do diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb index 695b295bd86..24e6f929bab 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb @@ -10,12 +10,12 @@ module QA issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338179', type: :bug }, - feature_flag: { name: 'vscode_web_ide', scope: :project }, + feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor ) do describe 'Web IDE web terminal' do before do - Runtime::Feature.disable(:vscode_web_ide, project: project) + Runtime::Feature.disable(:vscode_web_ide) project = Resource::Project.fabricate_via_api! do |project| project.name = 'web-terminal-project' end @@ -58,7 +58,7 @@ module QA end after do - Runtime::Feature.enable(:vscode_web_ide, project: project) + Runtime::Feature.enable(:vscode_web_ide) @runner.remove_via_api! if @runner end diff --git a/spec/frontend/ci/pipeline_schedules/components/pipeline_schedules_spec.js b/spec/frontend/ci/pipeline_schedules/components/pipeline_schedules_spec.js index 1aa08eb78cf..611993556e3 100644 --- a/spec/frontend/ci/pipeline_schedules/components/pipeline_schedules_spec.js +++ b/spec/frontend/ci/pipeline_schedules/components/pipeline_schedules_spec.js @@ -1,4 +1,4 @@ -import { GlAlert, GlLoadingIcon, GlTabs } from '@gitlab/ui'; +import { GlAlert, GlEmptyState, GlLink, GlLoadingIcon, GlTabs } from '@gitlab/ui'; import Vue, { nextTick } from 'vue'; import VueApollo from 'vue-apollo'; import { trimText } from 'helpers/text_helper'; @@ -19,6 +19,7 @@ import { deleteMutationResponse, playMutationResponse, takeOwnershipMutationResponse, + emptyPipelineSchedulesResponse, } from '../mock_data'; Vue.use(VueApollo); @@ -31,6 +32,7 @@ describe('Pipeline schedules app', () => { let wrapper; const successHandler = jest.fn().mockResolvedValue(mockGetPipelineSchedulesGraphQLResponse); + const successEmptyHandler = jest.fn().mockResolvedValue(emptyPipelineSchedulesResponse); const failedHandler = jest.fn().mockRejectedValue(new Error('GraphQL error')); const deleteMutationHandlerSuccess = jest.fn().mockResolvedValue(deleteMutationResponse); @@ -64,14 +66,18 @@ describe('Pipeline schedules app', () => { const findTable = () => wrapper.findComponent(PipelineSchedulesTable); const findAlert = () => wrapper.findComponent(GlAlert); - const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); const findDeleteModal = () => wrapper.findComponent(DeletePipelineScheduleModal); + const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); const findTakeOwnershipModal = () => wrapper.findComponent(TakeOwnershipModal); const findTabs = () => wrapper.findComponent(GlTabs); + const findEmptyState = () => wrapper.findComponent(GlEmptyState); + const findLink = () => wrapper.findComponent(GlLink); const findNewButton = () => wrapper.findByTestId('new-schedule-button'); const findAllTab = () => wrapper.findByTestId('pipeline-schedules-all-tab'); const findActiveTab = () => wrapper.findByTestId('pipeline-schedules-active-tab'); const findInactiveTab = () => wrapper.findByTestId('pipeline-schedules-inactive-tab'); + const findSchedulesCharacteristics = () => + wrapper.findByTestId('pipeline-schedules-characteristics'); afterEach(() => { wrapper.destroy(); @@ -320,4 +326,24 @@ describe('Pipeline schedules app', () => { expect(wrapper.vm.$apollo.queries.schedules.refetch).toHaveBeenCalledTimes(1); }); }); + + describe('Empty pipeline schedules response', () => { + it('should show an empty state', async () => { + createComponent([[getPipelineSchedulesQuery, successEmptyHandler]]); + + await waitForPromises(); + + const schedulesCharacteristics = findSchedulesCharacteristics(); + + expect(findEmptyState().exists()).toBe(true); + expect(schedulesCharacteristics.text()).toContain('Runs for a specific branch or tag.'); + expect(schedulesCharacteristics.text()).toContain('Can have custom CI/CD variables.'); + expect(schedulesCharacteristics.text()).toContain( + 'Runs with the same project permissions as the schedule owner.', + ); + + expect(findLink().exists()).toBe(true); + expect(findLink().text()).toContain('scheduled pipelines documentation.'); + }); + }); }); diff --git a/spec/frontend/ci/pipeline_schedules/mock_data.js b/spec/frontend/ci/pipeline_schedules/mock_data.js index 8767ae5bdcc..2826c054249 100644 --- a/spec/frontend/ci/pipeline_schedules/mock_data.js +++ b/spec/frontend/ci/pipeline_schedules/mock_data.js @@ -32,6 +32,14 @@ export const mockPipelineScheduleNodes = nodes; export const mockPipelineScheduleAsGuestNodes = guestNodes; export const mockTakeOwnershipNodes = takeOwnershipNodes; +export const emptyPipelineSchedulesResponse = { + data: { + project: { + id: 'gid://gitlab/Project/1', + pipelineSchedules: { nodes: [], count: 0 }, + }, + }, +}; export const deleteMutationResponse = { data: { diff --git a/spec/services/design_management/save_designs_service_spec.rb b/spec/services/design_management/save_designs_service_spec.rb index c69df5f2eb9..a87494d87f7 100644 --- a/spec/services/design_management/save_designs_service_spec.rb +++ b/spec/services/design_management/save_designs_service_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -RSpec.describe DesignManagement::SaveDesignsService do +RSpec.describe DesignManagement::SaveDesignsService, feature_category: :design_management do include DesignManagementTestHelpers include ConcurrentHelpers @@ -242,6 +242,27 @@ RSpec.describe DesignManagement::SaveDesignsService do expect(updated_designs.first.versions.size).to eq(1) end end + + context 'when detecting content type' do + it 'detects content type when feature flag is enabled' do + expect_next_instance_of(::Lfs::FileTransformer) do |file_transformer| + expect(file_transformer).to receive(:new_file) + .with(anything, anything, hash_including(detect_content_type: true)).and_call_original + end + + run_service + end + + it 'skips content type detection when feature flag is disabled' do + stub_feature_flags(design_management_allow_dangerous_images: false) + expect_next_instance_of(::Lfs::FileTransformer) do |file_transformer| + expect(file_transformer).to receive(:new_file) + .with(anything, anything, hash_including(detect_content_type: false)).and_call_original + end + + run_service + end + end end context 'when a design has not changed since its previous version' do diff --git a/spec/services/lfs/file_transformer_spec.rb b/spec/services/lfs/file_transformer_spec.rb index e87c80b4c6c..9d4d8851c2d 100644 --- a/spec/services/lfs/file_transformer_spec.rb +++ b/spec/services/lfs/file_transformer_spec.rb @@ -2,7 +2,7 @@ require "spec_helper" -RSpec.describe Lfs::FileTransformer do +RSpec.describe Lfs::FileTransformer, feature_category: :git_lfs do let(:project) { create(:project, :repository, :wiki_repo) } let(:repository) { project.repository } let(:file_content) { 'Test file content' } @@ -13,6 +13,10 @@ RSpec.describe Lfs::FileTransformer do describe '#new_file' do context 'with lfs disabled' do + before do + allow(project).to receive(:lfs_enabled?).and_return(false) + end + it 'skips gitattributes check' do expect(repository.raw).not_to receive(:blob_at) @@ -98,6 +102,38 @@ RSpec.describe Lfs::FileTransformer do expect(project.lfs_objects_projects.first.repository_type).to eq('design') end end + + context 'when content type detection enabled' do + let(:detect_content_type) { true } + + before do + allow(Gitlab::Utils::MimeType).to receive(:from_string).with(file_content).and_return(mime_type) + end + + context 'when mime type detected' do + let(:mime_type) { 'image/tiff' } + + it 'creates a file with custom content type' do + expect(CarrierWaveStringFile).to receive(:new_file).with({ + file_content: file_content, + filename: anything, + content_type: mime_type + }) + + subject.new_file(file_path, file, detect_content_type: detect_content_type) + end + end + + context 'when mime type not detected' do + let(:mime_type) { nil } + + it 'creates a file with default content type' do + expect(CarrierWaveStringFile).to receive(:new).with(file_content) + + subject.new_file(file_path, file, detect_content_type: detect_content_type) + end + end + end end context "when doesn't use LFS" do diff --git a/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb b/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb index c7e45e7e4d7..00c45255316 100644 --- a/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb +++ b/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb @@ -62,14 +62,38 @@ RSpec.describe Projects::RefreshBuildArtifactsSizeStatisticsWorker do describe '#max_running_jobs' do subject { worker.max_running_jobs } - it { is_expected.to eq(10) } + before do + stub_feature_flags( + projects_build_artifacts_size_refresh: false, + projects_build_artifacts_size_refresh_medium: false, + projects_build_artifacts_size_refresh_high: false + ) + end - context 'when projects_build_artifacts_size_refresh flag is disabled' do + it { is_expected.to eq(0) } + + context 'when projects_build_artifacts_size_refresh flag is enabled' do before do - stub_feature_flags(projects_build_artifacts_size_refresh: false) + stub_feature_flags(projects_build_artifacts_size_refresh: true) end - it { is_expected.to eq(0) } + it { is_expected.to eq(described_class::MAX_RUNNING_LOW) } + end + + context 'when projects_build_artifacts_size_refresh_medium flag is enabled' do + before do + stub_feature_flags(projects_build_artifacts_size_refresh_medium: true) + end + + it { is_expected.to eq(described_class::MAX_RUNNING_MEDIUM) } + end + + context 'when projects_build_artifacts_size_refresh_high flag is enabled' do + before do + stub_feature_flags(projects_build_artifacts_size_refresh_high: true) + end + + it { is_expected.to eq(described_class::MAX_RUNNING_HIGH) } end end end |