From 1fec509ff1a480c146f449a8397a32d11b65df55 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 29 Jul 2024 15:11:17 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .gitlab/ci/release-environments.gitlab-ci.yml | 2 + .../release-environments/main.gitlab-ci.yml | 1 - .../security.gitlab-ci.yml | 1 - .gitlab/ci/test-on-gdk/main.gitlab-ci.yml | 21 +++- Gemfile | 2 +- Gemfile.checksum | 2 +- Gemfile.lock | 7 +- app/assets/javascripts/boards/index.js | 28 +++++ .../get_pipeline_mini_graph.query.graphql | 14 ++- .../pipeline_mini_graph.vue | 11 +- .../ci/pipeline_mini_graph/pipeline_stage.vue | 4 +- .../runner_configuration_popover.vue | 9 +- app/assets/javascripts/ci/runner/constants.js | 1 + .../graphql_shared/issuable_client.js | 54 --------- .../group/components/group_settings_app.vue | 3 + .../command_palette/command_palette_items.vue | 32 +++-- .../work_item_links/work_item_links.vue | 1 + .../work_item_links/work_item_links_form.vue | 16 ++- .../work_item_projects_listbox.vue | 38 +++--- .../work_item_links/work_item_tree.vue | 6 + ...ce_projects_for_links_widget.query.graphql | 7 +- .../graphql/work_item_tree.query.graphql | 4 + app/assets/stylesheets/framework/buttons.scss | 8 -- .../page_bundles/_ide_theme_overrides.scss | 22 ---- .../page_bundles/ide_themes/_dark.scss | 6 - .../page_bundles/ide_themes/_monokai.scss | 6 - .../ide_themes/_solarized-dark.scss | 6 - .../stylesheets/page_bundles/members.scss | 6 - .../stylesheets/page_bundles/search.scss | 1 - app/assets/stylesheets/pages/note_form.scss | 6 - .../themes/dark_mode_overrides.scss | 1 - .../projects/mirrors_controller.rb | 32 ++--- app/controllers/search_controller.rb | 25 +++- app/finders/organizations/groups_finder.rb | 2 - .../mutations/notes/convert_to_thread.rb | 40 +++++++ .../organizations/groups_resolver.rb | 9 +- app/graphql/types/mutation_type.rb | 1 + app/models/integration.rb | 4 +- .../create_service.rb | 2 + db/docs/sbom_components.yml | 2 +- ...te_sbom_components_name_based_on_pep503.rb | 2 +- ..._namespace_from_os_type_sbom_components.rb | 2 +- ...ccurrences_to_components_without_prefix.rb | 2 +- doc/api/graphql/reference/index.md | 21 ++++ ..._troubleshooting.md => troubleshooting.md} | 0 ...urrences_component_name_based_on_pep503.rb | 1 + lib/gitlab/search/params.rb | 12 +- lib/search/group_settings.rb | 60 ++++++++++ .../{settings.rb => project_settings.rb} | 32 +++-- locale/gitlab.pot | 9 ++ package.json | 2 +- qa/tasks/ci.rake | 14 ++- scripts/rspec_check_order_dependence | 2 +- .../subscriptions_controller_spec.rb | 1 - .../projects/mirrors_controller_spec.rb | 20 ++++ .../ci/pipeline_mini_graph/mock_data.js | 35 +++++- .../pipeline_mini_graph_spec.js | 10 +- .../runner_configuration_popover_spec.js | 4 +- .../components/group_settings_app_spec.js | 14 ++- .../command_palette_items_spec.js | 23 +++- .../work_item_links_form_spec.js | 14 +-- .../work_item_projects_listbox_spec.js | 22 ++-- spec/frontend/work_items/mock_data.js | 2 + .../database/no_cross_db_foreign_keys_spec.rb | 4 +- spec/lib/gitlab/search/params_spec.rb | 35 +++++- spec/lib/search/group_settings_spec.rb | 7 ++ spec/lib/search/project_settings_spec.rb | 7 ++ spec/lib/search/settings_spec.rb | 7 -- ...lans_titles_with_legacy_plan_names_spec.rb | 2 +- ...om_components_name_based_on_pep503_spec.rb | 3 +- ...space_from_os_type_sbom_components_spec.rb | 3 +- ...ences_to_components_without_prefix_spec.rb | 3 +- spec/models/integration_spec.rb | 18 ++- .../mutations/notes/convert_to_thread_spec.rb | 74 ++++++++++++ spec/requests/search_controller_spec.rb | 46 ++++++- .../create_service_spec.rb | 11 ++ .../lib/search/settings_shared_examples.rb | 36 +++++- ...jira_cloud_app_deactivation_worker_spec.rb | 4 + yarn.lock | 112 +++++++++--------- 79 files changed, 766 insertions(+), 353 deletions(-) create mode 100644 app/graphql/mutations/notes/convert_to_thread.rb rename doc/user/project/codeowners/{code_owners_troubleshooting.md => troubleshooting.md} (100%) create mode 100644 lib/search/group_settings.rb rename lib/search/{settings.rb => project_settings.rb} (86%) create mode 100644 spec/lib/search/group_settings_spec.rb create mode 100644 spec/lib/search/project_settings_spec.rb delete mode 100644 spec/lib/search/settings_spec.rb create mode 100644 spec/requests/api/graphql/mutations/notes/convert_to_thread_spec.rb diff --git a/.gitlab/ci/release-environments.gitlab-ci.yml b/.gitlab/ci/release-environments.gitlab-ci.yml index bcd1a3b047c..82de8b99b74 100644 --- a/.gitlab/ci/release-environments.gitlab-ci.yml +++ b/.gitlab/ci/release-environments.gitlab-ci.yml @@ -26,6 +26,7 @@ start-release-environments-pipeline: - project: 'gitlab-org/gitlab' ref: 'master' file: '.gitlab/ci/release-environments/main.gitlab-ci.yml' + resource_group: release-environment-${CI_COMMIT_REF_SLUG} start-release-environments-security-pipeline: allow_failure: true @@ -54,3 +55,4 @@ start-release-environments-security-pipeline: - project: 'gitlab-org/security/gitlab' ref: 'master' file: '.gitlab/ci/release-environments/security.gitlab-ci.yml' + resource_group: release-environment-${CI_COMMIT_REF_SLUG} diff --git a/.gitlab/ci/release-environments/main.gitlab-ci.yml b/.gitlab/ci/release-environments/main.gitlab-ci.yml index df1f0b86dc0..c911da4618d 100644 --- a/.gitlab/ci/release-environments/main.gitlab-ci.yml +++ b/.gitlab/ci/release-environments/main.gitlab-ci.yml @@ -82,7 +82,6 @@ release-environments-deploy: branch: main strategy: depend needs: ["release-environments-deploy-env"] - resource_group: release-environment-${CI_COMMIT_REF_SLUG} release-environments-qa: stage: qa diff --git a/.gitlab/ci/release-environments/security.gitlab-ci.yml b/.gitlab/ci/release-environments/security.gitlab-ci.yml index cca5389d88a..7ad33654ed2 100644 --- a/.gitlab/ci/release-environments/security.gitlab-ci.yml +++ b/.gitlab/ci/release-environments/security.gitlab-ci.yml @@ -85,7 +85,6 @@ release-environments-deploy: branch: main strategy: depend needs: ["release-environments-deploy-env"] - resource_group: release-environment-${CI_COMMIT_REF_SLUG} release-environments-qa: stage: qa diff --git a/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml b/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml index 9c07e555ebc..6020ce1918b 100644 --- a/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml +++ b/.gitlab/ci/test-on-gdk/main.gitlab-ci.yml @@ -5,13 +5,23 @@ include: - local: .gitlab/ci/qa-common/variables.gitlab-ci.yml # code pattern changes -.code-pattern-changes: &code-pattern-changes - if: $MR_CODE_PATTERNS == "true" +.code-pattern-changes-with-selective-disabled: &code-pattern-changes-with-selective-disabled + if: $MR_CODE_PATTERNS == "true" && $SELECTIVE_EXECUTION_IMPROVED != "true" + +# code pattern changes with selective execution enabled +.code-pattern-with-selective-enabled-knapsack-set: &code-pattern-with-selective-enabled-knapsack-set + if: $MR_CODE_PATTERNS == "true" && $QA_TESTS != "" && $KNAPSACK_TEST_FILE_PATTERN != "" && $SELECTIVE_EXECUTION_IMPROVED == "true" + +.code-pattern-with-selective-enabled-knapsack-unset: &code-pattern-with-selective-enabled-knapsack-unset + if: $MR_CODE_PATTERNS == "true" && $QA_TESTS != "" && $KNAPSACK_TEST_FILE_PATTERN == "" && $SELECTIVE_EXECUTION_IMPROVED == "true" .rules:gdk:qa-selective: rules: - - <<: *code-pattern-changes + - <<: *code-pattern-changes-with-selective-disabled when: never + - <<: *code-pattern-with-selective-enabled-knapsack-set + when: never + - <<: *code-pattern-with-selective-enabled-knapsack-unset - !reference [.rules:test:qa-selective, rules] - if: $QA_SUITES =~ /Test::Instance::Blocking/ @@ -19,10 +29,13 @@ include: rules: # To account for cases where a group label is set which may trigger selective execution # But we want to execute full blocking suite on gdk in case of code-pattern-changes - - <<: *code-pattern-changes + - <<: *code-pattern-changes-with-selective-disabled variables: QA_TESTS: "" KNAPSACK_TEST_FILE_PATTERN: "" + - <<: *code-pattern-with-selective-enabled-knapsack-unset + when: never + - <<: *code-pattern-with-selective-enabled-knapsack-set - !reference [.rules:test:qa-parallel, rules] - if: $QA_SUITES =~ /Test::Instance::Blocking/ - !reference [.rules:test:manual, rules] diff --git a/Gemfile b/Gemfile index 42ae2957646..8f1b16391f2 100644 --- a/Gemfile +++ b/Gemfile @@ -536,7 +536,7 @@ group :development, :test, :coverage do gem 'simplecov', '~> 0.22', require: false, feature_category: :tooling gem 'simplecov-lcov', '~> 0.8.0', require: false, feature_category: :tooling gem 'simplecov-cobertura', '~> 2.1.0', require: false, feature_category: :tooling - gem 'undercover', '~> 0.4.4', require: false, feature_category: :tooling + gem 'undercover', '~> 0.5.0', require: false, feature_category: :tooling end # Gems required in omnibus-gitlab pipeline diff --git a/Gemfile.checksum b/Gemfile.checksum index c62ad21033c..6328b384d82 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -726,7 +726,7 @@ {"name":"typhoeus","version":"1.4.0","platform":"ruby","checksum":"fff9880d5dc35950e7706cf132fd297f377c049101794be1cf01c95567f642d4"}, {"name":"tzinfo","version":"2.0.6","platform":"ruby","checksum":"8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b"}, {"name":"uber","version":"0.1.0","platform":"ruby","checksum":"5beeb407ff807b5db994f82fa9ee07cfceaa561dad8af20be880bc67eba935dc"}, -{"name":"undercover","version":"0.4.6","platform":"ruby","checksum":"7255959205be7ba492731d4376d89d7cceaed1e675a14ae55c90f71a1621e6ae"}, +{"name":"undercover","version":"0.5.0","platform":"ruby","checksum":"ef99a8478be5466fb13fcd199f659ae308b81f71145a5a4e57428ff67d109fae"}, {"name":"unf","version":"0.1.4","platform":"java","checksum":"49a5972ec0b3d091d3b0b2e00113f2f342b9b212f0db855eb30a629637f6d302"}, {"name":"unf","version":"0.1.4","platform":"ruby","checksum":"4999517a531f2a955750f8831941891f6158498ec9b6cb1c81ce89388e63022e"}, {"name":"unf_ext","version":"0.0.8.2","platform":"ruby","checksum":"90b9623ee359cc4878461c5d2eab7d3d3ce5801a680a9e7ac83b8040c5b742fa"}, diff --git a/Gemfile.lock b/Gemfile.lock index 9fa46ee0694..446bb0638a3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1837,10 +1837,11 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) uber (0.1.0) - undercover (0.4.6) + undercover (0.5.0) + bigdecimal imagen (>= 0.1.8) rainbow (>= 2.1, < 4.0) - rugged (>= 0.27, < 1.7) + rugged (>= 0.27, < 1.8) unf (0.1.4) unf_ext unf_ext (0.0.8.2) @@ -2272,7 +2273,7 @@ DEPENDENCIES truncato (~> 0.7.12) tty-prompt (~> 0.23) typhoeus (~> 1.4.0) - undercover (~> 0.4.4) + undercover (~> 0.5.0) unleash (~> 3.2.2) valid_email (~> 0.1) validates_hostname (~> 1.0.13) diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index 4ae4d619774..73ddb96e000 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -17,6 +17,34 @@ import { fullBoardId } from './boards_util'; Vue.use(VueApollo); Vue.use(PortalVue); +defaultClient.cache.policies.addTypePolicies({ + BoardList: { + fields: { + issues: { + keyArgs: ['filters'], + }, + }, + }, + IssueConnection: { + merge(existing = { nodes: [] }, incoming, { args }) { + if (!args?.after) { + return incoming; + } + return { + ...incoming, + nodes: [...existing.nodes, ...incoming.nodes], + }; + }, + }, + Board: { + fields: { + epics: { + keyArgs: ['boardId'], + }, + }, + }, +}); + const apolloProvider = new VueApollo({ defaultClient, }); diff --git a/app/assets/javascripts/ci/pipeline_mini_graph/graphql/queries/get_pipeline_mini_graph.query.graphql b/app/assets/javascripts/ci/pipeline_mini_graph/graphql/queries/get_pipeline_mini_graph.query.graphql index 09977fed4ce..343afa99209 100644 --- a/app/assets/javascripts/ci/pipeline_mini_graph/graphql/queries/get_pipeline_mini_graph.query.graphql +++ b/app/assets/javascripts/ci/pipeline_mini_graph/graphql/queries/get_pipeline_mini_graph.query.graphql @@ -32,17 +32,21 @@ query getPipelineMiniGraph($fullPath: ID!, $iid: ID!) { downstream { nodes { id - path - project { - id - name - } detailedStatus { id detailsPath icon label } + path + project { + id + name + } + sourceJob { + id + retried + } } } } diff --git a/app/assets/javascripts/ci/pipeline_mini_graph/pipeline_mini_graph.vue b/app/assets/javascripts/ci/pipeline_mini_graph/pipeline_mini_graph.vue index 6957034cdbd..4bc9dfad0bb 100644 --- a/app/assets/javascripts/ci/pipeline_mini_graph/pipeline_mini_graph.vue +++ b/app/assets/javascripts/ci/pipeline_mini_graph/pipeline_mini_graph.vue @@ -2,6 +2,7 @@ import { GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui'; import { createAlert } from '~/alert'; import { __ } from '~/locale'; +import { reportToSentry } from '~/ci/utils'; import { keepLatestDownstreamPipelines } from '~/ci/pipeline_details/utils/parsing_utils'; import { getQueryHeaders, toggleQueryPollingByVisibility } from '~/ci/pipeline_details/graph/utils'; import { PIPELINE_MINI_GRAPH_POLL_INTERVAL } from '~/ci/pipeline_details/constants'; @@ -13,6 +14,7 @@ import PipelineStages from './pipeline_stages.vue'; * Renders the GraphQL instance of the pipeline mini graph. */ export default { + name: 'PipelineMiniGraph', i18n: { pipelineMiniGraphFetchError: __('There was a problem fetching the pipeline mini graph.'), }, @@ -74,8 +76,9 @@ export default { update({ project }) { return project?.pipeline || {}; }, - error() { + error(error) { createAlert({ message: this.$options.i18n.pipelineMiniGraphFetchError }); + reportToSentry(this.$options.name, error); }, }, }, @@ -83,15 +86,15 @@ export default { downstreamPipelines() { return keepLatestDownstreamPipelines(this.pipeline?.downstream?.nodes); }, - pipelineStages() { - return this.pipeline?.stages?.nodes || []; - }, hasDownstreamPipelines() { return Boolean(this.downstreamPipelines.length); }, pipelinePath() { return this.pipeline?.path || ''; }, + pipelineStages() { + return this.pipeline?.stages?.nodes || []; + }, upstreamPipeline() { return this.pipeline?.upstream; }, diff --git a/app/assets/javascripts/ci/pipeline_mini_graph/pipeline_stage.vue b/app/assets/javascripts/ci/pipeline_mini_graph/pipeline_stage.vue index 3a0db53d375..5b8705c21a0 100644 --- a/app/assets/javascripts/ci/pipeline_mini_graph/pipeline_stage.vue +++ b/app/assets/javascripts/ci/pipeline_mini_graph/pipeline_stage.vue @@ -2,6 +2,7 @@ import { GlButton, GlDisclosureDropdown, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui'; import { createAlert } from '~/alert'; import { s__, __, sprintf } from '~/locale'; +import { reportToSentry } from '~/ci/utils'; import { PIPELINE_MINI_GRAPH_POLL_INTERVAL } from '~/ci/pipeline_details/constants'; import CiIcon from '~/vue_shared/components/ci_icon/ci_icon.vue'; import { getQueryHeaders, toggleQueryPollingByVisibility } from '~/ci/pipeline_details/graph/utils'; @@ -74,8 +75,9 @@ export default { update(data) { return data?.ciPipelineStage?.jobs?.nodes || []; }, - error() { + error(error) { createAlert({ message: this.$options.i18n.stageJobsFetchError }); + reportToSentry(this.$options.name, error); }, }, }, diff --git a/app/assets/javascripts/ci/runner/components/runner_configuration_popover.vue b/app/assets/javascripts/ci/runner/components/runner_configuration_popover.vue index 805dad07626..2837a33ad68 100644 --- a/app/assets/javascripts/ci/runner/components/runner_configuration_popover.vue +++ b/app/assets/javascripts/ci/runner/components/runner_configuration_popover.vue @@ -1,7 +1,7 @@ @@ -27,7 +24,7 @@ export default { " > {{ content }} { - this.settings = response.data; - }) - .catch((e) => { - logError(e); - this.settings = []; - }); + settingsUrl = `${this.settingsPath}?project_id=${projectId}`; + } else if (groupId) { + settingsUrl = `${this.settingsPath}?group_id=${groupId}`; + } else { + this.settings = []; + return; } + + axios + .get(settingsUrl) + .then((response) => { + this.settings = response.data; + }) + .catch((e) => { + logError(e); + this.settings = []; + }); }, filterBySearchQuery(items, key = 'keywords') { return fuzzaldrinPlus.filter(items, this.searchQuery, { key }); diff --git a/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue b/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue index cae0abc682e..33467492032 100644 --- a/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue +++ b/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue @@ -325,6 +325,7 @@ export default { ref="wiLinksForm" data-testid="add-links-form" :full-path="fullPath" + :full-name="workItem.namespace.fullName" :issuable-gid="issuableGid" :work-item-iid="iid" :children-ids="childrenIds" diff --git a/app/assets/javascripts/work_items/components/work_item_links/work_item_links_form.vue b/app/assets/javascripts/work_items/components/work_item_links/work_item_links_form.vue index 79a81fdcf56..5b6d98bb717 100644 --- a/app/assets/javascripts/work_items/components/work_item_links/work_item_links_form.vue +++ b/app/assets/javascripts/work_items/components/work_item_links/work_item_links_form.vue @@ -83,6 +83,11 @@ export default { required: false, default: WORK_ITEM_TYPE_ENUM_TASK, }, + fullName: { + type: String, + required: false, + default: '', + }, }, apollo: { workItemTypes: { @@ -106,7 +111,7 @@ export default { error: null, isInputValid: true, search: '', - selectedProject: null, + selectedProjectFullPath: this.isGroup ? null : this.fullPath, childToCreateTitle: null, confidential: this.parentConfidential, submitInProgress: false, @@ -126,10 +131,10 @@ export default { confidential: this.parentConfidential || this.confidential, }; - if (this.selectedProject && !this.workItemChildIsEpic) { + if (this.selectedProjectFullPath && !this.workItemChildIsEpic) { workItemInput = { ...workItemInput, - namespacePath: this.selectedProject.fullPath, + namespacePath: this.selectedProjectFullPath, }; } else { workItemInput = { @@ -211,7 +216,7 @@ export default { return this.search.length > 0; }, hasSelectedProject() { - return this.selectedProject !== null && this.selectedProject !== undefined; + return Boolean(this.selectedProjectFullPath); }, canSubmitForm() { if (this.isCreateForm) { @@ -385,9 +390,10 @@ export default { :description="$options.i18n.projectValidationMessage" > diff --git a/app/assets/javascripts/work_items/components/work_item_links/work_item_projects_listbox.vue b/app/assets/javascripts/work_items/components/work_item_links/work_item_projects_listbox.vue index e0008e200e2..6c452c8b1d4 100644 --- a/app/assets/javascripts/work_items/components/work_item_links/work_item_projects_listbox.vue +++ b/app/assets/javascripts/work_items/components/work_item_links/work_item_projects_listbox.vue @@ -15,7 +15,7 @@ export default { ProjectAvatar, }, model: { - prop: 'selectedProject', + prop: 'selectedProjectFullPath', event: 'selectProject', }, props: { @@ -23,14 +23,19 @@ export default { required: true, type: String, }, + currentProjectName: { + required: false, + type: String, + default: '', + }, isGroup: { required: false, type: Boolean, default: false, }, - selectedProject: { + selectedProjectFullPath: { required: false, - type: Object, + type: String, default: null, }, }, @@ -38,8 +43,8 @@ export default { return { projects: [], frequentProjects: [], - selectedProjectFullPath: null, searchKey: '', + selectedProject: null, }; }, apollo: { @@ -57,14 +62,15 @@ export default { return data.namespace?.projects?.nodes; }, result() { - if (this.selectedProject === null) { - this.selectedProjectFullPath = this.fullPath; - } + this.selectedProject = this.findSelectedProject(this.selectedProjectFullPath); }, debounce: SEARCH_DEBOUNCE, }, }, computed: { + projectsLoading() { + return this.$apollo.queries.projects.loading; + }, dropdownToggleText() { if (this.selectedProject) { /** When selectedProject is fetched from localStorage @@ -73,7 +79,9 @@ export default { * */ return this.selectedProject.nameWithNamespace || this.selectedProject.namespace; } - return s__('WorkItem|Select a project'); + return this.selectedProjectFullPath && this.currentProjectName + ? this.currentProjectName + : s__('WorkItem|Select a project'); }, listItems() { const items = []; @@ -122,17 +130,15 @@ export default { return items; }, }, - watch: { - selectedProjectFullPath(projectFullPath) { - const project = this.findSelectedProject(projectFullPath); - this.$emit('selectProject', project); - }, - }, methods: { handleSearch(keyword) { this.searchKey = keyword; this.setFrequentProjects(keyword); }, + handleSelect(projectFullPath) { + this.selectedProject = this.findSelectedProject(projectFullPath); + this.$emit('selectProject', projectFullPath); + }, findSelectedProject(projectFullPath) { const project = this.projects.find((proj) => proj.fullPath === projectFullPath); if (project) { @@ -200,15 +206,17 @@ export default {