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
Tatuya Kamada
gitlab-ce
Commits
263abda3
Commit
263abda3
authored
Aug 27, 2015
by
Kirilll Zaitsev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Drone CI service
parent
308c6428
Changes
15
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1042 additions
and
136 deletions
+1042
-136
CHANGELOG
CHANGELOG
+3
-0
app/controllers/projects/services_controller.rb
app/controllers/projects/services_controller.rb
+1
-1
app/models/project.rb
app/models/project.rb
+2
-0
app/models/project_services/ci_service.rb
app/models/project_services/ci_service.rb
+33
-4
app/models/project_services/drone_ci_service.rb
app/models/project_services/drone_ci_service.rb
+170
-0
app/models/service.rb
app/models/service.rb
+1
-0
doc/api/services.md
doc/api/services.md
+498
-8
doc/web_hooks/web_hooks.md
doc/web_hooks/web_hooks.md
+4
-0
lib/api/helpers.rb
lib/api/helpers.rb
+26
-0
lib/api/services.rb
lib/api/services.rb
+31
-55
lib/gitlab/backend/grack_auth.rb
lib/gitlab/backend/grack_auth.rb
+15
-10
lib/tasks/services.rake
lib/tasks/services.rake
+89
-0
spec/models/project_services/drone_ci_service_spec.rb
spec/models/project_services/drone_ci_service_spec.rb
+107
-0
spec/requests/api/services_spec.rb
spec/requests/api/services_spec.rb
+41
-58
spec/support/services_shared_context.rb
spec/support/services_shared_context.rb
+21
-0
No files found.
CHANGELOG
View file @
263abda3
...
@@ -31,6 +31,9 @@ v 8.0.0 (unreleased)
...
@@ -31,6 +31,9 @@ v 8.0.0 (unreleased)
- Don't notify users without access to the project when they are (accidentally) mentioned in a note.
- Don't notify users without access to the project when they are (accidentally) mentioned in a note.
- Retrieving oauth token with LDAP credentials
- Retrieving oauth token with LDAP credentials
- Load Application settings from running database unless env var USE_DB=false
- Load Application settings from running database unless env var USE_DB=false
- Added Drone CI integration (Kirill Zaitsev)
- Refactored service API and added automatically service docs generator (Kirill Zaitsev)
- Added web_url key project hook_attrs (Kirill Zaitsev)
v 7.14.1
v 7.14.1
- Improve abuse reports management from admin area
- Improve abuse reports management from admin area
...
...
app/controllers/projects/services_controller.rb
View file @
263abda3
...
@@ -2,7 +2,7 @@ class Projects::ServicesController < Projects::ApplicationController
...
@@ -2,7 +2,7 @@ class Projects::ServicesController < Projects::ApplicationController
ALLOWED_PARAMS
=
[
:title
,
:token
,
:type
,
:active
,
:api_key
,
:api_version
,
:subdomain
,
ALLOWED_PARAMS
=
[
:title
,
:token
,
:type
,
:active
,
:api_key
,
:api_version
,
:subdomain
,
:room
,
:recipients
,
:project_url
,
:webhook
,
:room
,
:recipients
,
:project_url
,
:webhook
,
:user_key
,
:device
,
:priority
,
:sound
,
:bamboo_url
,
:username
,
:password
,
:user_key
,
:device
,
:priority
,
:sound
,
:bamboo_url
,
:username
,
:password
,
:build_key
,
:server
,
:teamcity_url
,
:build_type
,
:build_key
,
:server
,
:teamcity_url
,
:
drone_url
,
:
build_type
,
:description
,
:issues_url
,
:new_issue_url
,
:restrict_to_branch
,
:channel
,
:description
,
:issues_url
,
:new_issue_url
,
:restrict_to_branch
,
:channel
,
:colorize_messages
,
:channels
,
:colorize_messages
,
:channels
,
:push_events
,
:issues_events
,
:merge_requests_events
,
:tag_push_events
,
:push_events
,
:issues_events
,
:merge_requests_events
,
:tag_push_events
,
...
...
app/models/project.rb
View file @
263abda3
...
@@ -73,6 +73,7 @@ class Project < ActiveRecord::Base
...
@@ -73,6 +73,7 @@ class Project < ActiveRecord::Base
has_many
:services
has_many
:services
has_one
:gitlab_ci_service
,
dependent: :destroy
has_one
:gitlab_ci_service
,
dependent: :destroy
has_one
:campfire_service
,
dependent: :destroy
has_one
:campfire_service
,
dependent: :destroy
has_one
:drone_ci_service
,
dependent: :destroy
has_one
:emails_on_push_service
,
dependent: :destroy
has_one
:emails_on_push_service
,
dependent: :destroy
has_one
:irker_service
,
dependent: :destroy
has_one
:irker_service
,
dependent: :destroy
has_one
:pivotaltracker_service
,
dependent: :destroy
has_one
:pivotaltracker_service
,
dependent: :destroy
...
@@ -613,6 +614,7 @@ class Project < ActiveRecord::Base
...
@@ -613,6 +614,7 @@ class Project < ActiveRecord::Base
name:
name
,
name:
name
,
ssh_url:
ssh_url_to_repo
,
ssh_url:
ssh_url_to_repo
,
http_url:
http_url_to_repo
,
http_url:
http_url_to_repo
,
web_url:
web_url
,
namespace:
namespace
.
name
,
namespace:
namespace
.
name
,
visibility_level:
visibility_level
visibility_level:
visibility_level
}
}
...
...
app/models/project_services/ci_service.rb
View file @
263abda3
...
@@ -26,11 +26,23 @@ class CiService < Service
...
@@ -26,11 +26,23 @@ class CiService < Service
:ci
:ci
end
end
def
valid_token?
(
token
)
self
.
respond_to?
(
:token
)
&&
self
.
token
.
present?
&&
self
.
token
==
token
end
def
supported_events
def
supported_events
%w(push)
%w(push)
end
end
# Return complete url to build page
def
merge_request_page
(
iid
,
sha
,
ref
)
commit_page
(
sha
,
ref
)
end
def
commit_page
(
sha
,
ref
)
build_page
(
sha
,
ref
)
end
# Return complete url to merge_request page
#
#
# Ex.
# Ex.
# http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c
# http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c
...
@@ -45,10 +57,27 @@ class CiService < Service
...
@@ -45,10 +57,27 @@ class CiService < Service
#
#
#
#
# Ex.
# Ex.
# @service.commit_status('13be4ac')
# @service.merge_request_status(9, '13be4ac', 'dev')
# # => 'success'
#
# @service.merge_request_status(10, '2abe4ac', 'dev)
# # => 'running'
#
#
def
merge_request_status
(
iid
,
sha
,
ref
)
commit_status
(
sha
,
ref
)
end
# Return string with build status or :error symbol
#
# Allowed states: 'success', 'failed', 'running', 'pending', 'skipped'
#
#
# Ex.
# @service.commit_status('13be4ac', 'master')
# # => 'success'
# # => 'success'
#
#
# @service.commit_status('2abe4ac')
# @service.commit_status('2abe4ac'
, 'dev'
)
# # => 'running'
# # => 'running'
#
#
#
#
...
...
app/models/project_services/drone_ci_service.rb
0 → 100644
View file @
263abda3
class
DroneCiService
<
CiService
prop_accessor
:drone_url
,
:token
,
:enable_ssl_verification
validates
:drone_url
,
presence:
true
,
format:
{
with:
/\A
#{
URI
.
regexp
(
%w(http https)
)
}
\z/
,
message:
"should be a valid url"
},
if: :activated?
validates
:token
,
presence:
true
,
format:
{
with:
/\A([A-Za-z0-9]+)\z/
},
if: :activated?
after_save
:compose_service_hook
,
if: :activated?
def
compose_service_hook
hook
=
service_hook
||
build_service_hook
hook
.
url
=
[
drone_url
,
"/api/hook"
,
"?owner=
#{
project
.
namespace
.
path
}
"
,
"&name=
#{
project
.
path
}
"
,
"&access_token=
#{
token
}
"
].
join
hook
.
enable_ssl_verification
=
enable_ssl_verification
hook
.
save
end
def
execute
(
data
)
case
data
[
:object_kind
]
when
'push'
service_hook
.
execute
(
data
)
if
push_valid?
(
data
)
when
'merge_request'
service_hook
.
execute
(
data
)
if
merge_request_valid?
(
data
)
when
'tag_push'
service_hook
.
execute
(
data
)
if
tag_push_valid?
(
data
)
end
end
def
allow_target_ci?
true
end
def
supported_events
%w(push merge_request tag_push)
end
def
merge_request_status_path
(
iid
,
sha
=
nil
,
ref
=
nil
)
url
=
[
drone_url
,
"gitlab/
#{
project
.
namespace
.
path
}
/
#{
project
.
path
}
/pulls/
#{
iid
}
"
,
"?access_token=
#{
token
}
"
]
URI
.
join
(
*
url
).
to_s
end
def
commit_status_path
(
sha
,
ref
)
url
=
[
drone_url
,
"gitlab/
#{
project
.
namespace
.
path
}
/
#{
project
.
path
}
/commits/
#{
sha
}
"
,
"?branch=
#{
URI
::
encode
(
ref
.
to_s
)
}
&access_token=
#{
token
}
"
]
URI
.
join
(
*
url
).
to_s
end
def
merge_request_status
(
iid
,
sha
,
ref
)
response
=
HTTParty
.
get
(
merge_request_status_path
(
iid
),
verify:
enable_ssl_verification
)
if
response
.
code
==
200
and
response
[
'status'
]
case
response
[
'status'
]
when
'killed'
:canceled
when
'failure'
,
'error'
# Because drone return error if some test env failed
:failed
else
response
[
"status"
]
end
else
:error
end
rescue
Errno
::
ECONNREFUSED
:error
end
def
commit_status
(
sha
,
ref
)
response
=
HTTParty
.
get
(
commit_status_path
(
sha
,
ref
),
verify:
enable_ssl_verification
)
if
response
.
code
==
200
and
response
[
'status'
]
case
response
[
'status'
]
when
'killed'
:canceled
when
'failure'
,
'error'
# Because drone return error if some test env failed
:failed
else
response
[
"status"
]
end
else
:error
end
rescue
Errno
::
ECONNREFUSED
:error
end
def
merge_request_page
(
iid
,
sha
,
ref
)
url
=
[
drone_url
,
"gitlab/
#{
project
.
namespace
.
path
}
/
#{
project
.
path
}
/redirect/pulls/
#{
iid
}
"
]
URI
.
join
(
*
url
).
to_s
end
def
commit_page
(
sha
,
ref
)
url
=
[
drone_url
,
"gitlab/
#{
project
.
namespace
.
path
}
/
#{
project
.
path
}
/redirect/commits/
#{
sha
}
"
,
"?branch=
#{
URI
::
encode
(
ref
.
to_s
)
}
"
]
URI
.
join
(
*
url
).
to_s
end
def
commit_coverage
(
sha
,
ref
)
nil
end
def
build_page
(
sha
,
ref
)
commit_page
(
sha
,
ref
)
end
def
builds_path
url
=
[
drone_url
,
"
#{
project
.
namespace
.
path
}
/
#{
project
.
path
}
"
]
URI
.
join
(
*
url
).
to_s
end
def
status_img_path
url
=
[
drone_url
,
"api/badges/
#{
project
.
namespace
.
path
}
/
#{
project
.
path
}
/status.svg"
,
"?branch=
#{
URI
::
encode
(
project
.
default_branch
)
}
"
]
URI
.
join
(
*
url
).
to_s
end
def
title
'Drone CI'
end
def
description
'Drone is a Continuous Integration platform built on Docker, written in Go'
end
def
to_param
'drone_ci'
end
def
fields
[
{
type:
'text'
,
name:
'token'
,
placeholder:
'Drone CI project specific token'
},
{
type:
'text'
,
name:
'drone_url'
,
placeholder:
'http://drone.example.com'
},
{
type:
'checkbox'
,
name:
'enable_ssl_verification'
,
title:
"Enable SSL verification"
}
]
end
private
def
tag_push_valid?
(
data
)
data
[
:total_commits_count
]
>
0
&&
!
Gitlab
::
Git
.
blank_ref?
(
data
[
:after
])
end
def
push_valid?
(
data
)
opened_merge_requests
=
project
.
merge_requests
.
opened
.
where
(
source_project_id:
project
.
id
,
source_branch:
Gitlab
::
Git
.
ref_name
(
data
[
:ref
]))
opened_merge_requests
.
empty?
&&
data
[
:total_commits_count
]
>
0
&&
!
Gitlab
::
Git
.
blank_ref?
(
data
[
:after
])
end
def
merge_request_valid?
(
data
)
[
'opened'
,
'reopened'
].
include?
(
data
[
:object_attributes
][
:state
])
&&
data
[
:object_attributes
][
:merge_status
]
==
'unchecked'
end
end
app/models/service.rb
View file @
263abda3
...
@@ -135,6 +135,7 @@ class Service < ActiveRecord::Base
...
@@ -135,6 +135,7 @@ class Service < ActiveRecord::Base
buildkite
buildkite
campfire
campfire
custom_issue_tracker
custom_issue_tracker
drone_ci
emails_on_push
emails_on_push
external_wiki
external_wiki
flowdock
flowdock
...
...
doc/api/services.md
View file @
263abda3
This diff is collapsed.
Click to expand it.
doc/web_hooks/web_hooks.md
View file @
263abda3
...
@@ -279,6 +279,7 @@ X-Gitlab-Event: Note Hook
...
@@ -279,6 +279,7 @@ X-Gitlab-Event: Note Hook
"name"
:
"Gitlab Test"
,
"name"
:
"Gitlab Test"
,
"ssh_url"
:
"git@example.com:gitlab-org/gitlab-test.git"
,
"ssh_url"
:
"git@example.com:gitlab-org/gitlab-test.git"
,
"http_url"
:
"http://example.com/gitlab-org/gitlab-test.git"
,
"http_url"
:
"http://example.com/gitlab-org/gitlab-test.git"
,
"web_url"
:
"http://example.com/gitlab-org/gitlab-test"
,
"namespace"
:
"Gitlab Org"
,
"namespace"
:
"Gitlab Org"
,
"visibility_level"
:
10
"visibility_level"
:
10
},
},
...
@@ -286,6 +287,7 @@ X-Gitlab-Event: Note Hook
...
@@ -286,6 +287,7 @@ X-Gitlab-Event: Note Hook
"name"
:
"Gitlab Test"
,
"name"
:
"Gitlab Test"
,
"ssh_url"
:
"git@example.com:gitlab-org/gitlab-test.git"
,
"ssh_url"
:
"git@example.com:gitlab-org/gitlab-test.git"
,
"http_url"
:
"http://example.com/gitlab-org/gitlab-test.git"
,
"http_url"
:
"http://example.com/gitlab-org/gitlab-test.git"
,
"web_url"
:
"http://example.com/gitlab-org/gitlab-test"
,
"namespace"
:
"Gitlab Org"
,
"namespace"
:
"Gitlab Org"
,
"visibility_level"
:
10
"visibility_level"
:
10
},
},
...
@@ -462,6 +464,7 @@ X-Gitlab-Event: Merge Request Hook
...
@@ -462,6 +464,7 @@ X-Gitlab-Event: Merge Request Hook
"name"
:
"awesome_project"
,
"name"
:
"awesome_project"
,
"ssh_url"
:
"ssh://git@example.com/awesome_space/awesome_project.git"
,
"ssh_url"
:
"ssh://git@example.com/awesome_space/awesome_project.git"
,
"http_url"
:
"http://example.com/awesome_space/awesome_project.git"
,
"http_url"
:
"http://example.com/awesome_space/awesome_project.git"
,
"web_url"
:
"http://example.com/awesome_space/awesome_project"
,
"visibility_level"
:
20
,
"visibility_level"
:
20
,
"namespace"
:
"awesome_space"
"namespace"
:
"awesome_space"
},
},
...
@@ -469,6 +472,7 @@ X-Gitlab-Event: Merge Request Hook
...
@@ -469,6 +472,7 @@ X-Gitlab-Event: Merge Request Hook
"name"
:
"awesome_project"
,
"name"
:
"awesome_project"
,
"ssh_url"
:
"ssh://git@example.com/awesome_space/awesome_project.git"
,
"ssh_url"
:
"ssh://git@example.com/awesome_space/awesome_project.git"
,
"http_url"
:
"http://example.com/awesome_space/awesome_project.git"
,
"http_url"
:
"http://example.com/awesome_space/awesome_project.git"
,
"web_url"
:
"http://example.com/awesome_space/awesome_project"
,
"visibility_level"
:
20
,
"visibility_level"
:
20
,
"namespace"
:
"awesome_space"
"namespace"
:
"awesome_space"
},
},
...
...
lib/api/helpers.rb
View file @
263abda3
...
@@ -55,6 +55,32 @@ module API
...
@@ -55,6 +55,32 @@ module API
end
end
end
end
def
project_service
@project_service
||=
begin
underscored_service
=
params
[
:service_slug
].
underscore
if
Service
.
available_services_names
.
include?
(
underscored_service
)
user_project
.
build_missing_services
service_method
=
"
#{
underscored_service
}
_service"
send_service
(
service_method
)
end
end
@project_service
||
not_found!
(
"Service"
)
end
def
send_service
(
service_method
)
user_project
.
send
(
service_method
)
end
def
service_attributes
@service_attributes
||=
project_service
.
fields
.
inject
([])
do
|
arr
,
hash
|
arr
<<
hash
[
:name
].
to_sym
end
end
def
find_group
(
id
)
def
find_group
(
id
)
begin
begin
group
=
Group
.
find
(
id
)
group
=
Group
.
find
(
id
)
...
...
lib/api/services.rb
View file @
263abda3
...
@@ -4,74 +4,50 @@ module API
...
@@ -4,74 +4,50 @@ module API
before
{
authenticate!
}
before
{
authenticate!
}
before
{
authorize_admin_project
}
before
{
authorize_admin_project
}
resource
:projects
do
resource
:projects
do
# Set GitLab CI service for project
# Set <service_slug> service for project
#
# Parameters:
# token (required) - CI project token
# project_url (required) - CI project url
#
#
# Example Request:
# Example Request:
#
# PUT /projects/:id/services/gitlab-ci
# PUT /projects/:id/services/gitlab-ci
put
":id/services/gitlab-ci"
do
#
required_attributes!
[
:token
,
:project_url
]
put
':id/services/:service_slug'
do
attrs
=
attributes_for_keys
[
:token
,
:project_url
]
if
project_service
user_project
.
build_missing_services
validators
=
project_service
.
class
.
validators
.
select
do
|
s
|
s
.
class
==
ActiveRecord
::
Validations
::
PresenceValidator
&&
s
.
attributes
!=
[
:project_id
]
end
required_attributes!
validators
.
map
(
&
:attributes
).
flatten
.
uniq
attrs
=
attributes_for_keys
service_attributes
if
user_project
.
gitlab_ci
_service
.
update_attributes
(
attrs
.
merge
(
active:
true
))
if
project
_service
.
update_attributes
(
attrs
.
merge
(
active:
true
))
true
true
else
else
not_found!
not_found!
end
end
end
end
end
# Delete
GitLab CI service settings
# Delete
<service_slug> service for project
#
#
# Example Request:
# Example Request:
# DELETE /projects/:id/services/gitlab-ci
delete
":id/services/gitlab-ci"
do
if
user_project
.
gitlab_ci_service
user_project
.
gitlab_ci_service
.
update_attributes
(
active:
false
,
token:
nil
,
project_url:
nil
)
end
end
# Set Hipchat service for project
#
#
# Parameters:
# DELETE /project/:id/services/gitlab-ci
# token (required) - Hipchat token
# room (required) - Hipchat room name
#
#
# Example Request:
delete
':id/services/:service_slug'
do
# PUT /projects/:id/services/hipchat
if
project_service
put
':id/services/hipchat'
do
attrs
=
service_attributes
.
inject
({})
do
|
hash
,
key
|
required_attributes!
[
:token
,
:room
]
hash
.
merge!
(
key
=>
nil
)
attrs
=
attributes_for_keys
[
:token
,
:room
]
end
user_project
.
build_missing_services
if
user_project
.
hipchat_service
.
update_attributes
(
if
project_service
.
update_attributes
(
attrs
.
merge
(
active:
false
))
attrs
.
merge
(
active:
true
))
true
true
else
else
not_found!
not_found!
end
end
end
end
# Delete Hipchat service settings
#
# Example Request:
# DELETE /projects/:id/services/hipchat
delete
':id/services/hipchat'
do
if
user_project
.
hipchat_service
user_project
.
hipchat_service
.
update_attributes
(
active:
false
,
token:
nil
,
room:
nil
)
end
end
end
end
end
end
end
...
...
lib/gitlab/backend/grack_auth.rb
View file @
263abda3
...
@@ -10,7 +10,7 @@ module Grack
...
@@ -10,7 +10,7 @@ module Grack
@request
=
Rack
::
Request
.
new
(
env
)
@request
=
Rack
::
Request
.
new
(
env
)
@auth
=
Request
.
new
(
env
)
@auth
=
Request
.
new
(
env
)
@
gitlab_
ci
=
false
@ci
=
false
# Need this patch due to the rails mount
# Need this patch due to the rails mount
# Need this if under RELATIVE_URL_ROOT
# Need this if under RELATIVE_URL_ROOT
...
@@ -28,7 +28,7 @@ module Grack
...
@@ -28,7 +28,7 @@ module Grack
if
project
&&
authorized_request?
if
project
&&
authorized_request?
# Tell gitlab-git-http-server the request is OK, and what the GL_ID is
# Tell gitlab-git-http-server the request is OK, and what the GL_ID is
render_grack_auth_ok
render_grack_auth_ok
elsif
@user
.
nil?
&&
!
@
gitlab_
ci
elsif
@user
.
nil?
&&
!
@ci
unauthorized
unauthorized
else
else
render_not_found
render_not_found
...
@@ -47,8 +47,8 @@ module Grack
...
@@ -47,8 +47,8 @@ module Grack
# Allow authentication for GitLab CI service
# Allow authentication for GitLab CI service
# if valid token passed
# if valid token passed
if
gitlab_
ci_request?
(
login
,
password
)
if
ci_request?
(
login
,
password
)
@
gitlab_
ci
=
true
@ci
=
true
return
return
end
end
...
@@ -60,12 +60,17 @@ module Grack
...
@@ -60,12 +60,17 @@ module Grack
end
end
end
end
def
gitlab_ci_request?
(
login
,
password
)
def
ci_request?
(
login
,
password
)
if
login
==
"gitlab-ci-token"
&&
project
&&
project
.
gitlab_ci?
matched_login
=
/(?<s>^[a-zA-Z]*-ci)-token$/
.
match
(
login
)
token
=
project
.
gitlab_ci_service
.
token
if
token
.
present?
&&
token
==
password
&&
git_cmd
==
'git-upload-pack'
if
project
&&
matched_login
.
present?
&&
git_cmd
==
'git-upload-pack'
return
true
underscored_service
=
matched_login
[
's'
].
underscore
if
Service
.
available_services_names
.
include?
(
underscored_service
)
service_method
=
"
#{
underscored_service
}
_service"
service
=
project
.
send
(
service_method
)
return
service
&&
service
.
activated?
&&
service
.
valid_token?
(
password
)
end
end
end
end
...
@@ -124,7 +129,7 @@ module Grack
...
@@ -124,7 +129,7 @@ module Grack
end
end
def
authorized_request?
def
authorized_request?
return
true
if
@
gitlab_
ci
return
true
if
@ci
case
git_cmd
case
git_cmd
when
*
Gitlab
::
GitAccess
::
DOWNLOAD_COMMANDS
when
*
Gitlab
::
GitAccess
::
DOWNLOAD_COMMANDS
...
...
lib/tasks/services.rake
0 → 100644
View file @
263abda3
services_template
=
<<-
ERB
# Services
<% services.each do |service| %>
## <%= service[:title] %>
<% unless service[:description].blank? %>
<%= service[:description] %>
<% end %>
### Create/Edit <%= service[:title] %> service
Set <%= service[:title] %> service for a project.
<% unless service[:help].blank? %>
> <%= service[:help].gsub("
\n
", ' ') %>
<% end %>
```
PUT /projects/:id/services/<%= service[:dashed_name] %>
```
Parameters:
<% service[:params].each do |param| %>
- `<%= param[:name] %>` <%= param[:required] ? "(**required**)" : "(optional)" %><%= [" -", param[:description]].join(" ").gsub("
\n
", '') unless param[:description].blank? %>
<% end %>
### Delete <%= service[:title] %> service
Delete <%= service[:title] %> service for a project.
```
DELETE /projects/:id/services/<%= service[:dashed_name] %>
```
<% end %>
ERB
namespace
:services
do
task
:doc
do
services
=
Service
.
available_services_names
.
map
do
|
s
|
service_start
=
Time
.
now
klass
=
"
#{
s
}
_service"
.
classify
.
constantize
service
=
klass
.
new
service_hash
=
{}
service_hash
[
:title
]
=
service
.
title
service_hash
[
:dashed_name
]
=
s
.
dasherize
service_hash
[
:description
]
=
service
.
description
service_hash
[
:help
]
=
service
.
help
service_hash
[
:params
]
=
service
.
fields
.
map
do
|
p
|
param_hash
=
{}
param_hash
[
:name
]
=
p
[
:name
]
param_hash
[
:description
]
=
p
[
:placeholder
]
||
p
[
:title
]
param_hash
[
:required
]
=
klass
.
validators_on
(
p
[
:name
].
to_sym
).
any?
do
|
v
|
v
.
class
==
ActiveRecord
::
Validations
::
PresenceValidator
end
param_hash
end
.
sort_by
{
|
p
|
p
[
:required
]
?
0
:
1
}
puts
"Collected data for:
#{
service
.
title
}
,
#{
Time
.
now
-
service_start
}
"
service_hash
end
doc_start
=
Time
.
now
doc_path
=
File
.
join
(
Rails
.
root
,
'doc'
,
'api'
,
'services.md'
)
result
=
ERB
.
new
(
services_template
,
0
,
'>'
)
.
result
(
OpenStruct
.
new
(
services:
services
).
instance_eval
{
binding
})
File
.
open
(
doc_path
,
'w'
)
do
|
f
|
f
.
write
result
end
puts
"write a new service.md to:
#{
doc_path
.
to_s
}
,
#{
Time
.
now
-
doc_start
}
"
end
end
spec/models/project_services/drone_ci_service_spec.rb
0 → 100644
View file @
263abda3
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
# push_events :boolean default(TRUE)
# issues_events :boolean default(TRUE)
# merge_requests_events :boolean default(TRUE)
# tag_push_events :boolean default(TRUE)
# note_events :boolean default(TRUE), not null
#
require
'spec_helper'
describe
DroneCiService
do
describe
'associations'
do
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
have_one
(
:service_hook
)
}
end
describe
'validations'
do
context
'active'
do
before
{
allow
(
subject
).
to
receive
(
:activated?
).
and_return
(
true
)
}
it
{
is_expected
.
to
validate_presence_of
(
:token
)
}
it
{
is_expected
.
to
validate_presence_of
(
:drone_url
)
}
it
{
is_expected
.
to
allow_value
(
'ewf9843kdnfdfs89234n'
).
for
(
:token
)
}
it
{
is_expected
.
to
allow_value
(
'http://ci.example.com'
).
for
(
:drone_url
)
}
it
{
is_expected
.
not_to
allow_value
(
'token with spaces'
).
for
(
:token
)
}
it
{
is_expected
.
not_to
allow_value
(
'token/with%spaces'
).
for
(
:token
)
}
it
{
is_expected
.
not_to
allow_value
(
'this is not url'
).
for
(
:drone_url
)
}
it
{
is_expected
.
not_to
allow_value
(
'http//noturl'
).
for
(
:drone_url
)
}
it
{
is_expected
.
not_to
allow_value
(
'ftp://ci.example.com'
).
for
(
:drone_url
)
}
end
context
'inactive'
do
before
{
allow
(
subject
).
to
receive
(
:activated?
).
and_return
(
false
)
}
it
{
is_expected
.
not_to
validate_presence_of
(
:token
)
}
it
{
is_expected
.
not_to
validate_presence_of
(
:drone_url
)
}
it
{
is_expected
.
to
allow_value
(
'ewf9843kdnfdfs89234n'
).
for
(
:token
)
}
it
{
is_expected
.
to
allow_value
(
'http://drone.example.com'
).
for
(
:drone_url
)
}
it
{
is_expected
.
to
allow_value
(
'token with spaces'
).
for
(
:token
)
}
it
{
is_expected
.
to
allow_value
(
'ftp://drone.example.com'
).
for
(
:drone_url
)
}
end
end
shared_context
:drone_ci_service
do
let
(
:drone
)
{
DroneCiService
.
new
}
let
(
:project
)
{
create
(
:project
,
name:
'project'
)
}
let
(
:path
)
{
"
#{
project
.
namespace
.
path
}
/
#{
project
.
path
}
"
}
let
(
:drone_url
)
{
'http://drone.example.com'
}
let
(
:sha
)
{
'2ab7834c'
}
let
(
:branch
)
{
'dev'
}
let
(
:token
)
{
'secret'
}
let
(
:iid
)
{
rand
(
1
..
9999
)
}
before
(
:each
)
do
allow
(
drone
).
to
receive_messages
(
project_id:
project
.
id
,
project:
project
,
active:
true
,
drone_url:
drone_url
,
token:
token
)
end
end
describe
"service page/path methods"
do
include_context
:drone_ci_service
# URL's
let
(
:commit_page
)
{
"
#{
drone_url
}
/gitlab/
#{
path
}
/redirect/commits/
#{
sha
}
?branch=
#{
branch
}
"
}
let
(
:merge_request_page
)
{
"
#{
drone_url
}
/gitlab/
#{
path
}
/redirect/pulls/
#{
iid
}
"
}
let
(
:commit_status_path
)
{
"
#{
drone_url
}
/gitlab/
#{
path
}
/commits/
#{
sha
}
?branch=
#{
branch
}
&access_token=
#{
token
}
"
}
let
(
:merge_request_status_path
)
{
"
#{
drone_url
}
/gitlab/
#{
path
}
/pulls/
#{
iid
}
?access_token=
#{
token
}
"
}
it
{
expect
(
drone
.
build_page
(
sha
,
branch
)).
to
eq
(
commit_page
)
}
it
{
expect
(
drone
.
commit_page
(
sha
,
branch
)).
to
eq
(
commit_page
)
}
it
{
expect
(
drone
.
merge_request_page
(
iid
,
sha
,
branch
)).
to
eq
(
merge_request_page
)
}
it
{
expect
(
drone
.
commit_status_path
(
sha
,
branch
)).
to
eq
(
commit_status_path
)
}
it
{
expect
(
drone
.
merge_request_status_path
(
iid
,
sha
,
branch
)).
to
eq
(
merge_request_status_path
)
}
end
describe
"execute"
do
include_context
:drone_ci_service
let
(
:user
)
{
create
(
:user
,
username:
'username'
)
}
let
(
:push_sample_data
)
{
Gitlab
::
PushDataBuilder
.
build_sample
(
project
,
user
)
}
it
do
service_hook
=
double
expect
(
service_hook
).
to
receive
(
:execute
)
expect
(
drone
).
to
receive
(
:service_hook
).
and_return
(
service_hook
)
drone
.
execute
(
push_sample_data
)
end
end
end
spec/requests/api/services_spec.rb
View file @
263abda3
...
@@ -5,64 +5,47 @@ describe API::API, api: true do
...
@@ -5,64 +5,47 @@ describe API::API, api: true do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
creator_id:
user
.
id
,
namespace:
user
.
namespace
)
}
let
(
:project
)
{
create
(
:project
,
creator_id:
user
.
id
,
namespace:
user
.
namespace
)
}
describe
"POST /projects/:id/services/gitlab-ci"
do
Service
.
available_services_names
.
each
do
|
service
|
it
"should update gitlab-ci settings"
do
describe
"PUT /projects/:id/services/
#{
service
.
dasherize
}
"
do
put
api
(
"/projects/
#{
project
.
id
}
/services/gitlab-ci"
,
user
),
token:
'secrettoken'
,
project_url:
"http://ci.example.com/projects/1"
include_context
service
it
"should update
#{
service
}
settings"
do
put
api
(
"/projects/
#{
project
.
id
}
/services/
#{
dashed_service
}
"
,
user
),
service_attrs
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
response
.
status
).
to
eq
(
200
)
end
end
it
"should return if required fields missing"
do
it
"should return if required fields missing"
do
put
api
(
"/projects/
#{
project
.
id
}
/services/gitlab-ci"
,
user
),
project_url:
"http://ci.example.com/projects/1"
,
active:
true
attrs
=
service_attrs
expect
(
response
.
status
).
to
eq
(
400
)
required_attributes
=
service_attrs_list
.
select
do
|
attr
|
service_klass
.
validators_on
(
attr
).
any?
do
|
v
|
v
.
class
==
ActiveRecord
::
Validations
::
PresenceValidator
end
end
it
"should return if the format of token is invalid"
do
put
api
(
"/projects/
#{
project
.
id
}
/services/gitlab-ci"
,
user
),
token:
'token-with dashes and spaces%'
,
project_url:
"http://ci.example.com/projects/1"
,
active:
true
expect
(
response
.
status
).
to
eq
(
404
)
end
end
it
"should return if the format of token is invalid"
do
if
required_attributes
.
empty?
put
api
(
"/projects/
#{
project
.
id
}
/services/gitlab-ci"
,
user
),
token:
'token-with dashes and spaces%'
,
project_url:
"ftp://ci.example/projects/1"
,
active:
true
expected_code
=
200
else
expect
(
response
.
status
).
to
eq
(
404
)
attrs
.
delete
(
required_attributes
.
shuffle
.
first
)
end
expected_code
=
400
end
end
describe
"DELETE /projects/:id/services/gitlab-ci"
do
put
api
(
"/projects/
#{
project
.
id
}
/services/
#{
dashed_service
}
"
,
user
),
attrs
it
"should update gitlab-ci settings"
do
delete
api
(
"/projects/
#{
project
.
id
}
/services/gitlab-ci"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
response
.
status
).
to
eq
(
expected_code
)
expect
(
project
.
gitlab_ci_service
).
to
be_nil
end
end
end
describe
'PUT /projects/:id/services/hipchat'
do
it
'should update hipchat settings'
do
put
api
(
"/projects/
#{
project
.
id
}
/services/hipchat"
,
user
),
token:
'secret-token'
,
room:
'test'
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
project
.
hipchat_service
).
not_to
be_nil
end
end
it
'should return if required fields missing'
do
describe
"DELETE /projects/:id/services/
#{
service
.
dasherize
}
"
do
put
api
(
"/projects/
#{
project
.
id
}
/services/gitlab-ci"
,
user
),
include_context
service
token:
'secret-token'
,
active:
true
expect
(
response
.
status
).
to
eq
(
400
)
it
"should delete
#{
service
}
"
do
end
delete
api
(
"/projects/
#{
project
.
id
}
/services/
#{
dashed_service
}
"
,
user
)
end
describe
'DELETE /projects/:id/services/hipchat'
do
it
'should delete hipchat settings'
do
delete
api
(
"/projects/
#{
project
.
id
}
/services/hipchat"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
project
.
hipchat_service
).
to
be_nil
expect
(
project
.
send
(
service_method
).
activated?
).
to
be_falsey
end
end
end
end
end
end
end
spec/support/services_shared_context.rb
0 → 100644
View file @
263abda3
Service
.
available_services_names
.
each
do
|
service
|
shared_context
service
do
let
(
:dashed_service
)
{
service
.
dasherize
}
let
(
:service_method
)
{
"
#{
service
}
_service"
.
to_sym
}
let
(
:service_klass
)
{
"
#{
service
}
_service"
.
classify
.
constantize
}
let
(
:service_attrs_list
)
{
service_klass
.
new
.
fields
.
inject
([])
{
|
arr
,
hash
|
arr
<<
hash
[
:name
].
to_sym
}
}
let
(
:service_attrs
)
do
service_attrs_list
.
inject
({})
do
|
hash
,
k
|
if
k
=~
/^(token*|.*_token|.*_key)/
hash
.
merge!
(
k
=>
'secrettoken'
)
elsif
k
=~
/^(.*_url|url|webhook)/
hash
.
merge!
(
k
=>
"http://example.com"
)
elsif
service
==
'irker'
&&
k
==
:recipients
hash
.
merge!
(
k
=>
'irc://irc.network.net:666/#channel'
)
else
hash
.
merge!
(
k
=>
"someword"
)
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