Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
8c9dc985
Commit
8c9dc985
authored
Feb 12, 2020
by
GitLab Bot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add latest changes from gitlab-org/gitlab@master
parent
500626a5
Changes
45
Show whitespace changes
Inline
Side-by-side
Showing
45 changed files
with
774 additions
and
139 deletions
+774
-139
app/assets/javascripts/diffs/components/diff_line_gutter_content.vue
...javascripts/diffs/components/diff_line_gutter_content.vue
+4
-1
app/assets/javascripts/lib/utils/common_utils.js
app/assets/javascripts/lib/utils/common_utils.js
+4
-1
app/models/ci/bridge.rb
app/models/ci/bridge.rb
+0
-1
app/models/ci/build.rb
app/models/ci/build.rb
+0
-1
app/models/ci/processable.rb
app/models/ci/processable.rb
+19
-0
app/models/clusters/applications/elastic_stack.rb
app/models/clusters/applications/elastic_stack.rb
+13
-2
app/services/ci/retry_build_service.rb
app/services/ci/retry_build_service.rb
+5
-4
app/views/shared/boards/components/_board.html.haml
app/views/shared/boards/components/_board.html.haml
+1
-1
changelogs/unreleased/24020-copy-markdown-from-comments.yml
changelogs/unreleased/24020-copy-markdown-from-comments.yml
+5
-0
changelogs/unreleased/30235-support-allow-failure-for-ci-rules.yml
...s/unreleased/30235-support-allow-failure-for-ci-rules.yml
+5
-0
changelogs/unreleased/ak-wait-for-green-es.yml
changelogs/unreleased/ak-wait-for-green-es.yml
+5
-0
changelogs/unreleased/jdb-minimal-merge-ref-diff.yml
changelogs/unreleased/jdb-minimal-merge-ref-diff.yml
+5
-0
changelogs/unreleased/ss-fix-text-truncated-on-board-list.yml
...gelogs/unreleased/ss-fix-text-truncated-on-board-list.yml
+5
-0
db/fixtures/development/14_pipelines.rb
db/fixtures/development/14_pipelines.rb
+3
-2
db/migrate/20191223124940_add_scheduling_type_to_ci_builds.rb
...igrate/20191223124940_add_scheduling_type_to_ci_builds.rb
+11
-0
db/schema.rb
db/schema.rb
+1
-0
doc/ci/yaml/README.md
doc/ci/yaml/README.md
+21
-1
doc/user/clusters/applications.md
doc/user/clusters/applications.md
+2
-2
doc/user/group/index.md
doc/user/group/index.md
+2
-1
lib/gitlab/ci/build/rules.rb
lib/gitlab/ci/build/rules.rb
+5
-3
lib/gitlab/ci/config/entry/bridge.rb
lib/gitlab/ci/config/entry/bridge.rb
+2
-1
lib/gitlab/ci/config/entry/job.rb
lib/gitlab/ci/config/entry/job.rb
+2
-1
lib/gitlab/ci/config/entry/rules/rule.rb
lib/gitlab/ci/config/entry/rules/rule.rb
+3
-2
lib/gitlab/ci/yaml_processor.rb
lib/gitlab/ci/yaml_processor.rb
+1
-0
spec/factories/ci/bridge.rb
spec/factories/ci/bridge.rb
+1
-0
spec/factories/ci/builds.rb
spec/factories/ci/builds.rb
+1
-0
spec/frontend/diffs/components/diff_line_gutter_content_spec.js
...rontend/diffs/components/diff_line_gutter_content_spec.js
+160
-70
spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
...avascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
+14
-0
spec/lib/gitlab/ci/build/rules_spec.rb
spec/lib/gitlab/ci/build/rules_spec.rb
+48
-2
spec/lib/gitlab/ci/config/entry/bridge_spec.rb
spec/lib/gitlab/ci/config/entry/bridge_spec.rb
+4
-2
spec/lib/gitlab/ci/config/entry/job_spec.rb
spec/lib/gitlab/ci/config/entry/job_spec.rb
+6
-1
spec/lib/gitlab/ci/config/entry/jobs_spec.rb
spec/lib/gitlab/ci/config/entry/jobs_spec.rb
+4
-2
spec/lib/gitlab/ci/config/entry/root_spec.rb
spec/lib/gitlab/ci/config/entry/root_spec.rb
+10
-5
spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb
spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb
+42
-3
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+4
-2
spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
+3
-3
spec/lib/gitlab/ci/yaml_processor_spec.rb
spec/lib/gitlab/ci/yaml_processor_spec.rb
+36
-17
spec/lib/gitlab/import_export/safe_model_attributes.yml
spec/lib/gitlab/import_export/safe_model_attributes.yml
+1
-0
spec/models/ci/build_spec.rb
spec/models/ci/build_spec.rb
+2
-1
spec/models/ci/processable_spec.rb
spec/models/ci/processable_spec.rb
+68
-0
spec/services/ci/create_pipeline_service/needs_spec.rb
spec/services/ci/create_pipeline_service/needs_spec.rb
+4
-0
spec/services/ci/create_pipeline_service_spec.rb
spec/services/ci/create_pipeline_service_spec.rb
+196
-6
spec/services/ci/retry_build_service_spec.rb
spec/services/ci/retry_build_service_spec.rb
+22
-0
vendor/elastic_stack/values.yaml
vendor/elastic_stack/values.yaml
+1
-1
vendor/elastic_stack/wait-for-elasticsearch.sh
vendor/elastic_stack/wait-for-elasticsearch.sh
+23
-0
No files found.
app/assets/javascripts/diffs/components/diff_line_gutter_content.vue
View file @
8c9dc985
<
script
>
<
script
>
import
{
mapState
,
mapGetters
,
mapActions
}
from
'
vuex
'
;
import
{
mapState
,
mapGetters
,
mapActions
}
from
'
vuex
'
;
import
{
getParameterByName
,
parseBoolean
}
from
'
~/lib/utils/common_utils
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
DiffGutterAvatars
from
'
./diff_gutter_avatars.vue
'
;
import
DiffGutterAvatars
from
'
./diff_gutter_avatars.vue
'
;
import
{
LINE_POSITION_RIGHT
}
from
'
../constants
'
;
import
{
LINE_POSITION_RIGHT
}
from
'
../constants
'
;
...
@@ -98,7 +99,8 @@ export default {
...
@@ -98,7 +99,8 @@ export default {
return
this
.
showCommentButton
&&
this
.
hasDiscussions
;
return
this
.
showCommentButton
&&
this
.
hasDiscussions
;
},
},
shouldRenderCommentButton
()
{
shouldRenderCommentButton
()
{
return
this
.
isLoggedIn
&&
this
.
showCommentButton
;
const
isDiffHead
=
parseBoolean
(
getParameterByName
(
'
diff_head
'
));
return
!
isDiffHead
&&
this
.
isLoggedIn
&&
this
.
showCommentButton
;
},
},
},
},
methods
:
{
methods
:
{
...
@@ -130,6 +132,7 @@ export default {
...
@@ -130,6 +132,7 @@ export default {
</button>
</button>
<a
<a
v-if=
"lineNumber"
v-if=
"lineNumber"
ref=
"lineNumberRef"
:data-linenumber=
"lineNumber"
:data-linenumber=
"lineNumber"
:href=
"lineHref"
:href=
"lineHref"
@
click=
"setHighlightedRow(lineCode)"
@
click=
"setHighlightedRow(lineCode)"
...
...
app/assets/javascripts/lib/utils/common_utils.js
View file @
8c9dc985
...
@@ -327,7 +327,10 @@ export const getSelectedFragment = restrictToNode => {
...
@@ -327,7 +327,10 @@ export const getSelectedFragment = restrictToNode => {
documentFragment
.
originalNodes
.
push
(
range
.
commonAncestorContainer
);
documentFragment
.
originalNodes
.
push
(
range
.
commonAncestorContainer
);
}
}
}
}
if
(
documentFragment
.
textContent
.
length
===
0
)
return
null
;
if
(
documentFragment
.
textContent
.
length
===
0
&&
documentFragment
.
children
.
length
===
0
)
{
return
null
;
}
return
documentFragment
;
return
documentFragment
;
};
};
...
...
app/models/ci/bridge.rb
View file @
8c9dc985
...
@@ -8,7 +8,6 @@ module Ci
...
@@ -8,7 +8,6 @@ module Ci
include
Importable
include
Importable
include
AfterCommitQueue
include
AfterCommitQueue
include
HasRef
include
HasRef
include
Gitlab
::
Utils
::
StrongMemoize
InvalidBridgeTypeError
=
Class
.
new
(
StandardError
)
InvalidBridgeTypeError
=
Class
.
new
(
StandardError
)
...
...
app/models/ci/build.rb
View file @
8c9dc985
...
@@ -10,7 +10,6 @@ module Ci
...
@@ -10,7 +10,6 @@ module Ci
include
ObjectStorage
::
BackgroundMove
include
ObjectStorage
::
BackgroundMove
include
Presentable
include
Presentable
include
Importable
include
Importable
include
Gitlab
::
Utils
::
StrongMemoize
include
HasRef
include
HasRef
include
IgnorableColumns
include
IgnorableColumns
...
...
app/models/ci/processable.rb
View file @
8c9dc985
...
@@ -2,10 +2,14 @@
...
@@ -2,10 +2,14 @@
module
Ci
module
Ci
class
Processable
<
::
CommitStatus
class
Processable
<
::
CommitStatus
include
Gitlab
::
Utils
::
StrongMemoize
has_many
:needs
,
class_name:
'Ci::BuildNeed'
,
foreign_key: :build_id
,
inverse_of: :build
has_many
:needs
,
class_name:
'Ci::BuildNeed'
,
foreign_key: :build_id
,
inverse_of: :build
accepts_nested_attributes_for
:needs
accepts_nested_attributes_for
:needs
enum
scheduling_type:
{
stage:
0
,
dag:
1
},
_prefix:
true
scope
:preload_needs
,
->
{
preload
(
:needs
)
}
scope
:preload_needs
,
->
{
preload
(
:needs
)
}
def
self
.
select_with_aggregated_needs
(
project
)
def
self
.
select_with_aggregated_needs
(
project
)
...
@@ -23,6 +27,7 @@ module Ci
...
@@ -23,6 +27,7 @@ module Ci
end
end
validates
:type
,
presence:
true
validates
:type
,
presence:
true
validates
:scheduling_type
,
presence:
true
,
on: :create
,
if: :validate_scheduling_type?
def
aggregated_needs_names
def
aggregated_needs_names
read_attribute
(
:aggregated_needs_names
)
read_attribute
(
:aggregated_needs_names
)
...
@@ -47,5 +52,19 @@ module Ci
...
@@ -47,5 +52,19 @@ module Ci
def
scoped_variables_hash
def
scoped_variables_hash
raise
NotImplementedError
raise
NotImplementedError
end
end
# scheduling_type column of previous builds/bridges have not been populated,
# so we calculate this value on runtime when we need it.
def
find_legacy_scheduling_type
strong_memoize
(
:find_legacy_scheduling_type
)
do
needs
.
exists?
?
:dag
:
:stage
end
end
private
def
validate_scheduling_type?
!
importing?
&&
Feature
.
enabled?
(
:validate_scheduling_type_of_processables
,
project
)
end
end
end
end
end
app/models/clusters/applications/elastic_stack.rb
View file @
8c9dc985
...
@@ -30,7 +30,8 @@ module Clusters
...
@@ -30,7 +30,8 @@ module Clusters
version:
VERSION
,
version:
VERSION
,
rbac:
cluster
.
platform_kubernetes_rbac?
,
rbac:
cluster
.
platform_kubernetes_rbac?
,
chart:
chart
,
chart:
chart
,
files:
files
files:
files
,
postinstall:
post_install_script
)
)
end
end
...
@@ -43,6 +44,10 @@ module Clusters
...
@@ -43,6 +44,10 @@ module Clusters
)
)
end
end
def
files
super
.
merge
(
'wait-for-elasticsearch.sh'
:
File
.
read
(
"
#{
Rails
.
root
}
/vendor/elastic_stack/wait-for-elasticsearch.sh"
))
end
def
elasticsearch_client
def
elasticsearch_client
strong_memoize
(
:elasticsearch_client
)
do
strong_memoize
(
:elasticsearch_client
)
do
next
unless
kube_client
next
unless
kube_client
...
@@ -69,10 +74,16 @@ module Clusters
...
@@ -69,10 +74,16 @@ module Clusters
private
private
def
post_install_script
[
"timeout -t60 sh /data/helm/elastic-stack/config/wait-for-elasticsearch.sh http://elastic-stack-elasticsearch-client:9200"
]
end
def
post_delete_script
def
post_delete_script
[
[
Gitlab
::
Kubernetes
::
KubectlCmd
.
delete
(
"pvc"
,
"--selector"
,
"release=elastic-stack"
)
Gitlab
::
Kubernetes
::
KubectlCmd
.
delete
(
"pvc"
,
"--selector"
,
"release=elastic-stack"
)
]
.
compact
]
end
end
def
kube_client
def
kube_client
...
...
app/services/ci/retry_build_service.rb
View file @
8c9dc985
...
@@ -5,7 +5,7 @@ module Ci
...
@@ -5,7 +5,7 @@ module Ci
CLONE_ACCESSORS
=
%i[pipeline project ref tag options name
CLONE_ACCESSORS
=
%i[pipeline project ref tag options name
allow_failure stage stage_id stage_idx trigger_request
allow_failure stage stage_id stage_idx trigger_request
yaml_variables when environment coverage_regex
yaml_variables when environment coverage_regex
description tag_list protected needs resource_group]
.
freeze
description tag_list protected needs resource_group
scheduling_type
]
.
freeze
def
execute
(
build
)
def
execute
(
build
)
reprocess!
(
build
).
tap
do
|
new_build
|
reprocess!
(
build
).
tap
do
|
new_build
|
...
@@ -27,9 +27,10 @@ module Ci
...
@@ -27,9 +27,10 @@ module Ci
attributes
=
CLONE_ACCESSORS
.
map
do
|
attribute
|
attributes
=
CLONE_ACCESSORS
.
map
do
|
attribute
|
[
attribute
,
build
.
public_send
(
attribute
)]
# rubocop:disable GitlabSecurity/PublicSend
[
attribute
,
build
.
public_send
(
attribute
)]
# rubocop:disable GitlabSecurity/PublicSend
end
end
.
to_h
attributes
.
push
([
:user
,
current_user
])
attributes
[
:user
]
=
current_user
attributes
[
:scheduling_type
]
||=
build
.
find_legacy_scheduling_type
Ci
::
Build
.
transaction
do
Ci
::
Build
.
transaction
do
# mark all other builds of that name as retried
# mark all other builds of that name as retried
...
@@ -49,7 +50,7 @@ module Ci
...
@@ -49,7 +50,7 @@ module Ci
private
private
def
create_build!
(
attributes
)
def
create_build!
(
attributes
)
build
=
project
.
builds
.
new
(
Hash
[
attributes
]
)
build
=
project
.
builds
.
new
(
attributes
)
build
.
deployment
=
::
Gitlab
::
Ci
::
Pipeline
::
Seed
::
Deployment
.
new
(
build
).
to_resource
build
.
deployment
=
::
Gitlab
::
Ci
::
Pipeline
::
Seed
::
Deployment
.
new
(
build
).
to_resource
build
.
retried
=
false
build
.
retried
=
false
build
.
save!
build
.
save!
...
...
app/views/shared/boards/components/_board.html.haml
View file @
8c9dc985
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
":title"
=>
'(list.assignee && list.assignee.username || "")'
}
":title"
=>
'(list.assignee && list.assignee.username || "")'
}
@{{ list.assignee.username }}
@{{ list.assignee.username }}
%span
.has-tooltip.badge.color-label.title
{
"v-if"
:
"list.type ===
\"
label
\"
"
,
%span
.has-tooltip.badge.color-label.title
.d-inline-block.mw-100.text-truncate.align-middle
{
"v-if"
:
"list.type ===
\"
label
\"
"
,
":title"
=>
'(list.label ? list.label.description : "")'
,
":title"
=>
'(list.label ? list.label.description : "")'
,
data:
{
container:
"body"
,
placement:
"bottom"
},
data:
{
container:
"body"
,
placement:
"bottom"
},
":style"
=>
"{ backgroundColor: (list.label && list.label.color ? list.label.color : null), color: (list.label && list.label.textColor ? list.label.textColor :
\"
#2e2e2e
\"
) }"
}
":style"
=>
"{ backgroundColor: (list.label && list.label.color ? list.label.color : null), color: (list.label && list.label.textColor ? list.label.textColor :
\"
#2e2e2e
\"
) }"
}
...
...
changelogs/unreleased/24020-copy-markdown-from-comments.yml
0 → 100644
View file @
8c9dc985
---
title
:
Fix copy markdown with elements with no text content
merge_request
:
24020
author
:
type
:
fixed
changelogs/unreleased/30235-support-allow-failure-for-ci-rules.yml
0 → 100644
View file @
8c9dc985
---
title
:
Implement support of allow_failure keyword for CI rules
merge_request
:
24605
author
:
type
:
added
changelogs/unreleased/ak-wait-for-green-es.yml
0 → 100644
View file @
8c9dc985
---
title
:
Wait for elasticsearch to be green on install
merge_request
:
24489
author
:
type
:
added
changelogs/unreleased/jdb-minimal-merge-ref-diff.yml
0 → 100644
View file @
8c9dc985
---
title
:
Hide comment button if on diff HEAD
merge_request
:
24207
author
:
type
:
changed
changelogs/unreleased/ss-fix-text-truncated-on-board-list.yml
0 → 100644
View file @
8c9dc985
---
title
:
Add styles for board list labels when text is too long
merge_request
:
24627
author
:
type
:
fixed
db/fixtures/development/14_pipelines.rb
View file @
8c9dc985
...
@@ -165,9 +165,10 @@ class Gitlab::Seeder::Pipelines
...
@@ -165,9 +165,10 @@ class Gitlab::Seeder::Pipelines
end
end
def
job_attributes
(
pipeline
,
opts
)
def
job_attributes
(
pipeline
,
opts
)
{
name:
'test build'
,
stage:
'test'
,
stage_idx:
stage_index
(
opts
[
:stage
]),
{
name:
'test build'
,
stage:
'test'
,
stage_idx:
stage_index
(
opts
[
:stage
]),
ref:
pipeline
.
ref
,
tag:
false
,
user:
build_user
,
project:
@project
,
pipeline:
pipeline
,
ref:
pipeline
.
ref
,
tag:
false
,
user:
build_user
,
project:
@project
,
pipeline:
pipeline
,
created_at:
Time
.
now
,
updated_at:
Time
.
now
scheduling_type: :stage
,
created_at:
Time
.
now
,
updated_at:
Time
.
now
}.
merge
(
opts
)
}.
merge
(
opts
)
end
end
...
...
db/migrate/20191223124940_add_scheduling_type_to_ci_builds.rb
0 → 100644
View file @
8c9dc985
# frozen_string_literal: true
class
AddSchedulingTypeToCiBuilds
<
ActiveRecord
::
Migration
[
5.2
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
change
add_column
:ci_builds
,
:scheduling_type
,
:integer
,
limit:
2
end
end
db/schema.rb
View file @
8c9dc985
...
@@ -677,6 +677,7 @@ ActiveRecord::Schema.define(version: 2020_02_11_152410) do
...
@@ -677,6 +677,7 @@ ActiveRecord::Schema.define(version: 2020_02_11_152410) do
t
.
bigint
"resource_group_id"
t
.
bigint
"resource_group_id"
t
.
datetime_with_timezone
"waiting_for_resource_at"
t
.
datetime_with_timezone
"waiting_for_resource_at"
t
.
boolean
"processed"
t
.
boolean
"processed"
t
.
integer
"scheduling_type"
,
limit:
2
t
.
index
[
"artifacts_expire_at"
],
name:
"index_ci_builds_on_artifacts_expire_at"
,
where:
"(artifacts_file <> ''::text)"
t
.
index
[
"artifacts_expire_at"
],
name:
"index_ci_builds_on_artifacts_expire_at"
,
where:
"(artifacts_file <> ''::text)"
t
.
index
[
"auto_canceled_by_id"
],
name:
"index_ci_builds_on_auto_canceled_by_id"
t
.
index
[
"auto_canceled_by_id"
],
name:
"index_ci_builds_on_auto_canceled_by_id"
t
.
index
[
"commit_id"
,
"artifacts_expire_at"
,
"id"
],
name:
"index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial"
,
where:
"(((type)::text = 'Ci::Build'::text) AND ((retried = false) OR (retried IS NULL)) AND ((name)::text = ANY (ARRAY[('sast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('sast:container'::character varying)::text, ('container_scanning'::character varying)::text, ('dast'::character varying)::text])))"
t
.
index
[
"commit_id"
,
"artifacts_expire_at"
,
"id"
],
name:
"index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial"
,
where:
"(((type)::text = 'Ci::Build'::text) AND ((retried = false) OR (retried IS NULL)) AND ((name)::text = ANY (ARRAY[('sast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('sast:container'::character varying)::text, ('container_scanning'::character varying)::text, ('dast'::character varying)::text])))"
...
...
doc/ci/yaml/README.md
View file @
8c9dc985
...
@@ -851,7 +851,7 @@ In this example, if the first rule:
...
@@ -851,7 +851,7 @@ In this example, if the first rule:
-
Matches, the job will be given the
`when:always`
attribute.
-
Matches, the job will be given the
`when:always`
attribute.
-
Does not match, the second and third rules will be evaluated sequentially
-
Does not match, the second and third rules will be evaluated sequentially
until a match is found. That is, the job will be given either the:
until a match is found. That is, the job will be given either the:
-
`when: manual`
attribute if the second rule matches.
-
`when: manual`
attribute if the second rule matches.
**The stage will not complete until this manual job is triggered and completes successfully.**
-
`when: on_success`
attribute if the second rule does not match. The third
-
`when: on_success`
attribute if the second rule does not match. The third
rule will always match when reached because it has no conditional clauses.
rule will always match when reached because it has no conditional clauses.
...
@@ -937,6 +937,25 @@ NOTE: **Note:**
...
@@ -937,6 +937,25 @@ NOTE: **Note:**
For performance reasons, using
`exists`
with patterns is limited to 10000
For performance reasons, using
`exists`
with patterns is limited to 10000
checks. After the 10000th check, rules with patterned globs will always match.
checks. After the 10000th check, rules with patterned globs will always match.
#### `rules:allow_failure`
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/30235) in GitLab 12.8.
You can use
[
`allow_failure: true`
](
#allow_failure
)
within
`rules:`
to allow a job to fail, or a manual job to
wait for action, without stopping the pipeline itself. All jobs using
`rules:`
default to
`allow_failure: false`
if
`allow_failure:`
is not defined.
```
yaml
job
:
script
:
"
echo
Hello,
Rules!"
rules
:
-
if
:
'
$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
==
"master"'
when
:
manual
allow_failure
:
true
```
In this example, if the first rule matches, then the job will have
`when: manual`
and
`allow_failure: true`
.
#### Complex rule clauses
#### Complex rule clauses
To conjoin
`if`
,
`changes`
, and
`exists`
clauses with an AND, use them in the
To conjoin
`if`
,
`changes`
, and
`exists`
clauses with an AND, use them in the
...
@@ -976,6 +995,7 @@ The only job attributes currently set by `rules` are:
...
@@ -976,6 +995,7 @@ The only job attributes currently set by `rules` are:
-
`when`
.
-
`when`
.
-
`start_in`
, if
`when`
is set to
`delayed`
.
-
`start_in`
, if
`when`
is set to
`delayed`
.
-
`allow_failure`
.
A job will be included in a pipeline if
`when`
is evaluated to any value
A job will be included in a pipeline if
`when`
is evaluated to any value
except
`never`
.
except
`never`
.
...
...
doc/user/clusters/applications.md
View file @
8c9dc985
...
@@ -464,8 +464,8 @@ chart is used to install this application with a
...
@@ -464,8 +464,8 @@ chart is used to install this application with a
file.
file.
NOTE:
**Note:**
NOTE:
**Note:**
The chart will deploy
4 Elasticsearch nodes: 2 masters, 1
data and 1 client node,
The chart will deploy
5 Elasticsearch nodes: 2 masters, 2
data and 1 client node,
with resource requests totalling 0.1
CPU and 3
GB RAM. Each data node requests 1.5GB of memory,
with resource requests totalling 0.1
25 CPU and 4.5
GB RAM. Each data node requests 1.5GB of memory,
which makes it incompatible with clusters of
`f1-micro`
and
`g1-small`
instance types.
which makes it incompatible with clusters of
`f1-micro`
and
`g1-small`
instance types.
## Install using GitLab CI (alpha)
## Install using GitLab CI (alpha)
...
...
doc/user/group/index.md
View file @
8c9dc985
...
@@ -241,9 +241,10 @@ and give all group members access to the project at once.
...
@@ -241,9 +241,10 @@ and give all group members access to the project at once.
Alternatively, you can
[
lock the sharing with group feature
](
#share-with-group-lock
)
.
Alternatively, you can
[
lock the sharing with group feature
](
#share-with-group-lock
)
.
## Sharing a group with another group
## Sharing a group with another group
**(CORE ONLY)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/18328) in GitLab 12.7.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/18328) in GitLab 12.7.
> This feature has been [disabled on GitLab.com](https://gitlab.com/gitlab-com/gl-infra/production/issues/1635).
Similarly to
[
sharing a project with a group
](
#sharing-a-project-with-a-group
)
,
Similarly to
[
sharing a project with a group
](
#sharing-a-project-with-a-group
)
,
you can share a group with another group to give direct group members access
you can share a group with another group to give direct group members access
...
...
lib/gitlab/ci/build/rules.rb
View file @
8c9dc985
...
@@ -6,11 +6,12 @@ module Gitlab
...
@@ -6,11 +6,12 @@ module Gitlab
class
Rules
class
Rules
include
::
Gitlab
::
Utils
::
StrongMemoize
include
::
Gitlab
::
Utils
::
StrongMemoize
Result
=
Struct
.
new
(
:when
,
:start_in
)
do
Result
=
Struct
.
new
(
:when
,
:start_in
,
:allow_failure
)
do
def
build_attributes
def
build_attributes
{
{
when:
self
.
when
,
when:
self
.
when
,
options:
{
start_in:
start_in
}.
compact
options:
{
start_in:
start_in
}.
compact
,
allow_failure:
allow_failure
}.
compact
}.
compact
end
end
...
@@ -30,7 +31,8 @@ module Gitlab
...
@@ -30,7 +31,8 @@ module Gitlab
elsif
matched_rule
=
match_rule
(
pipeline
,
context
)
elsif
matched_rule
=
match_rule
(
pipeline
,
context
)
Result
.
new
(
Result
.
new
(
matched_rule
.
attributes
[
:when
]
||
@default_when
,
matched_rule
.
attributes
[
:when
]
||
@default_when
,
matched_rule
.
attributes
[
:start_in
]
matched_rule
.
attributes
[
:start_in
],
matched_rule
.
attributes
[
:allow_failure
]
)
)
else
else
Result
.
new
(
'never'
)
Result
.
new
(
'never'
)
...
...
lib/gitlab/ci/config/entry/bridge.rb
View file @
8c9dc985
...
@@ -132,7 +132,8 @@ module Gitlab
...
@@ -132,7 +132,8 @@ module Gitlab
variables:
(
variables_value
if
variables_defined?
),
variables:
(
variables_value
if
variables_defined?
),
rules:
(
rules_value
if
has_rules?
),
rules:
(
rules_value
if
has_rules?
),
only:
only_value
,
only:
only_value
,
except:
except_value
}.
compact
except:
except_value
,
scheduling_type:
needs_defined?
&&
!
bridge_needs
?
:dag
:
:stage
}.
compact
end
end
def
bridge_needs
def
bridge_needs
...
...
lib/gitlab/ci/config/entry/job.rb
View file @
8c9dc985
...
@@ -258,7 +258,8 @@ module Gitlab
...
@@ -258,7 +258,8 @@ module Gitlab
after_script:
after_script_value
,
after_script:
after_script_value
,
ignore:
ignored?
,
ignore:
ignored?
,
needs:
needs_defined?
?
needs_value
:
nil
,
needs:
needs_defined?
?
needs_value
:
nil
,
resource_group:
resource_group
}
resource_group:
resource_group
,
scheduling_type:
needs_defined?
?
:dag
:
:stage
}
end
end
end
end
end
end
...
...
lib/gitlab/ci/config/entry/rules/rule.rb
View file @
8c9dc985
...
@@ -9,10 +9,10 @@ module Gitlab
...
@@ -9,10 +9,10 @@ module Gitlab
include
::
Gitlab
::
Config
::
Entry
::
Attributable
include
::
Gitlab
::
Config
::
Entry
::
Attributable
CLAUSES
=
%i[if changes exists]
.
freeze
CLAUSES
=
%i[if changes exists]
.
freeze
ALLOWED_KEYS
=
%i[if changes exists when start_in]
.
freeze
ALLOWED_KEYS
=
%i[if changes exists when start_in
allow_failure
]
.
freeze
ALLOWABLE_WHEN
=
%w[on_success on_failure always never manual delayed]
.
freeze
ALLOWABLE_WHEN
=
%w[on_success on_failure always never manual delayed]
.
freeze
attributes
:if
,
:changes
,
:exists
,
:when
,
:start_in
attributes
:if
,
:changes
,
:exists
,
:when
,
:start_in
,
:allow_failure
validations
do
validations
do
validates
:config
,
presence:
true
validates
:config
,
presence:
true
...
@@ -26,6 +26,7 @@ module Gitlab
...
@@ -26,6 +26,7 @@ module Gitlab
validates
:if
,
expression:
true
validates
:if
,
expression:
true
validates
:changes
,
:exists
,
array_of_strings:
true
,
length:
{
maximum:
50
}
validates
:changes
,
:exists
,
array_of_strings:
true
,
length:
{
maximum:
50
}
validates
:when
,
allowed_values:
{
in:
ALLOWABLE_WHEN
}
validates
:when
,
allowed_values:
{
in:
ALLOWABLE_WHEN
}
validates
:allow_failure
,
boolean:
true
end
end
validate
do
validate
do
...
...
lib/gitlab/ci/yaml_processor.rb
View file @
8c9dc985
...
@@ -65,6 +65,7 @@ module Gitlab
...
@@ -65,6 +65,7 @@ module Gitlab
rules:
job
[
:rules
],
rules:
job
[
:rules
],
cache:
job
[
:cache
],
cache:
job
[
:cache
],
resource_group_key:
job
[
:resource_group
],
resource_group_key:
job
[
:resource_group
],
scheduling_type:
job
[
:scheduling_type
],
options:
{
options:
{
image:
job
[
:image
],
image:
job
[
:image
],
services:
job
[
:services
],
services:
job
[
:services
],
...
...
spec/factories/ci/bridge.rb
View file @
8c9dc985
...
@@ -9,6 +9,7 @@ FactoryBot.define do
...
@@ -9,6 +9,7 @@ FactoryBot.define do
tag
{
false
}
tag
{
false
}
created_at
{
'Di 29. Okt 09:50:00 CET 2013'
}
created_at
{
'Di 29. Okt 09:50:00 CET 2013'
}
status
{
:created
}
status
{
:created
}
scheduling_type
{
'stage'
}
pipeline
factory: :ci_pipeline
pipeline
factory: :ci_pipeline
...
...
spec/factories/ci/builds.rb
View file @
8c9dc985
...
@@ -11,6 +11,7 @@ FactoryBot.define do
...
@@ -11,6 +11,7 @@ FactoryBot.define do
tag
{
false
}
tag
{
false
}
add_attribute
(
:protected
)
{
false
}
add_attribute
(
:protected
)
{
false
}
created_at
{
'Di 29. Okt 09:50:00 CET 2013'
}
created_at
{
'Di 29. Okt 09:50:00 CET 2013'
}
scheduling_type
{
'stage'
}
pending
pending
options
do
options
do
...
...
spec/frontend/diffs/components/diff_line_gutter_content_spec.js
View file @
8c9dc985
import
Vue
from
'
vue
'
;
import
Vue
x
from
'
vuex
'
;
import
{
createComponentWithStore
}
from
'
helpers/vue_mount_component_helper
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
DiffLineGutterContent
from
'
~/diffs/components/diff_line_gutter_content.vue
'
;
import
DiffLineGutterContent
from
'
~/diffs/components/diff_line_gutter_content.vue
'
;
import
DiffGutterAvatars
from
'
~/diffs/components/diff_gutter_avatars.vue
'
;
import
{
LINE_POSITION_RIGHT
}
from
'
~/diffs/constants
'
;
import
{
createStore
}
from
'
~/mr_notes/stores
'
;
import
{
createStore
}
from
'
~/mr_notes/stores
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
discussionsMockData
from
'
../mock_data/diff_discussions
'
;
import
discussionsMockData
from
'
../mock_data/diff_discussions
'
;
import
diffFileMockData
from
'
../mock_data/diff_file
'
;
import
diffFileMockData
from
'
../mock_data/diff_file
'
;
const
localVue
=
createLocalVue
();
localVue
.
use
(
Vuex
);
const
TEST_USER_ID
=
'
abc123
'
;
const
TEST_USER
=
{
id
:
TEST_USER_ID
};
const
TEST_LINE_NUMBER
=
1
;
const
TEST_LINE_CODE
=
'
LC_42
'
;
const
TEST_FILE_HASH
=
diffFileMockData
.
file_hash
;
describe
(
'
DiffLineGutterContent
'
,
()
=>
{
describe
(
'
DiffLineGutterContent
'
,
()
=>
{
const
getDiffFileMock
=
()
=>
Object
.
assign
({},
diffFileMockData
);
let
wrapper
;
const
createComponent
=
(
options
=
{})
=>
{
let
line
;
const
cmp
=
Vue
.
extend
(
DiffLineGutterContent
);
let
store
;
const
props
=
Object
.
assign
({},
options
);
props
.
line
=
{
beforeEach
(()
=>
{
line_code
:
'
LC_42
'
,
store
=
createStore
();
store
.
state
.
notes
.
userData
=
TEST_USER
;
line
=
{
line_code
:
TEST_LINE_CODE
,
type
:
'
new
'
,
type
:
'
new
'
,
old_line
:
null
,
old_line
:
null
,
new_line
:
1
,
new_line
:
1
,
discussions
:
[{
...
discussionsMockData
}],
discussions
:
[{
...
discussionsMockData
}],
discussionsExpanded
:
true
,
text
:
'
+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>
\n
'
,
text
:
'
+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>
\n
'
,
rich_text
:
'
+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>
\n
'
,
rich_text
:
'
+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>
\n
'
,
meta_data
:
null
,
meta_data
:
null
,
};
};
props
.
fileHash
=
getDiffFileMock
().
file_hash
;
});
props
.
contextLinesPath
=
'
/context/lines/path
'
;
return
createComponentWithStore
(
cmp
,
createStore
(),
props
).
$mount
();
afterEach
(()
=>
{
};
wrapper
.
destroy
();
});
describe
(
'
computed
'
,
()
=>
{
const
setWindowLocation
=
value
=>
{
describe
(
'
lineHref
'
,
()
=>
{
Object
.
defineProperty
(
window
,
'
location
'
,
{
it
(
'
should prepend # to lineCode
'
,
()
=>
{
writable
:
true
,
const
lineCode
=
'
LC_42
'
;
value
,
const
component
=
createComponent
();
});
};
const
createComponent
=
(
props
=
{})
=>
{
wrapper
=
shallowMount
(
DiffLineGutterContent
,
{
localVue
,
store
,
propsData
:
{
line
,
fileHash
:
TEST_FILE_HASH
,
contextLinesPath
:
'
/context/lines/path
'
,
...
props
,
},
});
};
const
findNoteButton
=
()
=>
wrapper
.
find
(
'
.js-add-diff-note-button
'
);
const
findLineNumber
=
()
=>
wrapper
.
find
({
ref
:
'
lineNumberRef
'
});
const
findAvatars
=
()
=>
wrapper
.
find
(
DiffGutterAvatars
);
describe
(
'
comment button
'
,
()
=>
{
it
.
each
`
showCommentButton | userData | query | expectation
${
true
}
|
${
TEST_USER
}
|
${
'
diff_head=false
'
}
|
${
true
}
${
true
}
|
${
TEST_USER
}
|
${
'
diff_head=true
'
}
|
${
false
}
${
false
}
|
${
TEST_USER
}
|
${
'
bogus
'
}
|
${
false
}
${
true
}
|
${
null
}
|
${
''
}
|
${
false
}
`
(
'
exists is $expectation - with showCommentButton ($showCommentButton) userData ($userData) query ($query)
'
,
({
showCommentButton
,
userData
,
query
,
expectation
})
=>
{
store
.
state
.
notes
.
userData
=
userData
;
setWindowLocation
({
href
:
`
${
TEST_HOST
}
?
${
query
}
`
});
createComponent
({
showCommentButton
});
expect
(
findNoteButton
().
exists
()).
toBe
(
expectation
);
},
);
it
.
each
`
isHover | otherProps | discussions | expectation
${
true
}
|
${{}}
|
$
{[]}
|
${
true
}
${
false
}
|
${{}}
|
$
{[]}
|
${
false
}
${
true
}
|
${{
isMatchLine
:
true
}
} |
${[]}
|
${
false
}
${
true
}
|
${{
isContextLine
:
true
}
} |
${[]}
|
${
false
}
${
true
}
|
${{
isMetaLine
:
true
}
} |
${[]}
|
${
false
}
${
true
}
|
${{}}
|
$
{[{}]}
|
${
false
}
`
(
'
visible is $expectation - with isHover ($isHover), discussions ($discussions), otherProps ($otherProps)
'
,
({
isHover
,
otherProps
,
discussions
,
expectation
})
=>
{
line
.
discussions
=
discussions
;
createComponent
({
showCommentButton
:
true
,
isHover
,
...
otherProps
,
});
expect
(
component
.
lineHref
).
toEqual
(
`#
${
lineCode
}
`
);
expect
(
findNoteButton
().
isVisible
()).
toBe
(
expectation
);
},
);
});
});
it
(
'
should return # if there is no lineCode
'
,
()
=>
{
describe
(
'
line number
'
,
()
=>
{
const
component
=
createComponent
();
describe
(
'
without lineNumber prop
'
,
()
=>
{
component
.
line
.
line_code
=
''
;
it
(
'
does not render
'
,
()
=>
{
createComponent
();
expect
(
component
.
lineHref
).
toEqual
(
'
#
'
);
expect
(
findLineNumber
().
exists
()).
toBe
(
false
);
});
});
});
});
describe
(
'
discussions, hasDiscussions, shouldShowAvatarsOnGutter
'
,
()
=>
{
describe
(
'
with lineNumber prop
'
,
()
=>
{
it
(
'
should return empty array when there is no discussion
'
,
()
=>
{
describe
.
each
`
const
component
=
createComponent
();
lineProps | expectedHref | expectedClickArg
component
.
line
.
discussions
=
[];
${{
line_code
:
TEST_LINE_CODE
}
} |
${
`#
${
TEST_LINE_CODE
}
`
}
|
${
TEST_LINE_CODE
}
${{
line_code
:
undefined
}
} |
${
'
#
'
}
|
${
undefined
}
${{
line_code
:
undefined
,
left
:
{
line_code
:
TEST_LINE_CODE
}
}} |
${
'
#
'
}
|
${
TEST_LINE_CODE
}
${{
line_code
:
undefined
,
right
:
{
line_code
:
TEST_LINE_CODE
}
}} |
${
'
#
'
}
|
${
TEST_LINE_CODE
}
`
(
'
with line ($lineProps)
'
,
({
lineProps
,
expectedHref
,
expectedClickArg
})
=>
{
beforeEach
(()
=>
{
jest
.
spyOn
(
store
,
'
dispatch
'
).
mockImplementation
();
Object
.
assign
(
line
,
lineProps
);
createComponent
({
lineNumber
:
TEST_LINE_NUMBER
});
});
expect
(
component
.
hasDiscussions
).
toEqual
(
false
);
it
(
'
renders
'
,
()
=>
{
expect
(
component
.
shouldShowAvatarsOnGutter
).
toEqual
(
false
);
expect
(
findLineNumber
().
exists
()).
toBe
(
true
);
expect
(
findLineNumber
().
attributes
()).
toEqual
({
href
:
expectedHref
,
'
data-linenumber
'
:
TEST_LINE_NUMBER
.
toString
(),
});
});
});
it
(
'
should return discussions for the given lineCode
'
,
()
=>
{
it
(
'
on click, dispatches setHighlightedRow
'
,
()
=>
{
const
cmp
=
Vue
.
extend
(
DiffLineGutterContent
);
expect
(
store
.
dispatch
).
not
.
toHaveBeenCalled
();
const
props
=
{
line
:
getDiffFileMock
().
highlighted_diff_lines
[
1
],
findLineNumber
().
trigger
(
'
click
'
);
fileHash
:
getDiffFileMock
().
file_hash
,
showCommentButton
:
true
,
contextLinesPath
:
'
/context/lines/path
'
,
};
props
.
line
.
discussions
=
[
Object
.
assign
({},
discussionsMockData
)];
const
component
=
createComponentWithStore
(
cmp
,
createStore
(),
props
).
$mount
();
expect
(
component
.
hasDiscussions
).
toEqual
(
true
);
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
diffs/setHighlightedRow
'
,
expectedClickArg
);
expect
(
component
.
shouldShowAvatarsOnGutter
).
toEqual
(
true
);
});
});
});
});
});
});
describe
(
'
template
'
,
()
=>
{
it
(
'
should render comment button
'
,
()
=>
{
const
component
=
createComponent
({
showCommentButton
:
true
,
});
});
Object
.
defineProperty
(
component
,
'
isLoggedIn
'
,
{
get
()
{
describe
(
'
diff-gutter-avatars
'
,
()
=>
{
return
true
;
describe
(
'
with showCommentButton
'
,
()
=>
{
},
beforeEach
(()
=>
{
jest
.
spyOn
(
store
,
'
dispatch
'
).
mockImplementation
();
createComponent
({
showCommentButton
:
true
});
});
});
expect
(
component
.
$el
.
querySelector
(
'
.js-add-diff-note-button
'
)).
toBeDefined
();
it
(
'
renders
'
,
()
=>
{
expect
(
findAvatars
().
props
()).
toEqual
({
discussions
:
line
.
discussions
,
discussionsExpanded
:
line
.
discussionsExpanded
,
});
});
});
it
(
'
should render line link
'
,
()
=>
{
it
(
'
toggles line discussion
'
,
()
=>
{
const
lineNumber
=
42
;
expect
(
store
.
dispatch
).
not
.
toHaveBeenCalled
();
const
lineCode
=
`LC_
${
lineNumber
}
`
;
const
component
=
createComponent
({
lineNumber
,
lineCode
});
const
link
=
component
.
$el
.
querySelector
(
'
a
'
);
expect
(
link
.
href
.
indexOf
(
`#
${
lineCode
}
`
)).
toBeGreaterThan
(
-
1
);
findAvatars
().
vm
.
$emit
(
'
toggleLineDiscussions
'
);
expect
(
link
.
dataset
.
linenumber
).
toEqual
(
lineNumber
.
toString
());
});
it
(
'
should render user avatars
'
,
()
=>
{
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
diffs/toggleLineDiscussions
'
,
{
const
component
=
createComponent
({
lineCode
:
TEST_LINE_CODE
,
showCommentButton
:
true
,
fileHash
:
TEST_FILE_HASH
,
lineCode
:
getDiffFileMock
().
highlighted_diff_lines
[
1
].
line_code
,
expanded
:
!
line
.
discussionsExpanded
,
});
});
});
expect
(
component
.
$el
.
querySelector
(
'
.diff-comment-avatar-holders
'
)).
not
.
toBe
(
null
);
});
});
it
.
each
`
props | lineProps | expectation
${{
showCommentButton
:
true
}
} |
${{}}
|
$
{
true
}
${{
showCommentButton
:
false
}
} |
${{}}
|
$
{
false
}
${{
showCommentButton
:
true
,
linePosition
:
LINE_POSITION_RIGHT
}
} |
${{
type
:
null
}
} |
${
false
}
${{
showCommentButton
:
true
}
} |
${{
discussions
:
[]
}
} |
${
false
}
`
(
'
exists is $expectation - with props ($props), line ($lineProps)
'
,
({
props
,
lineProps
,
expectation
})
=>
{
Object
.
assign
(
line
,
lineProps
);
createComponent
(
props
);
expect
(
findAvatars
().
exists
()).
toBe
(
expectation
);
},
);
});
});
});
});
spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
View file @
8c9dc985
...
@@ -52,6 +52,7 @@ describe('ShortcutsIssuable', function() {
...
@@ -52,6 +52,7 @@ describe('ShortcutsIssuable', function() {
return
documentFragment
;
return
documentFragment
;
});
});
};
};
describe
(
'
with empty selection
'
,
()
=>
{
describe
(
'
with empty selection
'
,
()
=>
{
it
(
'
does not return an error
'
,
()
=>
{
it
(
'
does not return an error
'
,
()
=>
{
ShortcutsIssuable
.
replyWithSelectedText
(
true
);
ShortcutsIssuable
.
replyWithSelectedText
(
true
);
...
@@ -297,5 +298,18 @@ describe('ShortcutsIssuable', function() {
...
@@ -297,5 +298,18 @@ describe('ShortcutsIssuable', function() {
});
});
});
});
});
});
describe
(
'
with a valid selection with no text content
'
,
()
=>
{
it
(
'
returns the proper markdown
'
,
done
=>
{
stubSelection
(
'
<img src="foo" alt="image" />
'
);
ShortcutsIssuable
.
replyWithSelectedText
(
true
);
setTimeout
(()
=>
{
expect
(
$
(
FORM_SELECTOR
).
val
()).
toBe
(
'
> ![image](http://localhost:9876/foo)
\n\n
'
);
done
();
});
});
});
});
});
});
});
spec/lib/gitlab/ci/build/rules_spec.rb
View file @
8c9dc985
...
@@ -102,9 +102,9 @@ describe Gitlab::Ci::Build::Rules do
...
@@ -102,9 +102,9 @@ describe Gitlab::Ci::Build::Rules do
end
end
context
'with one rule without any clauses'
do
context
'with one rule without any clauses'
do
let
(
:rule_list
)
{
[{
when:
'manual'
}]
}
let
(
:rule_list
)
{
[{
when:
'manual'
,
allow_failure:
true
}]
}
it
{
is_expected
.
to
eq
(
described_class
::
Result
.
new
(
'manual'
))
}
it
{
is_expected
.
to
eq
(
described_class
::
Result
.
new
(
'manual'
,
nil
,
true
))
}
end
end
context
'with one matching rule'
do
context
'with one matching rule'
do
...
@@ -166,5 +166,51 @@ describe Gitlab::Ci::Build::Rules do
...
@@ -166,5 +166,51 @@ describe Gitlab::Ci::Build::Rules do
end
end
end
end
end
end
context
'with only allow_failure'
do
context
'with matching rule'
do
let
(
:rule_list
)
{
[{
if:
'$VAR == null'
,
allow_failure:
true
}]
}
it
{
is_expected
.
to
eq
(
described_class
::
Result
.
new
(
'on_success'
,
nil
,
true
))
}
end
context
'with non-matching rule'
do
let
(
:rule_list
)
{
[{
if:
'$VAR != null'
,
allow_failure:
true
}]
}
it
{
is_expected
.
to
eq
(
described_class
::
Result
.
new
(
'never'
))
}
end
end
end
describe
'Gitlab::Ci::Build::Rules::Result'
do
let
(
:when_value
)
{
'on_success'
}
let
(
:start_in
)
{
nil
}
let
(
:allow_failure
)
{
nil
}
subject
{
Gitlab
::
Ci
::
Build
::
Rules
::
Result
.
new
(
when_value
,
start_in
,
allow_failure
)
}
describe
'#build_attributes'
do
it
'compacts nil values'
do
expect
(
subject
.
build_attributes
).
to
eq
(
options:
{},
when:
'on_success'
)
end
end
describe
'#pass?'
do
context
"'when' is 'never'"
do
let!
(
:when_value
)
{
'never'
}
it
'returns false'
do
expect
(
subject
.
pass?
).
to
eq
(
false
)
end
end
context
"'when' is 'on_success'"
do
let!
(
:when_value
)
{
'on_success'
}
it
'returns true'
do
expect
(
subject
.
pass?
).
to
eq
(
true
)
end
end
end
end
end
end
end
spec/lib/gitlab/ci/config/entry/bridge_spec.rb
View file @
8c9dc985
...
@@ -105,7 +105,8 @@ describe Gitlab::Ci::Config::Entry::Bridge do
...
@@ -105,7 +105,8 @@ describe Gitlab::Ci::Config::Entry::Bridge do
trigger:
{
project:
'some/project'
},
trigger:
{
project:
'some/project'
},
ignore:
false
,
ignore:
false
,
stage:
'test'
,
stage:
'test'
,
only:
{
refs:
%w[branches tags]
})
only:
{
refs:
%w[branches tags]
},
scheduling_type: :stage
)
end
end
end
end
end
end
...
@@ -126,7 +127,8 @@ describe Gitlab::Ci::Config::Entry::Bridge do
...
@@ -126,7 +127,8 @@ describe Gitlab::Ci::Config::Entry::Bridge do
branch:
'feature'
},
branch:
'feature'
},
ignore:
false
,
ignore:
false
,
stage:
'test'
,
stage:
'test'
,
only:
{
refs:
%w[branches tags]
})
only:
{
refs:
%w[branches tags]
},
scheduling_type: :stage
)
end
end
end
end
end
end
...
...
spec/lib/gitlab/ci/config/entry/job_spec.rb
View file @
8c9dc985
...
@@ -110,6 +110,10 @@ describe Gitlab::Ci::Config::Entry::Job do
...
@@ -110,6 +110,10 @@ describe Gitlab::Ci::Config::Entry::Job do
it
{
expect
(
entry
).
to
be_valid
}
it
{
expect
(
entry
).
to
be_valid
}
it
"returns scheduling_type as :dag"
do
expect
(
entry
.
value
[
:scheduling_type
]).
to
eq
(
:dag
)
end
context
'when has dependencies'
do
context
'when has dependencies'
do
let
(
:config
)
do
let
(
:config
)
do
{
{
...
@@ -598,7 +602,8 @@ describe Gitlab::Ci::Config::Entry::Job do
...
@@ -598,7 +602,8 @@ describe Gitlab::Ci::Config::Entry::Job do
ignore:
false
,
ignore:
false
,
after_script:
%w[cleanup]
,
after_script:
%w[cleanup]
,
only:
{
refs:
%w[branches tags]
},
only:
{
refs:
%w[branches tags]
},
variables:
{})
variables:
{},
scheduling_type: :stage
)
end
end
end
end
end
end
...
...
spec/lib/gitlab/ci/config/entry/jobs_spec.rb
View file @
8c9dc985
...
@@ -98,7 +98,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do
...
@@ -98,7 +98,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do
name: :my_trigger
,
name: :my_trigger
,
only:
{
refs:
%w[branches tags]
},
only:
{
refs:
%w[branches tags]
},
stage:
'test'
,
stage:
'test'
,
trigger:
{
project:
'my/project'
}
trigger:
{
project:
'my/project'
},
scheduling_type: :stage
},
},
regular_job:
{
regular_job:
{
ignore:
false
,
ignore:
false
,
...
@@ -106,7 +107,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do
...
@@ -106,7 +107,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do
only:
{
refs:
%w[branches tags]
},
only:
{
refs:
%w[branches tags]
},
script:
[
'something'
],
script:
[
'something'
],
stage:
'test'
,
stage:
'test'
,
variables:
{}
variables:
{},
scheduling_type: :stage
})
})
end
end
end
end
...
...
spec/lib/gitlab/ci/config/entry/root_spec.rb
View file @
8c9dc985
...
@@ -130,7 +130,8 @@ describe Gitlab::Ci::Config::Entry::Root do
...
@@ -130,7 +130,8 @@ describe Gitlab::Ci::Config::Entry::Root do
variables:
{},
variables:
{},
ignore:
false
,
ignore:
false
,
after_script:
[
'make clean'
],
after_script:
[
'make clean'
],
only:
{
refs:
%w[branches tags]
}
}
only:
{
refs:
%w[branches tags]
},
scheduling_type: :stage
}
)
)
expect
(
root
.
jobs_value
[
:spinach
]).
to
eq
(
expect
(
root
.
jobs_value
[
:spinach
]).
to
eq
(
{
name: :spinach
,
{
name: :spinach
,
...
@@ -143,7 +144,8 @@ describe Gitlab::Ci::Config::Entry::Root do
...
@@ -143,7 +144,8 @@ describe Gitlab::Ci::Config::Entry::Root do
variables:
{},
variables:
{},
ignore:
false
,
ignore:
false
,
after_script:
[
'make clean'
],
after_script:
[
'make clean'
],
only:
{
refs:
%w[branches tags]
}
}
only:
{
refs:
%w[branches tags]
},
scheduling_type: :stage
}
)
)
expect
(
root
.
jobs_value
[
:release
]).
to
eq
(
expect
(
root
.
jobs_value
[
:release
]).
to
eq
(
{
name: :release
,
{
name: :release
,
...
@@ -157,7 +159,8 @@ describe Gitlab::Ci::Config::Entry::Root do
...
@@ -157,7 +159,8 @@ describe Gitlab::Ci::Config::Entry::Root do
only:
{
refs:
%w(branches tags)
},
only:
{
refs:
%w(branches tags)
},
variables:
{},
variables:
{},
after_script:
[],
after_script:
[],
ignore:
false
}
ignore:
false
,
scheduling_type: :stage
}
)
)
end
end
end
end
...
@@ -203,7 +206,8 @@ describe Gitlab::Ci::Config::Entry::Root do
...
@@ -203,7 +206,8 @@ describe Gitlab::Ci::Config::Entry::Root do
variables:
{},
variables:
{},
ignore:
false
,
ignore:
false
,
after_script:
[
'make clean'
],
after_script:
[
'make clean'
],
only:
{
refs:
%w[branches tags]
}
},
only:
{
refs:
%w[branches tags]
},
scheduling_type: :stage
},
spinach:
{
name: :spinach
,
spinach:
{
name: :spinach
,
before_script:
[],
before_script:
[],
script:
%w[spinach]
,
script:
%w[spinach]
,
...
@@ -214,7 +218,8 @@ describe Gitlab::Ci::Config::Entry::Root do
...
@@ -214,7 +218,8 @@ describe Gitlab::Ci::Config::Entry::Root do
variables:
{
'VAR'
=>
'AA'
},
variables:
{
'VAR'
=>
'AA'
},
ignore:
false
,
ignore:
false
,
after_script:
[
'make clean'
],
after_script:
[
'make clean'
],
only:
{
refs:
%w[branches tags]
}
}
only:
{
refs:
%w[branches tags]
},
scheduling_type: :stage
}
)
)
end
end
end
end
...
...
spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb
View file @
8c9dc985
...
@@ -27,8 +27,14 @@ describe Gitlab::Ci::Config::Entry::Rules::Rule do
...
@@ -27,8 +27,14 @@ describe Gitlab::Ci::Config::Entry::Rules::Rule do
it
{
is_expected
.
to
be_valid
}
it
{
is_expected
.
to
be_valid
}
end
end
context
'with an allow_failure: value but no clauses'
do
let
(
:config
)
{
{
allow_failure:
true
}
}
it
{
is_expected
.
to
be_valid
}
end
context
'when specifying an if: clause'
do
context
'when specifying an if: clause'
do
let
(
:config
)
{
{
if:
'$THIS || $THAT'
,
when:
'manual'
}
}
let
(
:config
)
{
{
if:
'$THIS || $THAT'
,
when:
'manual'
,
allow_failure:
true
}
}
it
{
is_expected
.
to
be_valid
}
it
{
is_expected
.
to
be_valid
}
...
@@ -37,6 +43,12 @@ describe Gitlab::Ci::Config::Entry::Rules::Rule do
...
@@ -37,6 +43,12 @@ describe Gitlab::Ci::Config::Entry::Rules::Rule do
it
{
is_expected
.
to
eq
(
'manual'
)
}
it
{
is_expected
.
to
eq
(
'manual'
)
}
end
end
describe
'#allow_failure'
do
subject
{
entry
.
allow_failure
}
it
{
is_expected
.
to
eq
(
true
)
}
end
end
end
context
'using a list of multiple expressions'
do
context
'using a list of multiple expressions'
do
...
@@ -328,16 +340,43 @@ describe Gitlab::Ci::Config::Entry::Rules::Rule do
...
@@ -328,16 +340,43 @@ describe Gitlab::Ci::Config::Entry::Rules::Rule do
end
end
end
end
end
end
context
'allow_failure: validation'
do
context
'with an invalid string allow_failure:'
do
let
(
:config
)
do
{
if:
'$THIS == "that"'
,
allow_failure:
'always'
}
end
it
{
is_expected
.
to
be_a
(
described_class
)
}
it
{
is_expected
.
not_to
be_valid
}
it
'returns an error about invalid allow_failure:'
do
expect
(
subject
.
errors
).
to
include
(
/rule allow failure should be a boolean value/
)
end
context
'when composed'
do
before
do
subject
.
compose!
end
it
{
is_expected
.
not_to
be_valid
}
it
'returns an error about invalid allow_failure:'
do
expect
(
subject
.
errors
).
to
include
(
/rule allow failure should be a boolean value/
)
end
end
end
end
end
end
describe
'#value'
do
describe
'#value'
do
subject
{
entry
.
value
}
subject
{
entry
.
value
}
context
'when specifying an if: clause'
do
context
'when specifying an if: clause'
do
let
(
:config
)
{
{
if:
'$THIS || $THAT'
,
when:
'manual'
}
}
let
(
:config
)
{
{
if:
'$THIS || $THAT'
,
when:
'manual'
,
allow_failure:
true
}
}
it
'stores the expression as "if"'
do
it
'stores the expression as "if"'
do
expect
(
subject
).
to
eq
(
if:
'$THIS || $THAT'
,
when:
'manual'
)
expect
(
subject
).
to
eq
(
if:
'$THIS || $THAT'
,
when:
'manual'
,
allow_failure:
true
)
end
end
end
end
...
...
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
View file @
8c9dc985
...
@@ -6,7 +6,7 @@ describe Gitlab::Ci::Pipeline::Seed::Build do
...
@@ -6,7 +6,7 @@ describe Gitlab::Ci::Pipeline::Seed::Build do
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:head_sha
)
{
project
.
repository
.
head_commit
.
id
}
let
(
:head_sha
)
{
project
.
repository
.
head_commit
.
id
}
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
,
project:
project
,
sha:
head_sha
)
}
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
,
project:
project
,
sha:
head_sha
)
}
let
(
:attributes
)
{
{
name:
'rspec'
,
ref:
'master'
}
}
let
(
:attributes
)
{
{
name:
'rspec'
,
ref:
'master'
,
scheduling_type: :stage
}
}
let
(
:previous_stages
)
{
[]
}
let
(
:previous_stages
)
{
[]
}
let
(
:seed_build
)
{
described_class
.
new
(
pipeline
,
attributes
,
previous_stages
)
}
let
(
:seed_build
)
{
described_class
.
new
(
pipeline
,
attributes
,
previous_stages
)
}
...
@@ -244,7 +244,9 @@ describe Gitlab::Ci::Pipeline::Seed::Build do
...
@@ -244,7 +244,9 @@ describe Gitlab::Ci::Pipeline::Seed::Build do
context
'when job is a bridge'
do
context
'when job is a bridge'
do
let
(
:attributes
)
do
let
(
:attributes
)
do
{
name:
'rspec'
,
ref:
'master'
,
options:
{
trigger:
'my/project'
}
}
{
name:
'rspec'
,
ref:
'master'
,
options:
{
trigger:
'my/project'
},
scheduling_type: :stage
}
end
end
it
{
is_expected
.
to
be_a
(
::
Ci
::
Bridge
)
}
it
{
is_expected
.
to
be_a
(
::
Ci
::
Bridge
)
}
...
...
spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
View file @
8c9dc985
...
@@ -10,9 +10,9 @@ describe Gitlab::Ci::Pipeline::Seed::Stage do
...
@@ -10,9 +10,9 @@ describe Gitlab::Ci::Pipeline::Seed::Stage do
let
(
:attributes
)
do
let
(
:attributes
)
do
{
name:
'test'
,
{
name:
'test'
,
index:
0
,
index:
0
,
builds:
[{
name:
'rspec'
},
builds:
[{
name:
'rspec'
,
scheduling_type: :stage
},
{
name:
'spinach'
},
{
name:
'spinach'
,
scheduling_type: :stage
},
{
name:
'deploy'
,
only:
{
refs:
[
'feature'
]
}
}]
}
{
name:
'deploy'
,
only:
{
refs:
[
'feature'
]
}
}]
,
scheduling_type: :stage
}
end
end
subject
do
subject
do
...
...
spec/lib/gitlab/ci/yaml_processor_spec.rb
View file @
8c9dc985
...
@@ -36,7 +36,8 @@ module Gitlab
...
@@ -36,7 +36,8 @@ module Gitlab
interruptible:
true
,
interruptible:
true
,
allow_failure:
false
,
allow_failure:
false
,
when:
"on_success"
,
when:
"on_success"
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
end
end
...
@@ -66,7 +67,8 @@ module Gitlab
...
@@ -66,7 +67,8 @@ module Gitlab
],
],
allow_failure:
false
,
allow_failure:
false
,
when:
'on_success'
,
when:
'on_success'
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
end
end
...
@@ -126,7 +128,8 @@ module Gitlab
...
@@ -126,7 +128,8 @@ module Gitlab
interruptible:
true
,
interruptible:
true
,
allow_failure:
false
,
allow_failure:
false
,
when:
"on_success"
,
when:
"on_success"
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
end
end
...
@@ -282,6 +285,7 @@ module Gitlab
...
@@ -282,6 +285,7 @@ module Gitlab
allow_failure:
false
,
allow_failure:
false
,
when:
"on_success"
,
when:
"on_success"
,
yaml_variables:
[],
yaml_variables:
[],
scheduling_type: :stage
,
options:
{
script:
[
"rspec"
]
},
options:
{
script:
[
"rspec"
]
},
only:
{
refs:
[
"branches"
]
}
}]
},
only:
{
refs:
[
"branches"
]
}
}]
},
{
name:
"deploy"
,
{
name:
"deploy"
,
...
@@ -293,6 +297,7 @@ module Gitlab
...
@@ -293,6 +297,7 @@ module Gitlab
allow_failure:
false
,
allow_failure:
false
,
when:
"on_success"
,
when:
"on_success"
,
yaml_variables:
[],
yaml_variables:
[],
scheduling_type: :stage
,
options:
{
script:
[
"cap prod"
]
},
options:
{
script:
[
"cap prod"
]
},
only:
{
refs:
[
"tags"
]
}
}]
},
only:
{
refs:
[
"tags"
]
}
}]
},
{
name:
".post"
,
{
name:
".post"
,
...
@@ -642,7 +647,8 @@ module Gitlab
...
@@ -642,7 +647,8 @@ module Gitlab
},
},
allow_failure:
false
,
allow_failure:
false
,
when:
"on_success"
,
when:
"on_success"
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
...
@@ -674,7 +680,8 @@ module Gitlab
...
@@ -674,7 +680,8 @@ module Gitlab
},
},
allow_failure:
false
,
allow_failure:
false
,
when:
"on_success"
,
when:
"on_success"
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
end
end
...
@@ -702,7 +709,8 @@ module Gitlab
...
@@ -702,7 +709,8 @@ module Gitlab
},
},
allow_failure:
false
,
allow_failure:
false
,
when:
"on_success"
,
when:
"on_success"
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
...
@@ -728,7 +736,8 @@ module Gitlab
...
@@ -728,7 +736,8 @@ module Gitlab
},
},
allow_failure:
false
,
allow_failure:
false
,
when:
"on_success"
,
when:
"on_success"
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
end
end
...
@@ -1250,7 +1259,8 @@ module Gitlab
...
@@ -1250,7 +1259,8 @@ module Gitlab
},
},
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
...
@@ -1604,7 +1614,8 @@ module Gitlab
...
@@ -1604,7 +1614,8 @@ module Gitlab
},
},
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
)
)
expect
(
subject
.
builds
[
4
]).
to
eq
(
expect
(
subject
.
builds
[
4
]).
to
eq
(
stage:
"test"
,
stage:
"test"
,
...
@@ -1618,7 +1629,8 @@ module Gitlab
...
@@ -1618,7 +1629,8 @@ module Gitlab
],
],
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :dag
)
)
end
end
end
end
...
@@ -1644,7 +1656,8 @@ module Gitlab
...
@@ -1644,7 +1656,8 @@ module Gitlab
},
},
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
)
)
expect
(
subject
.
builds
[
4
]).
to
eq
(
expect
(
subject
.
builds
[
4
]).
to
eq
(
stage:
"test"
,
stage:
"test"
,
...
@@ -1660,7 +1673,8 @@ module Gitlab
...
@@ -1660,7 +1673,8 @@ module Gitlab
],
],
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :dag
)
)
end
end
end
end
...
@@ -1682,7 +1696,8 @@ module Gitlab
...
@@ -1682,7 +1696,8 @@ module Gitlab
],
],
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :dag
)
)
end
end
end
end
...
@@ -1712,7 +1727,8 @@ module Gitlab
...
@@ -1712,7 +1727,8 @@ module Gitlab
],
],
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :dag
)
)
end
end
end
end
...
@@ -1849,7 +1865,8 @@ module Gitlab
...
@@ -1849,7 +1865,8 @@ module Gitlab
},
},
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
end
end
...
@@ -1895,7 +1912,8 @@ module Gitlab
...
@@ -1895,7 +1912,8 @@ module Gitlab
},
},
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
expect
(
subject
.
second
).
to
eq
({
expect
(
subject
.
second
).
to
eq
({
stage:
"build"
,
stage:
"build"
,
...
@@ -1907,7 +1925,8 @@ module Gitlab
...
@@ -1907,7 +1925,8 @@ module Gitlab
},
},
when:
"on_success"
,
when:
"on_success"
,
allow_failure:
false
,
allow_failure:
false
,
yaml_variables:
[]
yaml_variables:
[],
scheduling_type: :stage
})
})
end
end
end
end
...
...
spec/lib/gitlab/import_export/safe_model_attributes.yml
View file @
8c9dc985
...
@@ -360,6 +360,7 @@ CommitStatus:
...
@@ -360,6 +360,7 @@ CommitStatus:
-
upstream_pipeline_id
-
upstream_pipeline_id
-
interruptible
-
interruptible
-
processed
-
processed
-
scheduling_type
Ci::Variable:
Ci::Variable:
-
id
-
id
-
project_id
-
project_id
...
...
spec/models/ci/build_spec.rb
View file @
8c9dc985
...
@@ -3007,7 +3007,8 @@ describe Ci::Build do
...
@@ -3007,7 +3007,8 @@ describe Ci::Build do
stage:
'test'
,
stage:
'test'
,
ref:
'feature'
,
ref:
'feature'
,
project:
project
,
project:
project
,
pipeline:
pipeline
pipeline:
pipeline
,
scheduling_type: :stage
)
)
end
end
...
...
spec/models/ci/processable_spec.rb
View file @
8c9dc985
...
@@ -52,4 +52,72 @@ describe Ci::Processable do
...
@@ -52,4 +52,72 @@ describe Ci::Processable do
end
end
end
end
end
end
describe
'validate presence of scheduling_type'
do
context
'on create'
do
let
(
:processable
)
do
build
(
:ci_build
,
:created
,
project:
project
,
pipeline:
pipeline
,
importing:
importing
,
scheduling_type:
nil
)
end
context
'when importing'
do
let
(
:importing
)
{
true
}
context
'when validate_scheduling_type_of_processables is true'
do
before
do
stub_feature_flags
(
validate_scheduling_type_of_processables:
true
)
end
it
'does not validate'
do
expect
(
processable
).
to
be_valid
end
end
context
'when validate_scheduling_type_of_processables is false'
do
before
do
stub_feature_flags
(
validate_scheduling_type_of_processables:
false
)
end
it
'does not validate'
do
expect
(
processable
).
to
be_valid
end
end
end
context
'when not importing'
do
let
(
:importing
)
{
false
}
context
'when validate_scheduling_type_of_processables is true'
do
before
do
stub_feature_flags
(
validate_scheduling_type_of_processables:
true
)
end
it
'validates'
do
expect
(
processable
).
not_to
be_valid
end
end
context
'when validate_scheduling_type_of_processables is false'
do
before
do
stub_feature_flags
(
validate_scheduling_type_of_processables:
false
)
end
it
'does not validate'
do
expect
(
processable
).
to
be_valid
end
end
end
end
context
'on update'
do
let
(
:processable
)
{
create
(
:ci_build
,
:created
,
project:
project
,
pipeline:
pipeline
)
}
it
'does not validate'
do
processable
.
scheduling_type
=
nil
expect
(
processable
).
to
be_valid
end
end
end
end
end
spec/services/ci/create_pipeline_service/needs_spec.rb
View file @
8c9dc985
...
@@ -131,6 +131,10 @@ describe Ci::CreatePipelineService do
...
@@ -131,6 +131,10 @@ describe Ci::CreatePipelineService do
)
)
end
end
end
end
it
"sets scheduling_type as 'dag'"
do
expect
(
test_a_build
.
scheduling_type
).
to
eq
(
'dag'
)
end
end
end
context
'with an invalid config'
do
context
'with an invalid config'
do
...
...
spec/services/ci/create_pipeline_service_spec.rb
View file @
8c9dc985
...
@@ -1750,9 +1750,9 @@ describe Ci::CreatePipelineService do
...
@@ -1750,9 +1750,9 @@ describe Ci::CreatePipelineService do
let
(
:ref_name
)
{
'refs/heads/master'
}
let
(
:ref_name
)
{
'refs/heads/master'
}
let
(
:pipeline
)
{
execute_service
}
let
(
:pipeline
)
{
execute_service
}
let
(
:build_names
)
{
pipeline
.
builds
.
pluck
(
:name
)
}
let
(
:build_names
)
{
pipeline
.
builds
.
pluck
(
:name
)
}
let
(
:regular_job
)
{
pipeline
.
builds
.
find_by
(
name:
'regular-job'
)
}
let
(
:regular_job
)
{
find_job
(
'regular-job'
)
}
let
(
:rules_job
)
{
pipeline
.
builds
.
find_by
(
name:
'rules-job'
)
}
let
(
:rules_job
)
{
find_job
(
'rules-job'
)
}
let
(
:delayed_job
)
{
pipeline
.
builds
.
find_by
(
name:
'delayed-job'
)
}
let
(
:delayed_job
)
{
find_job
(
'delayed-job'
)
}
shared_examples
'rules jobs are excluded'
do
shared_examples
'rules jobs are excluded'
do
it
'only persists the job without rules'
do
it
'only persists the job without rules'
do
...
@@ -1763,6 +1763,10 @@ describe Ci::CreatePipelineService do
...
@@ -1763,6 +1763,10 @@ describe Ci::CreatePipelineService do
end
end
end
end
def
find_job
(
name
)
pipeline
.
builds
.
find_by
(
name:
name
)
end
before
do
before
do
stub_ci_pipeline_yaml_file
(
config
)
stub_ci_pipeline_yaml_file
(
config
)
allow_any_instance_of
(
Ci
::
BuildScheduleWorker
).
to
receive
(
:perform
).
and_return
(
true
)
allow_any_instance_of
(
Ci
::
BuildScheduleWorker
).
to
receive
(
:perform
).
and_return
(
true
)
...
@@ -1782,6 +1786,12 @@ describe Ci::CreatePipelineService do
...
@@ -1782,6 +1786,12 @@ describe Ci::CreatePipelineService do
- if: $CI_COMMIT_REF_NAME =~ /master/
- if: $CI_COMMIT_REF_NAME =~ /master/
when: manual
when: manual
negligible-job:
script: "exit 1"
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
allow_failure: true
delayed-job:
delayed-job:
script: "echo See you later, World!"
script: "echo See you later, World!"
rules:
rules:
...
@@ -1800,11 +1810,23 @@ describe Ci::CreatePipelineService do
...
@@ -1800,11 +1810,23 @@ describe Ci::CreatePipelineService do
context
'with matches'
do
context
'with matches'
do
it
'creates a pipeline with the vanilla and manual jobs'
do
it
'creates a pipeline with the vanilla and manual jobs'
do
expect
(
pipeline
).
to
be_persisted
expect
(
pipeline
).
to
be_persisted
expect
(
build_names
).
to
contain_exactly
(
'regular-job'
,
'delayed-job'
,
'master-job'
)
expect
(
build_names
).
to
contain_exactly
(
'regular-job'
,
'delayed-job'
,
'master-job'
,
'negligible-job'
)
end
end
it
'assigns job:when values to the builds'
do
it
'assigns job:when values to the builds'
do
expect
(
pipeline
.
builds
.
pluck
(
:when
)).
to
contain_exactly
(
'on_success'
,
'delayed'
,
'manual'
)
expect
(
find_job
(
'regular-job'
).
when
).
to
eq
(
'on_success'
)
expect
(
find_job
(
'master-job'
).
when
).
to
eq
(
'manual'
)
expect
(
find_job
(
'negligible-job'
).
when
).
to
eq
(
'on_success'
)
expect
(
find_job
(
'delayed-job'
).
when
).
to
eq
(
'delayed'
)
end
it
'assigns job:allow_failure values to the builds'
do
expect
(
find_job
(
'regular-job'
).
allow_failure
).
to
eq
(
false
)
expect
(
find_job
(
'master-job'
).
allow_failure
).
to
eq
(
false
)
expect
(
find_job
(
'negligible-job'
).
allow_failure
).
to
eq
(
true
)
expect
(
find_job
(
'delayed-job'
).
allow_failure
).
to
eq
(
false
)
end
end
it
'assigns start_in for delayed jobs'
do
it
'assigns start_in for delayed jobs'
do
...
@@ -1827,6 +1849,7 @@ describe Ci::CreatePipelineService do
...
@@ -1827,6 +1849,7 @@ describe Ci::CreatePipelineService do
rules:
rules:
- if: $VAR == 'present' && $OTHER || $CI_COMMIT_REF_NAME
- if: $VAR == 'present' && $OTHER || $CI_COMMIT_REF_NAME
when: manual
when: manual
allow_failure: true
EOY
EOY
end
end
...
@@ -1834,6 +1857,7 @@ describe Ci::CreatePipelineService do
...
@@ -1834,6 +1857,7 @@ describe Ci::CreatePipelineService do
expect
(
pipeline
).
to
be_persisted
expect
(
pipeline
).
to
be_persisted
expect
(
build_names
).
to
contain_exactly
(
'regular-job'
)
expect
(
build_names
).
to
contain_exactly
(
'regular-job'
)
expect
(
regular_job
.
when
).
to
eq
(
'manual'
)
expect
(
regular_job
.
when
).
to
eq
(
'manual'
)
expect
(
regular_job
.
allow_failure
).
to
eq
(
true
)
end
end
end
end
...
@@ -1860,6 +1884,13 @@ describe Ci::CreatePipelineService do
...
@@ -1860,6 +1884,13 @@ describe Ci::CreatePipelineService do
- README.md
- README.md
when: delayed
when: delayed
start_in: 4 hours
start_in: 4 hours
negligible-job:
script: "can be failed sometimes"
rules:
- changes:
- README.md
allow_failure: true
EOY
EOY
end
end
...
@@ -1872,7 +1903,7 @@ describe Ci::CreatePipelineService do
...
@@ -1872,7 +1903,7 @@ describe Ci::CreatePipelineService do
it
'creates two jobs'
do
it
'creates two jobs'
do
expect
(
pipeline
).
to
be_persisted
expect
(
pipeline
).
to
be_persisted
expect
(
build_names
)
expect
(
build_names
)
.
to
contain_exactly
(
'regular-job'
,
'rules-job'
,
'delayed-job'
)
.
to
contain_exactly
(
'regular-job'
,
'rules-job'
,
'delayed-job'
,
'negligible-job'
)
end
end
it
'sets when: for all jobs'
do
it
'sets when: for all jobs'
do
...
@@ -1881,6 +1912,10 @@ describe Ci::CreatePipelineService do
...
@@ -1881,6 +1912,10 @@ describe Ci::CreatePipelineService do
expect
(
delayed_job
.
when
).
to
eq
(
'delayed'
)
expect
(
delayed_job
.
when
).
to
eq
(
'delayed'
)
expect
(
delayed_job
.
options
[
:start_in
]).
to
eq
(
'4 hours'
)
expect
(
delayed_job
.
options
[
:start_in
]).
to
eq
(
'4 hours'
)
end
end
it
'sets allow_failure: for negligible job'
do
expect
(
find_job
(
'negligible-job'
).
allow_failure
).
to
eq
(
true
)
end
end
end
context
'and matches the second rule'
do
context
'and matches the second rule'
do
...
@@ -1922,12 +1957,14 @@ describe Ci::CreatePipelineService do
...
@@ -1922,12 +1957,14 @@ describe Ci::CreatePipelineService do
rules-job:
rules-job:
script: "echo hello world, $CI_COMMIT_REF_NAME"
script: "echo hello world, $CI_COMMIT_REF_NAME"
allow_failure: true
rules:
rules:
- changes:
- changes:
- README.md
- README.md
when: manual
when: manual
- if: $CI_COMMIT_REF_NAME == "master"
- if: $CI_COMMIT_REF_NAME == "master"
when: on_success
when: on_success
allow_failure: false
delayed-job:
delayed-job:
script: "echo See you later, World!"
script: "echo See you later, World!"
...
@@ -1936,6 +1973,7 @@ describe Ci::CreatePipelineService do
...
@@ -1936,6 +1973,7 @@ describe Ci::CreatePipelineService do
- README.md
- README.md
when: delayed
when: delayed
start_in: 4 hours
start_in: 4 hours
allow_failure: true
- if: $CI_COMMIT_REF_NAME == "master"
- if: $CI_COMMIT_REF_NAME == "master"
when: delayed
when: delayed
start_in: 1 hour
start_in: 1 hour
...
@@ -1960,6 +1998,12 @@ describe Ci::CreatePipelineService do
...
@@ -1960,6 +1998,12 @@ describe Ci::CreatePipelineService do
expect
(
delayed_job
.
when
).
to
eq
(
'delayed'
)
expect
(
delayed_job
.
when
).
to
eq
(
'delayed'
)
expect
(
delayed_job
.
options
[
:start_in
]).
to
eq
(
'4 hours'
)
expect
(
delayed_job
.
options
[
:start_in
]).
to
eq
(
'4 hours'
)
end
end
it
'sets allow_failure: for all jobs'
do
expect
(
regular_job
.
allow_failure
).
to
eq
(
false
)
expect
(
rules_job
.
allow_failure
).
to
eq
(
true
)
expect
(
delayed_job
.
allow_failure
).
to
eq
(
true
)
end
end
end
context
'and if: matches after changes'
do
context
'and if: matches after changes'
do
...
@@ -1999,6 +2043,7 @@ describe Ci::CreatePipelineService do
...
@@ -1999,6 +2043,7 @@ describe Ci::CreatePipelineService do
- if: $CI_COMMIT_REF_NAME =~ /master/
- if: $CI_COMMIT_REF_NAME =~ /master/
changes: [README.md]
changes: [README.md]
when: on_success
when: on_success
allow_failure: true
- if: $CI_COMMIT_REF_NAME =~ /master/
- if: $CI_COMMIT_REF_NAME =~ /master/
changes: [app.rb]
changes: [app.rb]
when: manual
when: manual
...
@@ -2016,6 +2061,7 @@ describe Ci::CreatePipelineService do
...
@@ -2016,6 +2061,7 @@ describe Ci::CreatePipelineService do
expect
(
regular_job
).
to
be_persisted
expect
(
regular_job
).
to
be_persisted
expect
(
rules_job
).
to
be_persisted
expect
(
rules_job
).
to
be_persisted
expect
(
rules_job
.
when
).
to
eq
(
'manual'
)
expect
(
rules_job
.
when
).
to
eq
(
'manual'
)
expect
(
rules_job
.
allow_failure
).
to
eq
(
false
)
end
end
end
end
...
@@ -2040,6 +2086,150 @@ describe Ci::CreatePipelineService do
...
@@ -2040,6 +2086,150 @@ describe Ci::CreatePipelineService do
it_behaves_like
'rules jobs are excluded'
it_behaves_like
'rules jobs are excluded'
end
end
end
end
context
'with complex if: allow_failure usages'
do
let
(
:config
)
do
<<-
EOY
job-1:
script: "exit 1"
allow_failure: true
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
allow_failure: false
job-2:
script: "exit 1"
allow_failure: true
rules:
- if: $CI_COMMIT_REF_NAME =~ /nonexistant-branch/
allow_failure: false
job-3:
script: "exit 1"
rules:
- if: $CI_COMMIT_REF_NAME =~ /nonexistant-branch/
allow_failure: true
job-4:
script: "exit 1"
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
allow_failure: false
job-5:
script: "exit 1"
allow_failure: false
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
allow_failure: true
job-6:
script: "exit 1"
rules:
- if: $CI_COMMIT_REF_NAME =~ /nonexistant-branch/
allow_failure: false
- allow_failure: true
EOY
end
it
'creates a pipeline'
do
expect
(
pipeline
).
to
be_persisted
expect
(
build_names
).
to
contain_exactly
(
'job-1'
,
'job-4'
,
'job-5'
,
'job-6'
)
end
it
'assigns job:allow_failure values to the builds'
do
expect
(
find_job
(
'job-1'
).
allow_failure
).
to
eq
(
false
)
expect
(
find_job
(
'job-4'
).
allow_failure
).
to
eq
(
false
)
expect
(
find_job
(
'job-5'
).
allow_failure
).
to
eq
(
true
)
expect
(
find_job
(
'job-6'
).
allow_failure
).
to
eq
(
true
)
end
end
context
'with complex if: allow_failure & when usages'
do
let
(
:config
)
do
<<-
EOY
job-1:
script: "exit 1"
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
when: manual
job-2:
script: "exit 1"
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
when: manual
allow_failure: true
job-3:
script: "exit 1"
allow_failure: true
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
when: manual
job-4:
script: "exit 1"
allow_failure: true
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
when: manual
allow_failure: false
job-5:
script: "exit 1"
rules:
- if: $CI_COMMIT_REF_NAME =~ /nonexistant-branch/
when: manual
allow_failure: false
- when: always
allow_failure: true
job-6:
script: "exit 1"
allow_failure: false
rules:
- if: $CI_COMMIT_REF_NAME =~ /master/
when: manual
job-7:
script: "exit 1"
allow_failure: false
rules:
- if: $CI_COMMIT_REF_NAME =~ /nonexistant-branch/
when: manual
- when: :on_failure
allow_failure: true
EOY
end
it
'creates a pipeline'
do
expect
(
pipeline
).
to
be_persisted
expect
(
build_names
).
to
contain_exactly
(
'job-1'
,
'job-2'
,
'job-3'
,
'job-4'
,
'job-5'
,
'job-6'
,
'job-7'
)
end
it
'assigns job:allow_failure values to the builds'
do
expect
(
find_job
(
'job-1'
).
allow_failure
).
to
eq
(
false
)
expect
(
find_job
(
'job-2'
).
allow_failure
).
to
eq
(
true
)
expect
(
find_job
(
'job-3'
).
allow_failure
).
to
eq
(
true
)
expect
(
find_job
(
'job-4'
).
allow_failure
).
to
eq
(
false
)
expect
(
find_job
(
'job-5'
).
allow_failure
).
to
eq
(
true
)
expect
(
find_job
(
'job-6'
).
allow_failure
).
to
eq
(
false
)
expect
(
find_job
(
'job-7'
).
allow_failure
).
to
eq
(
true
)
end
it
'assigns job:when values to the builds'
do
expect
(
find_job
(
'job-1'
).
when
).
to
eq
(
'manual'
)
expect
(
find_job
(
'job-2'
).
when
).
to
eq
(
'manual'
)
expect
(
find_job
(
'job-3'
).
when
).
to
eq
(
'manual'
)
expect
(
find_job
(
'job-4'
).
when
).
to
eq
(
'manual'
)
expect
(
find_job
(
'job-5'
).
when
).
to
eq
(
'always'
)
expect
(
find_job
(
'job-6'
).
when
).
to
eq
(
'manual'
)
expect
(
find_job
(
'job-7'
).
when
).
to
eq
(
'on_failure'
)
end
end
end
end
end
end
...
...
spec/services/ci/retry_build_service_spec.rb
View file @
8c9dc985
...
@@ -222,6 +222,28 @@ describe Ci::RetryBuildService do
...
@@ -222,6 +222,28 @@ describe Ci::RetryBuildService do
expect
{
new_build
}.
to
change
{
Deployment
.
count
}.
by
(
1
)
expect
{
new_build
}.
to
change
{
Deployment
.
count
}.
by
(
1
)
end
end
end
end
context
'when scheduling_type of build is nil'
do
before
do
build
.
update_columns
(
scheduling_type:
nil
)
end
context
'when build has not needs'
do
it
'sets scheduling_type as :stage'
do
expect
(
new_build
.
scheduling_type
).
to
eq
(
'stage'
)
end
end
context
'when build has needs'
do
before
do
create
(
:ci_build_need
,
build:
build
)
end
it
'sets scheduling_type as :dag'
do
expect
(
new_build
.
scheduling_type
).
to
eq
(
'dag'
)
end
end
end
end
end
context
'when user does not have ability to execute build'
do
context
'when user does not have ability to execute build'
do
...
...
vendor/elastic_stack/values.yaml
View file @
8c9dc985
...
@@ -8,7 +8,7 @@ elasticsearch:
...
@@ -8,7 +8,7 @@ elasticsearch:
client
:
client
:
replicas
:
1
replicas
:
1
data
:
data
:
replicas
:
1
replicas
:
2
kibana
:
kibana
:
enabled
:
false
enabled
:
false
...
...
vendor/elastic_stack/wait-for-elasticsearch.sh
0 → 100755
View file @
8c9dc985
#!/bin/bash
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
IFS
=
$'
\n\t
'
set
-euo
pipefail
HOST
=
"
$1
"
printf
'Waiting for ES to be reachable ...'
until
$(
wget
-O-
-q
"
$HOST
"
&>/dev/null
)
;
do
printf
'.'
sleep
1
done
echo
" OK!"
printf
'Waiting for ES to be healthy ...'
while
:
;
do
HEALTH
=
"
$(
wget
-O-
-q
"
$HOST
/_cat/health?h=status"
2> /dev/null
)
"
HEALTH
=
"
$(
echo
"
$HEALTH
"
|
sed
-r
's/^[[:space:]]+|[[:space:]]+$//g'
)
"
# trim whitespace (otherwise we'll have "green ")
([
"
$HEALTH
"
!=
"green"
]
&&
printf
'.'
&&
sleep
1
)
||
break
done
echo
" OK!"
echo
"Elastic Search is up!"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment