Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
dde89bf569
commit
3c867bb51a
|
|
@ -1,5 +1,5 @@
|
||||||
include:
|
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:
|
inputs:
|
||||||
job_image: "${DEFAULT_CI_IMAGE}"
|
job_image: "${DEFAULT_CI_IMAGE}"
|
||||||
# By default DANGER_DANGERFILE_PREFIX is not defined but allows JiHu to
|
# By default DANGER_DANGERFILE_PREFIX is not defined but allows JiHu to
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ workhorse:verify:
|
||||||
- make -C workhorse verify
|
- make -C workhorse verify
|
||||||
|
|
||||||
.workhorse:test:
|
.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
|
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:
|
services:
|
||||||
- name: redis:${REDIS_VERSION}-alpine
|
- name: redis:${REDIS_VERSION}-alpine
|
||||||
|
|
@ -31,6 +33,10 @@ workhorse:verify:
|
||||||
- sed -i 's|URL.*$|URL = "redis://redis:6379"|g' workhorse/config.toml
|
- sed -i 's|URL.*$|URL = "redis://redis:6379"|g' workhorse/config.toml
|
||||||
script:
|
script:
|
||||||
- make -C workhorse test
|
- make -C workhorse test
|
||||||
|
artifacts:
|
||||||
|
expire_in: 30 days
|
||||||
|
paths:
|
||||||
|
- log/gitaly-test.log
|
||||||
|
|
||||||
workhorse:test go:
|
workhorse:test go:
|
||||||
extends: .workhorse:test
|
extends: .workhorse:test
|
||||||
|
|
@ -45,6 +51,14 @@ workhorse:test go:
|
||||||
expire_in: 30 days
|
expire_in: 30 days
|
||||||
paths:
|
paths:
|
||||||
- workhorse/coverage.html
|
- 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:
|
workhorse:test fips:
|
||||||
extends: .workhorse:test
|
extends: .workhorse:test
|
||||||
|
|
|
||||||
|
|
@ -3522,7 +3522,6 @@ Gitlab/BoundedContexts:
|
||||||
- 'ee/app/services/llm/execute_method_service.rb'
|
- 'ee/app/services/llm/execute_method_service.rb'
|
||||||
- 'ee/app/services/llm/explain_code_service.rb'
|
- 'ee/app/services/llm/explain_code_service.rb'
|
||||||
- 'ee/app/services/llm/explain_vulnerability_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_commit_message_service.rb'
|
||||||
- 'ee/app/services/llm/generate_description_service.rb'
|
- 'ee/app/services/llm/generate_description_service.rb'
|
||||||
- 'ee/app/services/llm/generate_summary_service.rb'
|
- 'ee/app/services/llm/generate_summary_service.rb'
|
||||||
|
|
|
||||||
|
|
@ -30,19 +30,6 @@ Layout/ArgumentAlignment:
|
||||||
- 'ee/app/services/external_status_checks/destroy_service.rb'
|
- 'ee/app/services/external_status_checks/destroy_service.rb'
|
||||||
- 'ee/app/services/external_status_checks/update_service.rb'
|
- 'ee/app/services/external_status_checks/update_service.rb'
|
||||||
- 'lib/gitlab/config_checker/external_database_checker.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/bulk_imports/common/pipelines/lfs_objects_pipeline_spec.rb'
|
||||||
- 'spec/lib/container_registry/blob_spec.rb'
|
- 'spec/lib/container_registry/blob_spec.rb'
|
||||||
- 'spec/lib/container_registry/tag_spec.rb'
|
- 'spec/lib/container_registry/tag_spec.rb'
|
||||||
|
|
|
||||||
|
|
@ -609,7 +609,6 @@ RSpec/BeforeAllRoleAssignment:
|
||||||
- 'ee/spec/services/llm/base_service_spec.rb'
|
- 'ee/spec/services/llm/base_service_spec.rb'
|
||||||
- 'ee/spec/services/llm/chat_service_spec.rb'
|
- 'ee/spec/services/llm/chat_service_spec.rb'
|
||||||
- 'ee/spec/services/llm/explain_code_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_commit_message_service_spec.rb'
|
||||||
- 'ee/spec/services/llm/generate_description_service_spec.rb'
|
- 'ee/spec/services/llm/generate_description_service_spec.rb'
|
||||||
- 'ee/spec/services/llm/generate_summary_service_spec.rb'
|
- 'ee/spec/services/llm/generate_summary_service_spec.rb'
|
||||||
|
|
|
||||||
|
|
@ -440,11 +440,9 @@ RSpec/NamedSubject:
|
||||||
- 'ee/spec/lib/gitlab/llm/concerns/exponential_backoff_spec.rb'
|
- '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/categorize_question_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/llm/templates/explain_vulnerability_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/generate_commit_message_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/llm/templates/summarize_review_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/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/generate_commit_message_spec.rb'
|
||||||
- 'ee/spec/lib/gitlab/llm/vertex_ai/completions/summarize_review_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'
|
- 'ee/spec/lib/gitlab/llm/vertex_ai/model_configurations/chat_spec.rb'
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import CiIcon from '~/vue_shared/components/ci_icon/ci_icon.vue';
|
||||||
* Renders the downstream portion of the pipeline mini graph.
|
* Renders the downstream portion of the pipeline mini graph.
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
|
name: 'DownstreamPipelines',
|
||||||
directives: {
|
directives: {
|
||||||
GlTooltip: GlTooltipDirective,
|
GlTooltip: GlTooltipDirective,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ query getPipelineStageJobs($id: CiStageID!) {
|
||||||
tooltip
|
tooltip
|
||||||
}
|
}
|
||||||
name
|
name
|
||||||
|
scheduled
|
||||||
|
scheduledAt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,56 @@
|
||||||
<script>
|
<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 {
|
export default {
|
||||||
|
name: 'JobItem',
|
||||||
|
components: {
|
||||||
|
JobNameComponent,
|
||||||
|
GlDisclosureDropdownItem,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
GlTooltip: GlTooltipDirective,
|
||||||
|
},
|
||||||
|
mixins: [delayedJobMixin],
|
||||||
props: {
|
props: {
|
||||||
job: {
|
job: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
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>
|
</script>
|
||||||
<template>
|
<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>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
v-else
|
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"
|
data-testid="pipeline-stage-dropdown-menu-list"
|
||||||
@click.stop
|
@click.stop
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -68,12 +68,11 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #default>
|
<template #default>
|
||||||
<!-- This selector is temporarily disabled until the backend adds support for groups -->
|
|
||||||
<list-selector
|
<list-selector
|
||||||
v-show="false"
|
|
||||||
type="groups"
|
type="groups"
|
||||||
class="gl-m-5 gl-p-0!"
|
class="gl-m-5 gl-p-0!"
|
||||||
autofocus
|
autofocus
|
||||||
|
disable-namespace-dropdown
|
||||||
:selected-items="groupExclusions"
|
:selected-items="groupExclusions"
|
||||||
@select="handleSelectExclusion"
|
@select="handleSelectExclusion"
|
||||||
@delete="handleRemoveExclusion"
|
@delete="handleRemoveExclusion"
|
||||||
|
|
@ -82,7 +81,6 @@ export default {
|
||||||
<list-selector
|
<list-selector
|
||||||
type="projects"
|
type="projects"
|
||||||
class="gl-m-5 gl-p-0!"
|
class="gl-m-5 gl-p-0!"
|
||||||
autofocus
|
|
||||||
:selected-items="projectExclusions"
|
:selected-items="projectExclusions"
|
||||||
@select="handleSelectExclusion"
|
@select="handleSelectExclusion"
|
||||||
@delete="handleRemoveExclusion"
|
@delete="handleRemoveExclusion"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { differenceBy } from 'lodash';
|
||||||
import { s__, __, sprintf } from '~/locale';
|
import { s__, __, sprintf } from '~/locale';
|
||||||
import { createAlert } from '~/alert';
|
import { createAlert } from '~/alert';
|
||||||
import { fetchPolicies } from '~/lib/graphql';
|
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 { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||||
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
|
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
|
||||||
import globalToast from '~/vue_shared/plugins/global_toast';
|
import globalToast from '~/vue_shared/plugins/global_toast';
|
||||||
|
|
@ -90,6 +90,7 @@ export default {
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
projectIds: this.extractProjectIds(uniqueList),
|
projectIds: this.extractProjectIds(uniqueList),
|
||||||
|
groupIds: this.extractGroupIds(uniqueList),
|
||||||
integrationName: BEYOND_IDENTITY_INTEGRATION_NAME,
|
integrationName: BEYOND_IDENTITY_INTEGRATION_NAME,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -113,6 +114,11 @@ export default {
|
||||||
.filter((exclusion) => exclusion.type === PROJECT_TYPE)
|
.filter((exclusion) => exclusion.type === PROJECT_TYPE)
|
||||||
.map((exclusion) => convertToGraphQLId(TYPENAME_PROJECT, exclusion.id));
|
.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) {
|
nextPage(item) {
|
||||||
this.cursor = { after: item, last: null, before: null };
|
this.cursor = { after: item, last: null, before: null };
|
||||||
},
|
},
|
||||||
|
|
@ -139,7 +145,8 @@ export default {
|
||||||
mutation: deleteExclusion,
|
mutation: deleteExclusion,
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
projectIds: [exclusionToRemove.id],
|
projectIds: this.extractProjectIds([exclusionToRemove]),
|
||||||
|
groupIds: this.extractGroupIds([exclusionToRemove]),
|
||||||
integrationName: BEYOND_IDENTITY_INTEGRATION_NAME,
|
integrationName: BEYOND_IDENTITY_INTEGRATION_NAME,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,11 @@ query integrationExclusion($before: String, $after: String, $first: Int, $last:
|
||||||
name
|
name
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
group {
|
||||||
|
avatarUrl
|
||||||
|
name
|
||||||
|
id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pageInfo {
|
pageInfo {
|
||||||
...PageInfo
|
...PageInfo
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ export default {
|
||||||
<items-selector
|
<items-selector
|
||||||
type="users"
|
type="users"
|
||||||
:items="formatItemsIds(users)"
|
:items="formatItemsIds(users)"
|
||||||
is-project-only-namespace
|
disable-namespace-dropdown
|
||||||
:users-options="$options.projectUsersOptions"
|
:users-options="$options.projectUsersOptions"
|
||||||
data-testid="users-selector"
|
data-testid="users-selector"
|
||||||
@change="handleRuleDataUpdate('updatedUsers', $event)"
|
@change="handleRuleDataUpdate('updatedUsers', $event)"
|
||||||
|
|
@ -176,7 +176,7 @@ export default {
|
||||||
:items="formatItemsIds(groups)"
|
:items="formatItemsIds(groups)"
|
||||||
:group-id="groupId"
|
:group-id="groupId"
|
||||||
data-testid="groups-selector"
|
data-testid="groups-selector"
|
||||||
is-project-only-namespace
|
disable-namespace-dropdown
|
||||||
@change="handleRuleDataUpdate('updatedGroups', $event)"
|
@change="handleRuleDataUpdate('updatedGroups', $event)"
|
||||||
/>
|
/>
|
||||||
</gl-form-group>
|
</gl-form-group>
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ export default {
|
||||||
return ['FAILED', 'CANCELED'].indexOf(this.pipeline?.status) !== -1;
|
return ['FAILED', 'CANCELED'].indexOf(this.pipeline?.status) !== -1;
|
||||||
},
|
},
|
||||||
showMergeFailedPipelineConfirmationDialog() {
|
showMergeFailedPipelineConfirmationDialog() {
|
||||||
return this.status === PIPELINE_FAILED_STATE || this.isPipelineFailed;
|
return (this.status === PIPELINE_FAILED_STATE && this.isPipelineFailed) || this.mr.retargeted;
|
||||||
},
|
},
|
||||||
isMergeAllowed() {
|
isMergeAllowed() {
|
||||||
return this.state.mergeable || false;
|
return this.state.mergeable || false;
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
isProjectOnlyNamespace: {
|
disableNamespaceDropdown: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false,
|
default: false,
|
||||||
|
|
@ -69,7 +69,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchValue: '',
|
searchValue: '',
|
||||||
isProjectNamespace: 'true',
|
isProjectNamespace: this.disableNamespaceDropdown ? 'false' : 'true',
|
||||||
selected: [],
|
selected: [],
|
||||||
items: [],
|
items: [],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
|
@ -80,7 +80,7 @@ export default {
|
||||||
return CONFIG[this.type];
|
return CONFIG[this.type];
|
||||||
},
|
},
|
||||||
showNamespaceDropdown() {
|
showNamespaceDropdown() {
|
||||||
return this.config.showNamespaceDropdown && !this.isProjectOnlyNamespace;
|
return this.config.showNamespaceDropdown && !this.disableNamespaceDropdown;
|
||||||
},
|
},
|
||||||
namespaceDropdownText() {
|
namespaceDropdownText() {
|
||||||
return parseBoolean(this.isProjectNamespace)
|
return parseBoolean(this.isProjectNamespace)
|
||||||
|
|
@ -175,6 +175,7 @@ export default {
|
||||||
value: group.name,
|
value: group.name,
|
||||||
...group,
|
...group,
|
||||||
id: getIdFromGraphQLId(group.id),
|
id: getIdFromGraphQLId(group.id),
|
||||||
|
type: 'group',
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ class GraphqlController < ApplicationController
|
||||||
def authorize_access_api!
|
def authorize_access_api!
|
||||||
if current_user.nil? &&
|
if current_user.nil? &&
|
||||||
request_authenticator.authentication_token_present?
|
request_authenticator.authentication_token_present?
|
||||||
render_error('Invalid token', status: :unauthorized)
|
return render_error('Invalid token', status: :unauthorized)
|
||||||
end
|
end
|
||||||
|
|
||||||
return if can?(current_user, :access_api)
|
return if can?(current_user, :access_api)
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,6 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
|
||||||
before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path]
|
before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path]
|
||||||
before_action :build_merge_request, except: [:create]
|
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, [
|
urgency :low, [
|
||||||
:new,
|
:new,
|
||||||
:create,
|
:create,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ module Import
|
||||||
SOURCE_GROUP_EXPORT_IMPORT = :gitlab_group
|
SOURCE_GROUP_EXPORT_IMPORT = :gitlab_group
|
||||||
SOURCE_GITHUB = :github
|
SOURCE_GITHUB = :github
|
||||||
SOURCE_GITEA = :gitea
|
SOURCE_GITEA = :gitea
|
||||||
|
SOURCE_BITBUCKET = :bitbucket
|
||||||
SOURCE_BITBUCKET_SERVER = :bitbucket_server
|
SOURCE_BITBUCKET_SERVER = :bitbucket_server
|
||||||
|
|
||||||
module HasImportSource
|
module HasImportSource
|
||||||
|
|
@ -18,7 +19,7 @@ module Import
|
||||||
SOURCE_PROJECT_EXPORT_IMPORT => 2,
|
SOURCE_PROJECT_EXPORT_IMPORT => 2,
|
||||||
SOURCE_GROUP_EXPORT_IMPORT => 3,
|
SOURCE_GROUP_EXPORT_IMPORT => 3,
|
||||||
SOURCE_GITHUB => 4,
|
SOURCE_GITHUB => 4,
|
||||||
bitbucket: 5, # aka bitbucket cloud
|
SOURCE_BITBUCKET => 5, # aka bitbucket cloud
|
||||||
SOURCE_BITBUCKET_SERVER => 6,
|
SOURCE_BITBUCKET_SERVER => 6,
|
||||||
fogbugz: 7,
|
fogbugz: 7,
|
||||||
SOURCE_GITEA => 8,
|
SOURCE_GITEA => 8,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ module Search
|
||||||
state: params[:state],
|
state: params[:state],
|
||||||
confidential: params[:confidential],
|
confidential: params[:confidential],
|
||||||
include_archived: params[:include_archived],
|
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
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -52,12 +52,8 @@ module Projects
|
||||||
|
|
||||||
set_project_name_from_path
|
set_project_name_from_path
|
||||||
|
|
||||||
# get namespace id
|
@project.namespace_id = (params[:namespace_id] || current_user.namespace_id).to_i
|
||||||
namespace_id = params[:namespace_id] || current_user.namespace_id
|
@project.organization_id = (params[:organization_id] || @project.namespace.organization_id).to_i
|
||||||
@project.namespace_id = namespace_id.to_i
|
|
||||||
|
|
||||||
organization_id = params[:organization_id] || @project.namespace.organization_id
|
|
||||||
@project.organization_id = organization_id.to_i
|
|
||||||
|
|
||||||
@project.check_personal_projects_limit
|
@project.check_personal_projects_limit
|
||||||
return @project if @project.errors.any?
|
return @project if @project.errors.any?
|
||||||
|
|
@ -106,6 +102,7 @@ module Projects
|
||||||
|
|
||||||
def validate_import_permissions
|
def validate_import_permissions
|
||||||
return unless @project.import?
|
return unless @project.import?
|
||||||
|
return if @project.gitlab_project_import?
|
||||||
return if current_user.can?(:import_projects, parent_namespace)
|
return if current_user.can?(:import_projects, parent_namespace)
|
||||||
|
|
||||||
@project.errors.add(:user, 'is not allowed to import projects')
|
@project.errors.add(:user, 'is not allowed to import projects')
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
= gitlab_ui_form_for [@project, @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|
|
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
|
= render 'shared/issuable/form', f: f, issuable: @merge_request, presenter: @mr_presenter
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
%h1.page-title.gl-font-size-h-display
|
%h1.page-title.gl-font-size-h-display
|
||||||
= _('New merge request')
|
= _('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|
|
= 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
|
= render 'shared/issuable/form', f: f, issuable: @merge_request, commits: @commits, presenter: @mr_presenter
|
||||||
= f.hidden_field :source_project_id
|
= f.hidden_field :source_project_id
|
||||||
= f.hidden_field :source_branch
|
= f.hidden_field :source_branch
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
477ad03f6d8a3727d92b4236349af20802000a22554eef21fbfc06fce6e43663
|
||||||
|
|
@ -8319,7 +8319,7 @@ CREATE TABLE ci_sources_projects (
|
||||||
id bigint NOT NULL,
|
id bigint NOT NULL,
|
||||||
pipeline_id bigint NOT NULL,
|
pipeline_id bigint NOT NULL,
|
||||||
source_project_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
|
CREATE SEQUENCE ci_sources_projects_id_seq
|
||||||
|
|
|
||||||
|
|
@ -104,11 +104,11 @@ POST /v1/proxy/vertex-ai/(*path)
|
||||||
|
|
||||||
- Clients must send JWT issued by GitLab.com or Customer Dot.
|
- 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.
|
- 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.
|
- 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.
|
- Clients must send `X-Gitlab-Feature-Usage` headers in HTTP requests.
|
||||||
- This `X-Gitlab-Feature-Usage` header indicates the purpose of the API request.
|
- 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.
|
- 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 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`.
|
- 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`.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ creation-date: "2023-08-07"
|
||||||
authors: [ "@alberts-gitlab", "@iamricecake" ]
|
authors: [ "@alberts-gitlab", "@iamricecake" ]
|
||||||
coach: [ "@grzesiek", "@fabiopitino" ]
|
coach: [ "@grzesiek", "@fabiopitino" ]
|
||||||
approvers: [ "@jocelynjane", "@shampton" ]
|
approvers: [ "@jocelynjane", "@shampton" ]
|
||||||
owning-stage: "~devops::verify"
|
owning-stage: "~sec::govern"
|
||||||
participating-stages: []
|
participating-stages: []
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -102,13 +102,37 @@ A consumer can be:
|
||||||
1. A user who interacts manually with a client library, API, or UI.
|
1. A user who interacts manually with a client library, API, or UI.
|
||||||
1. An integration, for example, Vault integration on Runner.
|
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.
|
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.
|
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
|
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.
|
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 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)
|
- [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 -->
|
||||||
|
|
|
||||||
|
|
@ -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 |
|
| `[Rust Configuration]` | Integration accomplished by Configuring Existing Rust Functionality | Rust |
|
||||||
| `[GitLab Configuration]` | Integration accomplished by Configuring Existing GitLab Functionality | GitLab |
|
| `[GitLab Configuration]` | Integration accomplished by Configuring Existing GitLab Functionality | GitLab |
|
||||||
| `[Rust Built]` | Built into Rust by Product Team to Address Rust Integration | Rust |
|
| `[Rust Partner Built]` | Built into GitLab by Product Team to Address Rust Integration | GitLab |
|
||||||
| `[GitLab 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 |
|
||||||
| `[Rust 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 |
|
| `[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. |
|
| `[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]`
|
- [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.
|
- [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]`
|
- [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.
|
||||||
|
|
|
||||||
|
|
@ -310,3 +310,6 @@ To resolve a thread:
|
||||||
- In the upper-right corner of the original comment, select **Resolve thread** (**{check-circle}**).
|
- 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, select **Resolve thread**.
|
||||||
- Below the last reply, in the **Reply** field, enter text, select the **Resolve thread** checkbox, and select **Add comment now**.
|
- 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.
|
||||||
|
|
|
||||||
|
|
@ -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 the **Exclude service accounts** checkbox.
|
||||||
1. Select **Save changes**.
|
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.
|
> - [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:
|
FLAG:
|
||||||
The availability of this feature is controlled by a feature 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.
|
- 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. Sign in to GitLab as an administrator.
|
||||||
1. On the left sidebar, at the bottom, select **Admin Area**.
|
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 **Beyond Identity**.
|
||||||
1. Select the **Exclusions** tab.
|
1. Select the **Exclusions** tab.
|
||||||
1. Select **Add exclusions**.
|
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**.
|
1. Select **Add exclusions**.
|
||||||
|
|
|
||||||
|
|
@ -68,12 +68,22 @@ module API
|
||||||
.execute
|
.execute
|
||||||
end
|
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
|
# This is a separate method so that EE can extend its behaviour, without
|
||||||
# having to modify this code directly.
|
# having to modify this code directly.
|
||||||
#
|
#
|
||||||
def update_group(group)
|
def update_group(group)
|
||||||
|
safe_params = translate_params_for_compatibility
|
||||||
|
return unauthorized! unless authorized_params?(group, safe_params)
|
||||||
|
|
||||||
::Groups::UpdateService
|
::Groups::UpdateService
|
||||||
.new(group, current_user, translate_params_for_compatibility)
|
.new(group, current_user, safe_params)
|
||||||
.execute
|
.execute
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -291,7 +301,7 @@ module API
|
||||||
group.preload_shared_group_links
|
group.preload_shared_group_links
|
||||||
|
|
||||||
mark_throttle! :update_namespace_name, scope: group if params.key?(:name) && params[:name].present?
|
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?
|
group.remove_avatar! if params.key?(:avatar) && params[:avatar].nil?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
module API
|
module API
|
||||||
module Helpers
|
module Helpers
|
||||||
|
include Gitlab::Allowable
|
||||||
include Gitlab::Utils
|
include Gitlab::Utils
|
||||||
include Helpers::Caching
|
include Helpers::Caching
|
||||||
include Helpers::Pagination
|
include Helpers::Pagination
|
||||||
|
|
@ -352,6 +353,10 @@ module API
|
||||||
forbidden!(reason) unless can?(current_user, action, subject)
|
forbidden!(reason) unless can?(current_user, action, subject)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def authorize_any!(abilities, subject = :global, reason = nil)
|
||||||
|
forbidden!(reason) unless can_any?(current_user, abilities, subject)
|
||||||
|
end
|
||||||
|
|
||||||
def authorize_push_project
|
def authorize_push_project
|
||||||
authorize! :push_code, user_project
|
authorize! :push_code, user_project
|
||||||
end
|
end
|
||||||
|
|
@ -436,10 +441,6 @@ module API
|
||||||
not_found! unless Gitlab.config.pages.enabled
|
not_found! unless Gitlab.config.pages.enabled
|
||||||
end
|
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
|
# Checks the occurrences of required attributes, each attribute must be present in the params hash
|
||||||
# or a Bad Request error is invoked.
|
# or a Bad Request error is invoked.
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ module Gitlab
|
||||||
work_item_type_id: object[:issue_type_id],
|
work_item_type_id: object[:issue_type_id],
|
||||||
label_ids: [object[:label_id]].compact,
|
label_ids: [object[:label_id]].compact,
|
||||||
created_at: object[:created_at],
|
created_at: object[:created_at],
|
||||||
updated_at: object[:updated_at]
|
updated_at: object[:updated_at],
|
||||||
|
imported_from: ::Import::SOURCE_BITBUCKET
|
||||||
}
|
}
|
||||||
|
|
||||||
project.issues.create!(attributes)
|
project.issues.create!(attributes)
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ module Gitlab
|
||||||
note: comment_note(comment),
|
note: comment_note(comment),
|
||||||
author_id: user_finder.gitlab_user_id(project, comment.author),
|
author_id: user_finder.gitlab_user_id(project, comment.author),
|
||||||
created_at: comment.created_at,
|
created_at: comment.created_at,
|
||||||
updated_at: comment.updated_at
|
updated_at: comment.updated_at,
|
||||||
|
imported_from: ::Import::SOURCE_BITBUCKET
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,10 @@ module Gitlab
|
||||||
state_id: MergeRequest.available_states[object[:state]],
|
state_id: MergeRequest.available_states[object[:state]],
|
||||||
author_id: author_id,
|
author_id: author_id,
|
||||||
created_at: object[:created_at],
|
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)
|
creator = Gitlab::Import::MergeRequestCreator.new(project)
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,8 @@ module Gitlab
|
||||||
author_id: user_finder.gitlab_user_id(project, comment.author),
|
author_id: user_finder.gitlab_user_id(project, comment.author),
|
||||||
note: comment_note(comment),
|
note: comment_note(comment),
|
||||||
created_at: comment.created_at,
|
created_at: comment.created_at,
|
||||||
updated_at: comment.updated_at
|
updated_at: comment.updated_at,
|
||||||
|
imported_from: ::Import::SOURCE_BITBUCKET
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,9 @@ module Gitlab
|
||||||
connection.execute partition.to_sql
|
connection.execute partition.to_sql
|
||||||
|
|
||||||
Gitlab::AppLogger.info(message: "Created partition",
|
Gitlab::AppLogger.info(message: "Created partition",
|
||||||
partition_name: partition.partition_name,
|
partition_name: partition.partition_name,
|
||||||
table_name: partition.table,
|
table_name: partition.table,
|
||||||
connection_name: @connection_name)
|
connection_name: @connection_name)
|
||||||
|
|
||||||
lock_partitions_for_writes(partition) if should_lock_for_writes?
|
lock_partitions_for_writes(partition) if should_lock_for_writes?
|
||||||
end
|
end
|
||||||
|
|
@ -114,7 +114,7 @@ module Gitlab
|
||||||
connection.execute partition.to_detach_sql
|
connection.execute partition.to_detach_sql
|
||||||
|
|
||||||
Postgresql::DetachedPartition.create!(table_name: partition.partition_name,
|
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(
|
Gitlab::AppLogger.info(
|
||||||
message: "Detached Partition",
|
message: "Detached Partition",
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ module Gitlab
|
||||||
|
|
||||||
statements << alter_column_default(original_table, primary_key_column, expression: nil)
|
statements << alter_column_default(original_table, primary_key_column, expression: nil)
|
||||||
statements << alter_column_default(replacement_table, primary_key_column,
|
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)
|
statements << alter_sequence_owned_by(sequence, replacement_table, primary_key_column)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -316,11 +316,11 @@ module Gitlab
|
||||||
|
|
||||||
Gitlab::Database::Partitioning::List::ConvertTable
|
Gitlab::Database::Partitioning::List::ConvertTable
|
||||||
.new(migration_context: self,
|
.new(migration_context: self,
|
||||||
table_name: table_name,
|
table_name: table_name,
|
||||||
parent_table_name: parent_table_name,
|
parent_table_name: parent_table_name,
|
||||||
partitioning_column: partitioning_column,
|
partitioning_column: partitioning_column,
|
||||||
zero_partition_value: initial_partitioning_value
|
zero_partition_value: initial_partitioning_value
|
||||||
).prepare_for_partitioning(async: async)
|
).prepare_for_partitioning(async: async)
|
||||||
end
|
end
|
||||||
|
|
||||||
def revert_preparing_constraint_for_list_partitioning(table_name:, partitioning_column:, parent_table_name:, initial_partitioning_value:)
|
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
|
Gitlab::Database::Partitioning::List::ConvertTable
|
||||||
.new(migration_context: self,
|
.new(migration_context: self,
|
||||||
table_name: table_name,
|
table_name: table_name,
|
||||||
parent_table_name: parent_table_name,
|
parent_table_name: parent_table_name,
|
||||||
partitioning_column: partitioning_column,
|
partitioning_column: partitioning_column,
|
||||||
zero_partition_value: initial_partitioning_value
|
zero_partition_value: initial_partitioning_value
|
||||||
).revert_preparation_for_partitioning
|
).revert_preparation_for_partitioning
|
||||||
end
|
end
|
||||||
|
|
||||||
def convert_table_to_first_list_partition(table_name:, partitioning_column:, parent_table_name:, initial_partitioning_value:, lock_tables: [])
|
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
|
Gitlab::Database::Partitioning::List::ConvertTable
|
||||||
.new(migration_context: self,
|
.new(migration_context: self,
|
||||||
table_name: table_name,
|
table_name: table_name,
|
||||||
parent_table_name: parent_table_name,
|
parent_table_name: parent_table_name,
|
||||||
partitioning_column: partitioning_column,
|
partitioning_column: partitioning_column,
|
||||||
zero_partition_value: initial_partitioning_value
|
zero_partition_value: initial_partitioning_value
|
||||||
).partition
|
).partition
|
||||||
end
|
end
|
||||||
|
|
||||||
def revert_converting_table_to_first_list_partition(table_name:, partitioning_column:, parent_table_name:, initial_partitioning_value:)
|
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
|
Gitlab::Database::Partitioning::List::ConvertTable
|
||||||
.new(migration_context: self,
|
.new(migration_context: self,
|
||||||
table_name: table_name,
|
table_name: table_name,
|
||||||
parent_table_name: parent_table_name,
|
parent_table_name: parent_table_name,
|
||||||
partitioning_column: partitioning_column,
|
partitioning_column: partitioning_column,
|
||||||
zero_partition_value: initial_partitioning_value
|
zero_partition_value: initial_partitioning_value
|
||||||
).revert_partitioning
|
).revert_partitioning
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
@ -560,7 +560,7 @@ module Gitlab
|
||||||
|
|
||||||
def replace_table(original_table_name, replacement_table_name, replaced_table_name, primary_key_name)
|
def replace_table(original_table_name, replacement_table_name, replaced_table_name, primary_key_name)
|
||||||
replace_table = Gitlab::Database::Partitioning::ReplaceTable.new(connection,
|
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
|
transaction do
|
||||||
drop_sync_trigger(original_table_name)
|
drop_sync_trigger(original_table_name)
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,9 @@ module Gitlab
|
||||||
straight = start_sha == base_sha
|
straight = start_sha == base_sha
|
||||||
|
|
||||||
CompareService.new(project, head_sha).execute(project,
|
CompareService.new(project, head_sha).execute(project,
|
||||||
start_sha,
|
start_sha,
|
||||||
base_sha: base_sha,
|
base_sha: base_sha,
|
||||||
straight: straight)
|
straight: straight)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -116,11 +116,11 @@ module Gitlab
|
||||||
stats = diff_stats_collection&.find_by_path(diff.new_path)
|
stats = diff_stats_collection&.find_by_path(diff.new_path)
|
||||||
|
|
||||||
diff_file = Gitlab::Diff::File.new(diff,
|
diff_file = Gitlab::Diff::File.new(diff,
|
||||||
repository: project.repository,
|
repository: project.repository,
|
||||||
diff_refs: diff_refs,
|
diff_refs: diff_refs,
|
||||||
fallback_diff_refs: fallback_diff_refs,
|
fallback_diff_refs: fallback_diff_refs,
|
||||||
stats: stats,
|
stats: stats,
|
||||||
max_blob_size: self.class.max_blob_size(project))
|
max_blob_size: self.class.max_blob_size(project))
|
||||||
|
|
||||||
if @use_extra_viewer_as_main && diff_file.has_renderable?
|
if @use_extra_viewer_as_main && diff_file.has_renderable?
|
||||||
diff_file.rendered
|
diff_file.rendered
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ module Gitlab
|
||||||
DEFAULT_PER_PAGE = 30
|
DEFAULT_PER_PAGE = 30
|
||||||
|
|
||||||
delegate :limit_value, :current_page, :next_page, :prev_page, :total_count,
|
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)
|
def initialize(merge_request_diff, page, per_page)
|
||||||
super(merge_request_diff, diff_options: nil)
|
super(merge_request_diff, diff_options: nil)
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,13 @@ module Gitlab
|
||||||
|
|
||||||
def self.init_from_hash(hash)
|
def self.init_from_hash(hash)
|
||||||
new(hash[:text],
|
new(hash[:text],
|
||||||
hash[:type],
|
hash[:type],
|
||||||
hash[:index],
|
hash[:index],
|
||||||
hash[:old_pos],
|
hash[:old_pos],
|
||||||
hash[:new_pos],
|
hash[:new_pos],
|
||||||
parent_file: hash[:parent_file],
|
parent_file: hash[:parent_file],
|
||||||
line_code: hash[:line_code],
|
line_code: hash[:line_code],
|
||||||
rich_text: hash[:rich_text])
|
rich_text: hash[:rich_text])
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.safe_init_from_hash(hash)
|
def self.safe_init_from_hash(hash)
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ module Gitlab
|
||||||
|
|
||||||
blob_lines.each do |line|
|
blob_lines.each do |line|
|
||||||
new_blob_lines << Gitlab::Diff::Line.new(line.text, line.type, nil, old_pos, new_pos,
|
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
|
old_pos += 1
|
||||||
new_pos += 1
|
new_pos += 1
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,8 @@ module Gitlab
|
||||||
|
|
||||||
def filename?(line)
|
def filename?(line)
|
||||||
line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b',
|
line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b',
|
||||||
'+++ a', # The line will start with `+++ a` in the reverse diff of an orphan commit
|
'+++ a', # The line will start with `+++ a` in the reverse diff of an orphan commit
|
||||||
'--- /tmp/diffy', '+++ /tmp/diffy')
|
'--- /tmp/diffy', '+++ /tmp/diffy')
|
||||||
end
|
end
|
||||||
|
|
||||||
def identification_type(line)
|
def identification_type(line)
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,19 @@ module Gitlab
|
||||||
attr_accessor :formatter
|
attr_accessor :formatter
|
||||||
|
|
||||||
delegate :old_path,
|
delegate :old_path,
|
||||||
:new_path,
|
:new_path,
|
||||||
:base_sha,
|
:base_sha,
|
||||||
:start_sha,
|
:start_sha,
|
||||||
:head_sha,
|
:head_sha,
|
||||||
:old_line,
|
:old_line,
|
||||||
:new_line,
|
:new_line,
|
||||||
:width,
|
:width,
|
||||||
:height,
|
:height,
|
||||||
:x,
|
:x,
|
||||||
:y,
|
:y,
|
||||||
:line_range,
|
:line_range,
|
||||||
:position_type,
|
:position_type,
|
||||||
:ignore_whitespace_change, to: :formatter
|
:ignore_whitespace_change, to: :formatter
|
||||||
|
|
||||||
# A position can belong to a text line or to an image coordinate
|
# A position can belong to a text line or to an image coordinate
|
||||||
# it depends of the position_type argument.
|
# it depends of the position_type argument.
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ module Gitlab
|
||||||
attr_reader :source_diff
|
attr_reader :source_diff
|
||||||
|
|
||||||
delegate :repository, :diff_refs, :fallback_diff_refs, :unfolded, :unique_identifier,
|
delegate :repository, :diff_refs, :fallback_diff_refs, :unfolded, :unique_identifier,
|
||||||
to: :source_diff
|
to: :source_diff
|
||||||
|
|
||||||
def initialize(diff_file)
|
def initialize(diff_file)
|
||||||
@source_diff = diff_file
|
@source_diff = diff_file
|
||||||
|
|
@ -71,8 +71,8 @@ module Gitlab
|
||||||
|
|
||||||
Gitlab::RenderTimeout.timeout(background: RENDERED_TIMEOUT_BACKGROUND) do
|
Gitlab::RenderTimeout.timeout(background: RENDERED_TIMEOUT_BACKGROUND) do
|
||||||
IpynbDiff.diff(source_diff.old_blob&.data, source_diff.new_blob&.data,
|
IpynbDiff.diff(source_diff.old_blob&.data, source_diff.new_blob&.data,
|
||||||
raise_if_invalid_nb: true,
|
raise_if_invalid_nb: true,
|
||||||
diffy_opts: { include_diff_info: true })&.tap do
|
diffy_opts: { include_diff_info: true })&.tap do
|
||||||
log_event(LOG_IPYNBDIFF_GENERATED)
|
log_event(LOG_IPYNBDIFF_GENERATED)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ module Gitlab
|
||||||
return [] unless position.complete?
|
return [] unless position.complete?
|
||||||
|
|
||||||
html = Banzai.render(text, project: nil,
|
html = Banzai.render(text, project: nil,
|
||||||
no_original_data: true,
|
no_original_data: true,
|
||||||
suggestions_filter_enabled: supports_suggestion)
|
suggestions_filter_enabled: supports_suggestion)
|
||||||
doc = Nokogiri::HTML(html)
|
doc = Nokogiri::HTML(html)
|
||||||
suggestion_nodes = doc.xpath(XPATH)
|
suggestion_nodes = doc.xpath(XPATH)
|
||||||
|
|
||||||
|
|
@ -37,10 +37,10 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
Gitlab::Diff::Suggestion.new(node.text,
|
Gitlab::Diff::Suggestion.new(node.text,
|
||||||
line: position.new_line,
|
line: position.new_line,
|
||||||
above: lines_above.to_i,
|
above: lines_above.to_i,
|
||||||
below: lines_below.to_i,
|
below: lines_below.to_i,
|
||||||
diff_file: diff_file)
|
diff_file: diff_file)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,14 @@ module Gitlab
|
||||||
def self.delivery_attempts_counter
|
def self.delivery_attempts_counter
|
||||||
strong_memoize(:delivery_attempts_counter) do
|
strong_memoize(:delivery_attempts_counter) do
|
||||||
Gitlab::Metrics.counter(:gitlab_emails_delivery_attempts_total,
|
Gitlab::Metrics.counter(:gitlab_emails_delivery_attempts_total,
|
||||||
'Counter of total emails delivery attempts')
|
'Counter of total emails delivery attempts')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.delivered_emails_counter
|
def self.delivered_emails_counter
|
||||||
strong_memoize(:delivered_emails_counter) do
|
strong_memoize(:delivered_emails_counter) do
|
||||||
Gitlab::Metrics.counter(:gitlab_emails_delivered_total,
|
Gitlab::Metrics.counter(:gitlab_emails_delivered_total,
|
||||||
'Counter of total emails delievered')
|
'Counter of total emails delievered')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -22480,9 +22480,6 @@ msgstr ""
|
||||||
msgid "Files, directories, and submodules in the path %{path} for commit reference %{ref}"
|
msgid "Files, directories, and submodules in the path %{path} for commit reference %{ref}"
|
||||||
msgstr ""
|
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}"
|
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 ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -44256,9 +44253,6 @@ msgstr ""
|
||||||
msgid "Replace audio"
|
msgid "Replace audio"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Replace current template with filled in placeholders"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Replace file"
|
msgid "Replace file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
"@gitlab/favicon-overlay": "2.0.0",
|
"@gitlab/favicon-overlay": "2.0.0",
|
||||||
"@gitlab/fonts": "^1.3.0",
|
"@gitlab/fonts": "^1.3.0",
|
||||||
"@gitlab/svgs": "3.103.0",
|
"@gitlab/svgs": "3.103.0",
|
||||||
"@gitlab/ui": "85.4.1",
|
"@gitlab/ui": "85.12.1",
|
||||||
"@gitlab/web-ide": "^0.0.1-dev-20240613133550",
|
"@gitlab/web-ide": "^0.0.1-dev-20240613133550",
|
||||||
"@mattiasbuelens/web-streams-adapter": "^0.1.0",
|
"@mattiasbuelens/web-streams-adapter": "^0.1.0",
|
||||||
"@rails/actioncable": "7.0.8-4",
|
"@rails/actioncable": "7.0.8-4",
|
||||||
|
|
@ -131,7 +131,7 @@
|
||||||
"clipboard": "^2.0.8",
|
"clipboard": "^2.0.8",
|
||||||
"compression-webpack-plugin": "^5.0.2",
|
"compression-webpack-plugin": "^5.0.2",
|
||||||
"copy-webpack-plugin": "^6.4.1",
|
"copy-webpack-plugin": "^6.4.1",
|
||||||
"core-js": "^3.36.1",
|
"core-js": "^3.37.1",
|
||||||
"cron-validator": "^1.1.1",
|
"cron-validator": "^1.1.1",
|
||||||
"cronstrue": "^1.122.0",
|
"cronstrue": "^1.122.0",
|
||||||
"cropperjs": "^1.6.1",
|
"cropperjs": "^1.6.1",
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,9 @@ describe('Downstream Pipelines', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render the correct ci status icon', () => {
|
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', () => {
|
it('should have the correct title assigned for the tooltip', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import JobItem from '~/ci/pipeline_mini_graph/job_item.vue';
|
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', () => {
|
describe('JobItem', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
job: { id: '3' },
|
job: mockPipelineJob,
|
||||||
};
|
};
|
||||||
|
|
||||||
const createComponent = ({ props = {} } = {}) => {
|
const createComponent = ({ props = {} } = {}) => {
|
||||||
|
|
@ -17,13 +20,28 @@ describe('JobItem', () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const findJobNameComponent = () => wrapper.findComponent(JobNameComponent);
|
||||||
|
|
||||||
describe('when mounted', () => {
|
describe('when mounted', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent();
|
createComponent();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the received HTML', () => {
|
it('renders the job name component', () => {
|
||||||
expect(wrapper.html()).toContain(defaultProps.job.id);
|
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,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ export const pipelineStage = {
|
||||||
__typename: 'CiStage',
|
__typename: 'CiStage',
|
||||||
id: 'gid://gitlab/Ci::Stage/409',
|
id: 'gid://gitlab/Ci::Stage/409',
|
||||||
name: 'build',
|
name: 'build',
|
||||||
|
scheduled: false,
|
||||||
|
scheduledAt: null,
|
||||||
detailedStatus: {
|
detailedStatus: {
|
||||||
__typename: 'DetailedStatus',
|
__typename: 'DetailedStatus',
|
||||||
id: 'success-409-409',
|
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`
|
// for `pipeline_stage_spec.js`
|
||||||
export const mockPipelineStageJobs = {
|
export const mockPipelineStageJobs = {
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -97,6 +124,8 @@ export const mockPipelineStageJobs = {
|
||||||
tooltip: 'passed',
|
tooltip: 'passed',
|
||||||
},
|
},
|
||||||
name: 'test_job',
|
name: 'test_job',
|
||||||
|
scheduled: false,
|
||||||
|
scheduledAt: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__typename: 'CiJob',
|
__typename: 'CiJob',
|
||||||
|
|
@ -118,6 +147,8 @@ export const mockPipelineStageJobs = {
|
||||||
tooltip: 'passed',
|
tooltip: 'passed',
|
||||||
},
|
},
|
||||||
name: 'test_job_2',
|
name: 'test_job_2',
|
||||||
|
scheduled: false,
|
||||||
|
scheduledAt: null,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,11 @@ exports[`FindingsDrawer General Rendering matches the snapshot with detected bad
|
||||||
<span
|
<span
|
||||||
class="badge badge-pill badge-warning gl-badge text-capitalize"
|
class="badge badge-pill badge-warning gl-badge text-capitalize"
|
||||||
>
|
>
|
||||||
detected
|
<span
|
||||||
|
class="gl-badge-content"
|
||||||
|
>
|
||||||
|
detected
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -314,7 +318,11 @@ exports[`FindingsDrawer General Rendering matches the snapshot with dismissed ba
|
||||||
<span
|
<span
|
||||||
class="badge badge-pill badge-warning gl-badge text-capitalize"
|
class="badge badge-pill badge-warning gl-badge text-capitalize"
|
||||||
>
|
>
|
||||||
detected
|
<span
|
||||||
|
class="gl-badge-content"
|
||||||
|
>
|
||||||
|
detected
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -70,14 +70,12 @@ describe('AddExclusionsDrawer component', () => {
|
||||||
expect(findGroupsListSelector().props()).toMatchObject({
|
expect(findGroupsListSelector().props()).toMatchObject({
|
||||||
type: 'groups',
|
type: 'groups',
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
|
disableNamespaceDropdown: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a list selector for projects', () => {
|
it('renders a list selector for projects', () => {
|
||||||
expect(findProjectsListSelector().props()).toMatchObject({
|
expect(findProjectsListSelector().props('type')).toBe('projects');
|
||||||
type: 'projects',
|
|
||||||
autofocus: true,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a button for adding exclusions', () => {
|
it('renders a button for adding exclusions', () => {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import ConfirmRemovalModal from '~/integrations/beyond_identity/components/remov
|
||||||
import showToast from '~/vue_shared/plugins/global_toast';
|
import showToast from '~/vue_shared/plugins/global_toast';
|
||||||
import {
|
import {
|
||||||
projectExclusionsMock,
|
projectExclusionsMock,
|
||||||
|
groupExclusionsMock,
|
||||||
fetchExclusionsResponse,
|
fetchExclusionsResponse,
|
||||||
createExclusionMutationResponse,
|
createExclusionMutationResponse,
|
||||||
deleteExclusionMutationResponse,
|
deleteExclusionMutationResponse,
|
||||||
|
|
@ -147,7 +148,7 @@ describe('ExclusionsList component', () => {
|
||||||
|
|
||||||
describe('Exclusions added', () => {
|
describe('Exclusions added', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
findDrawer().vm.$emit('add', projectExclusionsMock);
|
findDrawer().vm.$emit('add', [...projectExclusionsMock, ...groupExclusionsMock]);
|
||||||
await waitForPromises();
|
await waitForPromises();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -156,6 +157,7 @@ describe('ExclusionsList component', () => {
|
||||||
input: {
|
input: {
|
||||||
integrationName: 'BEYOND_IDENTITY',
|
integrationName: 'BEYOND_IDENTITY',
|
||||||
projectIds: ['gid://gitlab/Project/1', 'gid://gitlab/Project/2'],
|
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', () => {
|
describe.each`
|
||||||
beforeEach(() => {
|
exclusionIndex | type | name | mutationPayload | successMessage
|
||||||
findListItems().at(1).vm.$emit('remove');
|
${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'}
|
||||||
|
`(
|
||||||
it('opens a confirmation modal', () => {
|
'removes $type exclusion',
|
||||||
expect(findConfirmRemoveModal().props()).toMatchObject({
|
({ exclusionIndex, type, name, mutationPayload, successMessage }) => {
|
||||||
name: 'project bar',
|
beforeEach(() => {
|
||||||
type: 'project',
|
findListItems().at(exclusionIndex).vm.$emit('remove');
|
||||||
visible: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('confirmation modal primary action', () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
findConfirmRemoveModal().vm.$emit('primary');
|
|
||||||
await waitForPromises();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls a GraphQL mutation to remove the exclusion', () => {
|
it('opens a confirmation modal', () => {
|
||||||
expect(deleteMutationMock).toHaveBeenCalledWith({
|
expect(findConfirmRemoveModal().props()).toMatchObject({
|
||||||
input: { integrationName: 'BEYOND_IDENTITY', projectIds: ['gid://gitlab/Project/2'] },
|
name,
|
||||||
|
type,
|
||||||
|
visible: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a toast', () => {
|
describe('confirmation modal primary action', () => {
|
||||||
expect(showToast).toHaveBeenCalledWith('Project exclusion removed', {
|
beforeEach(async () => {
|
||||||
action: {
|
findConfirmRemoveModal().vm.$emit('primary');
|
||||||
text: 'Undo',
|
await waitForPromises();
|
||||||
onClick: expect.any(Function),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Error handling', () => {
|
it('calls a GraphQL mutation to remove the exclusion', () => {
|
||||||
beforeEach(async () => {
|
expect(deleteMutationMock).toHaveBeenCalledWith({
|
||||||
const response = {
|
input: {
|
||||||
data: {
|
integrationName: 'BEYOND_IDENTITY',
|
||||||
integrationExclusionDelete: {
|
...mutationPayload,
|
||||||
...deleteExclusionMutationResponse.data.integrationExclusionDelete,
|
|
||||||
errors: ['some error'],
|
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
};
|
});
|
||||||
|
|
||||||
createComponent({ deleteSuccessHandler: jest.fn().mockResolvedValue(response) });
|
it('renders a toast', () => {
|
||||||
await waitForPromises();
|
expect(showToast).toHaveBeenCalledWith(successMessage, {
|
||||||
|
action: {
|
||||||
findListItems().at(1).vm.$emit('remove');
|
text: 'Undo',
|
||||||
await waitForPromises();
|
onClick: expect.any(Function),
|
||||||
findConfirmRemoveModal().vm.$emit('primary');
|
},
|
||||||
await waitForPromises();
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('renders an error', () => {
|
|
||||||
expect(createAlert).toHaveBeenCalledWith({
|
|
||||||
message: 'Failed to remove the exclusion. Try removing it again.',
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
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.',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ export const fetchExclusionsResponse = {
|
||||||
integrationExclusions: {
|
integrationExclusions: {
|
||||||
nodes: [
|
nodes: [
|
||||||
{
|
{
|
||||||
|
group: null,
|
||||||
project: {
|
project: {
|
||||||
name: 'project foo',
|
name: 'project foo',
|
||||||
avatarUrl: 'foo.png',
|
avatarUrl: 'foo.png',
|
||||||
|
|
@ -20,12 +21,21 @@ export const fetchExclusionsResponse = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
group: null,
|
||||||
project: {
|
project: {
|
||||||
name: 'project bar',
|
name: 'project bar',
|
||||||
avatarUrl: 'bar.png',
|
avatarUrl: 'bar.png',
|
||||||
id: 'gid://gitlab/Project/2',
|
id: 'gid://gitlab/Project/2',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
project: null,
|
||||||
|
group: {
|
||||||
|
name: 'group foo',
|
||||||
|
avatarUrl: 'foo.png',
|
||||||
|
id: 'gid://gitlab/Group/2',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
pageInfo: {},
|
pageInfo: {},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,11 @@ exports[`~/releases/components/issuable_stats.vue matches snapshot 1`] = `
|
||||||
<span
|
<span
|
||||||
class="badge badge-muted badge-pill gl-badge"
|
class="badge badge-muted badge-pill gl-badge"
|
||||||
>
|
>
|
||||||
10
|
<span
|
||||||
|
class="gl-badge-content"
|
||||||
|
>
|
||||||
|
10
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -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', () => {
|
describe('updating graphql data triggers commit message update when default changed', () => {
|
||||||
const UPDATED_MERGE_COMMIT_MESSAGE = 'New merge message from BE';
|
const UPDATED_MERGE_COMMIT_MESSAGE = 'New merge message from BE';
|
||||||
const UPDATED_SQUASH_COMMIT_MESSAGE = 'New squash message from BE';
|
const UPDATED_SQUASH_COMMIT_MESSAGE = 'New squash message from BE';
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,11 @@ exports[`Beta badge component renders the badge 1`] = `
|
||||||
href="#"
|
href="#"
|
||||||
target="_self"
|
target="_self"
|
||||||
>
|
>
|
||||||
Beta
|
<span
|
||||||
|
class="gl-badge-content"
|
||||||
|
>
|
||||||
|
Beta
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<div
|
<div
|
||||||
class="gl-popover"
|
class="gl-popover"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,11 @@ exports[`Experiment badge component renders the badge 1`] = `
|
||||||
href="#"
|
href="#"
|
||||||
target="_self"
|
target="_self"
|
||||||
>
|
>
|
||||||
Experiment
|
<span
|
||||||
|
class="gl-badge-content"
|
||||||
|
>
|
||||||
|
Experiment
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<div
|
<div
|
||||||
class="gl-popover"
|
class="gl-popover"
|
||||||
|
|
|
||||||
|
|
@ -127,9 +127,9 @@ describe('List Selector spec', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('namespace dropdown rendering', () => {
|
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);
|
expect(findNamespaceDropdown().exists()).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -183,6 +183,15 @@ describe('List Selector spec', () => {
|
||||||
expect(findNamespaceDropdown().props('items').length).toBe(2);
|
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', () => {
|
describe('searching', () => {
|
||||||
const searchResponse = GROUPS_RESPONSE_MOCK.data.groups.nodes.map((group) => ({
|
const searchResponse = GROUPS_RESPONSE_MOCK.data.groups.nodes.map((group) => ({
|
||||||
...group,
|
...group,
|
||||||
|
|
@ -229,6 +238,7 @@ describe('List Selector spec', () => {
|
||||||
name: 'Flightjs',
|
name: 'Flightjs',
|
||||||
text: 'Flightjs',
|
text: 'Flightjs',
|
||||||
value: 'Flightjs',
|
value: 'Flightjs',
|
||||||
|
type: 'group',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ RSpec.describe Gitlab::BitbucketImport::Importers::IssueImporter, :clean_gitlab_
|
||||||
expect(issue.labels).to eq([label])
|
expect(issue.labels).to eq([label])
|
||||||
expect(issue.created_at).to eq(Date.today)
|
expect(issue.created_at).to eq(Date.today)
|
||||||
expect(issue.updated_at).to eq(Date.today)
|
expect(issue.updated_at).to eq(Date.today)
|
||||||
|
expect(issue.imported_from).to eq('bitbucket')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'converts mentions in the description' do
|
it 'converts mentions in the description' do
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ RSpec.describe Gitlab::BitbucketImport::Importers::IssueNotesImporter, :clean_gi
|
||||||
expect(note.author).to eq(bitbucket_user)
|
expect(note.author).to eq(bitbucket_user)
|
||||||
expect(note.created_at).to eq(Date.today)
|
expect(note.created_at).to eq(Date.today)
|
||||||
expect(note.updated_at).to eq(Date.today)
|
expect(note.updated_at).to eq(Date.today)
|
||||||
|
expect(note.imported_from).to eq('bitbucket')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'converts mentions in the note' do
|
it 'converts mentions in the note' do
|
||||||
|
|
|
||||||
|
|
@ -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.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.merged_by_id).to eq(closed_by_user.id)
|
||||||
expect(merge_request.metrics.latest_closed_by_id).to be_nil
|
expect(merge_request.metrics.latest_closed_by_id).to be_nil
|
||||||
|
expect(merge_request.imported_from).to eq('bitbucket')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'converts mentions in the description' do
|
it 'converts mentions in the description' do
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ RSpec.describe Gitlab::BitbucketImport::Importers::PullRequestNotesImporter, :cl
|
||||||
expect(note.author).to eq(bitbucket_user)
|
expect(note.author).to eq(bitbucket_user)
|
||||||
expect(note.created_at).to eq(created_at)
|
expect(note.created_at).to eq(created_at)
|
||||||
expect(note.updated_at).to eq(updated_at)
|
expect(note.updated_at).to eq(updated_at)
|
||||||
|
expect(note.imported_from).to eq('bitbucket')
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the author does not have a bitbucket identity' do
|
context 'when the author does not have a bitbucket identity' do
|
||||||
|
|
|
||||||
|
|
@ -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_not_imported) { create(:snippet, :repository) }
|
||||||
let_it_be(:snippet_imported) { create(:snippet, imported_from: :bitbucket) }
|
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) { 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_github) { create(:snippet, imported_from: :github) }
|
||||||
let_it_be(:merge_request_imported_gitea) { create(:snippet, imported_from: :gitea) }
|
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_not_imported.imported?).to eq(false)
|
||||||
expect(snippet_imported.imported?).to eq(true)
|
expect(snippet_imported.imported?).to eq(true)
|
||||||
expect(merge_request_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_github.imported?).to eq(true)
|
||||||
expect(merge_request_imported_gitea.imported?).to eq(true)
|
expect(merge_request_imported_gitea.imported?).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
@ -24,6 +26,7 @@ RSpec.describe Import::HasImportSource, feature_category: :importers do
|
||||||
expect(snippet_not_imported.imported_from).to eq('none')
|
expect(snippet_not_imported.imported_from).to eq('none')
|
||||||
expect(snippet_imported.imported_from).to eq('bitbucket')
|
expect(snippet_imported.imported_from).to eq('bitbucket')
|
||||||
expect(merge_request_imported.imported_from).to eq('fogbugz')
|
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_github.imported_from).to eq('github')
|
||||||
expect(merge_request_imported_gitea.imported_from).to eq('gitea')
|
expect(merge_request_imported_gitea.imported_from).to eq('gitea')
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,32 +5,35 @@ require 'spec_helper'
|
||||||
RSpec.describe Projects::Packages::PackagesController, feature_category: :package_registry do
|
RSpec.describe Projects::Packages::PackagesController, feature_category: :package_registry do
|
||||||
let_it_be(:project) { create(:project, :public) }
|
let_it_be(:project) { create(:project, :public) }
|
||||||
|
|
||||||
describe 'GET #index' do
|
shared_examples 'having the feature flag "packagesProtectedPackages"' do
|
||||||
let(:get_namespace_project_packages_path) do
|
it 'pushes the feature flag to the view' do
|
||||||
get namespace_project_packages_path(namespace_id: project.namespace, project_id: project)
|
is_expected.to have_gitlab_http_status(:ok)
|
||||||
end
|
is_expected.to have_attributes(body: have_pushed_frontend_feature_flags(packagesProtectedPackages: true))
|
||||||
|
|
||||||
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) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when feature flag "packages_protected_packages" is disabled' do
|
context 'when feature flag "packages_protected_packages" is disabled' do
|
||||||
before do
|
before do
|
||||||
stub_feature_flags(packages_protected_packages: false)
|
stub_feature_flags(packages_protected_packages: false)
|
||||||
|
|
||||||
get_namespace_project_packages_path
|
|
||||||
end
|
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
|
||||||
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
|
describe 'GET #show' do
|
||||||
let_it_be(:package) { create(:package, project: project) }
|
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_gitlab_http_status(:ok) }
|
||||||
|
|
||||||
it { is_expected.to have_attributes(body: have_pushed_frontend_feature_flags(packagesProtectedPackages: true)) }
|
it_behaves_like 'having the feature flag "packagesProtectedPackages"'
|
||||||
|
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -278,19 +278,41 @@ RSpec.describe Projects::CreateService, '#execute', feature_category: :groups_an
|
||||||
it_behaves_like 'has sync-ed traversal_ids'
|
it_behaves_like 'has sync-ed traversal_ids'
|
||||||
|
|
||||||
context 'when project is an import' do
|
context 'when project is an import' do
|
||||||
before do
|
let(:group) do
|
||||||
stub_application_setting(import_sources: ['gitlab_project'])
|
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
|
end
|
||||||
|
|
||||||
context 'when user is not allowed to import projects' do
|
context 'when user is not allowed to import projects' do
|
||||||
let(:group) do
|
before do
|
||||||
create(:group).tap do |group|
|
stub_application_setting(import_sources: ['gitlab_project_migration'])
|
||||||
group.add_developer(user)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not create the project' do
|
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).not_to be_persisted
|
||||||
expect(project.errors.messages[:user].first).to eq('is not allowed to import projects')
|
expect(project.errors.messages[:user].first).to eq('is not allowed to import projects')
|
||||||
|
|
|
||||||
|
|
@ -112,10 +112,14 @@ module GitalySetup
|
||||||
FileUtils.mkdir_p(GitalySetup.second_storage_path)
|
FileUtils.mkdir_p(GitalySetup.second_storage_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
if ENV['CI'] && gitaly_with_transactions?
|
if gitaly_with_transactions? && !toml
|
||||||
# The configuration file with transactions is pre-generated in the CI. Here we check
|
# The configuration file with transactions is pre-generated. Here we check
|
||||||
# whether this job should actually run with transactions and choose the pre-generated
|
# whether this job should actually run with transactions and choose the pre-generated
|
||||||
# configuration with transactions enabled if so.
|
# 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"
|
toml = "#{config_path(service)}.transactions"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -247,7 +251,7 @@ module GitalySetup
|
||||||
runtime_dir: runtime_dir,
|
runtime_dir: runtime_dir,
|
||||||
prometheus_listen_addr: 'localhost:9236',
|
prometheus_listen_addr: 'localhost:9236',
|
||||||
config_filename: config_name(:gitaly),
|
config_filename: config_name(:gitaly),
|
||||||
transactions_enabled: gitaly_with_transactions?
|
transactions_enabled: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -256,7 +260,7 @@ module GitalySetup
|
||||||
runtime_dir: runtime_dir,
|
runtime_dir: runtime_dir,
|
||||||
gitaly_socket: "gitaly2.socket",
|
gitaly_socket: "gitaly2.socket",
|
||||||
config_filename: config_name(:gitaly2),
|
config_filename: config_name(:gitaly2),
|
||||||
transactions_enabled: gitaly_with_transactions?
|
transactions_enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
].each do |params|
|
].each do |params|
|
||||||
|
|
@ -272,12 +276,10 @@ module GitalySetup
|
||||||
# without transactions enabled.
|
# without transactions enabled.
|
||||||
#
|
#
|
||||||
# Similarly to the Praefect configuration, generate variant of the configuration file with
|
# 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.
|
# using the configuration with transactions enabled or not.
|
||||||
#
|
#
|
||||||
# These configuration files are only used in the CI.
|
# These configuration files are only used in the CI.
|
||||||
next unless ENV['CI']
|
|
||||||
|
|
||||||
params[:options][:config_filename] = "#{params[:options][:config_filename]}.transactions"
|
params[:options][:config_filename] = "#{params[:options][:config_filename]}.transactions"
|
||||||
params[:options][:transactions_enabled] = true
|
params[:options][:transactions_enabled] = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,17 @@ $(GITALY_PID_FILE): gitaly.toml
|
||||||
$(call message, "Starting gitaly")
|
$(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
|
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.*$$//' \
|
sed -e 's/^socket_path.*$$/listen_addr = "0.0.0.0:8075"/;s/^\[auth\]$$//;s/^token.*$$//;s/^internal_socket_dir.*$$//' \
|
||||||
$< > $@
|
$< > $@
|
||||||
|
|
||||||
|
|
|
||||||
16
yarn.lock
16
yarn.lock
|
|
@ -1331,10 +1331,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.103.0.tgz#af61387481100eadef2bea8fe8605250311ac582"
|
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.103.0.tgz#af61387481100eadef2bea8fe8605250311ac582"
|
||||||
integrity sha512-jVWCrRVRF6nw2A+Aowc0quXV2bdRPl2v08ElCPSestfdKjQ92tSlCrIsLB8GvdW5aI0eFsD1vJ1w2qkzZdpA4A==
|
integrity sha512-jVWCrRVRF6nw2A+Aowc0quXV2bdRPl2v08ElCPSestfdKjQ92tSlCrIsLB8GvdW5aI0eFsD1vJ1w2qkzZdpA4A==
|
||||||
|
|
||||||
"@gitlab/ui@85.4.1":
|
"@gitlab/ui@85.12.1":
|
||||||
version "85.4.1"
|
version "85.12.1"
|
||||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-85.4.1.tgz#4cc7ed0bec0d022003e996a790d7ea9c37cce5ff"
|
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-85.12.1.tgz#b990c57b5ab3941e8a8900a987a8642a8cf8aa50"
|
||||||
integrity sha512-Q2QsIILLlipv6StUEAjS11OaJFkoZ5jlIE3QpFpJeGkHnskD6viRdnFcFDCYXwGMtrm1JphEp7iZZs6uX/MIkw==
|
integrity sha512-T+LWKfYGhxSVPT5x72qx7ujv1xgEKJCxVXbwcrMcWdMMjTdLSK6hGA/G7pY4MW8t0e0ZHvlwj7+BO9NFSDmq3Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@floating-ui/dom" "1.4.3"
|
"@floating-ui/dom" "1.4.3"
|
||||||
echarts "^5.3.2"
|
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"
|
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.35.0.tgz#4660033304a050215ae82e476bd2513a419fbb34"
|
||||||
integrity sha512-f+eRYmkou59uh7BPcyJ8MC76DiGhspj1KMxVIcF24tzP8NA9HVa1uC7BTW2tgx7E1QVCzDzsgp7kArrzhlz8Ew==
|
integrity sha512-f+eRYmkou59uh7BPcyJ8MC76DiGhspj1KMxVIcF24tzP8NA9HVa1uC7BTW2tgx7E1QVCzDzsgp7kArrzhlz8Ew==
|
||||||
|
|
||||||
core-js@^3.29.1, core-js@^3.36.1, core-js@^3.6.5:
|
core-js@^3.29.1, core-js@^3.37.1, core-js@^3.6.5:
|
||||||
version "3.36.1"
|
version "3.37.1"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.36.1.tgz#c97a7160ebd00b2de19e62f4bbd3406ab720e578"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.1.tgz#d21751ddb756518ac5a00e4d66499df981a62db9"
|
||||||
integrity sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==
|
integrity sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==
|
||||||
|
|
||||||
core-util-is@~1.0.0:
|
core-util-is@~1.0.0:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue