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
0
Merge Requests
0
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
Léo-Paul Géneau
gitlab-ce
Commits
fb048d2c
Commit
fb048d2c
authored
Dec 05, 2018
by
Kamil Trzciński
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'mr-pipelines-2' into 'master'
Merge request pipelines See merge request gitlab-org/gitlab-ce!23217
parents
07779a46
08e50c99
Changes
26
Show whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1248 additions
and
28 deletions
+1248
-28
app/models/ci/pipeline.rb
app/models/ci/pipeline.rb
+20
-2
app/models/ci/pipeline_enums.rb
app/models/ci/pipeline_enums.rb
+2
-1
app/models/merge_request.rb
app/models/merge_request.rb
+9
-3
app/serializers/pipeline_entity.rb
app/serializers/pipeline_entity.rb
+1
-0
app/services/ci/create_pipeline_service.rb
app/services/ci/create_pipeline_service.rb
+2
-1
app/services/merge_requests/base_service.rb
app/services/merge_requests/base_service.rb
+18
-0
app/services/merge_requests/create_service.rb
app/services/merge_requests/create_service.rb
+2
-5
app/services/merge_requests/refresh_service.rb
app/services/merge_requests/refresh_service.rb
+1
-0
app/workers/update_head_pipeline_for_merge_request_worker.rb
app/workers/update_head_pipeline_for_merge_request_worker.rb
+3
-3
changelogs/unreleased/mr-pipelines-2.yml
changelogs/unreleased/mr-pipelines-2.yml
+5
-0
db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb
...te/20181119081539_add_merge_request_id_to_ci_pipelines.rb
+13
-0
db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb
...0091639_add_foreign_key_to_ci_pipelines_merge_requests.rb
+22
-0
db/schema.rb
db/schema.rb
+3
-0
lib/gitlab/ci/pipeline/chain/build.rb
lib/gitlab/ci/pipeline/chain/build.rb
+1
-0
lib/gitlab/ci/pipeline/chain/command.rb
lib/gitlab/ci/pipeline/chain/command.rb
+1
-1
spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
...s/merge_request/user_sees_merge_request_pipelines_spec.rb
+333
-0
spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
+29
-0
spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
+30
-0
spec/lib/gitlab/import_export/all_models.yml
spec/lib/gitlab/import_export/all_models.yml
+2
-0
spec/lib/gitlab/import_export/safe_model_attributes.yml
spec/lib/gitlab/import_export/safe_model_attributes.yml
+1
-0
spec/models/ci/pipeline_spec.rb
spec/models/ci/pipeline_spec.rb
+234
-4
spec/models/merge_request_spec.rb
spec/models/merge_request_spec.rb
+113
-0
spec/services/ci/create_pipeline_service_spec.rb
spec/services/ci/create_pipeline_service_spec.rb
+215
-8
spec/services/merge_requests/create_service_spec.rb
spec/services/merge_requests/create_service_spec.rb
+72
-0
spec/services/merge_requests/refresh_service_spec.rb
spec/services/merge_requests/refresh_service_spec.rb
+88
-0
spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb
...ers/update_head_pipeline_for_merge_request_worker_spec.rb
+28
-0
No files found.
app/models/ci/pipeline.rb
View file @
fb048d2c
...
...
@@ -16,6 +16,7 @@ module Ci
belongs_to
:user
belongs_to
:auto_canceled_by
,
class_name:
'Ci::Pipeline'
belongs_to
:pipeline_schedule
,
class_name:
'Ci::PipelineSchedule'
belongs_to
:merge_request
,
class_name:
'MergeRequest'
has_internal_id
:iid
,
scope: :project
,
presence:
false
,
init:
->
(
s
)
do
s
&
.
project
&
.
pipelines
&
.
maximum
(
:iid
)
||
s
&
.
project
&
.
pipelines
&
.
count
...
...
@@ -50,6 +51,9 @@ module Ci
validates
:sha
,
presence:
{
unless: :importing?
}
validates
:ref
,
presence:
{
unless: :importing?
}
validates
:merge_request
,
presence:
{
if: :merge_request?
}
validates
:merge_request
,
absence:
{
unless: :merge_request?
}
validates
:tag
,
inclusion:
{
in:
[
false
],
if: :merge_request?
}
validates
:status
,
presence:
{
unless: :importing?
}
validate
:valid_commit_sha
,
unless: :importing?
...
...
@@ -171,6 +175,13 @@ module Ci
scope
:internal
,
->
{
where
(
source:
internal_sources
)
}
scope
:sort_by_merge_request_pipelines
,
->
do
sql
=
'CASE ci_pipelines.source WHEN (?) THEN 0 ELSE 1 END, ci_pipelines.id DESC'
query
=
ActiveRecord
::
Base
.
send
(
:sanitize_sql_array
,
[
sql
,
sources
[
:merge_request
]])
# rubocop:disable GitlabSecurity/PublicSend
order
(
query
)
end
scope
:for_user
,
->
(
user
)
{
where
(
user:
user
)
}
# Returns the pipelines in descending order (= newest first), optionally
...
...
@@ -372,7 +383,7 @@ module Ci
end
def
branch?
!
tag?
!
tag?
&&
!
merge_request?
end
def
stuck?
...
...
@@ -619,7 +630,12 @@ module Ci
# All the merge requests for which the current pipeline runs/ran against
def
all_merge_requests
@all_merge_requests
||=
project
.
merge_requests
.
where
(
source_branch:
ref
)
@all_merge_requests
||=
if
merge_request?
project
.
merge_requests
.
where
(
id:
merge_request
.
id
)
else
project
.
merge_requests
.
where
(
source_branch:
ref
)
end
end
def
detailed_status
(
current_user
)
...
...
@@ -696,6 +712,8 @@ module Ci
def
git_ref
if
branch?
Gitlab
::
Git
::
BRANCH_REF_PREFIX
+
ref
.
to_s
elsif
merge_request?
Gitlab
::
Git
::
BRANCH_REF_PREFIX
+
ref
.
to_s
elsif
tag?
Gitlab
::
Git
::
TAG_REF_PREFIX
+
ref
.
to_s
else
...
...
app/models/ci/pipeline_enums.rb
View file @
fb048d2c
...
...
@@ -21,7 +21,8 @@ module Ci
trigger:
3
,
schedule:
4
,
api:
5
,
external:
6
external:
6
,
merge_request:
10
}
end
end
...
...
app/models/merge_request.rb
View file @
fb048d2c
...
...
@@ -63,6 +63,7 @@ class MergeRequest < ActiveRecord::Base
dependent: :delete_all
# rubocop:disable Cop/ActiveRecordDependent
has_many
:cached_closes_issues
,
through: :merge_requests_closing_issues
,
source: :issue
has_many
:merge_request_pipelines
,
foreign_key:
'merge_request_id'
,
class_name:
'Ci::Pipeline'
belongs_to
:assignee
,
class_name:
"User"
...
...
@@ -1052,12 +1053,17 @@ class MergeRequest < ActiveRecord::Base
diverged_commits_count
>
0
end
def
all_pipelines
def
all_pipelines
(
shas:
all_commit_shas
)
return
Ci
::
Pipeline
.
none
unless
source_project
@all_pipelines
||=
source_project
.
pipelines
.
where
(
sha:
all_commit_shas
,
ref:
source_branch
)
.
order
(
id: :desc
)
.
where
(
sha:
shas
,
ref:
source_branch
)
.
where
(
merge_request:
[
nil
,
self
])
.
sort_by_merge_request_pipelines
end
def
merge_request_pipeline_exists?
merge_request_pipelines
.
exists?
(
sha:
diff_head_sha
)
end
def
has_test_reports?
...
...
app/serializers/pipeline_entity.rb
View file @
fb048d2c
...
...
@@ -48,6 +48,7 @@ class PipelineEntity < Grape::Entity
expose
:tag?
,
as: :tag
expose
:branch?
,
as: :branch
expose
:merge_request?
,
as: :merge_request
end
expose
:commit
,
using:
CommitEntity
...
...
app/services/ci/create_pipeline_service.rb
View file @
fb048d2c
...
...
@@ -14,7 +14,7 @@ module Ci
Gitlab
::
Ci
::
Pipeline
::
Chain
::
Populate
,
Gitlab
::
Ci
::
Pipeline
::
Chain
::
Create
].
freeze
def
execute
(
source
,
ignore_skip_ci:
false
,
save_on_errors:
true
,
trigger_request:
nil
,
schedule:
nil
,
&
block
)
def
execute
(
source
,
ignore_skip_ci:
false
,
save_on_errors:
true
,
trigger_request:
nil
,
schedule:
nil
,
merge_request:
nil
,
&
block
)
@pipeline
=
Ci
::
Pipeline
.
new
command
=
Gitlab
::
Ci
::
Pipeline
::
Chain
::
Command
.
new
(
...
...
@@ -25,6 +25,7 @@ module Ci
before_sha:
params
[
:before
],
trigger_request:
trigger_request
,
schedule:
schedule
,
merge_request:
merge_request
,
ignore_skip_ci:
ignore_skip_ci
,
save_incompleted:
save_on_errors
,
seeds_block:
block
,
...
...
app/services/merge_requests/base_service.rb
View file @
fb048d2c
...
...
@@ -54,6 +54,24 @@ module MergeRequests
merge_request
,
merge_request
.
project
,
current_user
,
merge_request
.
assignee
)
end
def
create_merge_request_pipeline
(
merge_request
,
user
)
return
unless
Feature
.
enabled?
(
:ci_merge_request_pipeline
,
merge_request
.
source_project
,
default_enabled:
true
)
##
# UpdateMergeRequestsWorker could be retried by an exception.
# MR pipelines should not be recreated in such case.
return
if
merge_request
.
merge_request_pipeline_exists?
Ci
::
CreatePipelineService
.
new
(
merge_request
.
source_project
,
user
,
ref:
merge_request
.
source_branch
)
.
execute
(
:merge_request
,
ignore_skip_ci:
true
,
save_on_errors:
false
,
merge_request:
merge_request
)
end
# Returns all origin and fork merge requests from `@project` satisfying passed arguments.
# rubocop: disable CodeReuse/ActiveRecord
def
merge_requests_for
(
source_branch
,
mr_states:
[
:opened
])
...
...
app/services/merge_requests/create_service.rb
View file @
fb048d2c
...
...
@@ -25,6 +25,7 @@ module MergeRequests
def
after_create
(
issuable
)
todo_service
.
new_merge_request
(
issuable
,
current_user
)
issuable
.
cache_merge_request_closes_issues!
(
current_user
)
create_merge_request_pipeline
(
issuable
,
current_user
)
update_merge_requests_head_pipeline
(
issuable
)
super
...
...
@@ -49,18 +50,14 @@ module MergeRequests
merge_request
.
update
(
head_pipeline_id:
pipeline
.
id
)
if
pipeline
end
# rubocop: disable CodeReuse/ActiveRecord
def
head_pipeline_for
(
merge_request
)
return
unless
merge_request
.
source_project
sha
=
merge_request
.
source_branch_sha
return
unless
sha
pipelines
=
merge_request
.
source_project
.
pipelines
.
where
(
ref:
merge_request
.
source_branch
,
sha:
sha
)
pipelines
.
order
(
id: :desc
).
first
merge_request
.
all_pipelines
(
shas:
sha
).
first
end
# rubocop: enable CodeReuse/ActiveRecord
def
set_projects!
# @project is used to determine whether the user can set the merge request's
...
...
app/services/merge_requests/refresh_service.rb
View file @
fb048d2c
...
...
@@ -92,6 +92,7 @@ module MergeRequests
end
merge_request
.
mark_as_unchecked
create_merge_request_pipeline
(
merge_request
,
current_user
)
UpdateHeadPipelineForMergeRequestWorker
.
perform_async
(
merge_request
.
id
)
end
...
...
app/workers/update_head_pipeline_for_merge_request_worker.rb
View file @
fb048d2c
...
...
@@ -6,10 +6,11 @@ class UpdateHeadPipelineForMergeRequestWorker
queue_namespace
:pipeline_processing
# rubocop: disable CodeReuse/ActiveRecord
def
perform
(
merge_request_id
)
merge_request
=
MergeRequest
.
find
(
merge_request_id
)
pipeline
=
Ci
::
Pipeline
.
where
(
project:
merge_request
.
source_project
,
ref:
merge_request
.
source_branch
).
last
sha
=
merge_request
.
diff_head_sha
pipeline
=
merge_request
.
all_pipelines
(
shas:
sha
).
first
return
unless
pipeline
&&
pipeline
.
latest?
...
...
@@ -21,7 +22,6 @@ class UpdateHeadPipelineForMergeRequestWorker
merge_request
.
update_attribute
(
:head_pipeline_id
,
pipeline
.
id
)
end
# rubocop: enable CodeReuse/ActiveRecord
def
log_error_message_for
(
merge_request
)
Rails
.
logger
.
error
(
...
...
changelogs/unreleased/mr-pipelines-2.yml
0 → 100644
View file @
fb048d2c
---
title
:
Merge request pipelines
merge_request
:
23217
author
:
type
:
added
db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb
0 → 100644
View file @
fb048d2c
# frozen_string_literal: true
class
AddMergeRequestIdToCiPipelines
<
ActiveRecord
::
Migration
DOWNTIME
=
false
def
up
add_column
:ci_pipelines
,
:merge_request_id
,
:integer
end
def
down
remove_column
:ci_pipelines
,
:merge_request_id
,
:integer
end
end
db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb
0 → 100644
View file @
fb048d2c
# frozen_string_literal: true
class
AddForeignKeyToCiPipelinesMergeRequests
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
add_concurrent_index
:ci_pipelines
,
:merge_request_id
add_concurrent_foreign_key
:ci_pipelines
,
:merge_requests
,
column: :merge_request_id
,
on_delete: :cascade
end
def
down
if
foreign_key_exists?
(
:ci_pipelines
,
:merge_requests
,
column: :merge_request_id
)
remove_foreign_key
:ci_pipelines
,
:merge_requests
end
remove_concurrent_index
:ci_pipelines
,
:merge_request_id
end
end
db/schema.rb
View file @
fb048d2c
...
...
@@ -474,7 +474,9 @@ ActiveRecord::Schema.define(version: 20181126153547) do
t
.
boolean
"protected"
t
.
integer
"failure_reason"
t
.
integer
"iid"
t
.
integer
"merge_request_id"
t
.
index
[
"auto_canceled_by_id"
],
name:
"index_ci_pipelines_on_auto_canceled_by_id"
,
using: :btree
t
.
index
[
"merge_request_id"
],
name:
"index_ci_pipelines_on_merge_request_id"
,
using: :btree
t
.
index
[
"pipeline_schedule_id"
],
name:
"index_ci_pipelines_on_pipeline_schedule_id"
,
using: :btree
t
.
index
[
"project_id"
,
"iid"
],
name:
"index_ci_pipelines_on_project_id_and_iid"
,
unique:
true
,
where:
"(iid IS NOT NULL)"
,
using: :btree
t
.
index
[
"project_id"
,
"ref"
,
"status"
,
"id"
],
name:
"index_ci_pipelines_on_project_id_and_ref_and_status_and_id"
,
using: :btree
...
...
@@ -2292,6 +2294,7 @@ ActiveRecord::Schema.define(version: 20181126153547) do
add_foreign_key
"ci_pipeline_variables"
,
"ci_pipelines"
,
column:
"pipeline_id"
,
name:
"fk_f29c5f4380"
,
on_delete: :cascade
add_foreign_key
"ci_pipelines"
,
"ci_pipeline_schedules"
,
column:
"pipeline_schedule_id"
,
name:
"fk_3d34ab2e06"
,
on_delete: :nullify
add_foreign_key
"ci_pipelines"
,
"ci_pipelines"
,
column:
"auto_canceled_by_id"
,
name:
"fk_262d4c2d19"
,
on_delete: :nullify
add_foreign_key
"ci_pipelines"
,
"merge_requests"
,
name:
"fk_a23be95014"
,
on_delete: :cascade
add_foreign_key
"ci_pipelines"
,
"projects"
,
name:
"fk_86635dbd80"
,
on_delete: :cascade
add_foreign_key
"ci_runner_namespaces"
,
"ci_runners"
,
column:
"runner_id"
,
on_delete: :cascade
add_foreign_key
"ci_runner_namespaces"
,
"namespaces"
,
on_delete: :cascade
...
...
lib/gitlab/ci/pipeline/chain/build.rb
View file @
fb048d2c
...
...
@@ -16,6 +16,7 @@ module Gitlab
trigger_requests:
Array
(
@command
.
trigger_request
),
user:
@command
.
current_user
,
pipeline_schedule:
@command
.
schedule
,
merge_request:
@command
.
merge_request
,
protected:
@command
.
protected_ref?
,
variables_attributes:
Array
(
@command
.
variables_attributes
)
)
...
...
lib/gitlab/ci/pipeline/chain/command.rb
View file @
fb048d2c
...
...
@@ -8,7 +8,7 @@ module Gitlab
Command
=
Struct
.
new
(
:source
,
:project
,
:current_user
,
:origin_ref
,
:checkout_sha
,
:after_sha
,
:before_sha
,
:trigger_request
,
:schedule
,
:trigger_request
,
:schedule
,
:merge_request
,
:ignore_skip_ci
,
:save_incompleted
,
:seeds_block
,
:variables_attributes
)
do
...
...
spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
0 → 100644
View file @
fb048d2c
# frozen_string_literal: true
require
'rails_helper'
describe
'Merge request > User sees merge request pipelines'
,
:js
do
include
ProjectForksHelper
include
TestReportsHelper
let
(
:project
)
{
create
(
:project
,
:public
,
:repository
)
}
let
(
:user
)
{
project
.
creator
}
let
(
:config
)
do
{
build:
{
script:
'build'
},
test:
{
script:
'test'
,
only:
[
'merge_requests'
]
},
deploy:
{
script:
'deploy'
,
except:
[
'merge_requests'
]
}
}
end
before
do
stub_application_setting
(
auto_devops_enabled:
false
)
stub_feature_flags
(
ci_merge_request_pipeline:
true
)
stub_ci_pipeline_yaml_file
(
YAML
.
dump
(
config
))
project
.
add_maintainer
(
user
)
sign_in
(
user
)
end
context
'when a user created a merge request in the parent project'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
target_project:
project
,
source_branch:
'feature'
,
target_branch:
'master'
)
end
let!
(
:push_pipeline
)
do
Ci
::
CreatePipelineService
.
new
(
project
,
user
,
ref:
'feature'
)
.
execute
(
:push
)
end
let!
(
:merge_request_pipeline
)
do
Ci
::
CreatePipelineService
.
new
(
project
,
user
,
ref:
'feature'
)
.
execute
(
:merge_request
,
merge_request:
merge_request
)
end
before
do
visit
project_merge_request_path
(
project
,
merge_request
)
page
.
within
(
'.merge-request-tabs'
)
do
click_link
(
'Pipelines'
)
end
end
it
'sees branch pipelines and merge request pipelines in correct order'
do
page
.
within
(
'.ci-table'
)
do
expect
(
page
).
to
have_selector
(
'.ci-pending'
,
count:
2
)
expect
(
first
(
'.js-pipeline-url-link'
)).
to
have_content
(
"#
#{
merge_request_pipeline
.
id
}
"
)
end
end
it
'sees the latest merge request pipeline as the head pipeline'
do
page
.
within
(
'.ci-widget-content'
)
do
expect
(
page
).
to
have_content
(
"#
#{
merge_request_pipeline
.
id
}
"
)
end
end
context
'when a user updated a merge request in the parent project'
do
let!
(
:push_pipeline_2
)
do
Ci
::
CreatePipelineService
.
new
(
project
,
user
,
ref:
'feature'
)
.
execute
(
:push
)
end
let!
(
:merge_request_pipeline_2
)
do
Ci
::
CreatePipelineService
.
new
(
project
,
user
,
ref:
'feature'
)
.
execute
(
:merge_request
,
merge_request:
merge_request
)
end
before
do
visit
project_merge_request_path
(
project
,
merge_request
)
page
.
within
(
'.merge-request-tabs'
)
do
click_link
(
'Pipelines'
)
end
end
it
'sees branch pipelines and merge request pipelines in correct order'
do
page
.
within
(
'.ci-table'
)
do
expect
(
page
).
to
have_selector
(
'.ci-pending'
,
count:
4
)
expect
(
all
(
'.js-pipeline-url-link'
)[
0
])
.
to
have_content
(
"#
#{
merge_request_pipeline_2
.
id
}
"
)
expect
(
all
(
'.js-pipeline-url-link'
)[
1
])
.
to
have_content
(
"#
#{
merge_request_pipeline
.
id
}
"
)
expect
(
all
(
'.js-pipeline-url-link'
)[
2
])
.
to
have_content
(
"#
#{
push_pipeline_2
.
id
}
"
)
expect
(
all
(
'.js-pipeline-url-link'
)[
3
])
.
to
have_content
(
"#
#{
push_pipeline
.
id
}
"
)
end
end
it
'sees the latest merge request pipeline as the head pipeline'
do
page
.
within
(
'.ci-widget-content'
)
do
expect
(
page
).
to
have_content
(
"#
#{
merge_request_pipeline_2
.
id
}
"
)
end
end
end
context
'when a user merges a merge request in the parent project'
do
before
do
click_button
'Merge when pipeline succeeds'
wait_for_requests
end
context
'when merge request pipeline is pending'
do
it
'waits the head pipeline'
do
expect
(
page
).
to
have_content
(
'to be merged automatically when the pipeline succeeds'
)
expect
(
page
).
to
have_link
(
'Cancel automatic merge'
)
end
end
context
'when merge request pipeline succeeds'
do
before
do
merge_request_pipeline
.
succeed!
wait_for_requests
end
it
'merges the merge request'
do
expect
(
page
).
to
have_content
(
'Merged by'
)
expect
(
page
).
to
have_link
(
'Revert'
)
end
end
context
'when branch pipeline succeeds'
do
before
do
push_pipeline
.
succeed!
wait_for_requests
end
it
'waits the head pipeline'
do
expect
(
page
).
to
have_content
(
'to be merged automatically when the pipeline succeeds'
)
expect
(
page
).
to
have_link
(
'Cancel automatic merge'
)
end
end
end
context
'when there are no `merge_requests` keyword in .gitlab-ci.yml'
do
let
(
:config
)
do
{
build:
{
script:
'build'
},
test:
{
script:
'test'
},
deploy:
{
script:
'deploy'
}
}
end
it
'sees a branch pipeline in pipeline tab'
do
page
.
within
(
'.ci-table'
)
do
expect
(
page
).
to
have_selector
(
'.ci-pending'
,
count:
1
)
expect
(
first
(
'.js-pipeline-url-link'
)).
to
have_content
(
"#
#{
push_pipeline
.
id
}
"
)
end
end
it
'sees the latest branch pipeline as the head pipeline'
do
page
.
within
(
'.ci-widget-content'
)
do
expect
(
page
).
to
have_content
(
"#
#{
push_pipeline
.
id
}
"
)
end
end
end
end
context
'when a user created a merge request from a forked project to the parent project'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
forked_project
,
target_project:
project
,
source_branch:
'feature'
,
target_branch:
'master'
)
end
let!
(
:push_pipeline
)
do
Ci
::
CreatePipelineService
.
new
(
forked_project
,
user2
,
ref:
'feature'
)
.
execute
(
:push
)
end
let!
(
:merge_request_pipeline
)
do
Ci
::
CreatePipelineService
.
new
(
forked_project
,
user2
,
ref:
'feature'
)
.
execute
(
:merge_request
,
merge_request:
merge_request
)
end
let
(
:forked_project
)
{
fork_project
(
project
,
user2
,
repository:
true
)
}
let
(
:user2
)
{
create
(
:user
)
}
before
do
forked_project
.
add_maintainer
(
user2
)
visit
project_merge_request_path
(
project
,
merge_request
)
page
.
within
(
'.merge-request-tabs'
)
do
click_link
(
'Pipelines'
)
end
end
it
'sees branch pipelines and merge request pipelines in correct order'
do
page
.
within
(
'.ci-table'
)
do
expect
(
page
).
to
have_selector
(
'.ci-pending'
,
count:
2
)
expect
(
first
(
'.js-pipeline-url-link'
)).
to
have_content
(
"#
#{
merge_request_pipeline
.
id
}
"
)
end
end
it
'sees the latest merge request pipeline as the head pipeline'
do
page
.
within
(
'.ci-widget-content'
)
do
expect
(
page
).
to
have_content
(
"#
#{
merge_request_pipeline
.
id
}
"
)
end
end
it
'sees pipeline list in forked project'
do
visit
project_pipelines_path
(
forked_project
)
expect
(
page
).
to
have_selector
(
'.ci-pending'
,
count:
2
)
end
context
'when a user updated a merge request from a forked project to the parent project'
do
let!
(
:push_pipeline_2
)
do
Ci
::
CreatePipelineService
.
new
(
forked_project
,
user2
,
ref:
'feature'
)
.
execute
(
:push
)
end
let!
(
:merge_request_pipeline_2
)
do
Ci
::
CreatePipelineService
.
new
(
forked_project
,
user2
,
ref:
'feature'
)
.
execute
(
:merge_request
,
merge_request:
merge_request
)
end
before
do
visit
project_merge_request_path
(
project
,
merge_request
)
page
.
within
(
'.merge-request-tabs'
)
do
click_link
(
'Pipelines'
)
end
end
it
'sees branch pipelines and merge request pipelines in correct order'
do
page
.
within
(
'.ci-table'
)
do
expect
(
page
).
to
have_selector
(
'.ci-pending'
,
count:
4
)
expect
(
all
(
'.js-pipeline-url-link'
)[
0
])
.
to
have_content
(
"#
#{
merge_request_pipeline_2
.
id
}
"
)
expect
(
all
(
'.js-pipeline-url-link'
)[
1
])
.
to
have_content
(
"#
#{
merge_request_pipeline
.
id
}
"
)
expect
(
all
(
'.js-pipeline-url-link'
)[
2
])
.
to
have_content
(
"#
#{
push_pipeline_2
.
id
}
"
)
expect
(
all
(
'.js-pipeline-url-link'
)[
3
])
.
to
have_content
(
"#
#{
push_pipeline
.
id
}
"
)
end
end
it
'sees the latest merge request pipeline as the head pipeline'
do
page
.
within
(
'.ci-widget-content'
)
do
expect
(
page
).
to
have_content
(
"#
#{
merge_request_pipeline_2
.
id
}
"
)
end
end
it
'sees pipeline list in forked project'
do
visit
project_pipelines_path
(
forked_project
)
expect
(
page
).
to
have_selector
(
'.ci-pending'
,
count:
4
)
end
end
context
'when a user merges a merge request from a forked project to the parent project'
do
before
do
click_button
'Merge when pipeline succeeds'
wait_for_requests
end
context
'when merge request pipeline is pending'
do
it
'waits the head pipeline'
do
expect
(
page
).
to
have_content
(
'to be merged automatically when the pipeline succeeds'
)
expect
(
page
).
to
have_link
(
'Cancel automatic merge'
)
end
end
context
'when merge request pipeline succeeds'
do
before
do
merge_request_pipeline
.
succeed!
wait_for_requests
end
it
'merges the merge request'
do
expect
(
page
).
to
have_content
(
'Merged by'
)
expect
(
page
).
to
have_link
(
'Revert'
)
end
end
context
'when branch pipeline succeeds'
do
before
do
push_pipeline
.
succeed!
wait_for_requests
end
it
'waits the head pipeline'
do
expect
(
page
).
to
have_content
(
'to be merged automatically when the pipeline succeeds'
)
expect
(
page
).
to
have_link
(
'Cancel automatic merge'
)
end
end
end
end
end
spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
View file @
fb048d2c
...
...
@@ -18,6 +18,7 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
before_sha:
nil
,
trigger_request:
nil
,
schedule:
nil
,
merge_request:
nil
,
project:
project
,
current_user:
user
,
variables_attributes:
variables_attributes
)
...
...
@@ -76,6 +77,7 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
before_sha:
nil
,
trigger_request:
nil
,
schedule:
nil
,
merge_request:
nil
,
project:
project
,
current_user:
user
)
end
...
...
@@ -90,4 +92,31 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
expect
(
pipeline
).
to
be_tag
end
end
context
'when pipeline is running for a merge request'
do
let
(
:command
)
do
Gitlab
::
Ci
::
Pipeline
::
Chain
::
Command
.
new
(
source: :merge_request
,
origin_ref:
'feature'
,
checkout_sha:
project
.
commit
.
id
,
after_sha:
nil
,
before_sha:
nil
,
trigger_request:
nil
,
schedule:
nil
,
merge_request:
merge_request
,
project:
project
,
current_user:
user
)
end
let
(
:merge_request
)
{
build
(
:merge_request
,
target_project:
project
)
}
before
do
step
.
perform!
end
it
'correctly indicated that this is a merge request pipeline'
do
expect
(
pipeline
).
to
be_merge_request
expect
(
pipeline
.
merge_request
).
to
eq
(
merge_request
)
end
end
end
spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
View file @
fb048d2c
...
...
@@ -106,4 +106,34 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do
expect
(
step
.
break?
).
to
be
false
end
end
context
'when pipeline source is merge request'
do
before
do
stub_ci_pipeline_yaml_file
(
YAML
.
dump
(
config
))
end
let
(
:pipeline
)
{
build_stubbed
(
:ci_pipeline
,
project:
project
)
}
let
(
:merge_request_pipeline
)
do
build
(
:ci_pipeline
,
source: :merge_request
,
project:
project
)
end
let
(
:chain
)
{
described_class
.
new
(
merge_request_pipeline
,
command
).
tap
(
&
:perform!
)
}
context
"when config contains 'merge_requests' keyword"
do
let
(
:config
)
{
{
rspec:
{
script:
'echo'
,
only:
[
'merge_requests'
]
}
}
}
it
'does not break the chain'
do
expect
(
chain
).
not_to
be_break
end
end
context
"when config contains 'merge_request' keyword"
do
let
(
:config
)
{
{
rspec:
{
script:
'echo'
,
only:
[
'merge_request'
]
}
}
}
it
'does not break the chain'
do
expect
(
chain
).
not_to
be_break
end
end
end
end
spec/lib/gitlab/import_export/all_models.yml
View file @
fb048d2c
...
...
@@ -94,6 +94,7 @@ merge_requests:
-
timelogs
-
head_pipeline
-
latest_merge_request_diff
-
merge_request_pipelines
merge_request_diff
:
-
merge_request
-
merge_request_diff_commits
...
...
@@ -121,6 +122,7 @@ pipelines:
-
artifacts
-
pipeline_schedule
-
merge_requests
-
merge_request
-
deployments
-
environments
pipeline_variables
:
...
...
spec/lib/gitlab/import_export/safe_model_attributes.yml
View file @
fb048d2c
...
...
@@ -243,6 +243,7 @@ Ci::Pipeline:
-
failure_reason
-
protected
-
iid
-
merge_request_id
Ci::Stage:
-
id
-
name
...
...
spec/models/ci/pipeline_spec.rb
View file @
fb048d2c
...
...
@@ -14,6 +14,7 @@ describe Ci::Pipeline, :mailer do
it
{
is_expected
.
to
belong_to
(
:user
)
}
it
{
is_expected
.
to
belong_to
(
:auto_canceled_by
)
}
it
{
is_expected
.
to
belong_to
(
:pipeline_schedule
)
}
it
{
is_expected
.
to
belong_to
(
:merge_request
)
}
it
{
is_expected
.
to
have_many
(
:statuses
)
}
it
{
is_expected
.
to
have_many
(
:trigger_requests
)
}
...
...
@@ -37,6 +38,128 @@ describe Ci::Pipeline, :mailer do
end
end
describe
'.sort_by_merge_request_pipelines'
do
subject
{
described_class
.
sort_by_merge_request_pipelines
}
context
'when branch pipelines exist'
do
let!
(
:branch_pipeline_1
)
{
create
(
:ci_pipeline
,
source: :push
)
}
let!
(
:branch_pipeline_2
)
{
create
(
:ci_pipeline
,
source: :push
)
}
it
'returns pipelines order by id'
do
expect
(
subject
).
to
eq
([
branch_pipeline_2
,
branch_pipeline_1
])
end
end
context
'when merge request pipelines exist'
do
let!
(
:merge_request_pipeline_1
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
merge_request:
merge_request
)
end
let!
(
:merge_request_pipeline_2
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
merge_request:
merge_request
)
end
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
'feature'
,
target_project:
project
,
target_branch:
'master'
)
end
it
'returns pipelines order by id'
do
expect
(
subject
).
to
eq
([
merge_request_pipeline_2
,
merge_request_pipeline_1
])
end
end
context
'when both branch pipeline and merge request pipeline exist'
do
let!
(
:branch_pipeline_1
)
{
create
(
:ci_pipeline
,
source: :push
)
}
let!
(
:branch_pipeline_2
)
{
create
(
:ci_pipeline
,
source: :push
)
}
let!
(
:merge_request_pipeline_1
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
merge_request:
merge_request
)
end
let!
(
:merge_request_pipeline_2
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
merge_request:
merge_request
)
end
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
'feature'
,
target_project:
project
,
target_branch:
'master'
)
end
it
'returns merge request pipeline first'
do
expect
(
subject
).
to
eq
([
merge_request_pipeline_2
,
merge_request_pipeline_1
,
branch_pipeline_2
,
branch_pipeline_1
])
end
end
end
describe
'.merge_request'
do
subject
{
described_class
.
merge_request
}
context
'when there is a merge request pipeline'
do
let!
(
:pipeline
)
{
create
(
:ci_pipeline
,
source: :merge_request
,
merge_request:
merge_request
)
}
let
(
:merge_request
)
{
create
(
:merge_request
)
}
it
'returns merge request pipeline first'
do
expect
(
subject
).
to
eq
([
pipeline
])
end
end
context
'when there are no merge request pipelines'
do
let!
(
:pipeline
)
{
create
(
:ci_pipeline
,
source: :push
)
}
it
'returns empty array'
do
expect
(
subject
).
to
be_empty
end
end
end
describe
'Validations for merge request pipelines'
do
let
(
:pipeline
)
{
build
(
:ci_pipeline
,
source:
source
,
merge_request:
merge_request
)
}
context
'when source is merge request'
do
let
(
:source
)
{
:merge_request
}
context
'when merge request is specified'
do
let
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
,
source_branch:
'feature'
,
target_project:
project
,
target_branch:
'master'
)
}
it
{
expect
(
pipeline
).
to
be_valid
}
end
context
'when merge request is empty'
do
let
(
:merge_request
)
{
nil
}
it
{
expect
(
pipeline
).
not_to
be_valid
}
end
end
context
'when source is web'
do
let
(
:source
)
{
:web
}
context
'when merge request is specified'
do
let
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
,
source_branch:
'feature'
,
target_project:
project
,
target_branch:
'master'
)
}
it
{
expect
(
pipeline
).
not_to
be_valid
}
end
context
'when merge request is empty'
do
let
(
:merge_request
)
{
nil
}
it
{
expect
(
pipeline
).
to
be_valid
}
end
end
end
describe
'modules'
do
it_behaves_like
'AtomicInternalId'
,
validate_presence:
false
do
let
(
:internal_id_attribute
)
{
:iid
}
...
...
@@ -760,27 +883,85 @@ describe Ci::Pipeline, :mailer do
describe
'#branch?'
do
subject
{
pipeline
.
branch?
}
context
'is not a tag'
do
context
'
when ref
is not a tag'
do
before
do
pipeline
.
tag
=
false
end
it
'return true
when tag is set to false
'
do
it
'return true'
do
is_expected
.
to
be_truthy
end
context
'when source is merge request'
do
let
(
:pipeline
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
merge_request:
merge_request
)
end
context
'is not a tag'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
'feature'
,
target_project:
project
,
target_branch:
'master'
)
end
it
'returns false'
do
is_expected
.
to
be_falsey
end
end
end
context
'when ref is a tag'
do
before
do
pipeline
.
tag
=
true
end
it
'return false
when tag is set to true
'
do
it
'return false'
do
is_expected
.
to
be_falsey
end
end
end
describe
'#git_ref'
do
subject
{
pipeline
.
send
(
:git_ref
)
}
context
'when ref is branch'
do
let
(
:pipeline
)
{
create
(
:ci_pipeline
,
tag:
false
)
}
it
'returns branch ref'
do
is_expected
.
to
eq
(
Gitlab
::
Git
::
BRANCH_REF_PREFIX
+
pipeline
.
ref
.
to_s
)
end
end
context
'when ref is tag'
do
let
(
:pipeline
)
{
create
(
:ci_pipeline
,
tag:
true
)
}
it
'returns branch ref'
do
is_expected
.
to
eq
(
Gitlab
::
Git
::
TAG_REF_PREFIX
+
pipeline
.
ref
.
to_s
)
end
end
context
'when ref is merge request'
do
let
(
:pipeline
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
merge_request:
merge_request
)
end
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
'feature'
,
target_project:
project
,
target_branch:
'master'
)
end
it
'returns branch ref'
do
is_expected
.
to
eq
(
Gitlab
::
Git
::
BRANCH_REF_PREFIX
+
pipeline
.
ref
.
to_s
)
end
end
end
describe
'ref_exists?'
do
context
'when repository exists'
do
using
RSpec
::
Parameterized
::
TableSyntax
...
...
@@ -1855,6 +2036,55 @@ describe Ci::Pipeline, :mailer do
expect
(
pipeline
.
all_merge_requests
).
to
be_empty
end
context
'when there is a merge request pipeline'
do
let
(
:source_branch
)
{
'feature'
}
let
(
:target_branch
)
{
'master'
}
let!
(
:pipeline
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
project:
project
,
ref:
source_branch
,
merge_request:
merge_request
)
end
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
source_branch
,
target_project:
project
,
target_branch:
target_branch
)
end
it
'returns an associated merge request'
do
expect
(
pipeline
.
all_merge_requests
).
to
eq
([
merge_request
])
end
context
'when there is another merge request pipeline that targets a different branch'
do
let
(
:target_branch_2
)
{
'merge-test'
}
let!
(
:pipeline_2
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
project:
project
,
ref:
source_branch
,
merge_request:
merge_request_2
)
end
let
(
:merge_request_2
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
source_branch
,
target_project:
project
,
target_branch:
target_branch_2
)
end
it
'does not return an associated merge request'
do
expect
(
pipeline
.
all_merge_requests
).
not_to
include
(
merge_request_2
)
end
end
end
end
describe
'#stuck?'
do
...
...
spec/models/merge_request_spec.rb
View file @
fb048d2c
...
...
@@ -1206,6 +1206,119 @@ describe MergeRequest do
expect
(
subject
.
all_pipelines
).
to
contain_exactly
(
pipeline
)
end
end
context
'when pipelines exist for the branch and merge request'
do
let
(
:source_ref
)
{
'feature'
}
let
(
:target_ref
)
{
'master'
}
let!
(
:branch_pipeline
)
do
create
(
:ci_pipeline
,
source: :push
,
project:
project
,
ref:
source_ref
,
sha:
shas
.
second
)
end
let!
(
:merge_request_pipeline
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
project:
project
,
ref:
source_ref
,
sha:
shas
.
second
,
merge_request:
merge_request
)
end
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
source_ref
,
target_project:
project
,
target_branch:
target_ref
)
end
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:shas
)
{
project
.
repository
.
commits
(
source_ref
,
limit:
2
).
map
(
&
:id
)
}
before
do
allow
(
merge_request
).
to
receive
(
:all_commit_shas
)
{
shas
}
end
it
'returns merge request pipeline first'
do
expect
(
merge_request
.
all_pipelines
)
.
to
eq
([
merge_request_pipeline
,
branch_pipeline
])
end
context
'when there are a branch pipeline and a merge request pipeline'
do
let!
(
:branch_pipeline_2
)
do
create
(
:ci_pipeline
,
source: :push
,
project:
project
,
ref:
source_ref
,
sha:
shas
.
first
)
end
let!
(
:merge_request_pipeline_2
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
project:
project
,
ref:
source_ref
,
sha:
shas
.
first
,
merge_request:
merge_request
)
end
it
'returns merge request pipelines first'
do
expect
(
merge_request
.
all_pipelines
)
.
to
eq
([
merge_request_pipeline_2
,
merge_request_pipeline
,
branch_pipeline_2
,
branch_pipeline
])
end
end
context
'when there are multiple merge request pipelines from the same branch'
do
let!
(
:branch_pipeline_2
)
do
create
(
:ci_pipeline
,
source: :push
,
project:
project
,
ref:
source_ref
,
sha:
shas
.
first
)
end
let!
(
:merge_request_pipeline_2
)
do
create
(
:ci_pipeline
,
source: :merge_request
,
project:
project
,
ref:
source_ref
,
sha:
shas
.
first
,
merge_request:
merge_request_2
)
end
let
(
:merge_request_2
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
source_ref
,
target_project:
project
,
target_branch:
'stable'
)
end
before
do
allow
(
merge_request_2
).
to
receive
(
:all_commit_shas
)
{
shas
}
end
it
'returns only related merge request pipelines'
do
expect
(
merge_request
.
all_pipelines
)
.
to
eq
([
merge_request_pipeline
,
branch_pipeline_2
,
branch_pipeline
])
expect
(
merge_request_2
.
all_pipelines
)
.
to
eq
([
merge_request_pipeline_2
,
branch_pipeline_2
,
branch_pipeline
])
end
end
end
end
describe
'#has_test_reports?'
do
...
...
spec/services/ci/create_pipeline_service_spec.rb
View file @
fb048d2c
...
...
@@ -18,7 +18,8 @@ describe Ci::CreatePipelineService do
message:
'Message'
,
ref:
ref_name
,
trigger_request:
nil
,
variables_attributes:
nil
)
variables_attributes:
nil
,
merge_request:
nil
)
params
=
{
ref:
ref
,
before:
'00000000'
,
after:
after
,
...
...
@@ -26,7 +27,7 @@ describe Ci::CreatePipelineService do
variables_attributes:
variables_attributes
}
described_class
.
new
(
project
,
user
,
params
).
execute
(
source
,
trigger_request:
trigger_request
)
source
,
trigger_request:
trigger_request
,
merge_request:
merge_request
)
end
context
'valid params'
do
...
...
@@ -60,10 +61,10 @@ describe Ci::CreatePipelineService do
context
'when merge requests already exist for this source branch'
do
let
(
:merge_request_1
)
do
create
(
:merge_request
,
source_branch:
'
master'
,
target_branch:
"branch_1
"
,
source_project:
project
)
create
(
:merge_request
,
source_branch:
'
feature'
,
target_branch:
"master
"
,
source_project:
project
)
end
let
(
:merge_request_2
)
do
create
(
:merge_request
,
source_branch:
'
master'
,
target_branch:
"branch_2
"
,
source_project:
project
)
create
(
:merge_request
,
source_branch:
'
feature'
,
target_branch:
"v1.1.0
"
,
source_project:
project
)
end
context
'when related merge request is already merged'
do
...
...
@@ -83,7 +84,7 @@ describe Ci::CreatePipelineService do
merge_request_1
merge_request_2
head_pipeline
=
execute_service
head_pipeline
=
execute_service
(
ref:
'feature'
,
after:
nil
)
expect
(
merge_request_1
.
reload
.
head_pipeline
).
to
eq
(
head_pipeline
)
expect
(
merge_request_2
.
reload
.
head_pipeline
).
to
eq
(
head_pipeline
)
...
...
@@ -123,12 +124,12 @@ describe Ci::CreatePipelineService do
let!
(
:target_project
)
{
create
(
:project
,
:repository
)
}
it
'updates head pipeline for merge request'
do
merge_request
=
create
(
:merge_request
,
source_branch:
'
master
'
,
target_branch:
"
branch_1
"
,
merge_request
=
create
(
:merge_request
,
source_branch:
'
feature
'
,
target_branch:
"
master
"
,
source_project:
project
,
target_project:
target_project
)
head_pipeline
=
execute_service
head_pipeline
=
execute_service
(
ref:
'feature'
,
after:
nil
)
expect
(
merge_request
.
reload
.
head_pipeline
).
to
eq
(
head_pipeline
)
end
...
...
@@ -656,6 +657,212 @@ describe Ci::CreatePipelineService do
end
end
end
describe
'Merge request pipelines'
do
let
(
:pipeline
)
do
execute_service
(
source:
source
,
merge_request:
merge_request
,
ref:
ref_name
)
end
before
do
stub_ci_pipeline_yaml_file
(
YAML
.
dump
(
config
))
end
let
(
:ref_name
)
{
'feature'
}
context
'when source is merge request'
do
let
(
:source
)
{
:merge_request
}
context
"when config has merge_requests keywords"
do
let
(
:config
)
do
{
build:
{
stage:
'build'
,
script:
'echo'
},
test:
{
stage:
'test'
,
script:
'echo'
,
only:
[
'merge_requests'
]
},
pages:
{
stage:
'deploy'
,
script:
'echo'
,
except:
[
'merge_requests'
]
}
}
end
context
'when merge request is specified'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
ref_name
,
target_project:
project
,
target_branch:
'master'
)
end
it
'creates a merge request pipeline'
do
expect
(
pipeline
).
to
be_persisted
expect
(
pipeline
).
to
be_merge_request
expect
(
pipeline
.
merge_request
).
to
eq
(
merge_request
)
expect
(
pipeline
.
builds
.
order
(
:stage_id
).
map
(
&
:name
)).
to
eq
(
%w[test]
)
end
context
'when ref is tag'
do
let
(
:ref_name
)
{
'v1.1.0'
}
it
'does not create a merge request pipeline'
do
expect
(
pipeline
).
not_to
be_persisted
expect
(
pipeline
.
errors
[
:tag
]).
to
eq
([
"is not included in the list"
])
end
end
context
'when merge request is created from a forked project'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
ref_name
,
target_project:
target_project
,
target_branch:
'master'
)
end
let!
(
:project
)
{
fork_project
(
target_project
,
nil
,
repository:
true
)
}
let!
(
:target_project
)
{
create
(
:project
,
:repository
)
}
it
'creates a merge request pipeline in the forked project'
do
expect
(
pipeline
).
to
be_persisted
expect
(
project
.
pipelines
).
to
eq
([
pipeline
])
expect
(
target_project
.
pipelines
).
to
be_empty
end
end
context
"when there are no matched jobs"
do
let
(
:config
)
do
{
test:
{
stage:
'test'
,
script:
'echo'
,
except:
[
'merge_requests'
]
}
}
end
it
'does not create a merge request pipeline'
do
expect
(
pipeline
).
not_to
be_persisted
expect
(
pipeline
.
errors
[
:base
]).
to
eq
([
"No stages / jobs for this pipeline."
])
end
end
end
context
'when merge request is not specified'
do
let
(
:merge_request
)
{
nil
}
it
'does not create a merge request pipeline'
do
expect
(
pipeline
).
not_to
be_persisted
expect
(
pipeline
.
errors
[
:merge_request
]).
to
eq
([
"can't be blank"
])
end
end
end
context
"when config does not have merge_requests keywords"
do
let
(
:config
)
do
{
build:
{
stage:
'build'
,
script:
'echo'
},
test:
{
stage:
'test'
,
script:
'echo'
},
pages:
{
stage:
'deploy'
,
script:
'echo'
}
}
end
context
'when merge request is specified'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
ref_name
,
target_project:
project
,
target_branch:
'master'
)
end
it
'does not create a merge request pipeline'
do
expect
(
pipeline
).
not_to
be_persisted
expect
(
pipeline
.
errors
[
:base
])
.
to
eq
([
'No stages / jobs for this pipeline.'
])
end
end
context
'when merge request is not specified'
do
let
(
:merge_request
)
{
nil
}
it
'does not create a merge request pipeline'
do
expect
(
pipeline
).
not_to
be_persisted
expect
(
pipeline
.
errors
[
:base
])
.
to
eq
([
'No stages / jobs for this pipeline.'
])
end
end
end
end
context
'when source is web'
do
let
(
:source
)
{
:web
}
context
"when config has merge_requests keywords"
do
let
(
:config
)
do
{
build:
{
stage:
'build'
,
script:
'echo'
},
test:
{
stage:
'test'
,
script:
'echo'
,
only:
[
'merge_requests'
]
},
pages:
{
stage:
'deploy'
,
script:
'echo'
,
except:
[
'merge_requests'
]
}
}
end
context
'when merge request is specified'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
ref_name
,
target_project:
project
,
target_branch:
'master'
)
end
it
'does not create a merge request pipeline'
do
expect
(
pipeline
).
not_to
be_persisted
expect
(
pipeline
.
errors
[
:merge_request
]).
to
eq
([
"must be blank"
])
end
end
context
'when merge request is not specified'
do
let
(
:merge_request
)
{
nil
}
it
'creates a branch pipeline'
do
expect
(
pipeline
).
to
be_persisted
expect
(
pipeline
).
to
be_web
expect
(
pipeline
.
merge_request
).
to
be_nil
expect
(
pipeline
.
builds
.
order
(
:stage_id
).
map
(
&
:name
)).
to
eq
(
%w[build pages]
)
end
end
end
end
end
end
describe
'#execute!'
do
...
...
spec/services/merge_requests/create_service_spec.rb
View file @
fb048d2c
...
...
@@ -159,6 +159,78 @@ describe MergeRequests::CreateService do
end
end
end
describe
'Merge request pipelines'
do
before
do
stub_ci_pipeline_yaml_file
(
YAML
.
dump
(
config
))
end
context
"when .gitlab-ci.yml has merge_requests keywords"
do
let
(
:config
)
do
{
test:
{
stage:
'test'
,
script:
'echo'
,
only:
[
'merge_requests'
]
}
}
end
it
'creates a merge request pipeline and sets it as a head pipeline'
do
expect
(
merge_request
).
to
be_persisted
merge_request
.
reload
expect
(
merge_request
.
merge_request_pipelines
.
count
).
to
eq
(
1
)
expect
(
merge_request
.
actual_head_pipeline
).
to
be_merge_request
end
context
"when branch pipeline was created before a merge request pipline has been created"
do
before
do
create
(
:ci_pipeline
,
project:
merge_request
.
source_project
,
sha:
merge_request
.
diff_head_sha
,
ref:
merge_request
.
source_branch
,
tag:
false
)
merge_request
end
it
'sets the latest merge request pipeline as the head pipeline'
do
expect
(
merge_request
.
actual_head_pipeline
).
to
be_merge_request
end
end
context
"when the 'ci_merge_request_pipeline' feature flag is disabled"
do
before
do
stub_feature_flags
(
ci_merge_request_pipeline:
false
)
end
it
'does not create a merge request pipeline'
do
expect
(
merge_request
).
to
be_persisted
merge_request
.
reload
expect
(
merge_request
.
merge_request_pipelines
.
count
).
to
eq
(
0
)
end
end
end
context
"when .gitlab-ci.yml does not have merge_requests keywords"
do
let
(
:config
)
do
{
test:
{
stage:
'test'
,
script:
'echo'
}
}
end
it
'does not create a merge request pipeline'
do
expect
(
merge_request
).
to
be_persisted
merge_request
.
reload
expect
(
merge_request
.
merge_request_pipelines
.
count
).
to
eq
(
0
)
end
end
end
end
it_behaves_like
'new issuable record that supports quick actions'
do
...
...
spec/services/merge_requests/refresh_service_spec.rb
View file @
fb048d2c
...
...
@@ -132,6 +132,94 @@ describe MergeRequests::RefreshService do
end
end
describe
'Merge request pipelines'
do
before
do
stub_ci_pipeline_yaml_file
(
YAML
.
dump
(
config
))
end
subject
{
service
.
new
(
@project
,
@user
).
execute
(
@oldrev
,
@newrev
,
'refs/heads/master'
)
}
context
"when .gitlab-ci.yml has merge_requests keywords"
do
let
(
:config
)
do
{
test:
{
stage:
'test'
,
script:
'echo'
,
only:
[
'merge_requests'
]
}
}
end
it
'create merge request pipeline'
do
expect
{
subject
}
.
to
change
{
@merge_request
.
merge_request_pipelines
.
count
}.
by
(
1
)
.
and
change
{
@fork_merge_request
.
merge_request_pipelines
.
count
}.
by
(
1
)
.
and
change
{
@another_merge_request
.
merge_request_pipelines
.
count
}.
by
(
1
)
end
context
"when branch pipeline was created before a merge request pipline has been created"
do
before
do
create
(
:ci_pipeline
,
project:
@merge_request
.
source_project
,
sha:
@merge_request
.
diff_head_sha
,
ref:
@merge_request
.
source_branch
,
tag:
false
)
subject
end
it
'sets the latest merge request pipeline as a head pipeline'
do
@merge_request
.
reload
expect
(
@merge_request
.
actual_head_pipeline
).
to
be_merge_request
end
it
'returns pipelines in correct order'
do
@merge_request
.
reload
expect
(
@merge_request
.
all_pipelines
.
first
).
to
be_merge_request
expect
(
@merge_request
.
all_pipelines
.
second
).
to
be_push
end
end
context
"when MergeRequestUpdateWorker is retried by an exception"
do
it
'does not re-create a duplicate merge request pipeline'
do
expect
do
service
.
new
(
@project
,
@user
).
execute
(
@oldrev
,
@newrev
,
'refs/heads/master'
)
end
.
to
change
{
@merge_request
.
merge_request_pipelines
.
count
}.
by
(
1
)
expect
do
service
.
new
(
@project
,
@user
).
execute
(
@oldrev
,
@newrev
,
'refs/heads/master'
)
end
.
not_to
change
{
@merge_request
.
merge_request_pipelines
.
count
}
end
end
context
"when the 'ci_merge_request_pipeline' feature flag is disabled"
do
before
do
stub_feature_flags
(
ci_merge_request_pipeline:
false
)
end
it
'does not create a merge request pipeline'
do
expect
{
subject
}
.
not_to
change
{
@merge_request
.
merge_request_pipelines
.
count
}
end
end
end
context
"when .gitlab-ci.yml does not have merge_requests keywords"
do
let
(
:config
)
do
{
test:
{
stage:
'test'
,
script:
'echo'
}
}
end
it
'does not create a merge request pipeline'
do
expect
{
subject
}
.
not_to
change
{
@merge_request
.
merge_request_pipelines
.
count
}
end
end
end
context
'push to origin repo source branch when an MR was reopened'
do
let
(
:refresh_service
)
{
service
.
new
(
@project
,
@user
)
}
let
(
:notification_service
)
{
spy
(
'notification_service'
)
}
...
...
spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb
View file @
fb048d2c
...
...
@@ -34,5 +34,33 @@ describe UpdateHeadPipelineForMergeRequestWorker do
expect
{
subject
.
perform
(
merge_request
.
id
)
}.
not_to
change
{
merge_request
.
reload
.
head_pipeline_id
}
end
end
context
'when a merge request pipeline exists'
do
let!
(
:merge_request_pipeline
)
do
create
(
:ci_pipeline
,
project:
project
,
source: :merge_request
,
sha:
latest_sha
,
merge_request:
merge_request
)
end
it
'sets the merge request pipeline as the head pipeline'
do
expect
{
subject
.
perform
(
merge_request
.
id
)
}
.
to
change
{
merge_request
.
reload
.
head_pipeline_id
}
.
from
(
nil
).
to
(
merge_request_pipeline
.
id
)
end
context
'when branch pipeline exists'
do
let!
(
:branch_pipeline
)
do
create
(
:ci_pipeline
,
project:
project
,
source: :push
,
sha:
latest_sha
)
end
it
'prioritizes the merge request pipeline as the head pipeline'
do
expect
{
subject
.
perform
(
merge_request
.
id
)
}
.
to
change
{
merge_request
.
reload
.
head_pipeline_id
}
.
from
(
nil
).
to
(
merge_request_pipeline
.
id
)
end
end
end
end
end
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