Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-07-01 18:26:45 +00:00
parent dde89bf569
commit 3c867bb51a
91 changed files with 837 additions and 283 deletions

View File

@ -1,5 +1,5 @@
include:
- component: ${CI_SERVER_FQDN}/gitlab-org/components/danger-review/danger-review@1.2.0
- component: ${CI_SERVER_FQDN}/gitlab-org/components/danger-review/danger-review@1.4.1
inputs:
job_image: "${DEFAULT_CI_IMAGE}"
# By default DANGER_DANGERFILE_PREFIX is not defined but allows JiHu to

View File

@ -12,7 +12,9 @@ workhorse:verify:
- make -C workhorse verify
.workhorse:test:
extends: .workhorse:rules:workhorse
extends:
- .workhorse:rules:workhorse
- .gitaly-with-transactions
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/${BUILD_OS}-${OS_VERSION}-ruby-${RUBY_VERSION}-golang-${GO_VERSION}-rust-${RUST_VERSION}:rubygems-${RUBYGEMS_VERSION}-git-2.36-exiftool-12.60
services:
- name: redis:${REDIS_VERSION}-alpine
@ -31,6 +33,10 @@ workhorse:verify:
- sed -i 's|URL.*$|URL = "redis://redis:6379"|g' workhorse/config.toml
script:
- make -C workhorse test
artifacts:
expire_in: 30 days
paths:
- log/gitaly-test.log
workhorse:test go:
extends: .workhorse:test
@ -45,6 +51,14 @@ workhorse:test go:
expire_in: 30 days
paths:
- workhorse/coverage.html
- log/gitaly-test.log
workhorse:test no_gitaly_transactions:
extends:
- .workhorse:test
- .gitaly-without-transactions
variables:
REDIS_VERSION: "7.0"
workhorse:test fips:
extends: .workhorse:test

View File

@ -3522,7 +3522,6 @@ Gitlab/BoundedContexts:
- 'ee/app/services/llm/execute_method_service.rb'
- 'ee/app/services/llm/explain_code_service.rb'
- 'ee/app/services/llm/explain_vulnerability_service.rb'
- 'ee/app/services/llm/fill_in_merge_request_template_service.rb'
- 'ee/app/services/llm/generate_commit_message_service.rb'
- 'ee/app/services/llm/generate_description_service.rb'
- 'ee/app/services/llm/generate_summary_service.rb'

View File

@ -30,19 +30,6 @@ Layout/ArgumentAlignment:
- 'ee/app/services/external_status_checks/destroy_service.rb'
- 'ee/app/services/external_status_checks/update_service.rb'
- 'lib/gitlab/config_checker/external_database_checker.rb'
- 'lib/gitlab/database/partitioning/partition_manager.rb'
- 'lib/gitlab/database/partitioning/replace_table.rb'
- 'lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb'
- 'lib/gitlab/diff/diff_refs.rb'
- 'lib/gitlab/diff/file_collection/base.rb'
- 'lib/gitlab/diff/file_collection/paginated_merge_request_diff.rb'
- 'lib/gitlab/diff/line.rb'
- 'lib/gitlab/diff/lines_unfolder.rb'
- 'lib/gitlab/diff/parser.rb'
- 'lib/gitlab/diff/position.rb'
- 'lib/gitlab/diff/rendered/notebook/diff_file.rb'
- 'lib/gitlab/diff/suggestions_parser.rb'
- 'lib/gitlab/email/hook/delivery_metrics_observer.rb'
- 'spec/lib/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb'
- 'spec/lib/container_registry/blob_spec.rb'
- 'spec/lib/container_registry/tag_spec.rb'

View File

@ -609,7 +609,6 @@ RSpec/BeforeAllRoleAssignment:
- 'ee/spec/services/llm/base_service_spec.rb'
- 'ee/spec/services/llm/chat_service_spec.rb'
- 'ee/spec/services/llm/explain_code_service_spec.rb'
- 'ee/spec/services/llm/fill_in_merge_request_template_service_spec.rb'
- 'ee/spec/services/llm/generate_commit_message_service_spec.rb'
- 'ee/spec/services/llm/generate_description_service_spec.rb'
- 'ee/spec/services/llm/generate_summary_service_spec.rb'

View File

@ -440,11 +440,9 @@ RSpec/NamedSubject:
- 'ee/spec/lib/gitlab/llm/concerns/exponential_backoff_spec.rb'
- 'ee/spec/lib/gitlab/llm/templates/categorize_question_spec.rb'
- 'ee/spec/lib/gitlab/llm/templates/explain_vulnerability_spec.rb'
- 'ee/spec/lib/gitlab/llm/templates/fill_in_merge_request_template_spec.rb'
- 'ee/spec/lib/gitlab/llm/templates/generate_commit_message_spec.rb'
- 'ee/spec/lib/gitlab/llm/templates/summarize_review_spec.rb'
- 'ee/spec/lib/gitlab/llm/vertex_ai/completions/analyze_ci_job_failure_spec.rb'
- 'ee/spec/lib/gitlab/llm/vertex_ai/completions/fill_in_merge_request_template_spec.rb'
- 'ee/spec/lib/gitlab/llm/vertex_ai/completions/generate_commit_message_spec.rb'
- 'ee/spec/lib/gitlab/llm/vertex_ai/completions/summarize_review_spec.rb'
- 'ee/spec/lib/gitlab/llm/vertex_ai/model_configurations/chat_spec.rb'

View File

@ -6,6 +6,7 @@ import CiIcon from '~/vue_shared/components/ci_icon/ci_icon.vue';
* Renders the downstream portion of the pipeline mini graph.
*/
export default {
name: 'DownstreamPipelines',
directives: {
GlTooltip: GlTooltipDirective,
},

View File

@ -19,6 +19,8 @@ query getPipelineStageJobs($id: CiStageID!) {
tooltip
}
name
scheduled
scheduledAt
}
}
}

View File

@ -1,13 +1,56 @@
<script>
import { GlDisclosureDropdownItem, GlTooltipDirective } from '@gitlab/ui';
import { sprintf } from '~/locale';
import delayedJobMixin from '~/ci/mixins/delayed_job_mixin';
import JobNameComponent from '~/ci/common/private/job_name_component.vue';
export default {
name: 'JobItem',
components: {
JobNameComponent,
GlDisclosureDropdownItem,
},
directives: {
GlTooltip: GlTooltipDirective,
},
mixins: [delayedJobMixin],
props: {
job: {
type: Object,
required: true,
},
},
computed: {
item() {
return {
text: this.job.name,
href: this.status?.detailsPath || '',
};
},
status() {
return this.job.detailedStatus || {};
},
tooltipText() {
const { tooltip: statusTooltip } = this.status;
if (this.isDelayedJob) {
return sprintf(statusTooltip, { remainingTime: this.remainingTime });
}
return statusTooltip;
},
},
};
</script>
<template>
<div>{{ job.id }}</div>
<gl-disclosure-dropdown-item :item="item">
<template #list-item>
<job-name-component
v-gl-tooltip.viewport.left
class="-gl-my-2"
:title="tooltipText"
:name="job.name"
:status="status"
/>
</template>
</gl-disclosure-dropdown-item>
</template>

View File

@ -142,7 +142,7 @@ export default {
</div>
<ul
v-else
class="gl-overflow-y-auto gl-p-4"
class="gl-overflow-y-auto gl-p-0"
data-testid="pipeline-stage-dropdown-menu-list"
@click.stop
>

View File

@ -68,12 +68,11 @@ export default {
</template>
<template #default>
<!-- This selector is temporarily disabled until the backend adds support for groups -->
<list-selector
v-show="false"
type="groups"
class="gl-m-5 gl-p-0!"
autofocus
disable-namespace-dropdown
:selected-items="groupExclusions"
@select="handleSelectExclusion"
@delete="handleRemoveExclusion"
@ -82,7 +81,6 @@ export default {
<list-selector
type="projects"
class="gl-m-5 gl-p-0!"
autofocus
:selected-items="projectExclusions"
@select="handleSelectExclusion"
@delete="handleRemoveExclusion"

View File

@ -4,7 +4,7 @@ import { differenceBy } from 'lodash';
import { s__, __, sprintf } from '~/locale';
import { createAlert } from '~/alert';
import { fetchPolicies } from '~/lib/graphql';
import { TYPENAME_PROJECT } from '~/graphql_shared/constants';
import { TYPENAME_PROJECT, TYPENAME_GROUP } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
import globalToast from '~/vue_shared/plugins/global_toast';
@ -90,6 +90,7 @@ export default {
variables: {
input: {
projectIds: this.extractProjectIds(uniqueList),
groupIds: this.extractGroupIds(uniqueList),
integrationName: BEYOND_IDENTITY_INTEGRATION_NAME,
},
},
@ -113,6 +114,11 @@ export default {
.filter((exclusion) => exclusion.type === PROJECT_TYPE)
.map((exclusion) => convertToGraphQLId(TYPENAME_PROJECT, exclusion.id));
},
extractGroupIds(exclusions) {
return exclusions
.filter((exclusion) => exclusion.type === GROUP_TYPE)
.map((exclusion) => convertToGraphQLId(TYPENAME_GROUP, exclusion.id));
},
nextPage(item) {
this.cursor = { after: item, last: null, before: null };
},
@ -139,7 +145,8 @@ export default {
mutation: deleteExclusion,
variables: {
input: {
projectIds: [exclusionToRemove.id],
projectIds: this.extractProjectIds([exclusionToRemove]),
groupIds: this.extractGroupIds([exclusionToRemove]),
integrationName: BEYOND_IDENTITY_INTEGRATION_NAME,
},
},

View File

@ -14,6 +14,11 @@ query integrationExclusion($before: String, $after: String, $first: Int, $last:
name
id
}
group {
avatarUrl
name
id
}
}
pageInfo {
...PageInfo

View File

@ -166,7 +166,7 @@ export default {
<items-selector
type="users"
:items="formatItemsIds(users)"
is-project-only-namespace
disable-namespace-dropdown
:users-options="$options.projectUsersOptions"
data-testid="users-selector"
@change="handleRuleDataUpdate('updatedUsers', $event)"
@ -176,7 +176,7 @@ export default {
:items="formatItemsIds(groups)"
:group-id="groupId"
data-testid="groups-selector"
is-project-only-namespace
disable-namespace-dropdown
@change="handleRuleDataUpdate('updatedGroups', $event)"
/>
</gl-form-group>

View File

@ -213,7 +213,7 @@ export default {
return ['FAILED', 'CANCELED'].indexOf(this.pipeline?.status) !== -1;
},
showMergeFailedPipelineConfirmationDialog() {
return this.status === PIPELINE_FAILED_STATE || this.isPipelineFailed;
return (this.status === PIPELINE_FAILED_STATE && this.isPipelineFailed) || this.mr.retargeted;
},
isMergeAllowed() {
return this.state.mergeable || false;

View File

@ -60,7 +60,7 @@ export default {
required: false,
default: () => ({}),
},
isProjectOnlyNamespace: {
disableNamespaceDropdown: {
type: Boolean,
required: false,
default: false,
@ -69,7 +69,7 @@ export default {
data() {
return {
searchValue: '',
isProjectNamespace: 'true',
isProjectNamespace: this.disableNamespaceDropdown ? 'false' : 'true',
selected: [],
items: [],
isLoading: false,
@ -80,7 +80,7 @@ export default {
return CONFIG[this.type];
},
showNamespaceDropdown() {
return this.config.showNamespaceDropdown && !this.isProjectOnlyNamespace;
return this.config.showNamespaceDropdown && !this.disableNamespaceDropdown;
},
namespaceDropdownText() {
return parseBoolean(this.isProjectNamespace)
@ -175,6 +175,7 @@ export default {
value: group.name,
...group,
id: getIdFromGraphQLId(group.id),
type: 'group',
})),
);
},

View File

@ -285,7 +285,7 @@ class GraphqlController < ApplicationController
def authorize_access_api!
if current_user.nil? &&
request_authenticator.authentication_token_present?
render_error('Invalid token', status: :unauthorized)
return render_error('Invalid token', status: :unauthorized)
end
return if can?(current_user, :access_api)

View File

@ -11,12 +11,6 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path]
before_action :build_merge_request, except: [:create]
before_action only: [:new] do
if can?(current_user, :fill_in_merge_request_template, project)
push_frontend_feature_flag(:fill_in_mr_template, project)
end
end
urgency :low, [
:new,
:create,

View File

@ -7,6 +7,7 @@ module Import
SOURCE_GROUP_EXPORT_IMPORT = :gitlab_group
SOURCE_GITHUB = :github
SOURCE_GITEA = :gitea
SOURCE_BITBUCKET = :bitbucket
SOURCE_BITBUCKET_SERVER = :bitbucket_server
module HasImportSource
@ -18,7 +19,7 @@ module Import
SOURCE_PROJECT_EXPORT_IMPORT => 2,
SOURCE_GROUP_EXPORT_IMPORT => 3,
SOURCE_GITHUB => 4,
bitbucket: 5, # aka bitbucket cloud
SOURCE_BITBUCKET => 5, # aka bitbucket cloud
SOURCE_BITBUCKET_SERVER => 6,
fogbugz: 7,
SOURCE_GITEA => 8,

View File

@ -9,7 +9,8 @@ module Search
state: params[:state],
confidential: params[:confidential],
include_archived: params[:include_archived],
num_context_lines: params[:num_context_lines]&.to_i
num_context_lines: params[:num_context_lines]&.to_i,
hybrid_similarity: params[:hybrid_similarity]&.to_f
}
end
end

View File

@ -52,12 +52,8 @@ module Projects
set_project_name_from_path
# get namespace id
namespace_id = params[:namespace_id] || current_user.namespace_id
@project.namespace_id = namespace_id.to_i
organization_id = params[:organization_id] || @project.namespace.organization_id
@project.organization_id = organization_id.to_i
@project.namespace_id = (params[:namespace_id] || current_user.namespace_id).to_i
@project.organization_id = (params[:organization_id] || @project.namespace.organization_id).to_i
@project.check_personal_projects_limit
return @project if @project.errors.any?
@ -106,6 +102,7 @@ module Projects
def validate_import_permissions
return unless @project.import?
return if @project.gitlab_project_import?
return if current_user.can?(:import_projects, parent_namespace)
@project.errors.add(:user, 'is not allowed to import projects')

View File

@ -1,4 +1,3 @@
= gitlab_ui_form_for [@project, @merge_request],
html: { class: 'merge-request-form common-note-form js-requires-input js-quick-submit' } do |f|
= render 'source_and_target', mr: @merge_request
= render 'shared/issuable/form', f: f, issuable: @merge_request, presenter: @mr_presenter

View File

@ -1,10 +0,0 @@
%span{
id: "js-merge-request-metadata",
class: ["js-merge-request-metadata", "gl-display-none"],
data: {
"source-project-id": mr.source_project_id,
"source-branch": mr.source_branch,
"target-project-id": mr.target_project_id,
"target-branch": mr.target_branch
}
}

View File

@ -1,7 +1,6 @@
%h1.page-title.gl-font-size-h-display
= _('New merge request')
= gitlab_ui_form_for [@project, @merge_request], html: { class: 'merge-request-form common-note-form js-requires-input js-quick-submit' } do |f|
= render "projects/merge_requests/source_and_target", mr: @merge_request
= render 'shared/issuable/form', f: f, issuable: @merge_request, commits: @commits, presenter: @mr_presenter
= f.hidden_field :source_project_id
= f.hidden_field :source_branch

View File

@ -0,0 +1,16 @@
---
description: Tracks pageviews for the admin credentials page
internal_events: true
action: view_admin_credentials_pageload
identifiers:
- user
product_group: personal_productivity
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157522
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -0,0 +1,16 @@
---
description: Tracks pageviews for the admin geo sites page
internal_events: true
action: view_admin_geo_sites_pageload
identifiers:
- user
product_group: personal_productivity
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157497
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -0,0 +1,16 @@
---
description: Tracks pageviews for the admin subscription page
internal_events: true
action: view_admin_subscription_pageload
identifiers:
- user
product_group: personal_productivity
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157478
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -1,8 +0,0 @@
---
name: fill_in_mr_template
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121233
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/412796
milestone: '16.1'
type: development
group: group::code review
default_enabled: true

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_view_admin_credentials_pageload_monthly
description: Monthly count of unique users who visisted the admin credentials page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157522
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_credentials_pageload
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_view_admin_geo_sites_pageload_monthly
description: Monthly count of unique users who visited the admin geo sites page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157497
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_geo_sites_pageload
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_view_admin_subscription_pageload_monthly
description: Monthly count of unique users who visited the admin subscriptions page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157478
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_subscription_pageload
unique: user.id

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_view_admin_credentials_pageload_monthly
description: Monthly count of total users who visited the admin credentials page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157522
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_credentials_pageload

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_view_admin_geo_sites_pageload_monthly
description: Monthly count of total users who visited the admin geo sites page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157497
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_geo_sites_pageload

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_view_admin_subscription_pageload_monthly
description: Monthly count of total users who visited the admin subscriptions page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157478
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_subscription_pageload

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_view_admin_credentials_pageload_weekly
description: Weekly count of unique users who visisted the admin credentials page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157522
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_credentials_pageload
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_view_admin_geo_sites_pageload_weekly
description: Weekly count of unique users who visited the admin geo sites page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157497
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_geo_sites_pageload
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_view_admin_subscription_pageload_weekly
description: Weekly count of unique users who visited the admin subscriptions page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157478
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_subscription_pageload
unique: user.id

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_view_admin_credentials_pageload_weekly
description: Weekly count of total users who visited the admin credentials page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157522
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_credentials_pageload

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_view_admin_geo_sites_pageload_weekly
description: Weekly count of total users who visited the admin geo sites page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157497
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_geo_sites_pageload

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_view_admin_subscription_pageload_weekly
description: Weekly count of total users who visited the admin subscriptions page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157478
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_subscription_pageload

View File

@ -0,0 +1,12 @@
# frozen_string_literal: true
class RemovePartitionIdDefaultValueForCiSourcesProjects < Gitlab::Database::Migration[2.2]
milestone '17.2'
TABLE_NAME = :ci_sources_projects
COLUM_NAME = :partition_id
def change
change_column_default(TABLE_NAME, COLUM_NAME, from: 100, to: nil)
end
end

View File

@ -0,0 +1 @@
477ad03f6d8a3727d92b4236349af20802000a22554eef21fbfc06fce6e43663

View File

@ -8319,7 +8319,7 @@ CREATE TABLE ci_sources_projects (
id bigint NOT NULL,
pipeline_id bigint NOT NULL,
source_project_id bigint NOT NULL,
partition_id bigint DEFAULT 100 NOT NULL
partition_id bigint NOT NULL
);
CREATE SEQUENCE ci_sources_projects_id_seq

View File

@ -104,11 +104,11 @@ POST /v1/proxy/vertex-ai/(*path)
- Clients must send JWT issued by GitLab.com or Customer Dot.
- This JWT contains `scopes` that indicates the permissions given to the GitLab-instance. This `scopes` will vary per Duo subscription tier.
- To access these proxy endpoints, `scopes` must **include** one of: `explain_vulnerability`, `resolve_vulnerability`, `generate_description`, `summarize_all_open_notes`, `generate_commit_message`, `summarize_review`, `fill_in_merge_request_template`, `analyze_ci_job_failure`.
- To access these proxy endpoints, `scopes` must **include** one of: `explain_vulnerability`, `resolve_vulnerability`, `generate_description`, `summarize_all_open_notes`, `generate_commit_message`, `summarize_review`, `analyze_ci_job_failure`.
- Requests that do not meet the specified criteria will result in a 401 Unauthorized Access error.
- Clients must send `X-Gitlab-Feature-Usage` headers in HTTP requests.
- This `X-Gitlab-Feature-Usage` header indicates the purpose of the API request.
- To access these proxy endpoints, `X-Gitlab-Feature-Usage` must **be** one of: `explain_vulnerability`, `resolve_vulnerability`, `generate_description`, `summarize_all_open_notes`, `generate_commit_message`, `summarize_review`, `fill_in_merge_request_template`, `analyze_ci_job_failure`.
- To access these proxy endpoints, `X-Gitlab-Feature-Usage` must **be** one of: `explain_vulnerability`, `resolve_vulnerability`, `generate_description`, `summarize_all_open_notes`, `generate_commit_message`, `summarize_review`, `analyze_ci_job_failure`.
- Requests that do not meet the specified criteria will result in a 401 Unauthorized Access error.
- For logging, we add the value of `X-Gitlab-Feature-Usage` header in access logs in AI Gateway.
- For metrics, we instrument the concurrent requests with `ModelRequestInstrumentator` and input/output tokens with `TextGenModelInstrumentator` in AI Gateway. It should be labled with `X-Gitlab-Instance-Id`, `X-Gitlab-Global-User-Id` and `X-Gitlab-Feature-Usage`.

View File

@ -4,7 +4,7 @@ creation-date: "2023-08-07"
authors: [ "@alberts-gitlab", "@iamricecake" ]
coach: [ "@grzesiek", "@fabiopitino" ]
approvers: [ "@jocelynjane", "@shampton" ]
owning-stage: "~devops::verify"
owning-stage: "~sec::govern"
participating-stages: []
---
@ -102,13 +102,37 @@ A consumer can be:
1. A user who interacts manually with a client library, API, or UI.
1. An integration, for example, Vault integration on Runner.
**1. GitLab Rails**
### GitLab Rails
GitLab Rails would be the main interface that users would interact with when managing secrets using the Secrets Manager feature.
This component is a facade to OpenBao server.
**2. OpenBao Server**
#### Retrieve user secrets
To retrieve secrets for a given user and display them in GitLab UI we will create a new table to persist secrets metadata. Otherwise we can't pull all the secrets belonging to a user as there is no `OpenBao` endpoint to achieve this.
Here a `SQL` example of how this could look like:
```sql
CREATE TABLE secrets (
id bigint NOT NULL,
environment_id bigint,
project_id bigint,
group_id bigint,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
revoked_at timestamp with time zone,
expiration_date date,
name text,
description text,
branch_name text
)
```
Based on this metadata, we will be able to determine the secret path in `OpenBao` by using the name provided by the user: `kv-v2/data/projects/<project_id>/<secret#name>`.
### OpenBao Server
OpenBao Server will be a new component in the GitLab overall architecture. This component provides all the secrets management capabilities
including storing the secrets themselves.
@ -144,3 +168,21 @@ The following links provide additional information that may be relevant to secre
- [OWASP Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html)
- [OWASP Key Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Key_Management_Cheat_Sheet.html)
## Who
DRIs:
<!-- vale gitlab.Spelling = NO -->
| Role | Who |
|---------------------|------------------------------------------------|
| Author | Erick Bajao, Senior Engineer |
| Recommender | Fabio Pitino, Principal Engineer |
| Product Leadership | Jocelyn Eillis , Product Manager |
| Engineering Leadership | Scott Hampton, Engineering Manager |
| Lead Engineer | Erick Bajao, Senior Backend Engineer |
| Senior Engineer | Maxime Orefice, Senior Backend Engineer |
| Engineer | Shabini Rajadas, Backend Engineer |
<!-- vale gitlab.Spelling = YES -->

View File

@ -16,9 +16,8 @@ This page attempts to index the ways in which GitLab supports Rust. It does so w
| ------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| `[Rust Configuration]` | Integration accomplished by Configuring Existing Rust Functionality | Rust |
| `[GitLab Configuration]` | Integration accomplished by Configuring Existing GitLab Functionality | GitLab |
| `[Rust Built]` | Built into Rust by Product Team to Address Rust Integration | Rust |
| `[GitLab Built]` | Built into GitLab by Product Team to Address Rust Integration | GitLab |
| `[Rust Solution]` | Built as Solution Example by Rust or Rust Partners | Community/Example |
| `[Rust Partner Built]` | Built into GitLab by Product Team to Address Rust Integration | GitLab |
| `[Rust Partner Solution]` | Built as Solution Example by Rust or Rust Partners | Community/Example |
| `[GitLab Solution]` | Built as Solution Example by GitLab or GitLab Partners | Community/Example |
| `[CI Solution]` | Built using GitLab CI and therefore <br />more customer customizable. | Items tagged `[CI Solution]` will <br />also carry one of the other tags <br />that indicate the maintenance status. |
@ -43,3 +42,4 @@ This page attempts to index the ways in which GitLab supports Rust. It does so w
- [Testing Code Coverage](../../../ci/testing/code_coverage.md#test-coverage-examples) `[GitLab Built]`
- [GitLab SAST Scanning](../../../user/application_security/sast/index.md#supported-languages-and-frameworks) `[GitLab Built]`- requires custom ruleset be created.
- [Rust License Scanning (Currently in Prerelease)](https://gitlab.com/groups/gitlab-org/-/epics/13093) `[GitLab Built]`
- [CodeSecure CodeSonar Embedded C Deep SAST Scanner as a GitLab CI/CD Component](https://gitlab.com/explore/catalog/codesonar/components/codesonar-ci) `[Rust Partner Built]` `[CI Solution]` - supports deep Abstract Execution analysis by watching compiles. Supports GitLabs SAST JSON which enables the findings throughout GitLab Ultimate security features. Features MISRA support and direct support for many Embedded Systems compilers.

View File

@ -310,3 +310,6 @@ To resolve a thread:
- In the upper-right corner of the original comment, select **Resolve thread** (**{check-circle}**).
- Below the last reply, in the **Reply** field, select **Resolve thread**.
- Below the last reply, in the **Reply** field, enter text, select the **Resolve thread** checkbox, and select **Add comment now**.
Additionally, in merge requests, you can [do more with threads](../project/merge_requests/index.md#resolve-a-thread),
such as move unresolved threads to an issue or prevent merging until all threads are resolved.

View File

@ -67,9 +67,10 @@ To skip the push check for [service accounts](../../profile/service_accounts.md)
1. Select the **Exclude service accounts** checkbox.
1. Select **Save changes**.
## Exclude projects from the Beyond Identity check
## Exclude groups or projects from the Beyond Identity check
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/454372) in GitLab 17.0 [with a flag](../../../administration/feature_flags.md) named `beyond_identity_exclusions`. Enabled by default.
> - Ability to exclude groups [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/454372) in GitLab 17.1.
FLAG:
The availability of this feature is controlled by a feature flag.
@ -80,7 +81,7 @@ Prerequisites:
- You must have administrator access to the GitLab instance.
To exclude projects from the Beyond Identity check:
To exclude groups or projects from the Beyond Identity check:
1. Sign in to GitLab as an administrator.
1. On the left sidebar, at the bottom, select **Admin Area**.
@ -88,5 +89,5 @@ To exclude projects from the Beyond Identity check:
1. Select **Beyond Identity**.
1. Select the **Exclusions** tab.
1. Select **Add exclusions**.
1. On the drawer, search and select projects to exclude.
1. On the drawer, search and select groups or projects to exclude.
1. Select **Add exclusions**.

View File

@ -68,12 +68,22 @@ module API
.execute
end
def authorized_params?(group, params)
return true if can?(current_user, :admin_group, group)
can?(current_user, :admin_runner, group) &&
params.keys == [:shared_runners_setting]
end
# This is a separate method so that EE can extend its behaviour, without
# having to modify this code directly.
#
def update_group(group)
safe_params = translate_params_for_compatibility
return unauthorized! unless authorized_params?(group, safe_params)
::Groups::UpdateService
.new(group, current_user, translate_params_for_compatibility)
.new(group, current_user, safe_params)
.execute
end
@ -291,7 +301,7 @@ module API
group.preload_shared_group_links
mark_throttle! :update_namespace_name, scope: group if params.key?(:name) && params[:name].present?
authorize! :admin_group, group
authorize_any! [:admin_group, :admin_runner], group
group.remove_avatar! if params.key?(:avatar) && params[:avatar].nil?

View File

@ -2,6 +2,7 @@
module API
module Helpers
include Gitlab::Allowable
include Gitlab::Utils
include Helpers::Caching
include Helpers::Pagination
@ -352,6 +353,10 @@ module API
forbidden!(reason) unless can?(current_user, action, subject)
end
def authorize_any!(abilities, subject = :global, reason = nil)
forbidden!(reason) unless can_any?(current_user, abilities, subject)
end
def authorize_push_project
authorize! :push_code, user_project
end
@ -436,10 +441,6 @@ module API
not_found! unless Gitlab.config.pages.enabled
end
def can?(object, action, subject = :global)
Ability.allowed?(object, action, subject)
end
# Checks the occurrences of required attributes, each attribute must be present in the params hash
# or a Bad Request error is invoked.
#

View File

@ -32,7 +32,8 @@ module Gitlab
work_item_type_id: object[:issue_type_id],
label_ids: [object[:label_id]].compact,
created_at: object[:created_at],
updated_at: object[:updated_at]
updated_at: object[:updated_at],
imported_from: ::Import::SOURCE_BITBUCKET
}
project.issues.create!(attributes)

View File

@ -29,7 +29,8 @@ module Gitlab
note: comment_note(comment),
author_id: user_finder.gitlab_user_id(project, comment.author),
created_at: comment.created_at,
updated_at: comment.updated_at
updated_at: comment.updated_at,
imported_from: ::Import::SOURCE_BITBUCKET
)
end
end

View File

@ -33,7 +33,10 @@ module Gitlab
state_id: MergeRequest.available_states[object[:state]],
author_id: author_id,
created_at: object[:created_at],
updated_at: object[:updated_at]
updated_at: object[:updated_at],
# MergeRequestHelpers#create_merge_request_without_hooks requires
# that we pass the enum integer value rather than the key.
imported_from: ::Import::HasImportSource::IMPORT_SOURCES[:bitbucket]
}
creator = Gitlab::Import::MergeRequestCreator.new(project)

View File

@ -124,7 +124,8 @@ module Gitlab
author_id: user_finder.gitlab_user_id(project, comment.author),
note: comment_note(comment),
created_at: comment.created_at,
updated_at: comment.updated_at
updated_at: comment.updated_at,
imported_from: ::Import::SOURCE_BITBUCKET
}
end

View File

@ -87,9 +87,9 @@ module Gitlab
connection.execute partition.to_sql
Gitlab::AppLogger.info(message: "Created partition",
partition_name: partition.partition_name,
table_name: partition.table,
connection_name: @connection_name)
partition_name: partition.partition_name,
table_name: partition.table,
connection_name: @connection_name)
lock_partitions_for_writes(partition) if should_lock_for_writes?
end
@ -114,7 +114,7 @@ module Gitlab
connection.execute partition.to_detach_sql
Postgresql::DetachedPartition.create!(table_name: partition.partition_name,
drop_after: RETAIN_DETACHED_PARTITIONS_FOR.from_now)
drop_after: RETAIN_DETACHED_PARTITIONS_FOR.from_now)
Gitlab::AppLogger.info(
message: "Detached Partition",

View File

@ -51,7 +51,7 @@ module Gitlab
statements << alter_column_default(original_table, primary_key_column, expression: nil)
statements << alter_column_default(replacement_table, primary_key_column,
expression: "nextval('#{quote_table_name(sequence)}'::regclass)")
expression: "nextval('#{quote_table_name(sequence)}'::regclass)")
statements << alter_sequence_owned_by(sequence, replacement_table, primary_key_column)

View File

@ -316,11 +316,11 @@ module Gitlab
Gitlab::Database::Partitioning::List::ConvertTable
.new(migration_context: self,
table_name: table_name,
parent_table_name: parent_table_name,
partitioning_column: partitioning_column,
zero_partition_value: initial_partitioning_value
).prepare_for_partitioning(async: async)
table_name: table_name,
parent_table_name: parent_table_name,
partitioning_column: partitioning_column,
zero_partition_value: initial_partitioning_value
).prepare_for_partitioning(async: async)
end
def revert_preparing_constraint_for_list_partitioning(table_name:, partitioning_column:, parent_table_name:, initial_partitioning_value:)
@ -328,11 +328,11 @@ module Gitlab
Gitlab::Database::Partitioning::List::ConvertTable
.new(migration_context: self,
table_name: table_name,
parent_table_name: parent_table_name,
partitioning_column: partitioning_column,
zero_partition_value: initial_partitioning_value
).revert_preparation_for_partitioning
table_name: table_name,
parent_table_name: parent_table_name,
partitioning_column: partitioning_column,
zero_partition_value: initial_partitioning_value
).revert_preparation_for_partitioning
end
def convert_table_to_first_list_partition(table_name:, partitioning_column:, parent_table_name:, initial_partitioning_value:, lock_tables: [])
@ -340,11 +340,11 @@ module Gitlab
Gitlab::Database::Partitioning::List::ConvertTable
.new(migration_context: self,
table_name: table_name,
parent_table_name: parent_table_name,
partitioning_column: partitioning_column,
zero_partition_value: initial_partitioning_value
).partition
table_name: table_name,
parent_table_name: parent_table_name,
partitioning_column: partitioning_column,
zero_partition_value: initial_partitioning_value
).partition
end
def revert_converting_table_to_first_list_partition(table_name:, partitioning_column:, parent_table_name:, initial_partitioning_value:)
@ -352,11 +352,11 @@ module Gitlab
Gitlab::Database::Partitioning::List::ConvertTable
.new(migration_context: self,
table_name: table_name,
parent_table_name: parent_table_name,
partitioning_column: partitioning_column,
zero_partition_value: initial_partitioning_value
).revert_partitioning
table_name: table_name,
parent_table_name: parent_table_name,
partitioning_column: partitioning_column,
zero_partition_value: initial_partitioning_value
).revert_partitioning
end
private
@ -560,7 +560,7 @@ module Gitlab
def replace_table(original_table_name, replacement_table_name, replaced_table_name, primary_key_name)
replace_table = Gitlab::Database::Partitioning::ReplaceTable.new(connection,
original_table_name.to_s, replacement_table_name, replaced_table_name, primary_key_name)
original_table_name.to_s, replacement_table_name, replaced_table_name, primary_key_name)
transaction do
drop_sync_trigger(original_table_name)

View File

@ -48,9 +48,9 @@ module Gitlab
straight = start_sha == base_sha
CompareService.new(project, head_sha).execute(project,
start_sha,
base_sha: base_sha,
straight: straight)
start_sha,
base_sha: base_sha,
straight: straight)
end
end
end

View File

@ -116,11 +116,11 @@ module Gitlab
stats = diff_stats_collection&.find_by_path(diff.new_path)
diff_file = Gitlab::Diff::File.new(diff,
repository: project.repository,
diff_refs: diff_refs,
fallback_diff_refs: fallback_diff_refs,
stats: stats,
max_blob_size: self.class.max_blob_size(project))
repository: project.repository,
diff_refs: diff_refs,
fallback_diff_refs: fallback_diff_refs,
stats: stats,
max_blob_size: self.class.max_blob_size(project))
if @use_extra_viewer_as_main && diff_file.has_renderable?
diff_file.rendered

View File

@ -13,7 +13,7 @@ module Gitlab
DEFAULT_PER_PAGE = 30
delegate :limit_value, :current_page, :next_page, :prev_page, :total_count,
:total_pages, to: :paginated_collection
:total_pages, to: :paginated_collection
def initialize(merge_request_diff, page, per_page)
super(merge_request_diff, diff_options: nil)

View File

@ -29,13 +29,13 @@ module Gitlab
def self.init_from_hash(hash)
new(hash[:text],
hash[:type],
hash[:index],
hash[:old_pos],
hash[:new_pos],
parent_file: hash[:parent_file],
line_code: hash[:line_code],
rich_text: hash[:rich_text])
hash[:type],
hash[:index],
hash[:old_pos],
hash[:new_pos],
parent_file: hash[:parent_file],
line_code: hash[:line_code],
rich_text: hash[:rich_text])
end
def self.safe_init_from_hash(hash)

View File

@ -101,7 +101,7 @@ module Gitlab
blob_lines.each do |line|
new_blob_lines << Gitlab::Diff::Line.new(line.text, line.type, nil, old_pos, new_pos,
parent_file: @diff_file)
parent_file: @diff_file)
old_pos += 1
new_pos += 1

View File

@ -74,8 +74,8 @@ module Gitlab
def filename?(line)
line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b',
'+++ a', # The line will start with `+++ a` in the reverse diff of an orphan commit
'--- /tmp/diffy', '+++ /tmp/diffy')
'+++ a', # The line will start with `+++ a` in the reverse diff of an orphan commit
'--- /tmp/diffy', '+++ /tmp/diffy')
end
def identification_type(line)

View File

@ -8,19 +8,19 @@ module Gitlab
attr_accessor :formatter
delegate :old_path,
:new_path,
:base_sha,
:start_sha,
:head_sha,
:old_line,
:new_line,
:width,
:height,
:x,
:y,
:line_range,
:position_type,
:ignore_whitespace_change, to: :formatter
:new_path,
:base_sha,
:start_sha,
:head_sha,
:old_line,
:new_line,
:width,
:height,
:x,
:y,
:line_range,
:position_type,
:ignore_whitespace_change, to: :formatter
# A position can belong to a text line or to an image coordinate
# it depends of the position_type argument.

View File

@ -18,7 +18,7 @@ module Gitlab
attr_reader :source_diff
delegate :repository, :diff_refs, :fallback_diff_refs, :unfolded, :unique_identifier,
to: :source_diff
to: :source_diff
def initialize(diff_file)
@source_diff = diff_file
@ -71,8 +71,8 @@ module Gitlab
Gitlab::RenderTimeout.timeout(background: RENDERED_TIMEOUT_BACKGROUND) do
IpynbDiff.diff(source_diff.old_blob&.data, source_diff.new_blob&.data,
raise_if_invalid_nb: true,
diffy_opts: { include_diff_info: true })&.tap do
raise_if_invalid_nb: true,
diffy_opts: { include_diff_info: true })&.tap do
log_event(LOG_IPYNBDIFF_GENERATED)
end
end

View File

@ -17,8 +17,8 @@ module Gitlab
return [] unless position.complete?
html = Banzai.render(text, project: nil,
no_original_data: true,
suggestions_filter_enabled: supports_suggestion)
no_original_data: true,
suggestions_filter_enabled: supports_suggestion)
doc = Nokogiri::HTML(html)
suggestion_nodes = doc.xpath(XPATH)
@ -37,10 +37,10 @@ module Gitlab
end
Gitlab::Diff::Suggestion.new(node.text,
line: position.new_line,
above: lines_above.to_i,
below: lines_below.to_i,
diff_file: diff_file)
line: position.new_line,
above: lines_above.to_i,
below: lines_below.to_i,
diff_file: diff_file)
end
end

View File

@ -17,14 +17,14 @@ module Gitlab
def self.delivery_attempts_counter
strong_memoize(:delivery_attempts_counter) do
Gitlab::Metrics.counter(:gitlab_emails_delivery_attempts_total,
'Counter of total emails delivery attempts')
'Counter of total emails delivery attempts')
end
end
def self.delivered_emails_counter
strong_memoize(:delivered_emails_counter) do
Gitlab::Metrics.counter(:gitlab_emails_delivered_total,
'Counter of total emails delievered')
'Counter of total emails delievered')
end
end
end

View File

@ -22480,9 +22480,6 @@ msgstr ""
msgid "Files, directories, and submodules in the path %{path} for commit reference %{ref}"
msgstr ""
msgid "Fill in merge request template"
msgstr ""
msgid "Fill in the fields below, turn on %{strong_open}Enable SAML authentication for this group%{strong_close}, and press %{strong_open}Save changes%{strong_close}"
msgstr ""
@ -44256,9 +44253,6 @@ msgstr ""
msgid "Replace audio"
msgstr ""
msgid "Replace current template with filled in placeholders"
msgstr ""
msgid "Replace file"
msgstr ""

View File

@ -66,7 +66,7 @@
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/fonts": "^1.3.0",
"@gitlab/svgs": "3.103.0",
"@gitlab/ui": "85.4.1",
"@gitlab/ui": "85.12.1",
"@gitlab/web-ide": "^0.0.1-dev-20240613133550",
"@mattiasbuelens/web-streams-adapter": "^0.1.0",
"@rails/actioncable": "7.0.8-4",
@ -131,7 +131,7 @@
"clipboard": "^2.0.8",
"compression-webpack-plugin": "^5.0.2",
"copy-webpack-plugin": "^6.4.1",
"core-js": "^3.36.1",
"core-js": "^3.37.1",
"cron-validator": "^1.1.1",
"cronstrue": "^1.122.0",
"cropperjs": "^1.6.1",

View File

@ -33,7 +33,9 @@ describe('Downstream Pipelines', () => {
});
it('should render the correct ci status icon', () => {
expect(wrapper.find('[data-testid="status_success_borderless-icon"]').exists()).toBe(true);
const findIcon = () => wrapper.findByTestId('status_success_borderless-icon');
expect(findIcon().exists()).toBe(true);
});
it('should have the correct title assigned for the tooltip', () => {

View File

@ -1,11 +1,14 @@
import { shallowMount } from '@vue/test-utils';
import JobItem from '~/ci/pipeline_mini_graph/job_item.vue';
import JobNameComponent from '~/ci/common/private/job_name_component.vue';
import { mockPipelineJob } from './mock_data';
describe('JobItem', () => {
let wrapper;
const defaultProps = {
job: { id: '3' },
job: mockPipelineJob,
};
const createComponent = ({ props = {} } = {}) => {
@ -17,13 +20,28 @@ describe('JobItem', () => {
});
};
const findJobNameComponent = () => wrapper.findComponent(JobNameComponent);
describe('when mounted', () => {
beforeEach(() => {
createComponent();
});
it('renders the received HTML', () => {
expect(wrapper.html()).toContain(defaultProps.job.id);
it('renders the job name component', () => {
expect(findJobNameComponent().exists()).toBe(true);
});
it('sends the necessary props to the job name component', () => {
expect(findJobNameComponent().props()).toMatchObject({
name: mockPipelineJob.name,
status: mockPipelineJob.detailedStatus,
});
});
it('sets the correct tooltip for the job item', () => {
expect(findJobNameComponent().attributes('title')).toBe(
mockPipelineJob.detailedStatus.tooltip,
);
});
});
});

View File

@ -59,6 +59,8 @@ export const pipelineStage = {
__typename: 'CiStage',
id: 'gid://gitlab/Ci::Stage/409',
name: 'build',
scheduled: false,
scheduledAt: null,
detailedStatus: {
__typename: 'DetailedStatus',
id: 'success-409-409',
@ -68,6 +70,31 @@ export const pipelineStage = {
},
};
// for `job_item_spec.js`
export const mockPipelineJob = {
__typename: 'CiJob',
id: 'gid://gitlab/Ci::Build/1001',
detailedStatus: {
__typename: 'DetailedStatus',
id: 'running-1001-1001',
action: {
__typename: 'StatusAction',
id: 'Ci::Build-success-1001',
icon: 'cancel',
path: '/flightjs/Flight/-/jobs/1001/cancel',
title: 'Cancel',
},
detailsPath: '/flightjs/Flight/-/pipelines/1176',
group: 'running',
hasDetails: true,
icon: 'status_running',
tooltip: 'running',
},
name: 'test_job',
scheduled: false,
scheduledAt: null,
};
// for `pipeline_stage_spec.js`
export const mockPipelineStageJobs = {
data: {
@ -97,6 +124,8 @@ export const mockPipelineStageJobs = {
tooltip: 'passed',
},
name: 'test_job',
scheduled: false,
scheduledAt: null,
},
{
__typename: 'CiJob',
@ -118,6 +147,8 @@ export const mockPipelineStageJobs = {
tooltip: 'passed',
},
name: 'test_job_2',
scheduled: false,
scheduledAt: null,
},
],
},

View File

@ -94,7 +94,11 @@ exports[`FindingsDrawer General Rendering matches the snapshot with detected bad
<span
class="badge badge-pill badge-warning gl-badge text-capitalize"
>
detected
<span
class="gl-badge-content"
>
detected
</span>
</span>
</p>
</li>
@ -314,7 +318,11 @@ exports[`FindingsDrawer General Rendering matches the snapshot with dismissed ba
<span
class="badge badge-pill badge-warning gl-badge text-capitalize"
>
detected
<span
class="gl-badge-content"
>
detected
</span>
</span>
</p>
</li>

View File

@ -70,14 +70,12 @@ describe('AddExclusionsDrawer component', () => {
expect(findGroupsListSelector().props()).toMatchObject({
type: 'groups',
autofocus: true,
disableNamespaceDropdown: true,
});
});
it('renders a list selector for projects', () => {
expect(findProjectsListSelector().props()).toMatchObject({
type: 'projects',
autofocus: true,
});
expect(findProjectsListSelector().props('type')).toBe('projects');
});
it('renders a button for adding exclusions', () => {

View File

@ -16,6 +16,7 @@ import ConfirmRemovalModal from '~/integrations/beyond_identity/components/remov
import showToast from '~/vue_shared/plugins/global_toast';
import {
projectExclusionsMock,
groupExclusionsMock,
fetchExclusionsResponse,
createExclusionMutationResponse,
deleteExclusionMutationResponse,
@ -147,7 +148,7 @@ describe('ExclusionsList component', () => {
describe('Exclusions added', () => {
beforeEach(async () => {
findDrawer().vm.$emit('add', projectExclusionsMock);
findDrawer().vm.$emit('add', [...projectExclusionsMock, ...groupExclusionsMock]);
await waitForPromises();
});
@ -156,6 +157,7 @@ describe('ExclusionsList component', () => {
input: {
integrationName: 'BEYOND_IDENTITY',
projectIds: ['gid://gitlab/Project/1', 'gid://gitlab/Project/2'],
groupIds: ['gid://gitlab/Group/1', 'gid://gitlab/Group/2'],
},
});
});
@ -197,66 +199,76 @@ describe('ExclusionsList component', () => {
});
});
describe('removing Exclusions', () => {
beforeEach(() => {
findListItems().at(1).vm.$emit('remove');
});
it('opens a confirmation modal', () => {
expect(findConfirmRemoveModal().props()).toMatchObject({
name: 'project bar',
type: 'project',
visible: true,
});
});
describe('confirmation modal primary action', () => {
beforeEach(async () => {
findConfirmRemoveModal().vm.$emit('primary');
await waitForPromises();
describe.each`
exclusionIndex | type | name | mutationPayload | successMessage
${1} | ${'project'} | ${'project bar'} | ${{ projectIds: ['gid://gitlab/Project/2'], groupIds: [] }} | ${'Project exclusion removed'}
${2} | ${'group'} | ${'group foo'} | ${{ projectIds: [], groupIds: ['gid://gitlab/Group/2'] }} | ${'Group exclusion removed'}
`(
'removes $type exclusion',
({ exclusionIndex, type, name, mutationPayload, successMessage }) => {
beforeEach(() => {
findListItems().at(exclusionIndex).vm.$emit('remove');
});
it('calls a GraphQL mutation to remove the exclusion', () => {
expect(deleteMutationMock).toHaveBeenCalledWith({
input: { integrationName: 'BEYOND_IDENTITY', projectIds: ['gid://gitlab/Project/2'] },
it('opens a confirmation modal', () => {
expect(findConfirmRemoveModal().props()).toMatchObject({
name,
type,
visible: true,
});
});
it('renders a toast', () => {
expect(showToast).toHaveBeenCalledWith('Project exclusion removed', {
action: {
text: 'Undo',
onClick: expect.any(Function),
},
describe('confirmation modal primary action', () => {
beforeEach(async () => {
findConfirmRemoveModal().vm.$emit('primary');
await waitForPromises();
});
});
});
describe('Error handling', () => {
beforeEach(async () => {
const response = {
data: {
integrationExclusionDelete: {
...deleteExclusionMutationResponse.data.integrationExclusionDelete,
errors: ['some error'],
it('calls a GraphQL mutation to remove the exclusion', () => {
expect(deleteMutationMock).toHaveBeenCalledWith({
input: {
integrationName: 'BEYOND_IDENTITY',
...mutationPayload,
},
},
};
});
});
createComponent({ deleteSuccessHandler: jest.fn().mockResolvedValue(response) });
await waitForPromises();
findListItems().at(1).vm.$emit('remove');
await waitForPromises();
findConfirmRemoveModal().vm.$emit('primary');
await waitForPromises();
});
it('renders an error', () => {
expect(createAlert).toHaveBeenCalledWith({
message: 'Failed to remove the exclusion. Try removing it again.',
it('renders a toast', () => {
expect(showToast).toHaveBeenCalledWith(successMessage, {
action: {
text: 'Undo',
onClick: expect.any(Function),
},
});
});
});
});
});
describe('Error handling', () => {
beforeEach(async () => {
const response = {
data: {
integrationExclusionDelete: {
...deleteExclusionMutationResponse.data.integrationExclusionDelete,
errors: ['some error'],
},
},
};
createComponent({ deleteSuccessHandler: jest.fn().mockResolvedValue(response) });
await waitForPromises();
findListItems().at(1).vm.$emit('remove');
await waitForPromises();
findConfirmRemoveModal().vm.$emit('primary');
await waitForPromises();
});
it('renders an error', () => {
expect(createAlert).toHaveBeenCalledWith({
message: 'Failed to remove the exclusion. Try removing it again.',
});
});
});
},
);
});

View File

@ -13,6 +13,7 @@ export const fetchExclusionsResponse = {
integrationExclusions: {
nodes: [
{
group: null,
project: {
name: 'project foo',
avatarUrl: 'foo.png',
@ -20,12 +21,21 @@ export const fetchExclusionsResponse = {
},
},
{
group: null,
project: {
name: 'project bar',
avatarUrl: 'bar.png',
id: 'gid://gitlab/Project/2',
},
},
{
project: null,
group: {
name: 'group foo',
avatarUrl: 'foo.png',
id: 'gid://gitlab/Group/2',
},
},
],
pageInfo: {},
},

View File

@ -11,7 +11,11 @@ exports[`~/releases/components/issuable_stats.vue matches snapshot 1`] = `
<span
class="badge badge-muted badge-pill gl-badge"
>
10
<span
class="gl-badge-content"
>
10
</span>
</span>
</span>
<div

View File

@ -828,6 +828,22 @@ describe('ReadyToMerge', () => {
});
});
describe('Merge button when merge request has been retargeted', () => {
beforeEach(() => {
createComponent({
mr: { retargeted: true },
});
});
it('should display confirmation modal when merge button is clicked', async () => {
expect(findPipelineFailedConfirmModal().props()).toEqual({ visible: false });
await findMergeButton().vm.$emit('click');
expect(findPipelineFailedConfirmModal().props()).toEqual({ visible: true });
});
});
describe('updating graphql data triggers commit message update when default changed', () => {
const UPDATED_MERGE_COMMIT_MESSAGE = 'New merge message from BE';
const UPDATED_SQUASH_COMMIT_MESSAGE = 'New squash message from BE';

View File

@ -7,7 +7,11 @@ exports[`Beta badge component renders the badge 1`] = `
href="#"
target="_self"
>
Beta
<span
class="gl-badge-content"
>
Beta
</span>
</a>
<div
class="gl-popover"

View File

@ -7,7 +7,11 @@ exports[`Experiment badge component renders the badge 1`] = `
href="#"
target="_self"
>
Experiment
<span
class="gl-badge-content"
>
Experiment
</span>
</a>
<div
class="gl-popover"

View File

@ -127,9 +127,9 @@ describe('List Selector spec', () => {
});
describe('namespace dropdown rendering', () => {
beforeEach(() => createComponent({ ...USERS_MOCK_PROPS, isProjectOnlyNamespace: true }));
beforeEach(() => createComponent({ ...USERS_MOCK_PROPS, disableNamespaceDropdown: true }));
it('does not render namespace dropdown with isProjectOnlyNamespace prop', () => {
it('does not render namespace dropdown with disableNamespaceDropdown prop', () => {
expect(findNamespaceDropdown().exists()).toBe(false);
});
});
@ -183,6 +183,15 @@ describe('List Selector spec', () => {
expect(findNamespaceDropdown().props('items').length).toBe(2);
});
it('does not render namespace dropdown with disableNamespaceDropdown prop set to true', () => {
createComponent({
...GROUPS_MOCK_PROPS,
disableNamespaceDropdown: true,
});
expect(findNamespaceDropdown().exists()).toBe(false);
});
describe('searching', () => {
const searchResponse = GROUPS_RESPONSE_MOCK.data.groups.nodes.map((group) => ({
...group,
@ -229,6 +238,7 @@ describe('List Selector spec', () => {
name: 'Flightjs',
text: 'Flightjs',
value: 'Flightjs',
type: 'group',
},
],
]);

View File

@ -49,6 +49,7 @@ RSpec.describe Gitlab::BitbucketImport::Importers::IssueImporter, :clean_gitlab_
expect(issue.labels).to eq([label])
expect(issue.created_at).to eq(Date.today)
expect(issue.updated_at).to eq(Date.today)
expect(issue.imported_from).to eq('bitbucket')
end
it 'converts mentions in the description' do

View File

@ -49,6 +49,7 @@ RSpec.describe Gitlab::BitbucketImport::Importers::IssueNotesImporter, :clean_gi
expect(note.author).to eq(bitbucket_user)
expect(note.created_at).to eq(Date.today)
expect(note.updated_at).to eq(Date.today)
expect(note.imported_from).to eq('bitbucket')
end
it 'converts mentions in the note' do

View File

@ -70,6 +70,7 @@ RSpec.describe Gitlab::BitbucketImport::Importers::PullRequestImporter, :clean_g
expect(merge_request.merge_request_diffs.first.head_commit_sha).to eq(target_branch_sha)
expect(merge_request.metrics.merged_by_id).to eq(closed_by_user.id)
expect(merge_request.metrics.latest_closed_by_id).to be_nil
expect(merge_request.imported_from).to eq('bitbucket')
end
it 'converts mentions in the description' do

View File

@ -67,6 +67,7 @@ RSpec.describe Gitlab::BitbucketImport::Importers::PullRequestNotesImporter, :cl
expect(note.author).to eq(bitbucket_user)
expect(note.created_at).to eq(created_at)
expect(note.updated_at).to eq(updated_at)
expect(note.imported_from).to eq('bitbucket')
end
context 'when the author does not have a bitbucket identity' do

View File

@ -6,6 +6,7 @@ RSpec.describe Import::HasImportSource, feature_category: :importers do
let_it_be(:snippet_not_imported) { create(:snippet, :repository) }
let_it_be(:snippet_imported) { create(:snippet, imported_from: :bitbucket) }
let_it_be(:merge_request_imported) { create(:snippet, imported_from: :fogbugz) }
let_it_be(:merge_request_imported_bb_cloud) { create(:snippet, imported_from: :bitbucket) }
let_it_be(:merge_request_imported_github) { create(:snippet, imported_from: :github) }
let_it_be(:merge_request_imported_gitea) { create(:snippet, imported_from: :gitea) }
@ -14,6 +15,7 @@ RSpec.describe Import::HasImportSource, feature_category: :importers do
expect(snippet_not_imported.imported?).to eq(false)
expect(snippet_imported.imported?).to eq(true)
expect(merge_request_imported.imported?).to eq(true)
expect(merge_request_imported_bb_cloud.imported?).to eq(true)
expect(merge_request_imported_github.imported?).to eq(true)
expect(merge_request_imported_gitea.imported?).to eq(true)
end
@ -24,6 +26,7 @@ RSpec.describe Import::HasImportSource, feature_category: :importers do
expect(snippet_not_imported.imported_from).to eq('none')
expect(snippet_imported.imported_from).to eq('bitbucket')
expect(merge_request_imported.imported_from).to eq('fogbugz')
expect(merge_request_imported_bb_cloud.imported_from).to eq('bitbucket')
expect(merge_request_imported_github.imported_from).to eq('github')
expect(merge_request_imported_gitea.imported_from).to eq('gitea')
end

View File

@ -5,32 +5,35 @@ require 'spec_helper'
RSpec.describe Projects::Packages::PackagesController, feature_category: :package_registry do
let_it_be(:project) { create(:project, :public) }
describe 'GET #index' do
let(:get_namespace_project_packages_path) do
get namespace_project_packages_path(namespace_id: project.namespace, project_id: project)
end
subject { response.body }
context 'when feature flag "packages_protected_packages" is enabled' do
before do
get_namespace_project_packages_path
end
it { is_expected.to have_pushed_frontend_feature_flags(packagesProtectedPackages: true) }
shared_examples 'having the feature flag "packagesProtectedPackages"' do
it 'pushes the feature flag to the view' do
is_expected.to have_gitlab_http_status(:ok)
is_expected.to have_attributes(body: have_pushed_frontend_feature_flags(packagesProtectedPackages: true))
end
context 'when feature flag "packages_protected_packages" is disabled' do
before do
stub_feature_flags(packages_protected_packages: false)
get_namespace_project_packages_path
end
it { is_expected.to have_pushed_frontend_feature_flags(packagesProtectedPackages: false) }
it 'does not pushes the feature flag to the view' do
is_expected.to have_gitlab_http_status(:ok)
is_expected.to have_attributes(body: have_pushed_frontend_feature_flags(packagesProtectedPackages: false))
end
end
end
describe 'GET #index' do
subject do
get namespace_project_packages_path(namespace_id: project.namespace, project_id: project)
response
end
it { is_expected.to have_gitlab_http_status(:ok) }
it_behaves_like 'having the feature flag "packagesProtectedPackages"'
end
describe 'GET #show' do
let_it_be(:package) { create(:package, project: project) }
@ -41,16 +44,6 @@ RSpec.describe Projects::Packages::PackagesController, feature_category: :packag
it { is_expected.to have_gitlab_http_status(:ok) }
it { is_expected.to have_attributes(body: have_pushed_frontend_feature_flags(packagesProtectedPackages: true)) }
context 'when feature flag "packages_protected_packages" is disabled' do
before do
stub_feature_flags(packages_protected_packages: false)
end
it { is_expected.to have_gitlab_http_status(:ok) }
it { is_expected.to have_attributes(body: have_pushed_frontend_feature_flags(packagesProtectedPackages: false)) }
end
it_behaves_like 'having the feature flag "packagesProtectedPackages"'
end
end

View File

@ -278,19 +278,41 @@ RSpec.describe Projects::CreateService, '#execute', feature_category: :groups_an
it_behaves_like 'has sync-ed traversal_ids'
context 'when project is an import' do
before do
stub_application_setting(import_sources: ['gitlab_project'])
let(:group) do
create(:group).tap do |group|
group.add_developer(user)
end
end
context 'and import is from a built-in template' do
let(:project_template) { Gitlab::ProjectTemplate.find(:rails) }
it 'does create the project' do
project = create_project(user, opts.merge!(template_name: project_template.name))
expect(project).to be_persisted
expect(project.errors).to be_blank
end
end
context 'and import is from a sample template' do
let(:sample_template) { Gitlab::SampleDataTemplate.find(:sample) }
it 'does create the project' do
project = create_project(user, opts.merge!(template_name: sample_template.name))
expect(project).to be_persisted
expect(project.errors).to be_blank
end
end
context 'when user is not allowed to import projects' do
let(:group) do
create(:group).tap do |group|
group.add_developer(user)
end
before do
stub_application_setting(import_sources: ['gitlab_project_migration'])
end
it 'does not create the project' do
project = create_project(user, opts.merge!(namespace_id: group.id, import_type: 'gitlab_project'))
project = create_project(user, opts.merge!(namespace_id: group.id, import_type: 'gitlab_project_migration'))
expect(project).not_to be_persisted
expect(project.errors.messages[:user].first).to eq('is not allowed to import projects')

View File

@ -112,10 +112,14 @@ module GitalySetup
FileUtils.mkdir_p(GitalySetup.second_storage_path)
end
if ENV['CI'] && gitaly_with_transactions?
# The configuration file with transactions is pre-generated in the CI. Here we check
if gitaly_with_transactions? && !toml
# The configuration file with transactions is pre-generated. Here we check
# whether this job should actually run with transactions and choose the pre-generated
# configuration with transactions enabled if so.
#
# Workhorse provides its own configuration through 'toml'. If a configuration is
# explicitly provided, we don't override it. Workhorse test setup has its own logic
# to choose the configuration with transactions enabled.
toml = "#{config_path(service)}.transactions"
end
@ -247,7 +251,7 @@ module GitalySetup
runtime_dir: runtime_dir,
prometheus_listen_addr: 'localhost:9236',
config_filename: config_name(:gitaly),
transactions_enabled: gitaly_with_transactions?
transactions_enabled: false
}
},
{
@ -256,7 +260,7 @@ module GitalySetup
runtime_dir: runtime_dir,
gitaly_socket: "gitaly2.socket",
config_filename: config_name(:gitaly2),
transactions_enabled: gitaly_with_transactions?
transactions_enabled: false
}
}
].each do |params|
@ -272,12 +276,10 @@ module GitalySetup
# without transactions enabled.
#
# Similarly to the Praefect configuration, generate variant of the configuration file with
# transactions enabled in CI. Later when the rspec job runs, we decide whether to run Gitaly
# transactions enabled. Later when the rspec job runs, we decide whether to run Gitaly
# using the configuration with transactions enabled or not.
#
# These configuration files are only used in the CI.
next unless ENV['CI']
params[:options][:config_filename] = "#{params[:options][:config_filename]}.transactions"
params[:options][:transactions_enabled] = true

View File

@ -133,7 +133,17 @@ $(GITALY_PID_FILE): gitaly.toml
$(call message, "Starting gitaly")
cd ..; GITALY_TESTING_NO_GIT_HOOKS=1 GITALY_PID_FILE=workhorse/$(GITALY_PID_FILE) scripts/gitaly-test-spawn workhorse/gitaly.toml
gitaly.toml: ../tmp/tests/gitaly/config.toml
GITALY_CONFIGURATION_SOURCE_BASE = ../tmp/tests/gitaly/config.toml
ifeq ($(GITALY_TRANSACTIONS_ENABLED),true)
GITALY_CONFIGURATION_SOURCE = ${GITALY_CONFIGURATION_SOURCE_BASE}.transactions
else
GITALY_CONFIGURATION_SOURCE = ${GITALY_CONFIGURATION_SOURCE_BASE}
endif
# Mark the target phony so the configuration is always refreshed in case the `GITALY_TRANSACTIONS_ENABLED`
# environment variable has been changed.
.PHONY: gitaly.toml
gitaly.toml: ${GITALY_CONFIGURATION_SOURCE}
sed -e 's/^socket_path.*$$/listen_addr = "0.0.0.0:8075"/;s/^\[auth\]$$//;s/^token.*$$//;s/^internal_socket_dir.*$$//' \
$< > $@

View File

@ -1331,10 +1331,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.103.0.tgz#af61387481100eadef2bea8fe8605250311ac582"
integrity sha512-jVWCrRVRF6nw2A+Aowc0quXV2bdRPl2v08ElCPSestfdKjQ92tSlCrIsLB8GvdW5aI0eFsD1vJ1w2qkzZdpA4A==
"@gitlab/ui@85.4.1":
version "85.4.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-85.4.1.tgz#4cc7ed0bec0d022003e996a790d7ea9c37cce5ff"
integrity sha512-Q2QsIILLlipv6StUEAjS11OaJFkoZ5jlIE3QpFpJeGkHnskD6viRdnFcFDCYXwGMtrm1JphEp7iZZs6uX/MIkw==
"@gitlab/ui@85.12.1":
version "85.12.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-85.12.1.tgz#b990c57b5ab3941e8a8900a987a8642a8cf8aa50"
integrity sha512-T+LWKfYGhxSVPT5x72qx7ujv1xgEKJCxVXbwcrMcWdMMjTdLSK6hGA/G7pY4MW8t0e0ZHvlwj7+BO9NFSDmq3Q==
dependencies:
"@floating-ui/dom" "1.4.3"
echarts "^5.3.2"
@ -4994,10 +4994,10 @@ core-js-pure@^3.30.2:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.35.0.tgz#4660033304a050215ae82e476bd2513a419fbb34"
integrity sha512-f+eRYmkou59uh7BPcyJ8MC76DiGhspj1KMxVIcF24tzP8NA9HVa1uC7BTW2tgx7E1QVCzDzsgp7kArrzhlz8Ew==
core-js@^3.29.1, core-js@^3.36.1, core-js@^3.6.5:
version "3.36.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.36.1.tgz#c97a7160ebd00b2de19e62f4bbd3406ab720e578"
integrity sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==
core-js@^3.29.1, core-js@^3.37.1, core-js@^3.6.5:
version "3.37.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.1.tgz#d21751ddb756518ac5a00e4d66499df981a62db9"
integrity sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==
core-util-is@~1.0.0:
version "1.0.3"