Add latest changes from gitlab-org/gitlab@master
|
@ -1465,24 +1465,6 @@
|
||||||
- <<: *if-merge-request
|
- <<: *if-merge-request
|
||||||
changes: *static-analysis-patterns
|
changes: *static-analysis-patterns
|
||||||
|
|
||||||
.semgrep-appsec-custom-rules:rules:
|
|
||||||
rules:
|
|
||||||
- <<: *if-not-ee
|
|
||||||
when: never
|
|
||||||
- <<: *if-merge-request
|
|
||||||
changes: *code-backstage-qa-patterns
|
|
||||||
|
|
||||||
.ping-appsec-for-sast-findings:rules:
|
|
||||||
rules:
|
|
||||||
# Requiring $CUSTOM_SAST_RULES_BOT_PAT prevents the bot from running on forks or CE
|
|
||||||
# Without it the script would fail too.
|
|
||||||
- if: "$CUSTOM_SAST_RULES_BOT_PAT == null"
|
|
||||||
when: never
|
|
||||||
- <<: *if-not-ee
|
|
||||||
when: never
|
|
||||||
- <<: *if-merge-request
|
|
||||||
changes: *code-backstage-qa-patterns
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
# Vendored gems rules #
|
# Vendored gems rules #
|
||||||
#######################
|
#######################
|
||||||
|
@ -1569,6 +1551,7 @@
|
||||||
- '**/*.tsx'
|
- '**/*.tsx'
|
||||||
- '**/*.c'
|
- '**/*.c'
|
||||||
- '**/*.go'
|
- '**/*.go'
|
||||||
|
- '**/*.rb'
|
||||||
|
|
||||||
.reports:rules:secret_detection:
|
.reports:rules:secret_detection:
|
||||||
rules:
|
rules:
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
variables:
|
variables:
|
||||||
SETUP_DB: "false"
|
SETUP_DB: "false"
|
||||||
ENABLE_SPRING: "1"
|
ENABLE_SPRING: "1"
|
||||||
SKIP_LOG_INITIALIZER_CONNECTIONS: "1"
|
|
||||||
# Disable warnings in browserslist which can break on backports
|
# Disable warnings in browserslist which can break on backports
|
||||||
# https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384
|
# https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384
|
||||||
BROWSERSLIST_IGNORE_OLD_DATA: "true"
|
BROWSERSLIST_IGNORE_OLD_DATA: "true"
|
||||||
|
@ -160,39 +159,3 @@ feature-flags-usage:
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
- tmp/feature_flags/
|
- tmp/feature_flags/
|
||||||
|
|
||||||
semgrep-appsec-custom-rules:
|
|
||||||
stage: lint
|
|
||||||
extends:
|
|
||||||
- .semgrep-appsec-custom-rules:rules
|
|
||||||
image: returntocorp/semgrep
|
|
||||||
needs: []
|
|
||||||
script:
|
|
||||||
# Required to avoid a timeout https://github.com/returntocorp/semgrep/issues/5395
|
|
||||||
- git fetch origin master
|
|
||||||
# Include/exclude list isn't ideal https://github.com/returntocorp/semgrep/issues/5399
|
|
||||||
- |
|
|
||||||
semgrep ci --gitlab-sast --metrics off --config $CUSTOM_RULES_URL \
|
|
||||||
--include app --include lib --include workhorse \
|
|
||||||
--exclude '*_test.go' --exclude spec --exclude qa > gl-sast-report.json || true
|
|
||||||
variables:
|
|
||||||
CUSTOM_RULES_URL: https://gitlab.com/gitlab-com/gl-security/appsec/sast-custom-rules/-/raw/main/appsec-pings/rules.yml
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- gl-sast-report.json
|
|
||||||
reports:
|
|
||||||
sast: gl-sast-report.json
|
|
||||||
|
|
||||||
ping-appsec-for-sast-findings:
|
|
||||||
stage: lint
|
|
||||||
image: alpine:latest
|
|
||||||
extends:
|
|
||||||
- .ping-appsec-for-sast-findings:rules
|
|
||||||
variables:
|
|
||||||
# Project Access Token bot ID for /gitlab-com/gl-security/appsec/sast-custom-rules
|
|
||||||
BOT_USER_ID: 11727358
|
|
||||||
needs:
|
|
||||||
- semgrep-appsec-custom-rules
|
|
||||||
script:
|
|
||||||
- apk add jq curl
|
|
||||||
- scripts/process_custom_semgrep_results.sh
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
[semgrep]
|
||||||
|
description = 'semgrep custom rules configuration'
|
||||||
|
targetdir = "/sgrules"
|
||||||
|
validate = true
|
||||||
|
|
||||||
|
[[semgrep.passthrough]]
|
||||||
|
type = "git"
|
||||||
|
value = "https://gitlab.com/gitlab-com/gl-security/appsec/sast-custom-rules.git"
|
||||||
|
ref = "refs/heads/main"
|
||||||
|
subdir = "appsec-pings"
|
|
@ -15,10 +15,11 @@ import currentUserQuery from '~/graphql_shared/queries/current_user.query.graphq
|
||||||
import userSearchQuery from '~/graphql_shared/queries/users_search.query.graphql';
|
import userSearchQuery from '~/graphql_shared/queries/users_search.query.graphql';
|
||||||
import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
|
import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
|
||||||
import { n__, s__ } from '~/locale';
|
import { n__, s__ } from '~/locale';
|
||||||
|
import Tracking from '~/tracking';
|
||||||
import SidebarParticipant from '~/sidebar/components/assignees/sidebar_participant.vue';
|
import SidebarParticipant from '~/sidebar/components/assignees/sidebar_participant.vue';
|
||||||
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
|
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
|
||||||
import localUpdateWorkItemMutation from '../graphql/local_update_work_item.mutation.graphql';
|
import localUpdateWorkItemMutation from '../graphql/local_update_work_item.mutation.graphql';
|
||||||
import { i18n } from '../constants';
|
import { i18n, TRACKING_CATEGORY_SHOW } from '../constants';
|
||||||
|
|
||||||
function isTokenSelectorElement(el) {
|
function isTokenSelectorElement(el) {
|
||||||
return el?.classList.contains('gl-token-close') || el?.classList.contains('dropdown-item');
|
return el?.classList.contains('gl-token-close') || el?.classList.contains('dropdown-item');
|
||||||
|
@ -44,6 +45,7 @@ export default {
|
||||||
GlDropdownItem,
|
GlDropdownItem,
|
||||||
GlDropdownDivider,
|
GlDropdownDivider,
|
||||||
},
|
},
|
||||||
|
mixins: [Tracking.mixin()],
|
||||||
inject: ['fullPath'],
|
inject: ['fullPath'],
|
||||||
props: {
|
props: {
|
||||||
workItemId: {
|
workItemId: {
|
||||||
|
@ -58,6 +60,15 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
workItemType: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
canUpdate: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -95,6 +106,13 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
tracking() {
|
||||||
|
return {
|
||||||
|
category: TRACKING_CATEGORY_SHOW,
|
||||||
|
label: 'item_assignees',
|
||||||
|
property: `type_${this.workItemType}`,
|
||||||
|
};
|
||||||
|
},
|
||||||
assigneeListEmpty() {
|
assigneeListEmpty() {
|
||||||
return this.assignees.length === 0;
|
return this.assignees.length === 0;
|
||||||
},
|
},
|
||||||
|
@ -163,6 +181,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
this.track('updated_assignees');
|
||||||
},
|
},
|
||||||
handleFocus() {
|
handleFocus() {
|
||||||
this.isEditing = true;
|
this.isEditing = true;
|
||||||
|
@ -208,9 +227,11 @@ export default {
|
||||||
ref="tokenSelector"
|
ref="tokenSelector"
|
||||||
:selected-tokens="localAssignees"
|
:selected-tokens="localAssignees"
|
||||||
:container-class="containerClass"
|
:container-class="containerClass"
|
||||||
class="assignees-selector gl-flex-grow-1 gl-border gl-border-white gl-hover-border-gray-200 gl-rounded-base col-9 gl-align-self-start gl-px-0!"
|
class="assignees-selector gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0!"
|
||||||
|
:class="{ 'gl-hover-border-gray-200': canUpdate }"
|
||||||
:dropdown-items="dropdownItems"
|
:dropdown-items="dropdownItems"
|
||||||
:loading="isLoadingUsers"
|
:loading="isLoadingUsers"
|
||||||
|
:view-only="!canUpdate"
|
||||||
@input="handleAssigneesInput"
|
@input="handleAssigneesInput"
|
||||||
@text-input="debouncedSearchKeyUpdate"
|
@text-input="debouncedSearchKeyUpdate"
|
||||||
@focus="handleFocus"
|
@focus="handleFocus"
|
||||||
|
|
|
@ -216,9 +216,11 @@ export default {
|
||||||
<template v-if="workItemsMvc2Enabled">
|
<template v-if="workItemsMvc2Enabled">
|
||||||
<work-item-assignees
|
<work-item-assignees
|
||||||
v-if="workItemAssignees"
|
v-if="workItemAssignees"
|
||||||
|
:can-update="canUpdate"
|
||||||
:work-item-id="workItem.id"
|
:work-item-id="workItem.id"
|
||||||
:assignees="workItemAssignees.assignees.nodes"
|
:assignees="workItemAssignees.assignees.nodes"
|
||||||
:allows-multiple-assignees="workItemAssignees.allowsMultipleAssignees"
|
:allows-multiple-assignees="workItemAssignees.allowsMultipleAssignees"
|
||||||
|
:work-item-type="workItemType"
|
||||||
@error="error = $event"
|
@error="error = $event"
|
||||||
/>
|
/>
|
||||||
<work-item-labels
|
<work-item-labels
|
||||||
|
|
|
@ -124,8 +124,16 @@ ul.related-merge-requests > li gl-emoji {
|
||||||
|
|
||||||
.new-branch-col {
|
.new-branch-col {
|
||||||
.discussion-filter-container {
|
.discussion-filter-container {
|
||||||
&:not(:only-child) {
|
&:not(:last-child) {
|
||||||
margin-right: $gl-padding-8;
|
margin-right: $gl-spacing-scale-3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-down(xs) {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> div:not(:last-child) {
|
||||||
|
margin-bottom: $gl-spacing-scale-3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,6 +155,16 @@ ul.related-merge-requests > li gl-emoji {
|
||||||
|
|
||||||
.btn-group:not(.hidden) {
|
.btn-group:not(.hidden) {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
@include media-breakpoint-down(xs) {
|
||||||
|
.btn.btn-confirm {
|
||||||
|
@include gl-justify-content-start;
|
||||||
|
|
||||||
|
&.dropdown-toggle {
|
||||||
|
@include gl-flex-grow-0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.js-create-merge-request {
|
.js-create-merge-request {
|
||||||
|
|
|
@ -42,6 +42,11 @@ class SearchController < ApplicationController
|
||||||
@sort = params[:sort] || default_sort
|
@sort = params[:sort] || default_sort
|
||||||
|
|
||||||
@search_service = Gitlab::View::Presenter::Factory.new(search_service, current_user: current_user).fabricate!
|
@search_service = Gitlab::View::Presenter::Factory.new(search_service, current_user: current_user).fabricate!
|
||||||
|
|
||||||
|
@search_level = @search_service.level
|
||||||
|
@search_type = search_type
|
||||||
|
|
||||||
|
@global_search_duration_s = Benchmark.realtime do
|
||||||
@scope = @search_service.scope
|
@scope = @search_service.scope
|
||||||
@without_count = @search_service.without_count?
|
@without_count = @search_service.without_count?
|
||||||
@show_snippets = @search_service.show_snippets?
|
@show_snippets = @search_service.show_snippets?
|
||||||
|
@ -49,6 +54,7 @@ class SearchController < ApplicationController
|
||||||
@search_objects = @search_service.search_objects
|
@search_objects = @search_service.search_objects
|
||||||
@search_highlight = @search_service.search_highlight
|
@search_highlight = @search_service.search_highlight
|
||||||
@aggregations = @search_service.search_aggregations
|
@aggregations = @search_service.search_aggregations
|
||||||
|
end
|
||||||
|
|
||||||
increment_search_counters
|
increment_search_counters
|
||||||
end
|
end
|
||||||
|
@ -144,7 +150,9 @@ class SearchController < ApplicationController
|
||||||
payload[:metadata]['meta.search.filters.state'] = params[:state]
|
payload[:metadata]['meta.search.filters.state'] = params[:state]
|
||||||
payload[:metadata]['meta.search.force_search_results'] = params[:force_search_results]
|
payload[:metadata]['meta.search.force_search_results'] = params[:force_search_results]
|
||||||
payload[:metadata]['meta.search.project_ids'] = params[:project_ids]
|
payload[:metadata]['meta.search.project_ids'] = params[:project_ids]
|
||||||
payload[:metadata]['meta.search.search_level'] = params[:search_level]
|
payload[:metadata]['meta.search.type'] = @search_type if @search_type.present?
|
||||||
|
payload[:metadata]['meta.search.level'] = @search_level if @search_level.present?
|
||||||
|
payload[:metadata][:global_search_duration_s] = @global_search_duration_s if @global_search_duration_s.present?
|
||||||
|
|
||||||
if search_service.abuse_detected?
|
if search_service.abuse_detected?
|
||||||
payload[:metadata]['abuse.confidence'] = Gitlab::Abuse.confidence(:certain)
|
payload[:metadata]['abuse.confidence'] = Gitlab::Abuse.confidence(:certain)
|
||||||
|
@ -207,6 +215,10 @@ class SearchController < ApplicationController
|
||||||
def tracking_namespace_source
|
def tracking_namespace_source
|
||||||
search_service.project&.namespace || search_service.group
|
search_service.project&.namespace || search_service.group
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def search_type
|
||||||
|
'basic'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SearchController.prepend_mod_with('SearchController')
|
SearchController.prepend_mod_with('SearchController')
|
||||||
|
|
|
@ -5,11 +5,17 @@ module Mutations
|
||||||
module Widgetable
|
module Widgetable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
def extract_widget_params(work_item_type, attributes)
|
def extract_widget_params!(work_item_type, attributes)
|
||||||
# Get the list of widgets for the work item's type to extract only the supported attributes
|
# Get the list of widgets for the work item's type to extract only the supported attributes
|
||||||
widget_keys = work_item_type.widgets.map(&:api_symbol)
|
widget_keys = ::WorkItems::Type.available_widgets.map(&:api_symbol)
|
||||||
widget_params = attributes.extract!(*widget_keys)
|
widget_params = attributes.extract!(*widget_keys)
|
||||||
|
|
||||||
|
not_supported_keys = widget_params.keys - work_item_type.widgets.map(&:api_symbol)
|
||||||
|
if not_supported_keys.present?
|
||||||
|
raise Gitlab::Graphql::Errors::ArgumentError,
|
||||||
|
"Following widget keys are not supported by #{work_item_type.name} type: #{not_supported_keys}"
|
||||||
|
end
|
||||||
|
|
||||||
# Cannot use prepare to use `.to_h` on each input due to
|
# Cannot use prepare to use `.to_h` on each input due to
|
||||||
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87472#note_945199865
|
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87472#note_945199865
|
||||||
widget_params.transform_values { |values| values.to_h }
|
widget_params.transform_values { |values| values.to_h }
|
||||||
|
|
|
@ -43,7 +43,7 @@ module Mutations
|
||||||
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
|
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
|
||||||
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
|
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
|
||||||
type = ::WorkItems::Type.find(attributes[:work_item_type_id])
|
type = ::WorkItems::Type.find(attributes[:work_item_type_id])
|
||||||
widget_params = extract_widget_params(type, params)
|
widget_params = extract_widget_params!(type, params)
|
||||||
|
|
||||||
create_result = ::WorkItems::CreateService.new(
|
create_result = ::WorkItems::CreateService.new(
|
||||||
project: project,
|
project: project,
|
||||||
|
|
|
@ -25,7 +25,7 @@ module Mutations
|
||||||
end
|
end
|
||||||
|
|
||||||
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
|
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
|
||||||
widget_params = extract_widget_params(work_item.work_item_type, attributes)
|
widget_params = extract_widget_params!(work_item.work_item_type, attributes)
|
||||||
|
|
||||||
update_result = ::WorkItems::UpdateService.new(
|
update_result = ::WorkItems::UpdateService.new(
|
||||||
project: work_item.project,
|
project: work_item.project,
|
||||||
|
|
|
@ -14,7 +14,8 @@ module Types
|
||||||
argument :children_ids, [::Types::GlobalIDType[::WorkItem]],
|
argument :children_ids, [::Types::GlobalIDType[::WorkItem]],
|
||||||
required: false,
|
required: false,
|
||||||
description: 'Global IDs of children work items.',
|
description: 'Global IDs of children work items.',
|
||||||
prepare: ->(ids, _) { ids.map(&:model_id) }
|
loads: ::Types::WorkItemType,
|
||||||
|
as: :children
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1064,8 +1064,12 @@ module Ci
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_reports?(reports_scope)
|
def has_reports?(reports_scope)
|
||||||
|
if Feature.enabled?(:mr_show_reports_immediately, project, type: :development)
|
||||||
|
latest_report_builds(reports_scope).exists?
|
||||||
|
else
|
||||||
complete? && latest_report_builds(reports_scope).exists?
|
complete? && latest_report_builds(reports_scope).exists?
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def has_coverage_reports?
|
def has_coverage_reports?
|
||||||
pipeline_artifacts&.report_exists?(:code_coverage)
|
pipeline_artifacts&.report_exists?(:code_coverage)
|
||||||
|
|
|
@ -343,6 +343,10 @@ class Namespace < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def emails_enabled?
|
||||||
|
!emails_disabled?
|
||||||
|
end
|
||||||
|
|
||||||
def lfs_enabled?
|
def lfs_enabled?
|
||||||
# User namespace will always default to the global setting
|
# User namespace will always default to the global setting
|
||||||
Gitlab.config.lfs.enabled
|
Gitlab.config.lfs.enabled
|
||||||
|
|
|
@ -125,6 +125,10 @@ class NotificationRecipient
|
||||||
@project ? @project.emails_disabled? : @group&.emails_disabled?
|
@project ? @project.emails_disabled? : @group&.emails_disabled?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def emails_enabled?
|
||||||
|
!emails_disabled?
|
||||||
|
end
|
||||||
|
|
||||||
def read_ability
|
def read_ability
|
||||||
return if @skip_read_ability
|
return if @skip_read_ability
|
||||||
return @read_ability if instance_variable_defined?(:@read_ability)
|
return @read_ability if instance_variable_defined?(:@read_ability)
|
||||||
|
|
|
@ -1038,6 +1038,9 @@ class Project < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def emails_enabled?
|
||||||
|
!emails_disabled?
|
||||||
|
end
|
||||||
override :lfs_enabled?
|
override :lfs_enabled?
|
||||||
def lfs_enabled?
|
def lfs_enabled?
|
||||||
return namespace.lfs_enabled? if self[:lfs_enabled].nil?
|
return namespace.lfs_enabled? if self[:lfs_enabled].nil?
|
||||||
|
|
|
@ -91,6 +91,17 @@ class SearchService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def level
|
||||||
|
@level ||=
|
||||||
|
if project
|
||||||
|
'project'
|
||||||
|
elsif group
|
||||||
|
'group'
|
||||||
|
else
|
||||||
|
'global'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def page
|
def page
|
||||||
|
|
|
@ -38,12 +38,7 @@ module WorkItems
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_references
|
def extract_references
|
||||||
params[:issuable_references].map do |id|
|
params[:issuable_references]
|
||||||
::WorkItem.find(id)
|
|
||||||
rescue ActiveRecord::RecordNotFound
|
|
||||||
@errors << _("Task with ID: %{id} could not be found.") % { id: id }
|
|
||||||
next
|
|
||||||
end.compact
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Create system notes when work item's parent or children are updated
|
# TODO: Create system notes when work item's parent or children are updated
|
||||||
|
|
|
@ -12,8 +12,8 @@ module WorkItems
|
||||||
|
|
||||||
if params.key?(:parent)
|
if params.key?(:parent)
|
||||||
update_work_item_parent(params.delete(:parent))
|
update_work_item_parent(params.delete(:parent))
|
||||||
elsif params.key?(:children_ids)
|
elsif params.key?(:children)
|
||||||
update_work_item_children(params.delete(:children_ids))
|
update_work_item_children(params.delete(:children))
|
||||||
else
|
else
|
||||||
invalid_args_error
|
invalid_args_error
|
||||||
end
|
end
|
||||||
|
@ -42,9 +42,9 @@ module WorkItems
|
||||||
end
|
end
|
||||||
# rubocop: enable CodeReuse/ActiveRecord
|
# rubocop: enable CodeReuse/ActiveRecord
|
||||||
|
|
||||||
def update_work_item_children(children_ids)
|
def update_work_item_children(children)
|
||||||
::WorkItems::ParentLinks::CreateService
|
::WorkItems::ParentLinks::CreateService
|
||||||
.new(widget.work_item, current_user, { issuable_references: children_ids })
|
.new(widget.work_item, current_user, { issuable_references: children })
|
||||||
.execute
|
.execute
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ module WorkItems
|
||||||
end
|
end
|
||||||
|
|
||||||
def incompatible_args?(params)
|
def incompatible_args?(params)
|
||||||
params[:children_ids] && params[:parent]
|
params[:children] && params[:parent]
|
||||||
end
|
end
|
||||||
|
|
||||||
def feature_flag_error
|
def feature_flag_error
|
||||||
|
|
|
@ -504,19 +504,6 @@ module Gitlab
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# We know Rails closes database connections in the
|
|
||||||
# active_record.clear_active_connections initializer, so only log database
|
|
||||||
# connections opened after that.
|
|
||||||
initializer :start_logging_new_postgresql_connections, after: :finisher_hook do
|
|
||||||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.warn_on_new_connection = true
|
|
||||||
end
|
|
||||||
|
|
||||||
# It is legitimate to open database connections after initializers so stop
|
|
||||||
# logging
|
|
||||||
initializer :stop_logging_new_postgresql_connections, after: :set_routes_reloader_hook do
|
|
||||||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.warn_on_new_connection = false
|
|
||||||
end
|
|
||||||
|
|
||||||
# Add assets for variants of GitLab. They should take precedence over CE.
|
# Add assets for variants of GitLab. They should take precedence over CE.
|
||||||
# This means if multiple files exist, e.g.:
|
# This means if multiple files exist, e.g.:
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: mr_show_reports_immediately
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76612
|
||||||
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367027
|
||||||
|
milestone: '15.2'
|
||||||
|
type: development
|
||||||
|
group: group::pipeline insights
|
||||||
|
default_enabled: false
|
|
@ -1,26 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module NewConnectionLogger
|
|
||||||
extend ActiveSupport::Concern
|
|
||||||
|
|
||||||
prepended do |base|
|
|
||||||
base.class_attribute :warn_on_new_connection, default: false
|
|
||||||
end
|
|
||||||
|
|
||||||
class_methods do
|
|
||||||
def new_client(...)
|
|
||||||
if warn_on_new_connection && !ENV['SKIP_LOG_INITIALIZER_CONNECTIONS']
|
|
||||||
cleaned_caller = Gitlab::BacktraceCleaner.clean_backtrace(caller)
|
|
||||||
message = "Database connection should not be called during initializers. Read more at https://docs.gitlab.com/ee/development/rails_initializers.html#database-connections-in-initializers"
|
|
||||||
|
|
||||||
ActiveSupport::Deprecation.warn(message, cleaned_caller)
|
|
||||||
|
|
||||||
warn caller if ENV['DEBUG_INITIALIZER_CONNECTIONS']
|
|
||||||
end
|
|
||||||
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(NewConnectionLogger)
|
|
|
@ -1,6 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
Gitlab.ee do
|
Gitlab.ee do
|
||||||
|
if Gitlab::Geo.geo_database_configured?
|
||||||
|
# Make sure connects_to for geo gets called outside of config/routes.rb first
|
||||||
|
# See InitializerConnections.with_disabled_database_connections
|
||||||
|
Geo::TrackingBase
|
||||||
|
end
|
||||||
|
|
||||||
if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured?
|
if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured?
|
||||||
# The Geo::TrackingBase model does not yet use connects_to. So,
|
# The Geo::TrackingBase model does not yet use connects_to. So,
|
||||||
# this will not properly support geo: from config/databse.yml
|
# this will not properly support geo: from config/databse.yml
|
||||||
|
|
|
@ -4,6 +4,7 @@ require 'sidekiq/web'
|
||||||
require 'sidekiq/cron/web'
|
require 'sidekiq/cron/web'
|
||||||
require 'product_analytics/collector_app'
|
require 'product_analytics/collector_app'
|
||||||
|
|
||||||
|
InitializerConnections.with_disabled_database_connections do
|
||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
concern :access_requestable do
|
concern :access_requestable do
|
||||||
post :request_access, on: :collection
|
post :request_access, on: :collection
|
||||||
|
@ -337,3 +338,4 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
Gitlab::Routing.add_helpers(TimeboxesRoutingHelper)
|
Gitlab::Routing.add_helpers(TimeboxesRoutingHelper)
|
||||||
|
end
|
||||||
|
|
|
@ -22,14 +22,14 @@ GET /projects/:id/dora/metrics
|
||||||
```
|
```
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
| Attribute | Type | Required | Description |
|
||||||
|----------------------|------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|:---------------------|:-----------------|:---------|:------------|
|
||||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
|
||||||
| `metric` | string | yes | One of `deployment_frequency`, `lead_time_for_changes`, `time_to_restore_service` or `change_failure_rate`. |
|
| `metric` | string | yes | One of `deployment_frequency`, `lead_time_for_changes`, `time_to_restore_service` or `change_failure_rate`. |
|
||||||
| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
|
|
||||||
| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
|
| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
|
||||||
| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
|
|
||||||
| `environment_tier` | string | no | The [tier of the environment](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. Deprecated, please use `environment_tiers`. |
|
| `environment_tier` | string | no | The [tier of the environment](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. Deprecated, please use `environment_tiers`. |
|
||||||
| `environment_tiers` | array of strings | no | The [tiers of the environments](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
|
| `environment_tiers` | array of strings | no | The [tiers of the environments](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
|
||||||
|
| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
|
||||||
|
| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
|
||||||
|
|
||||||
Example request:
|
Example request:
|
||||||
|
|
||||||
|
@ -63,14 +63,14 @@ GET /groups/:id/dora/metrics
|
||||||
```
|
```
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
| Attribute | Type | Required | Description |
|
||||||
|---------------------|------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|:--------------------|:-----------------|:---------|:------------|
|
||||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
|
||||||
| `metric` | string | yes | One of `deployment_frequency`, `lead_time_for_changes`, `time_to_restore_service` or `change_failure_rate`. |
|
| `metric` | string | yes | One of `deployment_frequency`, `lead_time_for_changes`, `time_to_restore_service` or `change_failure_rate`. |
|
||||||
| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
|
|
||||||
| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
|
| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
|
||||||
| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
|
|
||||||
| `environment_tier` | string | no | The [tier of the environment](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. Deprecated, please use `environment_tiers`. |
|
| `environment_tier` | string | no | The [tier of the environment](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. Deprecated, please use `environment_tiers`. |
|
||||||
| `environment_tiers` | array of strings | no | The [tiers of the environments](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
|
| `environment_tiers` | array of strings | no | The [tiers of the environments](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
|
||||||
|
| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
|
||||||
|
| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
|
||||||
|
|
||||||
Example request:
|
Example request:
|
||||||
|
|
||||||
|
@ -100,8 +100,8 @@ API response has a different meaning depending on the provided `metric` query
|
||||||
parameter:
|
parameter:
|
||||||
|
|
||||||
| `metric` query parameter | Description of `value` in response |
|
| `metric` query parameter | Description of `value` in response |
|
||||||
| ------------------------ |--------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|:---------------------------|:-----------------------------------|
|
||||||
|
| `change_failure_rate` | The number of incidents divided by the number of deployments during the time period. Available only for production environment. |
|
||||||
| `deployment_frequency` | The number of successful deployments during the time period. |
|
| `deployment_frequency` | The number of successful deployments during the time period. |
|
||||||
| `lead_time_for_changes` | The median number of seconds between the merge of the merge request (MR) and the deployment of the MR's commits for all MRs deployed during the time period. |
|
| `lead_time_for_changes` | The median number of seconds between the merge of the merge request (MR) and the deployment of the MR's commits for all MRs deployed during the time period. |
|
||||||
| `time_to_restore_service` | The median number of seconds an incident was open during the time period. Available only for production environment. |
|
| `time_to_restore_service` | The median number of seconds an incident was open during the time period. Available only for production environment. |
|
||||||
| `change_failure_rate` | The number of incidents divided by the number of deployments during the time period. Available only for production environment. |
|
|
||||||
|
|
|
@ -1099,6 +1099,8 @@ that use the same cache key use the same cache, including in different pipelines
|
||||||
If not set, the default key is `default`. All jobs with the `cache` keyword but
|
If not set, the default key is `default`. All jobs with the `cache` keyword but
|
||||||
no `cache:key` share the `default` cache.
|
no `cache:key` share the `default` cache.
|
||||||
|
|
||||||
|
Must be used with `cache: path`, or nothing is cached.
|
||||||
|
|
||||||
**Keyword type**: Job keyword. You can use it only as part of a job or in the
|
**Keyword type**: Job keyword. You can use it only as part of a job or in the
|
||||||
[`default` section](#default).
|
[`default` section](#default).
|
||||||
|
|
||||||
|
@ -1263,6 +1265,8 @@ rspec:
|
||||||
|
|
||||||
Use `cache:when` to define when to save the cache, based on the status of the job.
|
Use `cache:when` to define when to save the cache, based on the status of the job.
|
||||||
|
|
||||||
|
Must be used with `cache: path`, or nothing is cached.
|
||||||
|
|
||||||
**Keyword type**: Job keyword. You can use it only as part of a job or in the
|
**Keyword type**: Job keyword. You can use it only as part of a job or in the
|
||||||
[`default` section](#default).
|
[`default` section](#default).
|
||||||
|
|
||||||
|
@ -1301,6 +1305,8 @@ Use the `pull` policy when you have many jobs executing in parallel that use the
|
||||||
This policy speeds up job execution and reduces load on the cache server. You can
|
This policy speeds up job execution and reduces load on the cache server. You can
|
||||||
use a job with the `push` policy to build the cache.
|
use a job with the `push` policy to build the cache.
|
||||||
|
|
||||||
|
Must be used with `cache: path`, or nothing is cached.
|
||||||
|
|
||||||
**Keyword type**: Job keyword. You can use it only as part of a job or in the
|
**Keyword type**: Job keyword. You can use it only as part of a job or in the
|
||||||
[`default` section](#default).
|
[`default` section](#default).
|
||||||
|
|
||||||
|
|
|
@ -289,9 +289,32 @@ Please read [versioning](#versioning) section for introducing breaking change sa
|
||||||
|
|
||||||
## Versioning
|
## Versioning
|
||||||
|
|
||||||
Versioning allows you to introduce a new template without modifying the existing
|
To introduce a breaking change without affecting the existing projects that depend on
|
||||||
one. This process is useful when we need to introduce a breaking change,
|
the current template, use [stable](#stable-version) and [latest](#latest-version) versioning.
|
||||||
but don't want to affect the existing projects that depends on the current template.
|
|
||||||
|
Stable templates usually only receive breaking changes in major version releases, while
|
||||||
|
latest templates can receive breaking changes in any release. In major release milestones,
|
||||||
|
the latest template is made the new stable template (and the latest template might be deleted).
|
||||||
|
|
||||||
|
Adding a latest template is safe, but comes with a maintenance burden:
|
||||||
|
|
||||||
|
- GitLab has to choose a DRI to overwrite the stable template with the contents of the
|
||||||
|
latest template at the next major release of GitLab. The DRI is responsible for
|
||||||
|
supporting users who have trouble with the change.
|
||||||
|
- When we make a new non-breaking change, both the stable and latest templates must be updated
|
||||||
|
to match, as must as possible.
|
||||||
|
- A latest template could remain for longer than planned because many users could
|
||||||
|
directly depend on it continuing to exist.
|
||||||
|
|
||||||
|
Before adding a new latest template, see if the change can be made to the stable
|
||||||
|
template instead, even if it's a breaking change. If the template is intended for copy-paste
|
||||||
|
usage only, it might be possible to directly change the stable version. Before changing
|
||||||
|
the stable template with a breaking change in a minor milestone, make sure:
|
||||||
|
|
||||||
|
- It's a [pipeline template](#template-types) and it has a [code comment](#explain-requirements-and-expectations)
|
||||||
|
explaining that it's not designed to be used with the `includes`.
|
||||||
|
- The [CI/CD template usage metrics](#add-metrics) doesn't show any usage. If the metrics
|
||||||
|
show zero usage for the template, the template is not actively being used with `include`.
|
||||||
|
|
||||||
### Stable version
|
### Stable version
|
||||||
|
|
||||||
|
@ -393,7 +416,9 @@ is updated in a major version GitLab release.
|
||||||
|
|
||||||
### Add metrics
|
### Add metrics
|
||||||
|
|
||||||
Every CI/CD template must also have metrics defined to track their use. The CI/CD template monthly usage report can be found in [Sisense (GitLab team members only)](https://app.periscopedata.com/app/gitlab/785953/Pipeline-Authoring-Dashboard?widget=14910475&udv=0).
|
Every CI/CD template must also have metrics defined to track their use. The CI/CD template monthly usage report
|
||||||
|
can be found in [Sisense (GitLab team members only)](https://app.periscopedata.com/app/gitlab/785953/Pipeline-Authoring-Dashboard?widget=13440051&udv=0).
|
||||||
|
Double click a template to see the graph for that single template.
|
||||||
|
|
||||||
To add a metric definition for a new template:
|
To add a metric definition for a new template:
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,18 @@ query) from an initializer means that tasks like `db:drop`, and
|
||||||
`db:test:prepare` will fail because an active session prevents the database from
|
`db:test:prepare` will fail because an active session prevents the database from
|
||||||
being dropped.
|
being dropped.
|
||||||
|
|
||||||
To help detect when database connections are opened from initializers, we now
|
To prevent this, we stop database connections from being opened during
|
||||||
warn in `STDERR`. For example:
|
routes loading. Doing will result in an error:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
DEPRECATION WARNING: Database connection should not be called during initializers (called from block in <module:HasVariable> at app/models/concerns/ci/has_variable.rb:22)
|
RuntimeError:
|
||||||
|
Database connection should not be called during initializers.
|
||||||
|
# ./config/initializers/00_connection_logger.rb:15:in `new_client'
|
||||||
|
# ./lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write'
|
||||||
|
# ./lib/gitlab/database/load_balancing/load_balancer.rb:184:in `retry_with_backoff'
|
||||||
|
# ./lib/gitlab/database/load_balancing/load_balancer.rb:111:in `read_write'
|
||||||
|
# ./lib/gitlab/database/load_balancing/connection_proxy.rb:119:in `write_using_load_balancer'
|
||||||
|
# ./lib/gitlab/database/load_balancing/connection_proxy.rb:89:in `method_missing'
|
||||||
|
# ./config/routes.rb:10:in `block in <main>'
|
||||||
|
# ./config/routes.rb:9:in `<main>'
|
||||||
```
|
```
|
||||||
|
|
||||||
If you wish to print out the full backtrace, set the
|
|
||||||
`DEBUG_INITIALIZER_CONNECTIONS` environment variable.
|
|
||||||
|
|
Before Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 11 KiB |
|
@ -152,9 +152,9 @@ become eligible approvers in the project. To enable this merge request approval
|
||||||
|
|
||||||
1. Go to your project and select **Settings > General**.
|
1. Go to your project and select **Settings > General**.
|
||||||
1. Expand **Merge request (MR) approvals**.
|
1. Expand **Merge request (MR) approvals**.
|
||||||
1. Locate **Eligible users** and select the number of approvals required:
|
1. Locate **All eligible users** and select the number of approvals required:
|
||||||
|
|
||||||
![MR approvals by Code Owners](img/mr_approvals_by_code_owners_v12_7.png)
|
![MR approvals by Code Owners](img/mr_approvals_by_code_owners_v15_2.png)
|
||||||
|
|
||||||
You can also
|
You can also
|
||||||
[require code owner approval](../../protected_branches.md#require-code-owner-approval-on-a-protected-branch)
|
[require code owner approval](../../protected_branches.md#require-code-owner-approval-on-a-protected-branch)
|
||||||
|
|
|
@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
||||||
|
|
||||||
[Burndown](#burndown-charts) and [burnup](#burnup-charts) charts show the progress of completing a milestone.
|
[Burndown](#burndown-charts) and [burnup](#burnup-charts) charts show the progress of completing a milestone.
|
||||||
|
|
||||||
![burndown and burnup chart](img/burndown_and_burnup_charts_v15_1.png)
|
![burndown and burnup chart](img/burndown_and_burnup_charts_v15_3.png)
|
||||||
|
|
||||||
## Burndown charts
|
## Burndown charts
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
||||||
|
|
||||||
Burndown charts show the number of issues over the course of a milestone.
|
Burndown charts show the number of issues over the course of a milestone.
|
||||||
|
|
||||||
![burndown chart](img/burndown_chart_v15_1.png)
|
![burndown chart](img/burndown_chart_v15_3.png)
|
||||||
|
|
||||||
At a glance, you see the current state for the completion a given milestone.
|
At a glance, you see the current state for the completion a given milestone.
|
||||||
Without them, you would have to organize the data from the milestone and plot it
|
Without them, you would have to organize the data from the milestone and plot it
|
||||||
|
@ -106,7 +106,7 @@ Reopened issues are considered as having been opened on the day after they were
|
||||||
|
|
||||||
Burnup charts show the assigned and completed work for a milestone.
|
Burnup charts show the assigned and completed work for a milestone.
|
||||||
|
|
||||||
![burnup chart](img/burnup_chart_v15_1.png)
|
![burnup chart](img/burnup_chart_v15_3.png)
|
||||||
|
|
||||||
To view a project's burnup chart:
|
To view a project's burnup chart:
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 26 KiB |
|
@ -196,7 +196,7 @@ There are also tabs below these that show the following:
|
||||||
The milestone view contains a [burndown and burnup chart](burndown_and_burnup_charts.md),
|
The milestone view contains a [burndown and burnup chart](burndown_and_burnup_charts.md),
|
||||||
showing the progress of completing a milestone.
|
showing the progress of completing a milestone.
|
||||||
|
|
||||||
![burndown chart](img/burndown_and_burnup_charts_v15_1.png)
|
![burndown chart](img/burndown_and_burnup_charts_v15_3.png)
|
||||||
|
|
||||||
### Milestone sidebar
|
### Milestone sidebar
|
||||||
|
|
||||||
|
|
|
@ -1284,3 +1284,5 @@ module API
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
API::Users.prepend_mod
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
|
||||||
# This specific template is located at:
|
|
||||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Chef.gitlab-ci.yml
|
|
||||||
|
|
||||||
# This template uses Test Kitchen with the kitchen-dokken driver to
|
# This template uses Test Kitchen with the kitchen-dokken driver to
|
||||||
# perform functional testing. Doing so requires that your runner be a
|
# perform functional testing. Doing so requires that your runner be a
|
||||||
# Docker runner configured for privileged mode. Please see
|
# Docker runner configured for privileged mode. Please see
|
||||||
# https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode
|
# https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode
|
||||||
# for help configuring your runner properly, or, if you want to switch
|
# for help configuring your runner properly, or, if you want to switch
|
||||||
# to a different driver, see http://kitchen.ci/docs/drivers
|
# to a different driver, see http://kitchen.ci/docs/drivers
|
||||||
|
#
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
|
# This specific template is located at:
|
||||||
|
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Chef.gitlab-ci.yml
|
||||||
|
|
||||||
image: "chef/chefdk"
|
image: "chef/chefdk"
|
||||||
services:
|
services:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
|
||||||
# This specific template is located at:
|
|
||||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
|
|
||||||
|
|
||||||
# This is a sample GitLab CI/CD configuration file that should run without any modifications.
|
# This is a sample GitLab CI/CD configuration file that should run without any modifications.
|
||||||
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
|
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
|
||||||
# it uses echo commands to simulate the pipeline execution.
|
# it uses echo commands to simulate the pipeline execution.
|
||||||
|
@ -11,6 +6,14 @@
|
||||||
# Stages run in sequential order, but jobs within stages run in parallel.
|
# Stages run in sequential order, but jobs within stages run in parallel.
|
||||||
#
|
#
|
||||||
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
|
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
|
||||||
|
#
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
|
# This specific template is located at:
|
||||||
|
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
|
||||||
|
|
||||||
stages: # List of stages for jobs, and their order of execution
|
stages: # List of stages for jobs, and their order of execution
|
||||||
- build
|
- build
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
|
||||||
# This specific template is located at:
|
|
||||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
|
|
||||||
|
|
||||||
# This template uses the java:8 docker image because there isn't any
|
# This template uses the java:8 docker image because there isn't any
|
||||||
# official Grails image at this moment
|
# official Grails image at this moment
|
||||||
#
|
#
|
||||||
|
@ -12,6 +7,14 @@
|
||||||
# Feel free to change GRAILS_VERSION version with your project version (3.0.1, 3.1.1,...)
|
# Feel free to change GRAILS_VERSION version with your project version (3.0.1, 3.1.1,...)
|
||||||
# Feel free to change GRADLE_VERSION version with your gradle project version (2.13, 2.14,...)
|
# Feel free to change GRADLE_VERSION version with your gradle project version (2.13, 2.14,...)
|
||||||
# If you use Angular profile, this yml it's prepared to work with it
|
# If you use Angular profile, this yml it's prepared to work with it
|
||||||
|
#
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
|
# This specific template is located at:
|
||||||
|
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
|
||||||
|
|
||||||
image: java:8
|
image: java:8
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
|
||||||
# This specific template is located at:
|
|
||||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Julia.gitlab-ci.yml
|
|
||||||
|
|
||||||
# This is an example .gitlab-ci.yml file to test (and optionally report the coverage
|
# This is an example .gitlab-ci.yml file to test (and optionally report the coverage
|
||||||
# results of) your [Julia][1] packages. Please refer to the [documentation][2]
|
# results of) your [Julia][1] packages. Please refer to the [documentation][2]
|
||||||
# for more information about package development in Julia.
|
# for more information about package development in Julia.
|
||||||
|
@ -12,6 +7,14 @@
|
||||||
#
|
#
|
||||||
# [1]: http://julialang.org/
|
# [1]: http://julialang.org/
|
||||||
# [2]: https://docs.julialang.org/en/v1/manual/documentation/index.html
|
# [2]: https://docs.julialang.org/en/v1/manual/documentation/index.html
|
||||||
|
#
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
|
# This specific template is located at:
|
||||||
|
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Julia.gitlab-ci.yml
|
||||||
|
|
||||||
# Below is the template to run your tests in Julia
|
# Below is the template to run your tests in Julia
|
||||||
.test_template: &test_definition
|
.test_template: &test_definition
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
|
||||||
# This specific template is located at:
|
|
||||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Mono.gitlab-ci.yml
|
|
||||||
|
|
||||||
# This is a simple gitlab continuous integration template (compatible with the shared runner provided on gitlab.com)
|
# This is a simple gitlab continuous integration template (compatible with the shared runner provided on gitlab.com)
|
||||||
# using the official mono docker image to build a visual studio project.
|
# using the official mono docker image to build a visual studio project.
|
||||||
#
|
#
|
||||||
|
@ -15,6 +10,14 @@
|
||||||
#
|
#
|
||||||
# Please find the full example project here:
|
# Please find the full example project here:
|
||||||
# https://gitlab.com/tobiaskoch/gitlab-ci-example-mono
|
# https://gitlab.com/tobiaskoch/gitlab-ci-example-mono
|
||||||
|
#
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
|
# This specific template is located at:
|
||||||
|
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Mono.gitlab-ci.yml
|
||||||
|
|
||||||
# see https://hub.docker.com/_/mono/
|
# see https://hub.docker.com/_/mono/
|
||||||
image: mono:latest
|
image: mono:latest
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
#
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
# This specific template is located at:
|
# This specific template is located at:
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
# You need to have the network drive mapped as Local System user for gitlab-runner service to see it
|
# You need to have the network drive mapped as Local System user for gitlab-runner service to see it
|
||||||
# The best way to persist the mapping is via a scheduled task
|
# The best way to persist the mapping is via a scheduled task
|
||||||
# running the following batch command: net use P: \\x.x.x.x\Projects /u:your_user your_pass /persistent:yes
|
# running the following batch command: net use P: \\x.x.x.x\Projects /u:your_user your_pass /persistent:yes
|
||||||
|
#
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
|
||||||
# place project specific paths in variables to make the rest of the script more generic
|
# place project specific paths in variables to make the rest of the script more generic
|
||||||
variables:
|
variables:
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
|
||||||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
|
||||||
# This specific template is located at:
|
|
||||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml
|
|
||||||
|
|
||||||
# This is a very simple template that mainly relies on FastLane to build and distribute your app.
|
# This is a very simple template that mainly relies on FastLane to build and distribute your app.
|
||||||
# Read more about how to use this template on the blog post https://about.gitlab.com/2019/03/06/ios-publishing-with-gitlab-and-fastlane/
|
# Read more about how to use this template on the blog post https://about.gitlab.com/2019/03/06/ios-publishing-with-gitlab-and-fastlane/
|
||||||
# You will also need fastlane and signing configuration for this to work, along with a MacOS runner.
|
# You will also need fastlane and signing configuration for this to work, along with a MacOS runner.
|
||||||
|
@ -15,6 +10,14 @@
|
||||||
# https://docs.gitlab.com/runner/security/#usage-of-shell-executor for additional
|
# https://docs.gitlab.com/runner/security/#usage-of-shell-executor for additional
|
||||||
# detail on what to keep in mind in this scenario.
|
# detail on what to keep in mind in this scenario.
|
||||||
|
|
||||||
|
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
|
||||||
|
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
|
||||||
|
|
||||||
|
# To contribute improvements to CI/CD templates, please follow the Development guide at:
|
||||||
|
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||||
|
# This specific template is located at:
|
||||||
|
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- test
|
- test
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module InitializerConnections
|
||||||
|
# Prevents any database connections within the block
|
||||||
|
# by using an empty connection handler
|
||||||
|
# rubocop:disable Database/MultipleDatabases
|
||||||
|
def self.with_disabled_database_connections
|
||||||
|
return yield if Gitlab::Utils.to_boolean(ENV['SKIP_RAISE_ON_INITIALIZE_CONNECTIONS'])
|
||||||
|
|
||||||
|
original_handler = ActiveRecord::Base.connection_handler
|
||||||
|
|
||||||
|
dummy_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
||||||
|
ActiveRecord::Base.connection_handler = dummy_handler
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
if dummy_handler&.connection_pool_names&.present?
|
||||||
|
raise "Unxpected connection_pools (#{dummy_handler.connection_pool_names}) ! Call `connects_to` before this block"
|
||||||
|
end
|
||||||
|
rescue ActiveRecord::ConnectionNotEstablished
|
||||||
|
message = "Database connection should not be called during initializers. Read more at https://docs.gitlab.com/ee/development/rails_initializers.html#database-connections-in-initializers"
|
||||||
|
|
||||||
|
raise message
|
||||||
|
ensure
|
||||||
|
ActiveRecord::Base.connection_handler = original_handler
|
||||||
|
dummy_handler&.clear_all_connections!
|
||||||
|
end
|
||||||
|
# rubocop:enable Database/MultipleDatabases
|
||||||
|
end
|
|
@ -3758,6 +3758,9 @@ msgstr ""
|
||||||
msgid "All changes are committed"
|
msgid "All changes are committed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "All eligible users"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "All email addresses will be used to identify your commits."
|
msgid "All email addresses will be used to identify your commits."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -14125,9 +14128,6 @@ msgstr ""
|
||||||
msgid "Elastic|None. Select projects to index."
|
msgid "Elastic|None. Select projects to index."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Eligible users"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -21916,6 +21916,9 @@ msgstr ""
|
||||||
msgid "Iterations|All"
|
msgid "Iterations|All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Iterations|Automatic scheduling"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Iterations|Cadence configuration is invalid."
|
msgid "Iterations|Cadence configuration is invalid."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -21937,6 +21940,9 @@ msgstr ""
|
||||||
msgid "Iterations|Create iteration"
|
msgid "Iterations|Create iteration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Iterations|Create iterations automatically on a regular schedule."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Iterations|Delete cadence"
|
msgid "Iterations|Delete cadence"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -21967,6 +21973,9 @@ msgstr ""
|
||||||
msgid "Iterations|Edit iteration cadence"
|
msgid "Iterations|Edit iteration cadence"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Iterations|Enable roll over"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Iterations|Error loading iteration cadences."
|
msgid "Iterations|Error loading iteration cadences."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -21979,6 +21988,9 @@ msgstr ""
|
||||||
msgid "Iterations|Iterations are a way to track issues over a period of time, allowing teams to also track velocity and volatility metrics."
|
msgid "Iterations|Iterations are a way to track issues over a period of time, allowing teams to also track velocity and volatility metrics."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Iterations|Iterations are scheduled to start on %{weekday}s."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Iterations|Learn more about automatic scheduling"
|
msgid "Iterations|Learn more about automatic scheduling"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -22006,9 +22018,6 @@ msgstr ""
|
||||||
msgid "Iterations|No iterations in cadence."
|
msgid "Iterations|No iterations in cadence."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Iterations|No one can change this date after the cadence has begun."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Iterations|No open iterations."
|
msgid "Iterations|No open iterations."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -23225,7 +23234,7 @@ msgstr ""
|
||||||
msgid "License Compliance"
|
msgid "License Compliance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "License Compliance| Used by"
|
msgid "License Compliance| Used by %{dependencies}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "License compliance"
|
msgid "License compliance"
|
||||||
|
@ -38225,9 +38234,6 @@ msgstr ""
|
||||||
msgid "Task list"
|
msgid "Task list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Task with ID: %{id} could not be found."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "TasksToBeDone|Create/import code into a project (repository)"
|
msgid "TasksToBeDone|Create/import code into a project (repository)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -42054,6 +42060,11 @@ msgstr ""
|
||||||
msgid "Used"
|
msgid "Used"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Used by %d package"
|
||||||
|
msgid_plural "Used by %d packages"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
msgid "Used by members to sign in to your group in GitLab"
|
msgid "Used by members to sign in to your group in GitLab"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ echo "Processing vuln report"
|
||||||
# Preparing the message for the comment that will be posted by the bot
|
# Preparing the message for the comment that will be posted by the bot
|
||||||
# Empty string if there are no findings
|
# Empty string if there are no findings
|
||||||
jq -crM '.vulnerabilities |
|
jq -crM '.vulnerabilities |
|
||||||
map( select( .identifiers[0].name | test( "glappsec_" ) ) |
|
map( select( .identifiersprocess_custom_semgrep_results[0].name | test( "glappsec_" ) ) |
|
||||||
"- `" + .location.file + "` line " + ( .location.start_line | tostring ) +
|
"- `" + .location.file + "` line " + ( .location.start_line | tostring ) +
|
||||||
(
|
(
|
||||||
if .location.start_line = .location.end_line then ""
|
if .location.start_line = .location.end_line then ""
|
||||||
|
|
|
@ -408,10 +408,11 @@ RSpec.describe SearchController do
|
||||||
expect(payload[:metadata]['meta.search.filters.confidential']).to eq('true')
|
expect(payload[:metadata]['meta.search.filters.confidential']).to eq('true')
|
||||||
expect(payload[:metadata]['meta.search.filters.state']).to eq('true')
|
expect(payload[:metadata]['meta.search.filters.state']).to eq('true')
|
||||||
expect(payload[:metadata]['meta.search.project_ids']).to eq(%w(456 789))
|
expect(payload[:metadata]['meta.search.project_ids']).to eq(%w(456 789))
|
||||||
expect(payload[:metadata]['meta.search.search_level']).to eq('multi-project')
|
expect(payload[:metadata]['meta.search.type']).to eq('basic')
|
||||||
|
expect(payload[:metadata]['meta.search.level']).to eq('global')
|
||||||
end
|
end
|
||||||
|
|
||||||
get :show, params: { scope: 'issues', search: 'hello world', group_id: '123', project_id: '456', project_ids: %w(456 789), search_level: 'multi-project', confidential: true, state: true, force_search_results: true }
|
get :show, params: { scope: 'issues', search: 'hello world', group_id: '123', project_id: '456', project_ids: %w(456 789), confidential: true, state: true, force_search_results: true }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'appends the default scope in meta.search.scope' do
|
it 'appends the default scope in meta.search.scope' do
|
||||||
|
@ -423,6 +424,16 @@ RSpec.describe SearchController do
|
||||||
|
|
||||||
get :show, params: { search: 'hello world', group_id: '123', project_id: '456' }
|
get :show, params: { search: 'hello world', group_id: '123', project_id: '456' }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'appends the search time based on the search' do
|
||||||
|
expect(controller).to receive(:append_info_to_payload).and_wrap_original do |method, payload|
|
||||||
|
method.call(payload)
|
||||||
|
|
||||||
|
expect(payload[:metadata][:global_search_duration_s]).to be_a_kind_of(Numeric)
|
||||||
|
end
|
||||||
|
|
||||||
|
get :show, params: { search: 'hello world', group_id: '123', project_id: '456' }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'abusive searches', :aggregate_failures do
|
context 'abusive searches', :aggregate_failures do
|
||||||
|
|
|
@ -24,23 +24,21 @@ RSpec.describe 'Merge request > User sees versions', :js do
|
||||||
visit diffs_project_merge_request_path(project, merge_request, params)
|
visit diffs_project_merge_request_path(project, merge_request, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'allows commenting' do |file_id:, line_code:, comment:|
|
shared_examples 'allows commenting' do |file_name:, line_text:, comment:|
|
||||||
it do
|
it do
|
||||||
diff_file_selector = ".diff-file[id='#{file_id}']"
|
page.within find_by_scrolling('.diff-file', text: file_name) do
|
||||||
line_code = "#{file_id}_#{line_code}"
|
line_code_element = page.find('.diff-grid-row', text: line_text)
|
||||||
|
|
||||||
page.within find_by_scrolling(diff_file_selector) do
|
|
||||||
line_code_element = first("[id='#{line_code}']")
|
|
||||||
# scrolling to element's bottom is required in order for .hover action to work
|
# scrolling to element's bottom is required in order for .hover action to work
|
||||||
# otherwise, the element could be hidden underneath a sticky header
|
# otherwise, the element could be hidden underneath a sticky header
|
||||||
scroll_to_elements_bottom(line_code_element)
|
scroll_to_elements_bottom(line_code_element)
|
||||||
line_code_element.hover
|
line_code_element.hover
|
||||||
first("[id='#{line_code}'] [role='button']").click
|
page.find("[data-testid='left-comment-button']", visible: true).click
|
||||||
|
|
||||||
page.within("form[data-line-code='#{line_code}']") do
|
expect(page).to have_selector("form", count: 1)
|
||||||
fill_in "note[note]", with: comment
|
|
||||||
|
fill_in("note[note]", with: comment)
|
||||||
click_button('Add comment now')
|
click_button('Add comment now')
|
||||||
end
|
|
||||||
|
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
|
@ -59,8 +57,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'allows commenting',
|
it_behaves_like 'allows commenting',
|
||||||
file_id: '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44',
|
file_name: '.gitmodules',
|
||||||
line_code: '1_1',
|
line_text: '[submodule "six"]',
|
||||||
comment: 'Typo, please fix.'
|
comment: 'Typo, please fix.'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -107,8 +105,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'allows commenting',
|
it_behaves_like 'allows commenting',
|
||||||
file_id: '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44',
|
file_name: '.gitmodules',
|
||||||
line_code: '2_2',
|
line_text: 'path = six',
|
||||||
comment: 'Typo, please fix.'
|
comment: 'Typo, please fix.'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -174,8 +172,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'allows commenting',
|
it_behaves_like 'allows commenting',
|
||||||
file_id: '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44',
|
file_name: '.gitmodules',
|
||||||
line_code: '4_4',
|
line_text: '[submodule "gitlab-shell"]',
|
||||||
comment: 'Typo, please fix.'
|
comment: 'Typo, please fix.'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -241,8 +239,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'allows commenting',
|
it_behaves_like 'allows commenting',
|
||||||
file_id: '2f6fcd96b88b36ce98c38da085c795a27d92a3dd',
|
file_name: 'files/ruby/popen.rb',
|
||||||
line_code: '6_6',
|
line_text: 'RuntimeError',
|
||||||
comment: 'Typo, please fix.'
|
comment: 'Typo, please fix.'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,13 +4,14 @@ import VueApollo from 'vue-apollo';
|
||||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||||
import waitForPromises from 'helpers/wait_for_promises';
|
import waitForPromises from 'helpers/wait_for_promises';
|
||||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||||
|
import { mockTracking } from 'helpers/tracking_helper';
|
||||||
import { stripTypenames } from 'helpers/graphql_helpers';
|
import { stripTypenames } from 'helpers/graphql_helpers';
|
||||||
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
|
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
|
||||||
import userSearchQuery from '~/graphql_shared/queries/users_search.query.graphql';
|
import userSearchQuery from '~/graphql_shared/queries/users_search.query.graphql';
|
||||||
import currentUserQuery from '~/graphql_shared/queries/current_user.query.graphql';
|
import currentUserQuery from '~/graphql_shared/queries/current_user.query.graphql';
|
||||||
import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
|
import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
|
||||||
import WorkItemAssignees from '~/work_items/components/work_item_assignees.vue';
|
import WorkItemAssignees from '~/work_items/components/work_item_assignees.vue';
|
||||||
import { i18n } from '~/work_items/constants';
|
import { i18n, TASK_TYPE_NAME, TRACKING_CATEGORY_SHOW } from '~/work_items/constants';
|
||||||
import { temporaryConfig, resolvers } from '~/work_items/graphql/provider';
|
import { temporaryConfig, resolvers } from '~/work_items/graphql/provider';
|
||||||
import {
|
import {
|
||||||
projectMembersResponseWithCurrentUser,
|
projectMembersResponseWithCurrentUser,
|
||||||
|
@ -50,6 +51,7 @@ describe('WorkItemAssignees component', () => {
|
||||||
searchQueryHandler = successSearchQueryHandler,
|
searchQueryHandler = successSearchQueryHandler,
|
||||||
currentUserQueryHandler = successCurrentUserQueryHandler,
|
currentUserQueryHandler = successCurrentUserQueryHandler,
|
||||||
allowsMultipleAssignees = true,
|
allowsMultipleAssignees = true,
|
||||||
|
canUpdate = true,
|
||||||
} = {}) => {
|
} = {}) => {
|
||||||
const apolloProvider = createMockApollo(
|
const apolloProvider = createMockApollo(
|
||||||
[
|
[
|
||||||
|
@ -78,6 +80,8 @@ describe('WorkItemAssignees component', () => {
|
||||||
assignees,
|
assignees,
|
||||||
workItemId,
|
workItemId,
|
||||||
allowsMultipleAssignees,
|
allowsMultipleAssignees,
|
||||||
|
workItemType: TASK_TYPE_NAME,
|
||||||
|
canUpdate,
|
||||||
},
|
},
|
||||||
attachTo: document.body,
|
attachTo: document.body,
|
||||||
apolloProvider,
|
apolloProvider,
|
||||||
|
@ -125,6 +129,18 @@ describe('WorkItemAssignees component', () => {
|
||||||
expect(findTokenSelector().props('selectedTokens')).toEqual([mockAssignees[0]]);
|
expect(findTokenSelector().props('selectedTokens')).toEqual([mockAssignees[0]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('passes `false` to `viewOnly` token selector prop if user can update assignees', () => {
|
||||||
|
createComponent();
|
||||||
|
|
||||||
|
expect(findTokenSelector().props('viewOnly')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes `true` to `viewOnly` token selector prop if user can not update assignees', () => {
|
||||||
|
createComponent({ canUpdate: false });
|
||||||
|
|
||||||
|
expect(findTokenSelector().props('viewOnly')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
describe('when searching for users', () => {
|
describe('when searching for users', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent();
|
createComponent();
|
||||||
|
@ -357,4 +373,36 @@ describe('WorkItemAssignees component', () => {
|
||||||
expect(findTokenSelector().props('containerClass')).toBe('gl-shadow-none!');
|
expect(findTokenSelector().props('containerClass')).toBe('gl-shadow-none!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('tracking', () => {
|
||||||
|
let trackingSpy;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
createComponent();
|
||||||
|
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
trackingSpy = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not track updating assignees until token selector blur event', async () => {
|
||||||
|
findTokenSelector().vm.$emit('input', [mockAssignees[0]]);
|
||||||
|
await waitForPromises();
|
||||||
|
|
||||||
|
expect(trackingSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tracks editing the assignees on token selector blur', async () => {
|
||||||
|
findTokenSelector().vm.$emit('input', [mockAssignees[0]]);
|
||||||
|
findTokenSelector().vm.$emit('blur', new FocusEvent({ relatedTarget: null }));
|
||||||
|
await waitForPromises();
|
||||||
|
|
||||||
|
expect(trackingSpy).toHaveBeenCalledWith(TRACKING_CATEGORY_SHOW, 'updated_assignees', {
|
||||||
|
category: TRACKING_CATEGORY_SHOW,
|
||||||
|
label: 'item_assignees',
|
||||||
|
property: 'type_Task',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
RSpec.describe ActiveRecord::ConnectionAdapters::PostgreSQLAdapter do # rubocop:disable RSpec/FilePath
|
|
||||||
before do
|
|
||||||
allow(PG).to receive(:connect)
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:conn_params) { PG::Connection.conndefaults_hash }
|
|
||||||
|
|
||||||
context 'when warn_on_new_connection is enabled' do
|
|
||||||
before do
|
|
||||||
described_class.warn_on_new_connection = true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'warns on new connection' do
|
|
||||||
expect(ActiveSupport::Deprecation)
|
|
||||||
.to receive(:warn).with(/Database connection should not be called during initializers/, anything)
|
|
||||||
|
|
||||||
expect(PG).to receive(:connect).with(conn_params)
|
|
||||||
|
|
||||||
described_class.new_client(conn_params)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when warn_on_new_connection is disabled' do
|
|
||||||
before do
|
|
||||||
described_class.warn_on_new_connection = false
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not warn on new connection' do
|
|
||||||
expect(ActiveSupport::Deprecation).not_to receive(:warn)
|
|
||||||
expect(PG).to receive(:connect).with(conn_params)
|
|
||||||
|
|
||||||
described_class.new_client(conn_params)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe InitializerConnections do
|
||||||
|
describe '.with_disabled_database_connections', :reestablished_active_record_base do
|
||||||
|
def block_with_database_call
|
||||||
|
described_class.with_disabled_database_connections do
|
||||||
|
Project.first
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def block_with_error
|
||||||
|
described_class.with_disabled_database_connections do
|
||||||
|
raise "oops, an error"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'prevents any database connection within the block' do
|
||||||
|
expect { block_with_database_call }.to raise_error(/Database connection should not be called during initializer/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not prevent database connection if SKIP_RAISE_ON_INITIALIZE_CONNECTIONS is set' do
|
||||||
|
stub_env('SKIP_RAISE_ON_INITIALIZE_CONNECTIONS', '1')
|
||||||
|
|
||||||
|
expect { block_with_database_call }.not_to raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'prevents any database connection if SKIP_RAISE_ON_INITIALIZE_CONNECTIONS is false' do
|
||||||
|
stub_env('SKIP_RAISE_ON_INITIALIZE_CONNECTIONS', 'false')
|
||||||
|
|
||||||
|
expect { block_with_database_call }.to raise_error(/Database connection should not be called during initializer/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'restores original connection handler' do
|
||||||
|
# rubocop:disable Database/MultipleDatabases
|
||||||
|
original_handler = ActiveRecord::Base.connection_handler
|
||||||
|
|
||||||
|
expect { block_with_database_call }.to raise_error(/Database connection should not be called during initializer/)
|
||||||
|
|
||||||
|
expect(ActiveRecord::Base.connection_handler).to eq(original_handler)
|
||||||
|
# rubocop:enabled Database/MultipleDatabases
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'restores original connection handler even there is an error' do
|
||||||
|
# rubocop:disable Database/MultipleDatabases
|
||||||
|
original_handler = ActiveRecord::Base.connection_handler
|
||||||
|
|
||||||
|
expect { block_with_error }.to raise_error(/an error/)
|
||||||
|
|
||||||
|
expect(ActiveRecord::Base.connection_handler).to eq(original_handler)
|
||||||
|
# rubocop:enabled Database/MultipleDatabases
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'raises if any new connection_pools are established in the block' do
|
||||||
|
expect do
|
||||||
|
described_class.with_disabled_database_connections do
|
||||||
|
ApplicationRecord.connects_to database: { writing: :main, reading: :main }
|
||||||
|
end
|
||||||
|
end.to raise_error(/Unxpected connection_pools/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -3953,7 +3953,21 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
||||||
context 'when pipeline status is running' do
|
context 'when pipeline status is running' do
|
||||||
let(:pipeline) { create(:ci_pipeline, :running) }
|
let(:pipeline) { create(:ci_pipeline, :running) }
|
||||||
|
|
||||||
it { is_expected.to be_falsey }
|
context 'with mr_show_reports_immediately flag enabled' do
|
||||||
|
before do
|
||||||
|
stub_feature_flags(mr_show_reports_immediately: project)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject).to be_truthy }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with mr_show_reports_immediately flag disabled' do
|
||||||
|
before do
|
||||||
|
stub_feature_flags(mr_show_reports_immediately: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject).to be_falsey }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when pipeline status is success' do
|
context 'when pipeline status is success' do
|
||||||
|
@ -4027,8 +4041,22 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
||||||
context 'when pipeline status is running' do
|
context 'when pipeline status is running' do
|
||||||
let(:pipeline) { create(:ci_pipeline, :running) }
|
let(:pipeline) { create(:ci_pipeline, :running) }
|
||||||
|
|
||||||
|
context 'with mr_show_reports_immediately flag enabled' do
|
||||||
|
before do
|
||||||
|
stub_feature_flags(mr_show_reports_immediately: project)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject).to be_truthy }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with mr_show_reports_immediately flag disabled' do
|
||||||
|
before do
|
||||||
|
stub_feature_flags(mr_show_reports_immediately: false)
|
||||||
|
end
|
||||||
|
|
||||||
it { expect(subject).to be_falsey }
|
it { expect(subject).to be_falsey }
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when pipeline status is success' do
|
context 'when pipeline status is success' do
|
||||||
let(:pipeline) { create(:ci_pipeline, :success) }
|
let(:pipeline) { create(:ci_pipeline, :success) }
|
||||||
|
|
|
@ -1884,6 +1884,14 @@ RSpec.describe Namespace do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#emails_enabled?' do
|
||||||
|
it "is the opposite of emails_disabled" do
|
||||||
|
group = create(:group, emails_disabled: false)
|
||||||
|
|
||||||
|
expect(group.emails_enabled?).to be_truthy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#pages_virtual_domain' do
|
describe '#pages_virtual_domain' do
|
||||||
let(:project) { create(:project, namespace: namespace) }
|
let(:project) { create(:project, namespace: namespace) }
|
||||||
let(:virtual_domain) { namespace.pages_virtual_domain }
|
let(:virtual_domain) { namespace.pages_virtual_domain }
|
||||||
|
|
|
@ -3595,6 +3595,14 @@ RSpec.describe Project, factory_default: :keep do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#emails_enabled?' do
|
||||||
|
let(:project) { build(:project, emails_disabled: false) }
|
||||||
|
|
||||||
|
it "is the opposite of emails_disabled" do
|
||||||
|
expect(project.emails_enabled?).to be_truthy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#lfs_enabled?' do
|
describe '#lfs_enabled?' do
|
||||||
let(:namespace) { create(:namespace) }
|
let(:namespace) { create(:namespace) }
|
||||||
let(:project) { build(:project, namespace: namespace) }
|
let(:project) { build(:project, namespace: namespace) }
|
||||||
|
|
|
@ -136,6 +136,20 @@ RSpec.describe 'Create a work item' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when unsupported widget input is sent' do
|
||||||
|
let(:input) do
|
||||||
|
{
|
||||||
|
'title' => 'new title',
|
||||||
|
'description' => 'new description',
|
||||||
|
'workItemTypeId' => WorkItems::Type.default_by_type(:test_case).to_global_id.to_s,
|
||||||
|
'hierarchyWidget' => {}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'a mutation that returns top-level errors',
|
||||||
|
errors: ['Following widget keys are not supported by Test Case type: [:hierarchy_widget]']
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the work_items feature flag is disabled' do
|
context 'when the work_items feature flag is disabled' do
|
||||||
|
|
|
@ -71,6 +71,20 @@ RSpec.describe 'Update a work item' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when unsupported widget input is sent' do
|
||||||
|
let_it_be(:test_case) { create(:work_item_type, :default, :test_case, name: 'some_test_case_name') }
|
||||||
|
let_it_be(:work_item) { create(:work_item, work_item_type: test_case, project: project) }
|
||||||
|
|
||||||
|
let(:input) do
|
||||||
|
{
|
||||||
|
'hierarchyWidget' => {}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'a mutation that returns top-level errors',
|
||||||
|
errors: ["Following widget keys are not supported by some_test_case_name type: [:hierarchy_widget]"]
|
||||||
|
end
|
||||||
|
|
||||||
it_behaves_like 'has spam protection' do
|
it_behaves_like 'has spam protection' do
|
||||||
let(:mutation_class) { ::Mutations::WorkItems::Update }
|
let(:mutation_class) { ::Mutations::WorkItems::Update }
|
||||||
end
|
end
|
||||||
|
@ -295,6 +309,19 @@ RSpec.describe 'Update a work item' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when there is a mix of existing and non existing work items' do
|
||||||
|
let(:children_ids) { [valid_child1.to_global_id.to_s, "gid://gitlab/WorkItem/#{non_existing_record_id}"] }
|
||||||
|
|
||||||
|
it 'returns a top level error and does not add valid work item' do
|
||||||
|
expect do
|
||||||
|
post_graphql_mutation(mutation, current_user: current_user)
|
||||||
|
work_item.reload
|
||||||
|
end.not_to change(work_item.work_item_children, :count)
|
||||||
|
|
||||||
|
expect(graphql_errors.first['message']).to include('No object found for `childrenIds')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when child work item type is valid' do
|
context 'when child work item type is valid' do
|
||||||
let(:children_ids) { [valid_child1.to_global_id.to_s, valid_child2.to_global_id.to_s] }
|
let(:children_ids) { [valid_child1.to_global_id.to_s, valid_child2.to_global_id.to_s] }
|
||||||
|
|
||||||
|
|
|
@ -49,19 +49,19 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when work item not found' do
|
context 'when work item not found' do
|
||||||
let(:params) { { issuable_references: [invalid_task.id] } }
|
let(:params) { { issuable_references: [invalid_task] } }
|
||||||
|
|
||||||
it_behaves_like 'returns not found error'
|
it_behaves_like 'returns not found error'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user has no permission to link work items' do
|
context 'when user has no permission to link work items' do
|
||||||
let(:params) { { issuable_references: [guest_task.id] } }
|
let(:params) { { issuable_references: [guest_task] } }
|
||||||
|
|
||||||
it_behaves_like 'returns not found error'
|
it_behaves_like 'returns not found error'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'child and parent are the same work item' do
|
context 'child and parent are the same work item' do
|
||||||
let(:params) { { issuable_references: [work_item.id] } }
|
let(:params) { { issuable_references: [work_item] } }
|
||||||
|
|
||||||
it 'no relationship is created' do
|
it 'no relationship is created' do
|
||||||
expect { subject }.not_to change(parent_link_class, :count)
|
expect { subject }.not_to change(parent_link_class, :count)
|
||||||
|
@ -69,7 +69,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when there are tasks to relate' do
|
context 'when there are tasks to relate' do
|
||||||
let(:params) { { issuable_references: [task1.id, task2.id] } }
|
let(:params) { { issuable_references: [task1, task2] } }
|
||||||
|
|
||||||
it 'creates relationships', :aggregate_failures do
|
it 'creates relationships', :aggregate_failures do
|
||||||
expect { subject }.to change(parent_link_class, :count).by(2)
|
expect { subject }.to change(parent_link_class, :count).by(2)
|
||||||
|
@ -85,7 +85,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when task is already assigned' do
|
context 'when task is already assigned' do
|
||||||
let(:params) { { issuable_references: [task.id, task2.id] } }
|
let(:params) { { issuable_references: [task, task2] } }
|
||||||
|
|
||||||
it 'creates links only for non related tasks' do
|
it 'creates links only for non related tasks' do
|
||||||
expect { subject }.to change(parent_link_class, :count).by(1)
|
expect { subject }.to change(parent_link_class, :count).by(1)
|
||||||
|
@ -97,7 +97,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
|
||||||
context 'when there are invalid children' do
|
context 'when there are invalid children' do
|
||||||
let_it_be(:issue) { create(:work_item, project: project) }
|
let_it_be(:issue) { create(:work_item, project: project) }
|
||||||
|
|
||||||
let(:params) { { issuable_references: [task1.id, issue.id, other_project_task.id] } }
|
let(:params) { { issuable_references: [task1, issue, other_project_task] } }
|
||||||
|
|
||||||
it 'creates links only for valid children' do
|
it 'creates links only for valid children' do
|
||||||
expect { subject }.to change { parent_link_class.count }.by(1)
|
expect { subject }.to change { parent_link_class.count }.by(1)
|
||||||
|
@ -124,7 +124,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when max depth is reached' do
|
context 'when max depth is reached' do
|
||||||
let(:params) { { issuable_references: [task2.id] } }
|
let(:params) { { issuable_references: [task2] } }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
stub_const("#{parent_link_class}::MAX_CHILDREN", 1)
|
stub_const("#{parent_link_class}::MAX_CHILDREN", 1)
|
||||||
|
@ -138,17 +138,11 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when params include invalid ids' do
|
context 'when params include invalid ids' do
|
||||||
let(:params) { { issuable_references: [task1.id, invalid_task.id] } }
|
let(:params) { { issuable_references: [task1, invalid_task] } }
|
||||||
|
|
||||||
it 'creates links only for valid IDs' do
|
it 'creates links only for valid IDs' do
|
||||||
expect { subject }.to change(parent_link_class, :count).by(1)
|
expect { subject }.to change(parent_link_class, :count).by(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns error for invalid ID' do
|
|
||||||
message = "Task with ID: #{invalid_task.id} could not be found."
|
|
||||||
|
|
||||||
expect(subject).to eq(service_error(message, http_status: 422))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user is a guest' do
|
context 'when user is a guest' do
|
||||||
|
|
|
@ -148,7 +148,7 @@ RSpec.describe WorkItems::UpdateService do
|
||||||
let(:opts) { { title: 'changed' } }
|
let(:opts) { { title: 'changed' } }
|
||||||
let_it_be(:child_work_item) { create(:work_item, :task, project: project) }
|
let_it_be(:child_work_item) { create(:work_item, :task, project: project) }
|
||||||
|
|
||||||
let(:widget_params) { { hierarchy_widget: { children_ids: [child_work_item.id] } } }
|
let(:widget_params) { { hierarchy_widget: { children: [child_work_item] } } }
|
||||||
|
|
||||||
it 'updates the children of the work item' do
|
it 'updates the children of the work item' do
|
||||||
expect do
|
expect do
|
||||||
|
|
|
@ -21,8 +21,8 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
|
||||||
describe '#update' do
|
describe '#update' do
|
||||||
subject { described_class.new(widget: widget, current_user: user).before_update_in_transaction(params: params) }
|
subject { described_class.new(widget: widget, current_user: user).before_update_in_transaction(params: params) }
|
||||||
|
|
||||||
context 'when parent and children_ids params are present' do
|
context 'when parent and children params are present' do
|
||||||
let(:params) { { parent: parent_work_item, children_ids: [child_work_item.id] } }
|
let(:params) { { parent: parent_work_item, children: [child_work_item] } }
|
||||||
|
|
||||||
it_behaves_like 'raises a WidgetError' do
|
it_behaves_like 'raises a WidgetError' do
|
||||||
let(:message) { 'A Work Item can be a parent or a child, but not both.' }
|
let(:message) { 'A Work Item can be a parent or a child, but not both.' }
|
||||||
|
@ -35,7 +35,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
|
||||||
let_it_be(:child_work_item4) { create(:work_item, :task, project: project) }
|
let_it_be(:child_work_item4) { create(:work_item, :task, project: project) }
|
||||||
|
|
||||||
context 'when work_items_hierarchy feature flag is disabled' do
|
context 'when work_items_hierarchy feature flag is disabled' do
|
||||||
let(:params) { { children_ids: [child_work_item4.id] }}
|
let(:params) { { children: [child_work_item4] }}
|
||||||
|
|
||||||
before do
|
before do
|
||||||
stub_feature_flags(work_items_hierarchy: false)
|
stub_feature_flags(work_items_hierarchy: false)
|
||||||
|
@ -47,7 +47,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user has insufficient permissions to link work items' do
|
context 'when user has insufficient permissions to link work items' do
|
||||||
let(:params) { { children_ids: [child_work_item4.id] }}
|
let(:params) { { children: [child_work_item4] }}
|
||||||
|
|
||||||
it_behaves_like 'raises a WidgetError' do
|
it_behaves_like 'raises a WidgetError' do
|
||||||
let(:message) { not_found_error }
|
let(:message) { not_found_error }
|
||||||
|
@ -60,7 +60,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with valid params' do
|
context 'with valid params' do
|
||||||
let(:params) { { children_ids: [child_work_item2.id, child_work_item3.id] }}
|
let(:params) { { children: [child_work_item2, child_work_item3] }}
|
||||||
|
|
||||||
it 'correctly sets work item parent' do
|
it 'correctly sets work item parent' do
|
||||||
subject
|
subject
|
||||||
|
@ -71,7 +71,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when child is already assigned' do
|
context 'when child is already assigned' do
|
||||||
let(:params) { { children_ids: [child_work_item.id] }}
|
let(:params) { { children: [child_work_item] }}
|
||||||
|
|
||||||
it_behaves_like 'raises a WidgetError' do
|
it_behaves_like 'raises a WidgetError' do
|
||||||
let(:message) { 'Task(s) already assigned' }
|
let(:message) { 'Task(s) already assigned' }
|
||||||
|
@ -81,7 +81,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
|
||||||
context 'when child type is invalid' do
|
context 'when child type is invalid' do
|
||||||
let_it_be(:child_issue) { create(:work_item, project: project) }
|
let_it_be(:child_issue) { create(:work_item, project: project) }
|
||||||
|
|
||||||
let(:params) { { children_ids: [child_issue.id] }}
|
let(:params) { { children: [child_issue] }}
|
||||||
|
|
||||||
it_behaves_like 'raises a WidgetError' do
|
it_behaves_like 'raises a WidgetError' do
|
||||||
let(:message) do
|
let(:message) do
|
||||||
|
|