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
615075e1
Commit
615075e1
authored
Jun 07, 2017
by
Grzegorz Bizon
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'cross-project-triggers-ee' into 'master'
Cross project triggers See merge request !2042
parents
36eaa3de
23712d20
Changes
42
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
720 additions
and
100 deletions
+720
-100
app/controllers/projects/jobs_controller.rb
app/controllers/projects/jobs_controller.rb
+11
-0
app/models/ci/build.rb
app/models/ci/build.rb
+16
-9
app/models/ci/pipeline.rb
app/models/ci/pipeline.rb
+7
-0
app/models/ci/sources/pipeline.rb
app/models/ci/sources/pipeline.rb
+21
-0
app/models/commit_status.rb
app/models/commit_status.rb
+5
-0
app/models/project.rb
app/models/project.rb
+4
-0
app/serializers/build_artifact_entity.rb
app/serializers/build_artifact_entity.rb
+31
-6
app/serializers/build_details_entity.rb
app/serializers/build_details_entity.rb
+50
-0
app/serializers/build_entity.rb
app/serializers/build_entity.rb
+1
-1
app/serializers/merge_request_entity.rb
app/serializers/merge_request_entity.rb
+1
-1
app/serializers/pipeline_details_entity.rb
app/serializers/pipeline_details_entity.rb
+10
-0
app/serializers/pipeline_entity.rb
app/serializers/pipeline_entity.rb
+9
-11
app/serializers/pipeline_serializer.rb
app/serializers/pipeline_serializer.rb
+3
-1
app/serializers/runner_entity.rb
app/serializers/runner_entity.rb
+18
-0
app/serializers/triggered_pipeline_entity.rb
app/serializers/triggered_pipeline_entity.rb
+30
-0
app/workers/expire_pipeline_cache_worker.rb
app/workers/expire_pipeline_cache_worker.rb
+10
-4
changelogs/unreleased-ee/add-relation-between-pipelines.yml
changelogs/unreleased-ee/add-relation-between-pipelines.yml
+4
-0
changelogs/unreleased/zj-job-view-goes-real-time.yml
changelogs/unreleased/zj-job-view-goes-real-time.yml
+4
-0
db/fixtures/development/14_pipelines.rb
db/fixtures/development/14_pipelines.rb
+13
-2
db/migrate/20170525174157_create_pipeline_source_pipeline.rb
db/migrate/20170525174157_create_pipeline_source_pipeline.rb
+16
-0
db/migrate/20170525174158_add_ci_pipeline_source_pipeline_indexes.rb
...20170525174158_add_ci_pipeline_source_pipeline_indexes.rb
+25
-0
db/migrate/20170525174159_add_ci_pipeline_source_pipeline_foreign_key.rb
...0525174159_add_ci_pipeline_source_pipeline_foreign_key.rb
+25
-0
db/schema.rb
db/schema.rb
+19
-0
lib/gitlab/etag_caching/router.rb
lib/gitlab/etag_caching/router.rb
+6
-2
spec/controllers/projects/jobs_controller_spec.rb
spec/controllers/projects/jobs_controller_spec.rb
+34
-11
spec/factories/ci/sources/pipelines.rb
spec/factories/ci/sources/pipelines.rb
+13
-0
spec/lib/gitlab/etag_caching/router_spec.rb
spec/lib/gitlab/etag_caching/router_spec.rb
+11
-0
spec/lib/gitlab/import_export/all_models.yml
spec/lib/gitlab/import_export/all_models.yml
+6
-0
spec/models/ci/build_spec.rb
spec/models/ci/build_spec.rb
+1
-0
spec/models/ci/pipeline_spec.rb
spec/models/ci/pipeline_spec.rb
+4
-0
spec/models/ci/sources/pipeline_spec.rb
spec/models/ci/sources/pipeline_spec.rb
+17
-0
spec/models/project_spec.rb
spec/models/project_spec.rb
+2
-0
spec/serializers/build_artifact_entity_spec.rb
spec/serializers/build_artifact_entity_spec.rb
+12
-2
spec/serializers/build_details_entity_spec.rb
spec/serializers/build_details_entity_spec.rb
+67
-0
spec/serializers/build_entity_spec.rb
spec/serializers/build_entity_spec.rb
+2
-1
spec/serializers/merge_request_entity_spec.rb
spec/serializers/merge_request_entity_spec.rb
+1
-1
spec/serializers/pipeline_details_entity_spec.rb
spec/serializers/pipeline_details_entity_spec.rb
+155
-0
spec/serializers/pipeline_entity_spec.rb
spec/serializers/pipeline_entity_spec.rb
+2
-46
spec/serializers/pipeline_serializer_spec.rb
spec/serializers/pipeline_serializer_spec.rb
+1
-1
spec/serializers/runner_entity_spec.rb
spec/serializers/runner_entity_spec.rb
+23
-0
spec/services/ci/retry_build_service_spec.rb
spec/services/ci/retry_build_service_spec.rb
+1
-1
spec/workers/expire_pipeline_cache_worker_spec.rb
spec/workers/expire_pipeline_cache_worker_spec.rb
+29
-0
No files found.
app/controllers/projects/jobs_controller.rb
View file @
615075e1
...
...
@@ -45,6 +45,17 @@ class Projects::JobsController < Projects::ApplicationController
@builds
=
@project
.
pipelines
.
find_by_sha
(
@build
.
sha
).
builds
.
order
(
'id DESC'
)
@builds
=
@builds
.
where
(
"id not in (?)"
,
@build
.
id
)
@pipeline
=
@build
.
pipeline
respond_to
do
|
format
|
format
.
html
format
.
json
do
Gitlab
::
PollingInterval
.
set_header
(
response
,
interval:
10_000
)
render
json:
BuildSerializer
.
new
(
project:
@project
,
current_user:
@current_user
)
.
represent
(
@build
,
{},
BuildDetailsEntity
)
end
end
end
def
trace
...
...
app/models/ci/build.rb
View file @
615075e1
...
...
@@ -9,6 +9,8 @@ module Ci
belongs_to
:trigger_request
belongs_to
:erased_by
,
class_name:
'User'
has_many
:sourced_pipelines
,
class_name:
Ci
::
Sources
::
Pipeline
,
foreign_key: :source_job_id
has_many
:deployments
,
as: :deployable
has_one
:last_deployment
,
->
{
order
(
'deployments.id DESC'
)
},
as: :deployable
,
class_name:
'Deployment'
...
...
@@ -206,14 +208,19 @@ module Ci
end
def
merge_request
merge_requests
=
MergeRequest
.
includes
(
:merge_request_diff
)
.
where
(
source_branch:
ref
,
source_project:
pipeline
.
project
)
.
reorder
(
iid: :asc
)
merge_requests
.
find
do
|
merge_request
|
merge_request
.
commits_sha
.
include?
(
pipeline
.
sha
)
end
return
@merge_request
if
defined?
(
@merge_request
)
@merge_request
||=
begin
merge_requests
=
MergeRequest
.
includes
(
:merge_request_diff
)
.
where
(
source_branch:
ref
,
source_project:
pipeline
.
project
)
.
reorder
(
iid: :desc
)
merge_requests
.
find
do
|
merge_request
|
merge_request
.
commits_sha
.
include?
(
pipeline
.
sha
)
end
end
end
def
repo_url
...
...
@@ -337,7 +344,7 @@ module Ci
end
def
has_expiring_artifacts?
artifacts_expire_at
.
present?
artifacts_expire_at
.
present?
&&
artifacts_expire_at
>
Time
.
now
end
def
keep_artifacts!
...
...
app/models/ci/pipeline.rb
View file @
615075e1
...
...
@@ -11,6 +11,13 @@ module Ci
belongs_to
:auto_canceled_by
,
class_name:
'Ci::Pipeline'
belongs_to
:pipeline_schedule
,
class_name:
'Ci::PipelineSchedule'
has_one
:source_pipeline
,
class_name:
Ci
::
Sources
::
Pipeline
has_many
:sourced_pipelines
,
class_name:
Ci
::
Sources
::
Pipeline
,
foreign_key: :source_pipeline_id
has_one
:triggered_by_pipeline
,
through: :source_pipeline
,
source: :source_pipeline
has_many
:triggered_pipelines
,
through: :sourced_pipelines
,
source: :pipeline
has_many
:auto_canceled_pipelines
,
class_name:
'Ci::Pipeline'
,
foreign_key:
'auto_canceled_by_id'
has_many
:auto_canceled_jobs
,
class_name:
'CommitStatus'
,
foreign_key:
'auto_canceled_by_id'
...
...
app/models/ci/sources/pipeline.rb
0 → 100644
View file @
615075e1
module
Ci
module
Sources
class
Pipeline
<
ActiveRecord
::
Base
self
.
table_name
=
"ci_sources_pipelines"
belongs_to
:project
,
class_name:
Project
belongs_to
:pipeline
,
class_name:
Ci
::
Pipeline
belongs_to
:source_project
,
class_name:
Project
,
foreign_key: :source_project_id
belongs_to
:source_job
,
class_name:
Ci
::
Build
,
foreign_key: :source_job_id
belongs_to
:source_pipeline
,
class_name:
Ci
::
Pipeline
,
foreign_key: :source_pipeline_id
validates
:project
,
presence:
true
validates
:pipeline
,
presence:
true
validates
:source_project
,
presence:
true
validates
:source_job
,
presence:
true
validates
:source_pipeline
,
presence:
true
end
end
end
app/models/commit_status.rb
View file @
615075e1
...
...
@@ -127,6 +127,11 @@ class CommitStatus < ActiveRecord::Base
false
end
# To be overriden when inherrited from
def
retryable?
false
end
def
stuck?
false
end
...
...
app/models/project.rb
View file @
615075e1
...
...
@@ -187,6 +187,10 @@ class Project < ActiveRecord::Base
has_many
:deployments
,
dependent: :destroy
has_many
:pipeline_schedules
,
dependent: :destroy
,
class_name:
'Ci::PipelineSchedule'
has_many
:sourced_pipelines
,
class_name:
Ci
::
Sources
::
Pipeline
,
foreign_key: :source_project_id
has_many
:source_pipelines
,
class_name:
Ci
::
Sources
::
Pipeline
,
foreign_key: :project_id
has_many
:path_locks
,
dependent: :destroy
has_many
:active_runners
,
->
{
active
},
through: :runner_projects
,
source: :runner
,
class_name:
'Ci::Runner'
...
...
app/serializers/build_artifact_entity.rb
View file @
615075e1
class
BuildArtifactEntity
<
Grape
::
Entity
include
RequestAwareEntity
expose
:name
do
|
build
|
build
.
name
expose
:name
do
|
job
|
job
.
name
end
expose
:path
do
|
build
|
expose
:artifacts_expired?
,
as: :expired
expose
:artifacts_expire_at
,
as: :expire_at
expose
:path
do
|
job
|
download_namespace_project_job_artifacts_path
(
build
.
project
.
namespace
,
build
.
project
,
build
)
project
.
namespace
,
project
,
job
)
end
expose
:keep_path
,
if:
->
(
*
)
{
job
.
has_expiring_artifacts?
}
do
|
job
|
keep_namespace_project_job_artifacts_path
(
project
.
namespace
,
project
,
job
)
end
expose
:browse_path
do
|
job
|
browse_namespace_project_job_artifacts_path
(
project
.
namespace
,
project
,
job
)
end
private
alias_method
:job
,
:object
def
project
job
.
project
end
end
app/serializers/build_details_entity.rb
0 → 100644
View file @
615075e1
class
BuildDetailsEntity
<
BuildEntity
expose
:coverage
,
:erased_at
,
:duration
expose
:tag_list
,
as: :tags
expose
:user
,
using:
UserEntity
expose
:erased_by
,
if:
->
(
*
)
{
build
.
erased?
},
using:
UserEntity
expose
:erase_path
,
if:
->
(
*
)
{
build
.
erasable?
&&
can?
(
current_user
,
:update_build
,
project
)
}
do
|
build
|
erase_namespace_project_job_path
(
project
.
namespace
,
project
,
build
)
end
expose
:artifacts
,
using:
BuildArtifactEntity
expose
:runner
,
using:
RunnerEntity
expose
:pipeline
,
using:
PipelineEntity
expose
:merge_request
,
if:
->
(
*
)
{
can?
(
current_user
,
:read_merge_request
,
build
.
merge_request
)
}
do
expose
:iid
do
|
build
|
build
.
merge_request
.
iid
end
expose
:path
do
|
build
|
namespace_project_merge_request_path
(
project
.
namespace
,
project
,
build
.
merge_request
)
end
end
expose
:new_issue_path
,
if:
->
(
*
)
{
can?
(
request
.
current_user
,
:create_issue
,
project
)
&&
build
.
failed?
}
do
|
build
|
new_namespace_project_issue_path
(
project
.
namespace
,
project
,
issue:
build_failed_issue_options
)
end
expose
:raw_path
do
|
build
|
raw_namespace_project_build_path
(
project
.
namespace
,
project
,
build
)
end
private
def
build_failed_issue_options
{
title:
"Build Failed #
#{
build
.
id
}
"
,
description:
namespace_project_job_url
(
project
.
namespace
,
project
,
build
)
}
end
def
current_user
request
.
current_user
end
def
project
build
.
project
end
end
app/serializers/build_entity.rb
View file @
615075e1
...
...
@@ -8,7 +8,7 @@ class BuildEntity < Grape::Entity
path_to
(
:namespace_project_job
,
build
)
end
expose
:retry_path
do
|
build
|
expose
:retry_path
,
if:
->
(
*
)
{
build
&
.
retryable?
}
do
|
build
|
path_to
(
:retry_namespace_project_job
,
build
)
end
...
...
app/serializers/merge_request_entity.rb
View file @
615075e1
...
...
@@ -48,7 +48,7 @@ class MergeRequestEntity < IssuableEntity
expose
:merge_commit_sha
expose
:merge_commit_message
expose
:head_pipeline
,
with:
PipelineEntity
,
as: :pipeline
expose
:head_pipeline
,
with:
Pipeline
Details
Entity
,
as: :pipeline
# Booleans
expose
:work_in_progress?
,
as: :work_in_progress
...
...
app/serializers/pipeline_details_entity.rb
0 → 100644
View file @
615075e1
class
PipelineDetailsEntity
<
PipelineEntity
expose
:details
do
expose
:stages
,
using:
StageEntity
expose
:artifacts
,
using:
BuildArtifactEntity
expose
:manual_actions
,
using:
BuildActionEntity
end
expose
:triggered_by_pipeline
,
as: :triggered_by
,
with:
TriggeredPipelineEntity
expose
:triggered_pipelines
,
as: :triggered
,
using:
TriggeredPipelineEntity
end
app/serializers/pipeline_entity.rb
View file @
615075e1
...
...
@@ -7,6 +7,8 @@ class PipelineEntity < Grape::Entity
expose
:coverage
expose
:source
expose
:created_at
,
:updated_at
expose
:path
do
|
pipeline
|
namespace_project_pipeline_path
(
pipeline
.
project
.
namespace
,
...
...
@@ -14,15 +16,6 @@ class PipelineEntity < Grape::Entity
pipeline
)
end
expose
:details
do
expose
:detailed_status
,
as: :status
,
with:
StatusEntity
expose
:duration
expose
:finished_at
expose
:stages
,
using:
StageEntity
expose
:artifacts
,
using:
BuildArtifactEntity
expose
:manual_actions
,
using:
BuildActionEntity
end
expose
:flags
do
expose
:latest?
,
as: :latest
expose
:stuck?
,
as: :stuck
...
...
@@ -31,6 +24,12 @@ class PipelineEntity < Grape::Entity
expose
:can_cancel?
,
as: :cancelable
end
expose
:details
do
expose
:detailed_status
,
as: :status
,
with:
StatusEntity
expose
:duration
expose
:finished_at
end
expose
:ref
do
expose
:name
do
|
pipeline
|
pipeline
.
ref
...
...
@@ -47,7 +46,6 @@ class PipelineEntity < Grape::Entity
end
expose
:commit
,
using:
CommitEntity
expose
:yaml_errors
,
if:
->
(
pipeline
,
_
)
{
pipeline
.
has_yaml_errors?
}
expose
:retry_path
,
if:
->
(
*
)
{
can_retry?
}
do
|
pipeline
|
retry_namespace_project_pipeline_path
(
pipeline
.
project
.
namespace
,
...
...
@@ -61,7 +59,7 @@ class PipelineEntity < Grape::Entity
pipeline
.
id
)
end
expose
:
created_at
,
:updated_at
expose
:
yaml_errors
,
if:
->
(
pipeline
,
_
)
{
pipeline
.
has_yaml_errors?
}
private
...
...
app/serializers/pipeline_serializer.rb
View file @
615075e1
class
PipelineSerializer
<
BaseSerializer
InvalidResourceError
=
Class
.
new
(
StandardError
)
entity
PipelineEntity
entity
Pipeline
Details
Entity
def
with_pagination
(
request
,
response
)
tap
{
@paginator
=
Gitlab
::
Serializer
::
Pagination
.
new
(
request
,
response
)
}
...
...
@@ -18,6 +18,8 @@ class PipelineSerializer < BaseSerializer
:cancelable_statuses
,
:trigger_requests
,
:project
,
{
triggered_by_pipeline:
[
:project
,
:user
]
},
{
triggered_pipelines:
[
:project
,
:user
]
},
{
pending_builds: :project
},
{
manual_actions: :project
},
{
artifacts: :project
}
...
...
app/serializers/runner_entity.rb
0 → 100644
View file @
615075e1
class
RunnerEntity
<
Grape
::
Entity
include
RequestAwareEntity
expose
:id
,
:description
expose
:edit_path
,
if:
->
(
*
)
{
can?
(
request
.
current_user
,
:admin_build
,
project
)
&&
runner
.
specific?
}
do
|
runner
|
edit_namespace_project_runner_path
(
project
.
namespace
,
project
,
runner
)
end
private
alias_method
:runner
,
:object
def
project
request
.
project
end
end
app/serializers/triggered_pipeline_entity.rb
0 → 100644
View file @
615075e1
class
TriggeredPipelineEntity
<
Grape
::
Entity
include
RequestAwareEntity
expose
:id
expose
:user
,
using:
UserEntity
expose
:active?
,
as: :active
expose
:coverage
expose
:source
expose
:path
do
|
pipeline
|
namespace_project_pipeline_path
(
pipeline
.
project
.
namespace
,
pipeline
.
project
,
pipeline
)
end
expose
:details
do
expose
:detailed_status
,
as: :status
,
with:
StatusEntity
end
expose
:project
,
using:
ProjectEntity
private
alias_method
:pipeline
,
:object
def
detailed_status
pipeline
.
detailed_status
(
request
.
current_user
)
end
end
app/workers/expire_pipeline_cache_worker.rb
View file @
615075e1
...
...
@@ -10,13 +10,19 @@ class ExpirePipelineCacheWorker
store
=
Gitlab
::
EtagCaching
::
Store
.
new
store
.
touch
(
project_pipelines_path
(
project
))
store
.
touch
(
project_pipeline_path
(
p
roject
,
p
ipeline
))
store
.
touch
(
project_pipeline_path
(
pipeline
))
store
.
touch
(
commit_pipelines_path
(
project
,
pipeline
.
commit
))
if
pipeline
.
commit
store
.
touch
(
new_merge_request_pipelines_path
(
project
))
each_pipelines_merge_request_path
(
project
,
pipeline
)
do
|
path
|
store
.
touch
(
path
)
end
store
.
touch
(
project_pipeline_path
(
pipeline
.
triggered_by_pipeline
))
if
pipeline
.
triggered_by_pipeline
pipeline
.
triggered_pipelines
.
each
do
|
triggered
|
store
.
touch
(
project_pipeline_path
(
triggered
))
end
Gitlab
::
Cache
::
Ci
::
ProjectPipelineStatus
.
update_for_pipeline
(
pipeline
)
end
...
...
@@ -29,10 +35,10 @@ class ExpirePipelineCacheWorker
format: :json
)
end
def
project_pipeline_path
(
p
roject
,
p
ipeline
)
def
project_pipeline_path
(
pipeline
)
Gitlab
::
Routing
.
url_helpers
.
namespace_project_pipeline_path
(
project
.
namespace
,
project
,
p
ipeline
.
p
roject
.
namespace
,
p
ipeline
.
p
roject
,
pipeline
,
format: :json
)
end
...
...
changelogs/unreleased-ee/add-relation-between-pipelines.yml
0 → 100644
View file @
615075e1
---
title
:
Add relation between Pipelines
merge_request
:
author
:
changelogs/unreleased/zj-job-view-goes-real-time.yml
0 → 100644
View file @
615075e1
---
title
:
Job details page update real time
merge_request
:
11651
author
:
db/fixtures/development/14_pipelines.rb
View file @
615075e1
...
...
@@ -75,7 +75,15 @@ class Gitlab::Seeder::Pipelines
def
create_master_pipelines
@project
.
repository
.
commits
(
'master'
,
limit:
4
).
map
do
|
commit
|
create_pipeline!
(
@project
,
'master'
,
commit
)
create_pipeline!
(
@project
,
'master'
,
commit
).
tap
do
|
pipeline
|
random_pipeline
.
tap
do
|
triggered_by_pipeline
|
triggered_by_pipeline
.
sourced_pipelines
.
create
(
source_job:
triggered_by_pipeline
.
builds
.
all
.
sample
,
source_project:
triggered_by_pipeline
.
project
,
project:
pipeline
.
project
,
pipeline:
pipeline
)
end
end
end
rescue
[]
...
...
@@ -96,7 +104,6 @@ class Gitlab::Seeder::Pipelines
[]
end
def
create_pipeline!
(
project
,
ref
,
commit
)
project
.
pipelines
.
create
(
sha:
commit
.
id
,
ref:
ref
,
source: :push
)
end
...
...
@@ -151,6 +158,10 @@ class Gitlab::Seeder::Pipelines
@project
.
team
.
users
.
sample
end
def
random_pipeline
Ci
::
Pipeline
.
limit
(
4
).
all
.
sample
end
def
build_status
Ci
::
Build
::
AVAILABLE_STATUSES
.
sample
end
...
...
db/migrate/20170525174157_create_pipeline_source_pipeline.rb
0 → 100644
View file @
615075e1
class
CreatePipelineSourcePipeline
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
change
create_table
:ci_sources_pipelines
,
force: :cascade
do
|
t
|
t
.
integer
:project_id
t
.
integer
:pipeline_id
t
.
integer
:source_project_id
t
.
integer
:source_job_id
t
.
integer
:source_pipeline_id
end
end
end
db/migrate/20170525174158_add_ci_pipeline_source_pipeline_indexes.rb
0 → 100644
View file @
615075e1
class
AddCiPipelineSourcePipelineIndexes
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
add_concurrent_index
:ci_sources_pipelines
,
:project_id
add_concurrent_index
:ci_sources_pipelines
,
:pipeline_id
add_concurrent_index
:ci_sources_pipelines
,
:source_project_id
add_concurrent_index
:ci_sources_pipelines
,
:source_job_id
add_concurrent_index
:ci_sources_pipelines
,
:source_pipeline_id
end
def
down
remove_concurrent_index
:ci_sources_pipelines
,
:project_id
if
index_exists?
:ci_sources_pipelines
,
:project_id
remove_concurrent_index
:ci_sources_pipelines
,
:pipeline_id
if
index_exists?
:ci_sources_pipelines
,
:pipeline_id
remove_concurrent_index
:ci_sources_pipelines
,
:source_project_id
if
index_exists?
:ci_sources_pipelines
,
:source_project_id
remove_concurrent_index
:ci_sources_pipelines
,
:source_job_id
if
index_exists?
:ci_sources_pipelines
,
:source_job_id
remove_concurrent_index
:ci_sources_pipelines
,
:source_pipeline_id
if
index_exists?
:ci_sources_pipelines
,
:source_pipeline_id
end
end
db/migrate/20170525174159_add_ci_pipeline_source_pipeline_foreign_key.rb
0 → 100644
View file @
615075e1
class
AddCiPipelineSourcePipelineForeignKey
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
add_concurrent_foreign_key
:ci_sources_pipelines
,
:projects
,
column: :project_id
add_concurrent_foreign_key
:ci_sources_pipelines
,
:ci_pipelines
,
column: :pipeline_id
add_concurrent_foreign_key
:ci_sources_pipelines
,
:projects
,
column: :source_project_id
add_concurrent_foreign_key
:ci_sources_pipelines
,
:ci_builds
,
column: :source_job_id
add_concurrent_foreign_key
:ci_sources_pipelines
,
:ci_pipelines
,
column: :source_pipeline_id
end
def
down
remove_foreign_key
:ci_sources_pipelines
,
column: :project_id
remove_foreign_key
:ci_sources_pipelines
,
column: :pipeline_id
remove_foreign_key
:ci_sources_pipelines
,
column: :source_project_id
remove_foreign_key
:ci_sources_pipelines
,
column: :source_job_id
remove_foreign_key
:ci_sources_pipelines
,
column: :source_pipeline_id
end
end
db/schema.rb
View file @
615075e1
...
...
@@ -377,6 +377,20 @@ ActiveRecord::Schema.define(version: 20170602003304) do
add_index
"ci_runners"
,
[
"locked"
],
name:
"index_ci_runners_on_locked"
,
using: :btree
add_index
"ci_runners"
,
[
"token"
],
name:
"index_ci_runners_on_token"
,
using: :btree
create_table
"ci_sources_pipelines"
,
force: :cascade
do
|
t
|
t
.
integer
"project_id"
t
.
integer
"pipeline_id"
t
.
integer
"source_project_id"
t
.
integer
"source_job_id"
t
.
integer
"source_pipeline_id"
end
add_index
"ci_sources_pipelines"
,
[
"pipeline_id"
],
name:
"index_ci_pipeline_source_pipelines_on_pipeline_id"
,
using: :btree
add_index
"ci_sources_pipelines"
,
[
"project_id"
],
name:
"index_ci_pipeline_source_pipelines_on_project_id"
,
using: :btree
add_index
"ci_sources_pipelines"
,
[
"source_job_id"
],
name:
"index_ci_pipeline_source_pipelines_on_source_job_id"
,
using: :btree
add_index
"ci_sources_pipelines"
,
[
"source_pipeline_id"
],
name:
"index_ci_pipeline_source_pipelines_on_source_pipeline_id"
,
using: :btree
add_index
"ci_sources_pipelines"
,
[
"source_project_id"
],
name:
"index_ci_pipeline_source_pipelines_on_source_project_id"
,
using: :btree
create_table
"ci_trigger_requests"
,
force: :cascade
do
|
t
|
t
.
integer
"trigger_id"
,
null:
false
t
.
text
"variables"
...
...
@@ -1683,6 +1697,11 @@ ActiveRecord::Schema.define(version: 20170602003304) do
add_foreign_key
"ci_pipeline_schedules"
,
"users"
,
column:
"owner_id"
,
name:
"fk_9ea99f58d2"
,
on_delete: :nullify
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_sources_pipelines"
,
"ci_builds"
,
column:
"source_job_id"
,
name:
"fk_3f0c88d7dc"
,
on_delete: :cascade
add_foreign_key
"ci_sources_pipelines"
,
"ci_pipelines"
,
column:
"pipeline_id"
,
name:
"fk_b8c0fac459"
,
on_delete: :cascade
add_foreign_key
"ci_sources_pipelines"
,
"ci_pipelines"
,
column:
"source_pipeline_id"
,
name:
"fk_3a3e3cb83a"
,
on_delete: :cascade
add_foreign_key
"ci_sources_pipelines"
,
"projects"
,
column:
"source_project_id"
,
name:
"fk_8868d0f3e4"
,
on_delete: :cascade
add_foreign_key
"ci_sources_pipelines"
,
"projects"
,
name:
"fk_83b4346e48"
,
on_delete: :cascade
add_foreign_key
"ci_trigger_requests"
,
"ci_triggers"
,
column:
"trigger_id"
,
name:
"fk_b8ec8b7245"
,
on_delete: :cascade
add_foreign_key
"ci_triggers"
,
"users"
,
column:
"owner_id"
,
name:
"fk_e8e10d1964"
,
on_delete: :cascade
add_foreign_key
"ci_variables"
,
"projects"
,
name:
"fk_ada5eb64b3"
,
on_delete: :cascade
...
...
lib/gitlab/etag_caching/router.rb
View file @
615075e1
...
...
@@ -9,8 +9,8 @@ module Gitlab
# - Ending in `noteable/issue/<id>/notes` for the `issue_notes` route
# - Ending in `issues/id`/realtime_changes` for the `issue_title` route
USED_IN_ROUTES
=
%w[noteable issue notes issues realtime_changes
commit pipelines merge_requests
new
environments]
.
freeze
commit pipelines merge_requests
builds
new
environments]
.
freeze
RESERVED_WORDS
=
Gitlab
::
PathRegex
::
ILLEGAL_PROJECT_PATH_WORDS
-
USED_IN_ROUTES
RESERVED_WORDS_REGEX
=
Regexp
.
union
(
*
RESERVED_WORDS
.
map
(
&
Regexp
.
method
(
:escape
)))
...
...
@@ -43,6 +43,10 @@ module Gitlab
%r(^(?!.*(
#{
RESERVED_WORDS_REGEX
}
)).*/pipelines/
\d
+
\.
json
\z
)
,
'project_pipeline'
),
Gitlab
::
EtagCaching
::
Router
::
Route
.
new
(
%r(^(?!.*(
#{
RESERVED_WORDS_REGEX
}
)).*/builds/
\d
+
\.
json
\z
)
,
'project_build'
),
Gitlab
::
EtagCaching
::
Router
::
Route
.
new
(
%r(^(?!.*(
#{
RESERVED_WORDS_REGEX
}
)).*/environments
\.
json
\z
)
,
'environments'
...
...
spec/controllers/projects/jobs_controller_spec.rb
View file @
615075e1
...
...
@@ -101,26 +101,49 @@ describe Projects::JobsController do
end
describe
'GET show'
do
context
'when build exists'
do
let!
(
:build
)
{
create
(
:ci_build
,
pipeline:
pipeline
)
}
let!
(
:build
)
{
create
(
:ci_build
,
:failed
,
pipeline:
pipeline
)
}
before
do
get_show
(
id:
build
.
id
)
context
'when requesting HTML'
do
context
'when build exists'
do
before
do
get_show
(
id:
build
.
id
)
end
it
'has a build'
do
expect
(
response
).
to
have_http_status
(
:ok
)
expect
(
assigns
(
:build
).
id
).
to
eq
(
build
.
id
)
end
end
it
'has a build'
do
expect
(
response
).
to
have_http_status
(
:ok
)
expect
(
assigns
(
:build
).
id
).
to
eq
(
build
.
id
)
context
'when build does not exist'
do
before
do
get_show
(
id:
1234
)
end
it
'renders not_found'
do
expect
(
response
).
to
have_http_status
(
:not_found
)
end
end
end
context
'when build does not exist'
do
context
'when requesting JSON'
do
let
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
)
}
before
do
get_show
(
id:
1234
)
project
.
add_developer
(
user
)
sign_in
(
user
)
allow_any_instance_of
(
Ci
::
Build
).
to
receive
(
:merge_request
).
and_return
(
merge_request
)
get_show
(
id:
build
.
id
,
format: :json
)
end
it
'renders not_found'
do
expect
(
response
).
to
have_http_status
(
:not_found
)
it
'exposes needed information'
do
expect
(
response
).
to
have_http_status
(
:ok
)
expect
(
json_response
[
'raw_path'
]).
to
match
(
/builds\/\d+\/raw\z/
)
expect
(
json_response
.
dig
(
'merge_request'
,
'path'
)).
to
match
(
/merge_requests\/\d+\z/
)
expect
(
json_response
[
'new_issue_path'
])
.
to
include
(
'/issues/new'
)
end
end
...
...
spec/factories/ci/sources/pipelines.rb
0 → 100644
View file @
615075e1
FactoryGirl
.
define
do
factory
:ci_sources_pipeline
,
class:
Ci
::
Sources
::
Pipeline
do
after
(
:build
)
do
|
source
|
source
.
project
||=
source
.
pipeline
.
project
source
.
source_pipeline
||=
source
.
source_job
.
pipeline
source
.
source_project
||=
source
.
source_pipeline
.
project
end
source_job
factory: :ci_build
pipeline
factory: :ci_empty_pipeline
end
end
spec/lib/gitlab/etag_caching/router_spec.rb
View file @
615075e1
...
...
@@ -67,6 +67,17 @@ describe Gitlab::EtagCaching::Router do
expect
(
result
.
name
).
to
eq
'merge_request_pipelines'
end
it
'matches build endpoint'
do
env
=
build_env
(
'/my-group/my-project/builds/234.json'
)
result
=
described_class
.
match
(
env
)
expect
(
result
).
to
be_present
expect
(
result
.
name
).
to
eq
'project_build'
end
it
'does not match blob with confusing name'
do
env
=
build_env
(
'/my-group/my-project/blob/master/pipelines.json'
...
...
spec/lib/gitlab/import_export/all_models.yml
View file @
615075e1
...
...
@@ -108,6 +108,10 @@ pipelines:
-
artifacts
-
pipeline_schedule
-
merge_requests
-
source_pipeline
-
sourced_pipelines
-
triggered_by_pipeline
-
triggered_pipelines
statuses
:
-
project
-
pipeline
...
...
@@ -263,6 +267,8 @@ project:
-
container_repositories
-
uploads
-
mirror_data
-
source_pipelines
-
sourced_pipelines
award_emoji
:
-
awardable
-
user
...
...
spec/models/ci/build_spec.rb
View file @
615075e1
...
...
@@ -17,6 +17,7 @@ describe Ci::Build, :models do
it
{
is_expected
.
to
belong_to
(
:trigger_request
)
}
it
{
is_expected
.
to
belong_to
(
:erased_by
)
}
it
{
is_expected
.
to
have_many
(
:deployments
)
}
it
{
is_expected
.
to
have_many
(
:sourced_pipelines
)
}
it
{
is_expected
.
to
validate_presence_of
(
:ref
)
}
it
{
is_expected
.
to
respond_to
(
:has_trace?
)
}
it
{
is_expected
.
to
respond_to
(
:trace
)
}
...
...
spec/models/ci/pipeline_spec.rb
View file @
615075e1
...
...
@@ -20,6 +20,10 @@ describe Ci::Pipeline, models: true do
it
{
is_expected
.
to
have_many
(
:builds
)
}
it
{
is_expected
.
to
have_many
(
:auto_canceled_pipelines
)
}
it
{
is_expected
.
to
have_many
(
:auto_canceled_jobs
)
}
it
{
is_expected
.
to
have_one
(
:source_pipeline
)
}
it
{
is_expected
.
to
have_many
(
:sourced_pipelines
)
}
it
{
is_expected
.
to
have_one
(
:triggered_by_pipeline
)
}
it
{
is_expected
.
to
have_many
(
:triggered_pipelines
)
}
it
{
is_expected
.
to
validate_presence_of
(
:sha
)
}
it
{
is_expected
.
to
validate_presence_of
(
:status
)
}
...
...
spec/models/ci/sources/pipeline_spec.rb
0 → 100644
View file @
615075e1
require
'spec_helper'
describe
Ci
::
Sources
::
Pipeline
,
models:
true
do
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:pipeline
)
}
it
{
is_expected
.
to
belong_to
(
:source_project
)
}
it
{
is_expected
.
to
belong_to
(
:source_job
)
}
it
{
is_expected
.
to
belong_to
(
:source_pipeline
)
}
it
{
is_expected
.
to
validate_presence_of
(
:project
)
}
it
{
is_expected
.
to
validate_presence_of
(
:pipeline
)
}
it
{
is_expected
.
to
validate_presence_of
(
:source_project
)
}
it
{
is_expected
.
to
validate_presence_of
(
:source_job
)
}
it
{
is_expected
.
to
validate_presence_of
(
:source_pipeline
)
}
end
spec/models/project_spec.rb
View file @
615075e1
...
...
@@ -77,6 +77,8 @@ describe Project, models: true do
it
{
is_expected
.
to
have_many
(
:approver_groups
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:uploads
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:pipeline_schedules
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:sourced_pipelines
)
}
it
{
is_expected
.
to
have_many
(
:source_pipelines
)
}
context
'after initialized'
do
it
"has a project_feature"
do
...
...
spec/serializers/build_artifact_entity_spec.rb
View file @
615075e1
require
'spec_helper'
describe
BuildArtifactEntity
do
let
(
:job
)
{
create
(
:ci_build
,
name:
'test:job'
)
}
let
(
:job
)
{
create
(
:ci_build
,
name:
'test:job'
,
artifacts_expire_at:
1
.
hour
.
from_now
)
}
let
(
:entity
)
do
described_class
.
new
(
job
,
request:
double
)
...
...
@@ -14,9 +14,19 @@ describe BuildArtifactEntity do
expect
(
subject
[
:name
]).
to
eq
'test:job'
end
it
'contains path to the artifacts'
do
it
'exposes information about expiration of artifacts'
do
expect
(
subject
).
to
include
(
:expired
,
:expire_at
)
end
it
'contains paths to the artifacts'
do
expect
(
subject
[
:path
])
.
to
include
"jobs/
#{
job
.
id
}
/artifacts/download"
expect
(
subject
[
:keep_path
])
.
to
include
"jobs/
#{
job
.
id
}
/artifacts/keep"
expect
(
subject
[
:browse_path
])
.
to
include
"jobs/
#{
job
.
id
}
/artifacts/browse"
end
end
end
spec/serializers/build_details_entity_spec.rb
0 → 100644
View file @
615075e1
require
'spec_helper'
describe
BuildDetailsEntity
do
set
(
:user
)
{
create
(
:admin
)
}
it
'inherits from BuildEntity'
do
expect
(
described_class
).
to
be
<
BuildEntity
end
describe
'#as_json'
do
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let!
(
:build
)
{
create
(
:ci_build
,
:failed
,
project:
project
)
}
let
(
:request
)
{
double
(
'request'
)
}
let
(
:entity
)
{
described_class
.
new
(
build
,
request:
request
,
current_user:
user
,
project:
project
)
}
subject
{
entity
.
as_json
}
before
do
allow
(
request
).
to
receive
(
:current_user
).
and_return
(
user
)
end
context
'when the user has access to issues and merge requests'
do
let!
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
build
.
ref
)
end
before
do
allow
(
build
).
to
receive
(
:merge_request
).
and_return
(
merge_request
)
end
it
'contains the needed key value pairs'
do
expect
(
subject
).
to
include
(
:coverage
,
:erased_at
,
:duration
)
expect
(
subject
).
to
include
(
:artifacts
,
:runner
,
:pipeline
)
expect
(
subject
).
to
include
(
:raw_path
,
:merge_request
)
expect
(
subject
).
to
include
(
:new_issue_path
)
end
it
'exposes details of the merge request'
do
expect
(
subject
[
:merge_request
]).
to
include
(
:iid
,
:path
)
end
context
'when the build has been erased'
do
let!
(
:build
)
{
create
(
:ci_build
,
:erasable
,
project:
project
)
}
it
'exposes the user whom erased the build'
do
expect
(
subject
).
to
include
(
:erase_path
)
end
end
context
'when the build has been erased'
do
let!
(
:build
)
{
create
(
:ci_build
,
erased_at:
Time
.
now
,
project:
project
,
erased_by:
user
)
}
it
'exposes the user whom erased the build'
do
expect
(
subject
).
to
include
(
:erased_by
)
end
end
end
context
'when the user can only read the build'
do
let
(
:user
)
{
create
(
:user
)
}
it
"won't display the paths to issues and merge requests"
do
expect
(
subject
[
'new_issue_path'
]).
to
be_nil
expect
(
subject
[
'merge_request_path'
]).
to
be_nil
end
end
end
end
spec/serializers/build_entity_spec.rb
View file @
615075e1
...
...
@@ -2,7 +2,7 @@ require 'spec_helper'
describe
BuildEntity
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:build
)
{
create
(
:ci_build
)
}
let
(
:build
)
{
create
(
:ci_build
,
:failed
)
}
let
(
:project
)
{
build
.
project
}
let
(
:request
)
{
double
(
'request'
)
}
...
...
@@ -18,6 +18,7 @@ describe BuildEntity do
it
'contains paths to build page and retry action'
do
expect
(
subject
).
to
include
(
:build_path
,
:retry_path
)
expect
(
subject
[
:retry_path
]).
not_to
be_nil
end
it
'does not contain sensitive information'
do
...
...
spec/serializers/merge_request_entity_spec.rb
View file @
615075e1
...
...
@@ -26,7 +26,7 @@ describe MergeRequestEntity do
pipeline
=
build_stubbed
(
:ci_pipeline
)
allow
(
resource
).
to
receive
(
:head_pipeline
).
and_return
(
pipeline
)
pipeline_payload
=
PipelineEntity
pipeline_payload
=
Pipeline
Details
Entity
.
represent
(
pipeline
,
request:
req
)
.
as_json
...
...
spec/serializers/pipeline_details_entity_spec.rb
0 → 100644
View file @
615075e1
require
'spec_helper'
describe
PipelineDetailsEntity
do
set
(
:user
)
{
create
(
:user
)
}
let
(
:request
)
{
double
(
'request'
)
}
it
'inherrits from PipelineEntity'
do
expect
(
described_class
).
to
be
<
PipelineEntity
end
before
do
allow
(
request
).
to
receive
(
:current_user
).
and_return
(
user
)
end
let
(
:entity
)
do
described_class
.
represent
(
pipeline
,
request:
request
)
end
describe
'#as_json'
do
subject
{
entity
.
as_json
}
context
'when pipeline is empty'
do
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
)
}
it
'contains details'
do
expect
(
subject
).
to
include
:details
expect
(
subject
[
:details
])
.
to
include
:duration
,
:finished_at
expect
(
subject
[
:details
])
.
to
include
:stages
,
:artifacts
,
:manual_actions
expect
(
subject
[
:details
][
:status
]).
to
include
:icon
,
:favicon
,
:text
,
:label
end
it
'contains flags'
do
expect
(
subject
).
to
include
:flags
expect
(
subject
[
:flags
])
.
to
include
:latest
,
:stuck
,
:yaml_errors
,
:retryable
,
:cancelable
end
end
context
'when pipeline is retryable'
do
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:pipeline
)
do
create
(
:ci_pipeline
,
status: :success
,
project:
project
)
end
before
do
create
(
:ci_build
,
:failed
,
pipeline:
pipeline
)
end
context
'user has ability to retry pipeline'
do
before
{
project
.
team
<<
[
user
,
:developer
]
}
it
'retryable flag is true'
do
expect
(
subject
[
:flags
][
:retryable
]).
to
eq
true
end
end
context
'user does not have ability to retry pipeline'
do
it
'retryable flag is false'
do
expect
(
subject
[
:flags
][
:retryable
]).
to
eq
false
end
end
end
context
'when pipeline is cancelable'
do
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:pipeline
)
do
create
(
:ci_pipeline
,
status: :running
,
project:
project
)
end
before
do
create
(
:ci_build
,
:pending
,
pipeline:
pipeline
)
end
context
'user has ability to cancel pipeline'
do
before
{
project
.
add_developer
(
user
)
}
it
'cancelable flag is true'
do
expect
(
subject
[
:flags
][
:cancelable
]).
to
eq
true
end
end
context
'user does not have ability to cancel pipeline'
do
it
'cancelable flag is false'
do
expect
(
subject
[
:flags
][
:cancelable
]).
to
eq
false
end
end
end
context
'when pipeline has YAML errors'
do
let
(
:pipeline
)
do
create
(
:ci_pipeline
,
config:
{
rspec:
{
invalid: :value
}
})
end
it
'contains information about error'
do
expect
(
subject
[
:yaml_errors
]).
to
be_present
end
it
'contains flag that indicates there are errors'
do
expect
(
subject
[
:flags
][
:yaml_errors
]).
to
be
true
end
end
context
'when pipeline does not have YAML errors'
do
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
)
}
it
'does not contain field that normally holds an error'
do
expect
(
subject
).
not_to
have_key
(
:yaml_errors
)
end
it
'contains flag that indicates there are no errors'
do
expect
(
subject
[
:flags
][
:yaml_errors
]).
to
be
false
end
end
context
'when pipeline is triggered by other pipeline'
do
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
)
}
before
do
create
(
:ci_sources_pipeline
,
pipeline:
pipeline
)
end
it
'contains an information about depedent pipeline'
do
expect
(
subject
[
:triggered_by
]).
to
be_a
(
Hash
)
expect
(
subject
[
:triggered_by
][
:path
]).
not_to
be_nil
expect
(
subject
[
:triggered_by
][
:details
]).
not_to
be_nil
expect
(
subject
[
:triggered_by
][
:details
][
:status
]).
not_to
be_nil
expect
(
subject
[
:triggered_by
][
:project
]).
not_to
be_nil
end
end
context
'when pipeline triggered other pipeline'
do
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
)
}
let
(
:build
)
{
create
(
:ci_build
,
pipeline:
pipeline
)
}
before
do
create
(
:ci_sources_pipeline
,
source_job:
build
)
create
(
:ci_sources_pipeline
,
source_job:
build
)
end
it
'contains an information about depedent pipeline'
do
expect
(
subject
[
:triggered
]).
to
be_a
(
Array
)
expect
(
subject
[
:triggered
].
length
).
to
eq
(
2
)
expect
(
subject
[
:triggered
].
first
[
:path
]).
not_to
be_nil
expect
(
subject
[
:triggered
].
first
[
:details
]).
not_to
be_nil
expect
(
subject
[
:triggered
].
first
[
:details
][
:status
]).
not_to
be_nil
expect
(
subject
[
:triggered
].
first
[
:project
]).
not_to
be_nil
end
end
end
end
spec/serializers/pipeline_entity_spec.rb
View file @
615075e1
require
'spec_helper'
describe
PipelineEntity
do
l
et
(
:user
)
{
create
(
:user
)
}
s
et
(
:user
)
{
create
(
:user
)
}
let
(
:request
)
{
double
(
'request'
)
}
before
do
...
...
@@ -28,8 +28,6 @@ describe PipelineEntity do
expect
(
subject
).
to
include
:details
expect
(
subject
[
:details
])
.
to
include
:duration
,
:finished_at
expect
(
subject
[
:details
])
.
to
include
:stages
,
:artifacts
,
:manual_actions
expect
(
subject
[
:details
][
:status
]).
to
include
:icon
,
:favicon
,
:text
,
:label
end
...
...
@@ -55,20 +53,12 @@ describe PipelineEntity do
context
'user has ability to retry pipeline'
do
before
{
project
.
team
<<
[
user
,
:developer
]
}
it
'retryable flag is true'
do
expect
(
subject
[
:flags
][
:retryable
]).
to
eq
true
end
it
'contains retry path'
do
expect
(
subject
[
:retry_path
]).
to
be_present
end
end
context
'user does not have ability to retry pipeline'
do
it
'retryable flag is false'
do
expect
(
subject
[
:flags
][
:retryable
]).
to
eq
false
end
it
'does not contain retry path'
do
expect
(
subject
).
not_to
have_key
(
:retry_path
)
end
...
...
@@ -87,11 +77,7 @@ describe PipelineEntity do
end
context
'user has ability to cancel pipeline'
do
before
{
project
.
team
<<
[
user
,
:developer
]
}
it
'cancelable flag is true'
do
expect
(
subject
[
:flags
][
:cancelable
]).
to
eq
true
end
before
{
project
.
add_developer
(
user
)
}
it
'contains cancel path'
do
expect
(
subject
[
:cancel_path
]).
to
be_present
...
...
@@ -99,42 +85,12 @@ describe PipelineEntity do
end
context
'user does not have ability to cancel pipeline'
do
it
'cancelable flag is false'
do
expect
(
subject
[
:flags
][
:cancelable
]).
to
eq
false
end
it
'does not contain cancel path'
do
expect
(
subject
).
not_to
have_key
(
:cancel_path
)
end
end
end
context
'when pipeline has YAML errors'
do
let
(
:pipeline
)
do
create
(
:ci_pipeline
,
config:
{
rspec:
{
invalid: :value
}
})
end
it
'contains flag that indicates there are errors'
do
expect
(
subject
[
:flags
][
:yaml_errors
]).
to
be
true
end
it
'contains information about error'
do
expect
(
subject
[
:yaml_errors
]).
to
be_present
end
end
context
'when pipeline does not have YAML errors'
do
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
)
}
it
'contains flag that indicates there are no errors'
do
expect
(
subject
[
:flags
][
:yaml_errors
]).
to
be
false
end
it
'does not contain field that normally holds an error'
do
expect
(
subject
).
not_to
have_key
(
:yaml_errors
)
end
end
context
'when pipeline ref is empty'
do
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
)
}
...
...
spec/serializers/pipeline_serializer_spec.rb
View file @
615075e1
...
...
@@ -113,7 +113,7 @@ describe PipelineSerializer do
it
"verifies number of queries"
do
recorded
=
ActiveRecord
::
QueryRecorder
.
new
{
subject
}
expect
(
recorded
.
count
).
to
be_within
(
1
).
of
(
6
1
)
expect
(
recorded
.
count
).
to
be_within
(
1
).
of
(
6
4
)
expect
(
recorded
.
cached_count
).
to
eq
(
0
)
end
...
...
spec/serializers/runner_entity_spec.rb
0 → 100644
View file @
615075e1
require
'spec_helper'
describe
RunnerEntity
do
let
(
:runner
)
{
create
(
:ci_runner
,
:specific
)
}
let
(
:entity
)
{
described_class
.
new
(
runner
,
request:
request
,
current_user:
user
)
}
let
(
:request
)
{
double
(
'request'
)
}
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:user
)
{
create
(
:admin
)
}
before
do
allow
(
request
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
request
).
to
receive
(
:project
).
and_return
(
project
)
end
describe
'#as_json'
do
subject
{
entity
.
as_json
}
it
'contains required fields'
do
expect
(
subject
).
to
include
(
:id
,
:description
)
expect
(
subject
).
to
include
(
:edit_path
)
end
end
end
spec/services/ci/retry_build_service_spec.rb
View file @
615075e1
...
...
@@ -22,7 +22,7 @@ describe Ci::RetryBuildService, :services do
%i[type lock_version target_url base_tags
commit_id deployments erased_by_id last_deployment project_id
runner_id tag_taggings taggings tags trigger_request_id
user_id auto_canceled_by_id retried]
.
freeze
user_id auto_canceled_by_id retried
sourced_pipelines
]
.
freeze
shared_examples
'build duplication'
do
let
(
:build
)
do
...
...
spec/workers/expire_pipeline_cache_worker_spec.rb
View file @
615075e1
...
...
@@ -42,5 +42,34 @@ describe ExpirePipelineCacheWorker do
subject
.
perform
(
pipeline
.
id
)
end
context
'when pipeline is triggered by other pipeline'
do
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
)
}
let
(
:source
)
{
create
(
:ci_sources_pipeline
,
pipeline:
pipeline
)
}
it
'updates the cache of dependent pipeline'
do
dependent_pipeline_path
=
"/
#{
source
.
source_project
.
full_path
}
/pipelines/
#{
source
.
source_pipeline
.
id
}
.json"
allow_any_instance_of
(
Gitlab
::
EtagCaching
::
Store
).
to
receive
(
:touch
)
expect_any_instance_of
(
Gitlab
::
EtagCaching
::
Store
).
to
receive
(
:touch
).
with
(
dependent_pipeline_path
)
subject
.
perform
(
pipeline
.
id
)
end
end
context
'when pipeline triggered other pipeline'
do
let
(
:pipeline
)
{
create
(
:ci_empty_pipeline
)
}
let
(
:build
)
{
create
(
:ci_build
,
pipeline:
pipeline
)
}
let
(
:source
)
{
create
(
:ci_sources_pipeline
,
source_job:
build
)
}
it
'updates the cache of dependent pipeline'
do
dependent_pipeline_path
=
"/
#{
source
.
project
.
full_path
}
/pipelines/
#{
source
.
pipeline
.
id
}
.json"
allow_any_instance_of
(
Gitlab
::
EtagCaching
::
Store
).
to
receive
(
:touch
)
expect_any_instance_of
(
Gitlab
::
EtagCaching
::
Store
).
to
receive
(
:touch
).
with
(
dependent_pipeline_path
)
subject
.
perform
(
pipeline
.
id
)
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