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
7bab81b1
Commit
7bab81b1
authored
Feb 25, 2013
by
Dmitriy Zaporozhets
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move git post push logic to service
parent
9611640e
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
235 additions
and
240 deletions
+235
-240
app/models/project.rb
app/models/project.rb
+9
-108
app/services/git_push_service.rb
app/services/git_push_service.rb
+114
-0
app/workers/post_receive.rb
app/workers/post_receive.rb
+1
-1
spec/models/project_hooks_spec.rb
spec/models/project_hooks_spec.rb
+0
-128
spec/models/project_spec.rb
spec/models/project_spec.rb
+0
-3
spec/services/git_push_service.rb
spec/services/git_push_service.rb
+111
-0
No files found.
app/models/project.rb
View file @
7bab81b1
...
...
@@ -295,53 +295,6 @@ class Project < ActiveRecord::Base
end
end
# This method will be called after each post receive and only if the provided
# user is present in GitLab.
#
# All callbacks for post receive should be placed here.
def
trigger_post_receive
(
oldrev
,
newrev
,
ref
,
user
)
data
=
post_receive_data
(
oldrev
,
newrev
,
ref
,
user
)
# Create satellite
self
.
satellite
.
create
unless
self
.
satellite
.
exists?
# Create push event
self
.
observe_push
(
data
)
if
push_to_branch?
ref
,
oldrev
# Close merged MR
self
.
update_merge_requests
(
oldrev
,
newrev
,
ref
,
user
)
# Execute web hooks
self
.
execute_hooks
(
data
.
dup
)
# Execute project services
self
.
execute_services
(
data
.
dup
)
end
# Discover the default branch, but only if it hasn't already been set to
# something else
if
repository
&&
default_branch
.
nil?
update_attributes
(
default_branch:
self
.
repository
.
discover_default_branch
)
end
end
def
push_to_branch?
ref
,
oldrev
ref_parts
=
ref
.
split
(
'/'
)
# Return if this is not a push to a branch (e.g. new commits)
!
(
ref_parts
[
1
]
!~
/heads/
||
oldrev
==
"00000000000000000000000000000000"
)
end
def
observe_push
(
data
)
Event
.
create
(
project:
self
,
action:
Event
::
PUSHED
,
data:
data
,
author_id:
data
[
:user_id
]
)
end
def
execute_hooks
(
data
)
hooks
.
each
{
|
hook
|
hook
.
async_execute
(
data
)
}
end
...
...
@@ -354,68 +307,12 @@ class Project < ActiveRecord::Base
end
end
# Produce a hash of post-receive data
#
# data = {
# before: String,
# after: String,
# ref: String,
# user_id: String,
# user_name: String,
# repository: {
# name: String,
# url: String,
# description: String,
# homepage: String,
# },
# commits: Array,
# total_commits_count: Fixnum
# }
#
def
post_receive_data
(
oldrev
,
newrev
,
ref
,
user
)
push_commits
=
repository
.
commits_between
(
oldrev
,
newrev
)
# Total commits count
push_commits_count
=
push_commits
.
size
# Get latest 20 commits ASC
push_commits_limited
=
push_commits
.
last
(
20
)
# Hash to be passed as post_receive_data
data
=
{
before:
oldrev
,
after:
newrev
,
ref:
ref
,
user_id:
user
.
id
,
user_name:
user
.
name
,
repository:
{
name:
name
,
url:
url_to_repo
,
description:
description
,
homepage:
web_url
,
},
commits:
[],
total_commits_count:
push_commits_count
}
# For perfomance purposes maximum 20 latest commits
# will be passed as post receive hook data.
#
push_commits_limited
.
each
do
|
commit
|
data
[
:commits
]
<<
{
id:
commit
.
id
,
message:
commit
.
safe_message
,
timestamp:
commit
.
date
.
xmlschema
,
url:
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
path_with_namespace
}
/commit/
#{
commit
.
id
}
"
,
author:
{
name:
commit
.
author_name
,
email:
commit
.
author_email
}
}
end
data
def
discover_default_branch
# Discover the default branch, but only if it hasn't already been set to
# something else
if
repository
&&
default_branch
.
nil?
update_attributes
(
default_branch:
self
.
repository
.
discover_default_branch
)
end
end
def
update_merge_requests
(
oldrev
,
newrev
,
ref
,
user
)
...
...
@@ -446,6 +343,10 @@ class Project < ActiveRecord::Base
!
repository
||
repository
.
empty?
end
def
ensure_satellite_exists
self
.
satellite
.
create
unless
self
.
satellite
.
exists?
end
def
satellite
@satellite
||=
Gitlab
::
Satellite
::
Satellite
.
new
(
self
)
end
...
...
app/services/git_push_service.rb
0 → 100644
View file @
7bab81b1
class
GitPushService
attr_accessor
:project
,
:user
,
:push_data
# This method will be called after each git update
# and only if the provided user and project is present in GitLab.
#
# All callbacks for post receive action should be placed here.
#
# Now this method do next:
# 1. Ensure project satellite exists
# 2. Update merge requests
# 3. Execute project web hooks
# 4. Execute project services
# 5. Create Push Event
#
def
execute
(
project
,
user
,
oldrev
,
newrev
,
ref
)
@project
,
@user
=
project
,
user
# Collect data for this git push
@push_data
=
post_receive_data
(
oldrev
,
newrev
,
ref
)
project
.
ensure_satellite_exists
project
.
discover_default_branch
if
push_to_branch?
(
ref
,
oldrev
)
project
.
update_merge_requests
(
oldrev
,
newrev
,
ref
,
@user
)
project
.
execute_hooks
(
@push_data
.
dup
)
project
.
execute_services
(
@push_data
.
dup
)
end
create_push_event
end
protected
def
create_push_event
Event
.
create
(
project:
project
,
action:
Event
::
PUSHED
,
data:
push_data
,
author_id:
push_data
[
:user_id
]
)
end
# Produce a hash of post-receive data
#
# data = {
# before: String,
# after: String,
# ref: String,
# user_id: String,
# user_name: String,
# repository: {
# name: String,
# url: String,
# description: String,
# homepage: String,
# },
# commits: Array,
# total_commits_count: Fixnum
# }
#
def
post_receive_data
(
oldrev
,
newrev
,
ref
)
push_commits
=
project
.
repository
.
commits_between
(
oldrev
,
newrev
)
# Total commits count
push_commits_count
=
push_commits
.
size
# Get latest 20 commits ASC
push_commits_limited
=
push_commits
.
last
(
20
)
# Hash to be passed as post_receive_data
data
=
{
before:
oldrev
,
after:
newrev
,
ref:
ref
,
user_id:
user
.
id
,
user_name:
user
.
name
,
repository:
{
name:
project
.
name
,
url:
project
.
url_to_repo
,
description:
project
.
description
,
homepage:
project
.
web_url
,
},
commits:
[],
total_commits_count:
push_commits_count
}
# For perfomance purposes maximum 20 latest commits
# will be passed as post receive hook data.
#
push_commits_limited
.
each
do
|
commit
|
data
[
:commits
]
<<
{
id:
commit
.
id
,
message:
commit
.
safe_message
,
timestamp:
commit
.
date
.
xmlschema
,
url:
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
project
.
path_with_namespace
}
/commit/
#{
commit
.
id
}
"
,
author:
{
name:
commit
.
author_name
,
email:
commit
.
author_email
}
}
end
data
end
def
push_to_branch?
ref
,
oldrev
ref_parts
=
ref
.
split
(
'/'
)
# Return if this is not a push to a branch (e.g. new commits)
!
(
ref_parts
[
1
]
!~
/heads/
||
oldrev
==
"00000000000000000000000000000000"
)
end
end
app/workers/post_receive.rb
View file @
7bab81b1
...
...
@@ -42,6 +42,6 @@ class PostReceive
return
false
end
project
.
trigger_post_receive
(
oldrev
,
newrev
,
ref
,
user
)
GitPushService
.
new
.
execute
(
project
,
user
,
oldrev
,
newrev
,
ref
)
end
end
spec/models/project_hooks_spec.rb
deleted
100644 → 0
View file @
9611640e
require
'spec_helper'
describe
Project
,
"Hooks"
do
let
(
:project
)
{
create
(
:project
)
}
before
do
@key
=
create
(
:key
,
user:
project
.
owner
)
@user
=
@key
.
user
@key_id
=
@key
.
identifier
end
describe
"Post Receive Event"
do
it
"should create push event"
do
oldrev
,
newrev
,
ref
=
'00000000000000000000000000000000'
,
'newrev'
,
'refs/heads/master'
data
=
project
.
post_receive_data
(
oldrev
,
newrev
,
ref
,
@user
)
project
.
observe_push
(
data
)
event
=
Event
.
last
event
.
should_not
be_nil
event
.
project
.
should
==
project
event
.
action
.
should
==
Event
::
PUSHED
event
.
data
.
should
==
data
end
end
describe
"Project hooks"
do
context
"with no web hooks"
do
it
"raises no errors"
do
lambda
{
project
.
execute_hooks
({})
}.
should_not
raise_error
end
end
context
"with web hooks"
do
before
do
@project_hook
=
create
(
:project_hook
)
@project_hook_2
=
create
(
:project_hook
)
project
.
hooks
<<
[
@project_hook
,
@project_hook_2
]
stub_request
(
:post
,
@project_hook
.
url
)
stub_request
(
:post
,
@project_hook_2
.
url
)
end
it
"executes multiple web hook"
do
@project_hook
.
should_receive
(
:async_execute
).
once
@project_hook_2
.
should_receive
(
:async_execute
).
once
project
.
trigger_post_receive
(
'oldrev'
,
'newrev'
,
'refs/heads/master'
,
@user
)
end
end
context
"does not execute web hooks"
do
before
do
@project_hook
=
create
(
:project_hook
)
project
.
hooks
<<
[
@project_hook
]
end
it
"when pushing a branch for the first time"
do
@project_hook
.
should_not_receive
(
:execute
)
project
.
trigger_post_receive
(
'00000000000000000000000000000000'
,
'newrev'
,
'refs/heads/master'
,
@user
)
end
it
"when pushing tags"
do
@project_hook
.
should_not_receive
(
:execute
)
project
.
trigger_post_receive
(
'oldrev'
,
'newrev'
,
'refs/tags/v1.0.0'
,
@user
)
end
end
context
"when pushing new branches"
do
end
context
"when gathering commit data"
do
before
do
@oldrev
,
@newrev
,
@ref
=
project
.
repository
.
fresh_commits
(
2
).
last
.
sha
,
project
.
repository
.
fresh_commits
(
2
).
first
.
sha
,
'refs/heads/master'
@commit
=
project
.
repository
.
fresh_commits
(
2
).
first
# Fill nil/empty attributes
project
.
description
=
"This is a description"
@data
=
project
.
post_receive_data
(
@oldrev
,
@newrev
,
@ref
,
@user
)
end
subject
{
@data
}
it
{
should
include
(
before:
@oldrev
)
}
it
{
should
include
(
after:
@newrev
)
}
it
{
should
include
(
ref:
@ref
)
}
it
{
should
include
(
user_id:
project
.
owner
.
id
)
}
it
{
should
include
(
user_name:
project
.
owner
.
name
)
}
context
"with repository data"
do
subject
{
@data
[
:repository
]
}
it
{
should
include
(
name:
project
.
name
)
}
it
{
should
include
(
url:
project
.
url_to_repo
)
}
it
{
should
include
(
description:
project
.
description
)
}
it
{
should
include
(
homepage:
project
.
web_url
)
}
end
context
"with commits"
do
subject
{
@data
[
:commits
]
}
it
{
should
be_an
(
Array
)
}
it
{
should
have
(
1
).
element
}
context
"the commit"
do
subject
{
@data
[
:commits
].
first
}
it
{
should
include
(
id:
@commit
.
id
)
}
it
{
should
include
(
message:
@commit
.
safe_message
)
}
it
{
should
include
(
timestamp:
@commit
.
date
.
xmlschema
)
}
it
{
should
include
(
url:
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
project
.
code
}
/commit/
#{
@commit
.
id
}
"
)
}
context
"with a author"
do
subject
{
@data
[
:commits
].
first
[
:author
]
}
it
{
should
include
(
name:
@commit
.
author_name
)
}
it
{
should
include
(
email:
@commit
.
author_email
)
}
end
end
end
end
end
end
spec/models/project_spec.rb
View file @
7bab81b1
...
...
@@ -72,11 +72,8 @@ describe Project do
it
{
should
respond_to
(
:url_to_repo
)
}
it
{
should
respond_to
(
:repo_exists?
)
}
it
{
should
respond_to
(
:satellite
)
}
it
{
should
respond_to
(
:observe_push
)
}
it
{
should
respond_to
(
:update_merge_requests
)
}
it
{
should
respond_to
(
:execute_hooks
)
}
it
{
should
respond_to
(
:post_receive_data
)
}
it
{
should
respond_to
(
:trigger_post_receive
)
}
it
{
should
respond_to
(
:transfer
)
}
it
{
should
respond_to
(
:name_with_namespace
)
}
it
{
should
respond_to
(
:namespace_owner
)
}
...
...
spec/services/git_push_service.rb
0 → 100644
View file @
7bab81b1
require
'spec_helper'
describe
GitPushService
do
let
(
:user
)
{
create
:user
}
let
(
:project
)
{
create
:project
}
let
(
:service
)
{
GitPushService
.
new
}
before
do
@oldrev
=
'b98a310def241a6fd9c9a9a3e7934c48e498fe81'
@newrev
=
'b19a04f53caeebf4fe5ec2327cb83e9253dc91bb'
@ref
=
'refs/heads/master'
end
describe
"Git Push Data"
do
before
do
service
.
execute
(
project
,
user
,
@oldrev
,
@newrev
,
@ref
)
@push_data
=
service
.
push_data
@commit
=
project
.
repository
.
commit
(
@newrev
)
end
subject
{
@push_data
}
it
{
should
include
(
before:
@oldrev
)
}
it
{
should
include
(
after:
@newrev
)
}
it
{
should
include
(
ref:
@ref
)
}
it
{
should
include
(
user_id:
user
.
id
)
}
it
{
should
include
(
user_name:
user
.
name
)
}
context
"with repository data"
do
subject
{
@push_data
[
:repository
]
}
it
{
should
include
(
name:
project
.
name
)
}
it
{
should
include
(
url:
project
.
url_to_repo
)
}
it
{
should
include
(
description:
project
.
description
)
}
it
{
should
include
(
homepage:
project
.
web_url
)
}
end
context
"with commits"
do
subject
{
@push_data
[
:commits
]
}
it
{
should
be_an
(
Array
)
}
it
{
should
have
(
1
).
element
}
context
"the commit"
do
subject
{
@push_data
[
:commits
].
first
}
it
{
should
include
(
id:
@commit
.
id
)
}
it
{
should
include
(
message:
@commit
.
safe_message
)
}
it
{
should
include
(
timestamp:
@commit
.
date
.
xmlschema
)
}
it
{
should
include
(
url:
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
project
.
code
}
/commit/
#{
@commit
.
id
}
"
)
}
context
"with a author"
do
subject
{
@push_data
[
:commits
].
first
[
:author
]
}
it
{
should
include
(
name:
@commit
.
author_name
)
}
it
{
should
include
(
email:
@commit
.
author_email
)
}
end
end
end
end
describe
"Push Event"
do
before
do
service
.
execute
(
project
,
user
,
@oldrev
,
@newrev
,
@ref
)
@event
=
Event
.
last
end
it
{
@event
.
should_not
be_nil
}
it
{
@event
.
project
.
should
==
project
}
it
{
@event
.
action
.
should
==
Event
::
PUSHED
}
it
{
@event
.
data
.
should
==
service
.
push_data
}
end
describe
"Web Hooks"
do
context
"with web hooks"
do
before
do
@project_hook
=
create
(
:project_hook
)
@project_hook_2
=
create
(
:project_hook
)
project
.
hooks
<<
[
@project_hook
,
@project_hook_2
]
stub_request
(
:post
,
@project_hook
.
url
)
stub_request
(
:post
,
@project_hook_2
.
url
)
end
it
"executes multiple web hook"
do
@project_hook
.
should_receive
(
:async_execute
).
once
@project_hook_2
.
should_receive
(
:async_execute
).
once
service
.
execute
(
project
,
user
,
@oldrev
,
@newrev
,
@ref
)
end
end
context
"does not execute web hooks"
do
before
do
@project_hook
=
create
(
:project_hook
)
project
.
hooks
<<
[
@project_hook
]
end
it
"when pushing a branch for the first time"
do
@project_hook
.
should_not_receive
(
:execute
)
service
.
execute
(
project
,
user
,
'00000000000000000000000000000000'
,
'newrev'
,
'refs/heads/master'
)
end
it
"when pushing tags"
do
@project_hook
.
should_not_receive
(
:execute
)
service
.
execute
(
project
,
user
,
'newrev'
,
'newrev'
,
'refs/tags/v1.0.0'
)
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