Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
67d7b691b1
commit
22856b8780
6
Gemfile
6
Gemfile
|
|
@ -157,7 +157,7 @@ gem 'github-markup', '~> 1.7.0', require: 'github/markup'
|
||||||
gem 'commonmarker', '~> 0.21'
|
gem 'commonmarker', '~> 0.21'
|
||||||
gem 'kramdown', '~> 2.3.1'
|
gem 'kramdown', '~> 2.3.1'
|
||||||
gem 'RedCloth', '~> 4.3.2'
|
gem 'RedCloth', '~> 4.3.2'
|
||||||
gem 'gitlab-rdoc', '~> 6.3.2', require: 'rdoc' # We need this fork until rdoc releases a new version. See https://gitlab.com/gitlab-org/gitlab/-/issues/334695
|
gem 'rdoc', '~> 6.3.2'
|
||||||
gem 'org-ruby', '~> 0.9.12'
|
gem 'org-ruby', '~> 0.9.12'
|
||||||
gem 'creole', '~> 0.5.0'
|
gem 'creole', '~> 0.5.0'
|
||||||
gem 'wikicloth', '0.8.1'
|
gem 'wikicloth', '0.8.1'
|
||||||
|
|
@ -197,7 +197,7 @@ gem 'acts-as-taggable-on', '~> 7.0'
|
||||||
# Background jobs
|
# Background jobs
|
||||||
gem 'sidekiq', '~> 5.2.7'
|
gem 'sidekiq', '~> 5.2.7'
|
||||||
gem 'sidekiq-cron', '~> 1.0'
|
gem 'sidekiq-cron', '~> 1.0'
|
||||||
gem 'redis-namespace', '~> 1.7.0'
|
gem 'redis-namespace', '~> 1.8.1'
|
||||||
gem 'gitlab-sidekiq-fetcher', '0.5.6', require: 'sidekiq-reliable-fetch'
|
gem 'gitlab-sidekiq-fetcher', '0.5.6', require: 'sidekiq-reliable-fetch'
|
||||||
|
|
||||||
# Cron Parser
|
# Cron Parser
|
||||||
|
|
@ -229,7 +229,7 @@ gem 'js_regex', '~> 3.4'
|
||||||
gem 'device_detector'
|
gem 'device_detector'
|
||||||
|
|
||||||
# Redis
|
# Redis
|
||||||
gem 'redis', '~> 4.0'
|
gem 'redis', '~> 4.1.4'
|
||||||
gem 'connection_pool', '~> 2.0'
|
gem 'connection_pool', '~> 2.0'
|
||||||
|
|
||||||
# Redis session store
|
# Redis session store
|
||||||
|
|
|
||||||
12
Gemfile.lock
12
Gemfile.lock
|
|
@ -499,7 +499,6 @@ GEM
|
||||||
openid_connect (~> 1.2)
|
openid_connect (~> 1.2)
|
||||||
gitlab-pg_query (2.0.4)
|
gitlab-pg_query (2.0.4)
|
||||||
google-protobuf (>= 3.17.1)
|
google-protobuf (>= 3.17.1)
|
||||||
gitlab-rdoc (6.3.2)
|
|
||||||
gitlab-sidekiq-fetcher (0.5.6)
|
gitlab-sidekiq-fetcher (0.5.6)
|
||||||
sidekiq (~> 5)
|
sidekiq (~> 5)
|
||||||
gitlab-styles (6.2.0)
|
gitlab-styles (6.2.0)
|
||||||
|
|
@ -1026,11 +1025,12 @@ GEM
|
||||||
msgpack (>= 0.4.3)
|
msgpack (>= 0.4.3)
|
||||||
optimist (>= 3.0.0)
|
optimist (>= 3.0.0)
|
||||||
rchardet (1.8.0)
|
rchardet (1.8.0)
|
||||||
|
rdoc (6.3.2)
|
||||||
re2 (1.2.0)
|
re2 (1.2.0)
|
||||||
recaptcha (4.13.1)
|
recaptcha (4.13.1)
|
||||||
json
|
json
|
||||||
recursive-open-struct (1.1.2)
|
recursive-open-struct (1.1.2)
|
||||||
redis (4.1.3)
|
redis (4.1.4)
|
||||||
redis-actionpack (5.2.0)
|
redis-actionpack (5.2.0)
|
||||||
actionpack (>= 5, < 7)
|
actionpack (>= 5, < 7)
|
||||||
redis-rack (>= 2.1.0, < 3)
|
redis-rack (>= 2.1.0, < 3)
|
||||||
|
|
@ -1038,7 +1038,7 @@ GEM
|
||||||
redis-activesupport (5.2.0)
|
redis-activesupport (5.2.0)
|
||||||
activesupport (>= 3, < 7)
|
activesupport (>= 3, < 7)
|
||||||
redis-store (>= 1.3, < 2)
|
redis-store (>= 1.3, < 2)
|
||||||
redis-namespace (1.7.0)
|
redis-namespace (1.8.1)
|
||||||
redis (>= 3.0.4)
|
redis (>= 3.0.4)
|
||||||
redis-rack (2.1.2)
|
redis-rack (2.1.2)
|
||||||
rack (>= 2.0.8, < 3)
|
rack (>= 2.0.8, < 3)
|
||||||
|
|
@ -1497,7 +1497,6 @@ DEPENDENCIES
|
||||||
gitlab-markup (~> 1.7.1)
|
gitlab-markup (~> 1.7.1)
|
||||||
gitlab-net-dns (~> 0.9.1)
|
gitlab-net-dns (~> 0.9.1)
|
||||||
gitlab-omniauth-openid-connect (~> 0.4.0)
|
gitlab-omniauth-openid-connect (~> 0.4.0)
|
||||||
gitlab-rdoc (~> 6.3.2)
|
|
||||||
gitlab-sidekiq-fetcher (= 0.5.6)
|
gitlab-sidekiq-fetcher (= 0.5.6)
|
||||||
gitlab-styles (~> 6.2.0)
|
gitlab-styles (~> 6.2.0)
|
||||||
gitlab_chronic_duration (~> 0.10.6.2)
|
gitlab_chronic_duration (~> 0.10.6.2)
|
||||||
|
|
@ -1607,10 +1606,11 @@ DEPENDENCIES
|
||||||
rainbow (~> 3.0)
|
rainbow (~> 3.0)
|
||||||
rblineprof (~> 0.3.6)
|
rblineprof (~> 0.3.6)
|
||||||
rbtrace (~> 0.4)
|
rbtrace (~> 0.4)
|
||||||
|
rdoc (~> 6.3.2)
|
||||||
re2 (~> 1.2.0)
|
re2 (~> 1.2.0)
|
||||||
recaptcha (~> 4.11)
|
recaptcha (~> 4.11)
|
||||||
redis (~> 4.0)
|
redis (~> 4.1.4)
|
||||||
redis-namespace (~> 1.7.0)
|
redis-namespace (~> 1.8.1)
|
||||||
redis-rails (~> 5.0.2)
|
redis-rails (~> 5.0.2)
|
||||||
request_store (~> 1.5)
|
request_store (~> 1.5)
|
||||||
responders (~> 3.0)
|
responders (~> 3.0)
|
||||||
|
|
|
||||||
|
|
@ -75,15 +75,6 @@ export default {
|
||||||
validProjectKey() {
|
validProjectKey() {
|
||||||
return !this.enableJiraIssues || Boolean(this.projectKey) || !this.validated;
|
return !this.enableJiraIssues || Boolean(this.projectKey) || !this.validated;
|
||||||
},
|
},
|
||||||
showJiraVulnerabilitiesOptions() {
|
|
||||||
return this.showJiraVulnerabilitiesIntegration;
|
|
||||||
},
|
|
||||||
showUltimateUpgrade() {
|
|
||||||
return this.showJiraIssuesIntegration && !this.showJiraVulnerabilitiesIntegration;
|
|
||||||
},
|
|
||||||
showPremiumUpgrade() {
|
|
||||||
return !this.showJiraIssuesIntegration;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
eventHub.$on('validateForm', this.validateForm);
|
eventHub.$on('validateForm', this.validateForm);
|
||||||
|
|
@ -128,23 +119,30 @@ export default {
|
||||||
}}
|
}}
|
||||||
</template>
|
</template>
|
||||||
</gl-form-checkbox>
|
</gl-form-checkbox>
|
||||||
<jira-issue-creation-vulnerabilities
|
<template v-if="enableJiraIssues">
|
||||||
v-if="enableJiraIssues"
|
<jira-issue-creation-vulnerabilities
|
||||||
:project-key="projectKey"
|
:project-key="projectKey"
|
||||||
:initial-is-enabled="initialEnableJiraVulnerabilities"
|
:initial-is-enabled="initialEnableJiraVulnerabilities"
|
||||||
:initial-issue-type-id="initialVulnerabilitiesIssuetype"
|
:initial-issue-type-id="initialVulnerabilitiesIssuetype"
|
||||||
:show-full-feature="showJiraVulnerabilitiesOptions"
|
:show-full-feature="showJiraVulnerabilitiesIntegration"
|
||||||
data-testid="jira-for-vulnerabilities"
|
data-testid="jira-for-vulnerabilities"
|
||||||
@request-get-issue-types="getJiraIssueTypes"
|
@request-get-issue-types="getJiraIssueTypes"
|
||||||
/>
|
/>
|
||||||
|
<jira-upgrade-cta
|
||||||
|
v-if="!showJiraVulnerabilitiesIntegration"
|
||||||
|
class="gl-mt-2 gl-ml-6"
|
||||||
|
data-testid="ultimate-upgrade-cta"
|
||||||
|
show-ultimate-message
|
||||||
|
:upgrade-plan-path="upgradePlanPath"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<jira-upgrade-cta
|
<jira-upgrade-cta
|
||||||
v-if="showUltimateUpgrade || showPremiumUpgrade"
|
v-else
|
||||||
class="gl-mt-2"
|
class="gl-mt-2"
|
||||||
:class="{ 'gl-ml-6': showUltimateUpgrade }"
|
data-testid="premium-upgrade-cta"
|
||||||
|
show-premium-message
|
||||||
:upgrade-plan-path="upgradePlanPath"
|
:upgrade-plan-path="upgradePlanPath"
|
||||||
:show-ultimate-message="showUltimateUpgrade"
|
|
||||||
:show-premium-message="showPremiumUpgrade"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</gl-form-group>
|
</gl-form-group>
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,9 @@ export default {
|
||||||
isLoadingLegacyViewer: false,
|
isLoadingLegacyViewer: false,
|
||||||
activeViewerType: SIMPLE_BLOB_VIEWER,
|
activeViewerType: SIMPLE_BLOB_VIEWER,
|
||||||
project: {
|
project: {
|
||||||
|
userPermissions: {
|
||||||
|
pushCode: false,
|
||||||
|
},
|
||||||
repository: {
|
repository: {
|
||||||
blobs: {
|
blobs: {
|
||||||
nodes: [
|
nodes: [
|
||||||
|
|
@ -86,7 +89,6 @@ export default {
|
||||||
canLock: false,
|
canLock: false,
|
||||||
isLocked: false,
|
isLocked: false,
|
||||||
lockLink: '',
|
lockLink: '',
|
||||||
canModifyBlob: true,
|
|
||||||
forkPath: '',
|
forkPath: '',
|
||||||
simpleViewer: {},
|
simpleViewer: {},
|
||||||
richViewer: null,
|
richViewer: null,
|
||||||
|
|
@ -168,7 +170,7 @@ export default {
|
||||||
:path="path"
|
:path="path"
|
||||||
:name="blobInfo.name"
|
:name="blobInfo.name"
|
||||||
:replace-path="blobInfo.replacePath"
|
:replace-path="blobInfo.replacePath"
|
||||||
:can-push-code="blobInfo.canModifyBlob"
|
:can-push-code="project.userPermissions.pushCode"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</blob-header>
|
</blob-header>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
query getBlobInfo($projectPath: ID!, $filePath: String!) {
|
query getBlobInfo($projectPath: ID!, $filePath: String!) {
|
||||||
project(fullPath: $projectPath) {
|
project(fullPath: $projectPath) {
|
||||||
|
userPermissions {
|
||||||
|
pushCode
|
||||||
|
}
|
||||||
repository {
|
repository {
|
||||||
blobs(paths: [$filePath]) {
|
blobs(paths: [$filePath]) {
|
||||||
nodes {
|
nodes {
|
||||||
|
|
@ -15,7 +18,6 @@ query getBlobInfo($projectPath: ID!, $filePath: String!) {
|
||||||
storedExternally
|
storedExternally
|
||||||
rawPath
|
rawPath
|
||||||
replacePath
|
replacePath
|
||||||
canModifyBlob
|
|
||||||
simpleViewer {
|
simpleViewer {
|
||||||
fileType
|
fileType
|
||||||
tooLarge
|
tooLarge
|
||||||
|
|
|
||||||
|
|
@ -56,24 +56,19 @@ $notification-box-shadow-color: rgba(0, 0, 0, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.flash-alert {
|
.flash-alert {
|
||||||
background-color: $red-100;
|
background-color: $red-50;
|
||||||
color: $red-700;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.flash-notice {
|
.flash-notice {
|
||||||
background-color: $blue-100;
|
background-color: $blue-50;
|
||||||
color: $blue-700;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.flash-success {
|
.flash-success {
|
||||||
background-color: $theme-green-100;
|
background-color: $green-50;
|
||||||
color: $green-700;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.flash-warning {
|
.flash-warning {
|
||||||
background-color: $orange-50;
|
background-color: $orange-50;
|
||||||
color: $gray-900;
|
|
||||||
cursor: default;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.flash-text,
|
.flash-text,
|
||||||
|
|
|
||||||
|
|
@ -84,11 +84,7 @@ module Repositories
|
||||||
|
|
||||||
return if Feature.enabled?(:disable_git_http_fetch_writes)
|
return if Feature.enabled?(:disable_git_http_fetch_writes)
|
||||||
|
|
||||||
if Feature.enabled?(:project_statistics_sync, project, default_enabled: true)
|
Projects::FetchStatisticsIncrementService.new(project).execute
|
||||||
Projects::FetchStatisticsIncrementService.new(project).execute
|
|
||||||
else
|
|
||||||
ProjectDailyStatisticsWorker.perform_async(project.id) # rubocop:disable CodeReuse/Worker
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def access
|
def access
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ module Ci
|
||||||
secret_detection: 'gl-secret-detection-report.json',
|
secret_detection: 'gl-secret-detection-report.json',
|
||||||
dependency_scanning: 'gl-dependency-scanning-report.json',
|
dependency_scanning: 'gl-dependency-scanning-report.json',
|
||||||
container_scanning: 'gl-container-scanning-report.json',
|
container_scanning: 'gl-container-scanning-report.json',
|
||||||
|
cluster_image_scanning: 'gl-cluster-image-scanning-report.json',
|
||||||
dast: 'gl-dast-report.json',
|
dast: 'gl-dast-report.json',
|
||||||
license_scanning: 'gl-license-scanning-report.json',
|
license_scanning: 'gl-license-scanning-report.json',
|
||||||
performance: 'performance.json',
|
performance: 'performance.json',
|
||||||
|
|
@ -71,6 +72,7 @@ module Ci
|
||||||
secret_detection: :raw,
|
secret_detection: :raw,
|
||||||
dependency_scanning: :raw,
|
dependency_scanning: :raw,
|
||||||
container_scanning: :raw,
|
container_scanning: :raw,
|
||||||
|
cluster_image_scanning: :raw,
|
||||||
dast: :raw,
|
dast: :raw,
|
||||||
license_scanning: :raw,
|
license_scanning: :raw,
|
||||||
|
|
||||||
|
|
@ -108,6 +110,7 @@ module Ci
|
||||||
sast
|
sast
|
||||||
secret_detection
|
secret_detection
|
||||||
requirements
|
requirements
|
||||||
|
cluster_image_scanning
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
TYPE_AND_FORMAT_PAIRS = INTERNAL_TYPES.merge(REPORT_TYPES).freeze
|
TYPE_AND_FORMAT_PAIRS = INTERNAL_TYPES.merge(REPORT_TYPES).freeze
|
||||||
|
|
@ -212,7 +215,8 @@ module Ci
|
||||||
coverage_fuzzing: 23, ## EE-specific
|
coverage_fuzzing: 23, ## EE-specific
|
||||||
browser_performance: 24, ## EE-specific
|
browser_performance: 24, ## EE-specific
|
||||||
load_performance: 25, ## EE-specific
|
load_performance: 25, ## EE-specific
|
||||||
api_fuzzing: 26 ## EE-specific
|
api_fuzzing: 26, ## EE-specific
|
||||||
|
cluster_image_scanning: 27 ## EE-specific
|
||||||
}
|
}
|
||||||
|
|
||||||
# `file_location` indicates where actual files are stored.
|
# `file_location` indicates where actual files are stored.
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ class UserCallout < ApplicationRecord
|
||||||
pipeline_needs_banner: 29,
|
pipeline_needs_banner: 29,
|
||||||
pipeline_needs_hover_tip: 30,
|
pipeline_needs_hover_tip: 30,
|
||||||
web_ide_ci_environments_guidance: 31,
|
web_ide_ci_environments_guidance: 31,
|
||||||
security_configuration_upgrade_banner: 32
|
security_configuration_upgrade_banner: 32,
|
||||||
|
cloud_licensing_subscription_activation_banner: 33 # EE-only
|
||||||
}
|
}
|
||||||
|
|
||||||
validates :user, presence: true
|
validates :user, presence: true
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
%head
|
%head
|
||||||
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
|
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
|
||||||
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }
|
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }
|
||||||
%link{ href: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600", rel: "stylesheet", type: "text/css" }
|
%link{ href: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600", rel: "stylesheet", type: "text/css", data: { premailer: 'ignore' } }
|
||||||
%title= message.subject
|
%title= message.subject
|
||||||
:css
|
:css
|
||||||
/* CLIENT-SPECIFIC STYLES */
|
/* CLIENT-SPECIFIC STYLES */
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
---
|
|
||||||
name: project_statistics_sync
|
|
||||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29636
|
|
||||||
rollout_issue_url:
|
|
||||||
milestone: '12.10'
|
|
||||||
type: development
|
|
||||||
group: group::source code
|
|
||||||
default_enabled: true
|
|
||||||
|
|
@ -9237,6 +9237,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
|
||||||
| <a id="groupcustomemoji"></a>`customEmoji` | [`CustomEmojiConnection`](#customemojiconnection) | Custom emoji within this namespace. Available only when feature flag `custom_emoji` is enabled. (see [Connections](#connections)) |
|
| <a id="groupcustomemoji"></a>`customEmoji` | [`CustomEmojiConnection`](#customemojiconnection) | Custom emoji within this namespace. Available only when feature flag `custom_emoji` is enabled. (see [Connections](#connections)) |
|
||||||
| <a id="groupdescription"></a>`description` | [`String`](#string) | Description of the namespace. |
|
| <a id="groupdescription"></a>`description` | [`String`](#string) | Description of the namespace. |
|
||||||
| <a id="groupdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
|
| <a id="groupdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
|
||||||
|
| <a id="groupdora"></a>`dora` | [`Dora`](#dora) | The group's DORA metrics. |
|
||||||
| <a id="groupemailsdisabled"></a>`emailsDisabled` | [`Boolean`](#boolean) | Indicates if a group has email notifications disabled. |
|
| <a id="groupemailsdisabled"></a>`emailsDisabled` | [`Boolean`](#boolean) | Indicates if a group has email notifications disabled. |
|
||||||
| <a id="groupepicboards"></a>`epicBoards` | [`EpicBoardConnection`](#epicboardconnection) | Find epic boards. (see [Connections](#connections)) |
|
| <a id="groupepicboards"></a>`epicBoards` | [`EpicBoardConnection`](#epicboardconnection) | Find epic boards. (see [Connections](#connections)) |
|
||||||
| <a id="groupepicsenabled"></a>`epicsEnabled` | [`Boolean`](#boolean) | Indicates if Epics are enabled for namespace. |
|
| <a id="groupepicsenabled"></a>`epicsEnabled` | [`Boolean`](#boolean) | Indicates if Epics are enabled for namespace. |
|
||||||
|
|
@ -14681,6 +14682,7 @@ Iteration ID wildcard values.
|
||||||
| <a id="jobartifactfiletypearchive"></a>`ARCHIVE` | ARCHIVE job artifact file type. |
|
| <a id="jobartifactfiletypearchive"></a>`ARCHIVE` | ARCHIVE job artifact file type. |
|
||||||
| <a id="jobartifactfiletypebrowser_performance"></a>`BROWSER_PERFORMANCE` | BROWSER PERFORMANCE job artifact file type. |
|
| <a id="jobartifactfiletypebrowser_performance"></a>`BROWSER_PERFORMANCE` | BROWSER PERFORMANCE job artifact file type. |
|
||||||
| <a id="jobartifactfiletypecluster_applications"></a>`CLUSTER_APPLICATIONS` | CLUSTER APPLICATIONS job artifact file type. |
|
| <a id="jobartifactfiletypecluster_applications"></a>`CLUSTER_APPLICATIONS` | CLUSTER APPLICATIONS job artifact file type. |
|
||||||
|
| <a id="jobartifactfiletypecluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | CLUSTER IMAGE SCANNING job artifact file type. |
|
||||||
| <a id="jobartifactfiletypecobertura"></a>`COBERTURA` | COBERTURA job artifact file type. |
|
| <a id="jobartifactfiletypecobertura"></a>`COBERTURA` | COBERTURA job artifact file type. |
|
||||||
| <a id="jobartifactfiletypecodequality"></a>`CODEQUALITY` | CODE QUALITY job artifact file type. |
|
| <a id="jobartifactfiletypecodequality"></a>`CODEQUALITY` | CODE QUALITY job artifact file type. |
|
||||||
| <a id="jobartifactfiletypecontainer_scanning"></a>`CONTAINER_SCANNING` | CONTAINER SCANNING job artifact file type. |
|
| <a id="jobartifactfiletypecontainer_scanning"></a>`CONTAINER_SCANNING` | CONTAINER SCANNING job artifact file type. |
|
||||||
|
|
@ -15210,6 +15212,7 @@ Name of the feature that the callout is for.
|
||||||
| <a id="usercalloutfeaturenameenumactive_user_count_threshold"></a>`ACTIVE_USER_COUNT_THRESHOLD` | Callout feature name for active_user_count_threshold. |
|
| <a id="usercalloutfeaturenameenumactive_user_count_threshold"></a>`ACTIVE_USER_COUNT_THRESHOLD` | Callout feature name for active_user_count_threshold. |
|
||||||
| <a id="usercalloutfeaturenameenumbuy_pipeline_minutes_notification_dot"></a>`BUY_PIPELINE_MINUTES_NOTIFICATION_DOT` | Callout feature name for buy_pipeline_minutes_notification_dot. |
|
| <a id="usercalloutfeaturenameenumbuy_pipeline_minutes_notification_dot"></a>`BUY_PIPELINE_MINUTES_NOTIFICATION_DOT` | Callout feature name for buy_pipeline_minutes_notification_dot. |
|
||||||
| <a id="usercalloutfeaturenameenumcanary_deployment"></a>`CANARY_DEPLOYMENT` | Callout feature name for canary_deployment. |
|
| <a id="usercalloutfeaturenameenumcanary_deployment"></a>`CANARY_DEPLOYMENT` | Callout feature name for canary_deployment. |
|
||||||
|
| <a id="usercalloutfeaturenameenumcloud_licensing_subscription_activation_banner"></a>`CLOUD_LICENSING_SUBSCRIPTION_ACTIVATION_BANNER` | Callout feature name for cloud_licensing_subscription_activation_banner. |
|
||||||
| <a id="usercalloutfeaturenameenumcluster_security_warning"></a>`CLUSTER_SECURITY_WARNING` | Callout feature name for cluster_security_warning. |
|
| <a id="usercalloutfeaturenameenumcluster_security_warning"></a>`CLUSTER_SECURITY_WARNING` | Callout feature name for cluster_security_warning. |
|
||||||
| <a id="usercalloutfeaturenameenumcustomize_homepage"></a>`CUSTOMIZE_HOMEPAGE` | Callout feature name for customize_homepage. |
|
| <a id="usercalloutfeaturenameenumcustomize_homepage"></a>`CUSTOMIZE_HOMEPAGE` | Callout feature name for customize_homepage. |
|
||||||
| <a id="usercalloutfeaturenameenumeoa_bronze_plan_banner"></a>`EOA_BRONZE_PLAN_BANNER` | Callout feature name for eoa_bronze_plan_banner. |
|
| <a id="usercalloutfeaturenameenumeoa_bronze_plan_banner"></a>`EOA_BRONZE_PLAN_BANNER` | Callout feature name for eoa_bronze_plan_banner. |
|
||||||
|
|
|
||||||
|
|
@ -3064,6 +3064,18 @@ as artifacts.
|
||||||
The collected coverage fuzzing report uploads to GitLab as an artifact and is summarized in merge
|
The collected coverage fuzzing report uploads to GitLab as an artifact and is summarized in merge
|
||||||
requests and the pipeline view. It's also used to provide data for security dashboards.
|
requests and the pipeline view. It's also used to provide data for security dashboards.
|
||||||
|
|
||||||
|
##### `artifacts:reports:cluster_image_scanning` **(ULTIMATE)**
|
||||||
|
|
||||||
|
> - Introduced in GitLab 14.1.
|
||||||
|
> - Requires GitLab Runner 14.1 and above.
|
||||||
|
|
||||||
|
The `cluster_image_scanning` report collects `CLUSTER_IMAGE_SCANNING` vulnerabilities
|
||||||
|
as artifacts.
|
||||||
|
|
||||||
|
The collected `CLUSTER_IMAGE_SCANNING` report uploads to GitLab as an artifact and
|
||||||
|
is summarized in the pipeline view. It's also used to provide data for security
|
||||||
|
dashboards.
|
||||||
|
|
||||||
##### `artifacts:reports:dast` **(ULTIMATE)**
|
##### `artifacts:reports:dast` **(ULTIMATE)**
|
||||||
|
|
||||||
> - Introduced in GitLab 11.5.
|
> - Introduced in GitLab 11.5.
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ module Gitlab
|
||||||
%i[junit codequality sast secret_detection dependency_scanning container_scanning
|
%i[junit codequality sast secret_detection dependency_scanning container_scanning
|
||||||
dast performance browser_performance load_performance license_scanning metrics lsif
|
dast performance browser_performance load_performance license_scanning metrics lsif
|
||||||
dotenv cobertura terraform accessibility cluster_applications
|
dotenv cobertura terraform accessibility cluster_applications
|
||||||
requirements coverage_fuzzing api_fuzzing].freeze
|
requirements coverage_fuzzing api_fuzzing cluster_image_scanning].freeze
|
||||||
|
|
||||||
attributes ALLOWED_KEYS
|
attributes ALLOWED_KEYS
|
||||||
|
|
||||||
|
|
@ -32,6 +32,7 @@ module Gitlab
|
||||||
validates :secret_detection, array_of_strings_or_string: true
|
validates :secret_detection, array_of_strings_or_string: true
|
||||||
validates :dependency_scanning, array_of_strings_or_string: true
|
validates :dependency_scanning, array_of_strings_or_string: true
|
||||||
validates :container_scanning, array_of_strings_or_string: true
|
validates :container_scanning, array_of_strings_or_string: true
|
||||||
|
validates :cluster_image_scanning, array_of_strings_or_string: true
|
||||||
validates :dast, array_of_strings_or_string: true
|
validates :dast, array_of_strings_or_string: true
|
||||||
validates :performance, array_of_strings_or_string: true
|
validates :performance, array_of_strings_or_string: true
|
||||||
validates :browser_performance, array_of_strings_or_string: true
|
validates :browser_performance, array_of_strings_or_string: true
|
||||||
|
|
|
||||||
|
|
@ -34,18 +34,6 @@ RSpec.describe Repositories::GitHttpController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when project_statistics_sync feature flag is disabled' do
|
|
||||||
before do
|
|
||||||
stub_feature_flags(project_statistics_sync: false, disable_git_http_fetch_writes: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates project statistics async for projects' do
|
|
||||||
expect(ProjectDailyStatisticsWorker).to receive(:perform_async)
|
|
||||||
|
|
||||||
send_request
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates project statistics sync for projects' do
|
it 'updates project statistics sync for projects' do
|
||||||
stub_feature_flags(disable_git_http_fetch_writes: false)
|
stub_feature_flags(disable_git_http_fetch_writes: false)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -508,6 +508,14 @@ FactoryBot.define do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :cluster_image_scanning do
|
||||||
|
options do
|
||||||
|
{
|
||||||
|
artifacts: { reports: { cluster_image_scanning: 'gl-cluster-image-scanning-report.json' } }
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
trait :license_scanning do
|
trait :license_scanning do
|
||||||
options do
|
options do
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { GlFormCheckbox, GlFormInput } from '@gitlab/ui';
|
||||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||||
|
|
||||||
import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue';
|
import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue';
|
||||||
import JiraUpgradeCta from '~/integrations/edit/components/jira_upgrade_cta.vue';
|
|
||||||
import eventHub from '~/integrations/edit/event_hub';
|
import eventHub from '~/integrations/edit/event_hub';
|
||||||
import { createStore } from '~/integrations/edit/store';
|
import { createStore } from '~/integrations/edit/store';
|
||||||
|
|
||||||
|
|
@ -14,6 +13,7 @@ describe('JiraIssuesFields', () => {
|
||||||
editProjectPath: '/edit',
|
editProjectPath: '/edit',
|
||||||
showJiraIssuesIntegration: true,
|
showJiraIssuesIntegration: true,
|
||||||
showJiraVulnerabilitiesIntegration: true,
|
showJiraVulnerabilitiesIntegration: true,
|
||||||
|
upgradePlanPath: 'https://gitlab.com',
|
||||||
};
|
};
|
||||||
|
|
||||||
const createComponent = ({ isInheriting = false, props, ...options } = {}) => {
|
const createComponent = ({ isInheriting = false, props, ...options } = {}) => {
|
||||||
|
|
@ -37,60 +37,79 @@ describe('JiraIssuesFields', () => {
|
||||||
const findEnableCheckboxDisabled = () =>
|
const findEnableCheckboxDisabled = () =>
|
||||||
findEnableCheckbox().find('[type=checkbox]').attributes('disabled');
|
findEnableCheckbox().find('[type=checkbox]').attributes('disabled');
|
||||||
const findProjectKey = () => wrapper.findComponent(GlFormInput);
|
const findProjectKey = () => wrapper.findComponent(GlFormInput);
|
||||||
const findJiraUpgradeCta = () => wrapper.findComponent(JiraUpgradeCta);
|
const findPremiumUpgradeCTA = () => wrapper.findByTestId('premium-upgrade-cta');
|
||||||
|
const findUltimateUpgradeCTA = () => wrapper.findByTestId('ultimate-upgrade-cta');
|
||||||
const findJiraForVulnerabilities = () => wrapper.findByTestId('jira-for-vulnerabilities');
|
const findJiraForVulnerabilities = () => wrapper.findByTestId('jira-for-vulnerabilities');
|
||||||
const setEnableCheckbox = async (isEnabled = true) =>
|
const setEnableCheckbox = async (isEnabled = true) =>
|
||||||
findEnableCheckbox().vm.$emit('input', isEnabled);
|
findEnableCheckbox().vm.$emit('input', isEnabled);
|
||||||
|
|
||||||
describe('jira issues call to action', () => {
|
|
||||||
it('shows the premium message', () => {
|
|
||||||
createComponent({
|
|
||||||
props: { showJiraIssuesIntegration: false },
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(findJiraUpgradeCta().props()).toMatchObject({
|
|
||||||
showPremiumMessage: true,
|
|
||||||
showUltimateMessage: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows the ultimate message', () => {
|
|
||||||
createComponent({
|
|
||||||
props: {
|
|
||||||
showJiraIssuesIntegration: true,
|
|
||||||
showJiraVulnerabilitiesIntegration: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(findJiraUpgradeCta().props()).toMatchObject({
|
|
||||||
showPremiumMessage: false,
|
|
||||||
showUltimateMessage: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('template', () => {
|
describe('template', () => {
|
||||||
describe('upgrade banner for non-Premium user', () => {
|
describe.each`
|
||||||
beforeEach(() => {
|
showJiraIssuesIntegration | showJiraVulnerabilitiesIntegration
|
||||||
createComponent({ props: { initialProjectKey: '', showJiraIssuesIntegration: false } });
|
${false} | ${false}
|
||||||
});
|
${false} | ${true}
|
||||||
|
${true} | ${false}
|
||||||
|
${true} | ${true}
|
||||||
|
`(
|
||||||
|
'when `showJiraIssuesIntegration` is $jiraIssues and `showJiraVulnerabilitiesIntegration` is $jiraVulnerabilities',
|
||||||
|
({ showJiraIssuesIntegration, showJiraVulnerabilitiesIntegration }) => {
|
||||||
|
beforeEach(() => {
|
||||||
|
createComponent({
|
||||||
|
props: {
|
||||||
|
showJiraIssuesIntegration,
|
||||||
|
showJiraVulnerabilitiesIntegration,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('does not show checkbox and input field', () => {
|
if (showJiraIssuesIntegration) {
|
||||||
expect(findEnableCheckbox().exists()).toBe(false);
|
it('renders checkbox and input field', () => {
|
||||||
expect(findProjectKey().exists()).toBe(false);
|
expect(findEnableCheckbox().exists()).toBe(true);
|
||||||
});
|
expect(findEnableCheckboxDisabled()).toBeUndefined();
|
||||||
});
|
expect(findProjectKey().exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render the Premium CTA', () => {
|
||||||
|
expect(findPremiumUpgradeCTA().exists()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!showJiraVulnerabilitiesIntegration) {
|
||||||
|
it.each`
|
||||||
|
scenario | enableJiraIssues
|
||||||
|
${'when "Enable Jira issues" is checked, renders Ultimate upgrade CTA'} | ${true}
|
||||||
|
${'when "Enable Jira issues" is unchecked, does not render Ultimate upgrade CTA'} | ${false}
|
||||||
|
`('$scenario', async ({ enableJiraIssues }) => {
|
||||||
|
if (enableJiraIssues) {
|
||||||
|
await setEnableCheckbox();
|
||||||
|
}
|
||||||
|
expect(findUltimateUpgradeCTA().exists()).toBe(enableJiraIssues);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
it('does not render checkbox and input field', () => {
|
||||||
|
expect(findEnableCheckbox().exists()).toBe(false);
|
||||||
|
expect(findProjectKey().exists()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the Premium CTA', () => {
|
||||||
|
const premiumUpgradeCTA = findPremiumUpgradeCTA();
|
||||||
|
|
||||||
|
expect(premiumUpgradeCTA.exists()).toBe(true);
|
||||||
|
expect(premiumUpgradeCTA.props('upgradePlanPath')).toBe(defaultProps.upgradePlanPath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it('does not render the Ultimate CTA', () => {
|
||||||
|
expect(findUltimateUpgradeCTA().exists()).toBe(false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
describe('Enable Jira issues checkbox', () => {
|
describe('Enable Jira issues checkbox', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent({ props: { initialProjectKey: '' } });
|
createComponent({ props: { initialProjectKey: '' } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders enabled checkbox', () => {
|
|
||||||
expect(findEnableCheckbox().exists()).toBe(true);
|
|
||||||
expect(findEnableCheckboxDisabled()).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders disabled project_key input', () => {
|
it('renders disabled project_key input', () => {
|
||||||
const projectKey = findProjectKey();
|
const projectKey = findProjectKey();
|
||||||
|
|
||||||
|
|
@ -99,10 +118,6 @@ describe('JiraIssuesFields', () => {
|
||||||
expect(projectKey.attributes('required')).toBeUndefined();
|
expect(projectKey.attributes('required')).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not show upgrade banner', () => {
|
|
||||||
expect(findJiraUpgradeCta().exists()).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// As per https://vuejs.org/v2/guide/forms.html#Checkbox-1,
|
// As per https://vuejs.org/v2/guide/forms.html#Checkbox-1,
|
||||||
// browsers don't include unchecked boxes in form submissions.
|
// browsers don't include unchecked boxes in form submissions.
|
||||||
it('includes issues_enabled as false even if unchecked', () => {
|
it('includes issues_enabled as false even if unchecked', () => {
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ const simpleMockData = {
|
||||||
canLock: true,
|
canLock: true,
|
||||||
isLocked: false,
|
isLocked: false,
|
||||||
lockLink: 'some_file.js/lock',
|
lockLink: 'some_file.js/lock',
|
||||||
canModifyBlob: true,
|
|
||||||
forkPath: 'some_file.js/fork',
|
forkPath: 'some_file.js/fork',
|
||||||
simpleViewer: {
|
simpleViewer: {
|
||||||
fileType: 'text',
|
fileType: 'text',
|
||||||
|
|
@ -56,16 +55,26 @@ const richMockData = {
|
||||||
renderError: null,
|
renderError: null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
const userPermissionsMockData = {
|
||||||
|
userPermissions: {
|
||||||
|
pushCode: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const localVue = createLocalVue();
|
const localVue = createLocalVue();
|
||||||
const mockAxios = new MockAdapter(axios);
|
const mockAxios = new MockAdapter(axios);
|
||||||
|
|
||||||
const createComponentWithApollo = (mockData) => {
|
const createComponentWithApollo = (mockData, mockPermissionData = true) => {
|
||||||
localVue.use(VueApollo);
|
localVue.use(VueApollo);
|
||||||
|
|
||||||
const mockResolver = jest
|
const mockResolver = jest.fn().mockResolvedValue({
|
||||||
.fn()
|
data: {
|
||||||
.mockResolvedValue({ data: { project: { repository: { blobs: { nodes: [mockData] } } } } });
|
project: {
|
||||||
|
userPermissions: { pushCode: mockPermissionData },
|
||||||
|
repository: { blobs: { nodes: [mockData] } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const fakeApollo = createMockApollo([[blobInfoQuery, mockResolver]]);
|
const fakeApollo = createMockApollo([[blobInfoQuery, mockResolver]]);
|
||||||
|
|
||||||
|
|
@ -276,13 +285,16 @@ describe('Blob content viewer component', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('BlobButtonGroup', () => {
|
describe('BlobButtonGroup', () => {
|
||||||
const { name, path } = simpleMockData;
|
const { name, path, replacePath } = simpleMockData;
|
||||||
|
const {
|
||||||
|
userPermissions: { pushCode },
|
||||||
|
} = userPermissionsMockData;
|
||||||
|
|
||||||
it('renders component', async () => {
|
it('renders component', async () => {
|
||||||
window.gon.current_user_id = 1;
|
window.gon.current_user_id = 1;
|
||||||
|
|
||||||
fullFactory({
|
fullFactory({
|
||||||
mockData: { blobInfo: simpleMockData },
|
mockData: { blobInfo: simpleMockData, project: userPermissionsMockData },
|
||||||
stubs: {
|
stubs: {
|
||||||
BlobContent: true,
|
BlobContent: true,
|
||||||
BlobButtonGroup: true,
|
BlobButtonGroup: true,
|
||||||
|
|
@ -294,6 +306,8 @@ describe('Blob content viewer component', () => {
|
||||||
expect(findBlobButtonGroup().props()).toMatchObject({
|
expect(findBlobButtonGroup().props()).toMatchObject({
|
||||||
name,
|
name,
|
||||||
path,
|
path,
|
||||||
|
replacePath,
|
||||||
|
canPushCode: pushCode,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Reports do
|
||||||
:secret_detection | 'gl-secret-detection-report.json'
|
:secret_detection | 'gl-secret-detection-report.json'
|
||||||
:dependency_scanning | 'gl-dependency-scanning-report.json'
|
:dependency_scanning | 'gl-dependency-scanning-report.json'
|
||||||
:container_scanning | 'gl-container-scanning-report.json'
|
:container_scanning | 'gl-container-scanning-report.json'
|
||||||
|
:cluster_image_scanning | 'gl-cluster-image-scanning-report.json'
|
||||||
:dast | 'gl-dast-report.json'
|
:dast | 'gl-dast-report.json'
|
||||||
:license_scanning | 'gl-license-scanning-report.json'
|
:license_scanning | 'gl-license-scanning-report.json'
|
||||||
:performance | 'performance.json'
|
:performance | 'performance.json'
|
||||||
|
|
|
||||||
|
|
@ -1969,6 +1969,19 @@ RSpec.describe Notify do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'in product marketing', :mailer do
|
||||||
|
let_it_be(:group) { create(:group) }
|
||||||
|
|
||||||
|
let(:mail) { ActionMailer::Base.deliveries.last }
|
||||||
|
|
||||||
|
it 'does not raise error' do
|
||||||
|
described_class.in_product_marketing_email(user.id, group.id, :trial, 0).deliver
|
||||||
|
|
||||||
|
expect(mail.subject).to eq('Go farther with GitLab')
|
||||||
|
expect(mail.body.parts.first.to_s).to include('Start a GitLab Ultimate trial today in less than one minute, no credit card required.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def expect_sender(user)
|
def expect_sender(user)
|
||||||
sender = subject.header[:from].addrs[0]
|
sender = subject.header[:from].addrs[0]
|
||||||
expect(sender.display_name).to eq("#{user.name} (@#{user.username})")
|
expect(sender.display_name).to eq("#{user.name} (@#{user.username})")
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ RSpec.describe Ci::RetryBuildService do
|
||||||
erased_at auto_canceled_by job_artifacts job_artifacts_archive
|
erased_at auto_canceled_by job_artifacts job_artifacts_archive
|
||||||
job_artifacts_metadata job_artifacts_trace job_artifacts_junit
|
job_artifacts_metadata job_artifacts_trace job_artifacts_junit
|
||||||
job_artifacts_sast job_artifacts_secret_detection job_artifacts_dependency_scanning
|
job_artifacts_sast job_artifacts_secret_detection job_artifacts_dependency_scanning
|
||||||
job_artifacts_container_scanning job_artifacts_dast
|
job_artifacts_container_scanning job_artifacts_cluster_image_scanning job_artifacts_dast
|
||||||
job_artifacts_license_scanning
|
job_artifacts_license_scanning
|
||||||
job_artifacts_performance job_artifacts_browser_performance job_artifacts_load_performance
|
job_artifacts_performance job_artifacts_browser_performance job_artifacts_load_performance
|
||||||
job_artifacts_lsif job_artifacts_terraform job_artifacts_cluster_applications
|
job_artifacts_lsif job_artifacts_terraform job_artifacts_cluster_applications
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue