Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-shell
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
nexedi
gitlab-shell
Commits
e0824f17
Commit
e0824f17
authored
Apr 03, 2019
by
Jacob Vosmaer
Committed by
Nick Thomas
Apr 03, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove hooks, they belong to Gitaly now
parent
433cc965
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
11 additions
and
998 deletions
+11
-998
README.md
README.md
+2
-6
hooks/post-receive
hooks/post-receive
+3
-21
hooks/pre-receive
hooks/pre-receive
+3
-31
hooks/update
hooks/update
+3
-17
lib/gitlab_access.rb
lib/gitlab_access.rb
+0
-43
lib/gitlab_custom_hook.rb
lib/gitlab_custom_hook.rb
+0
-98
lib/gitlab_net.rb
lib/gitlab_net.rb
+0
-1
lib/gitlab_post_receive.rb
lib/gitlab_post_receive.rb
+0
-125
spec/gitlab_access_spec.rb
spec/gitlab_access_spec.rb
+0
-77
spec/gitlab_custom_hook_spec.rb
spec/gitlab_custom_hook_spec.rb
+0
-295
spec/gitlab_post_receive_spec.rb
spec/gitlab_post_receive_spec.rb
+0
-284
No files found.
README.md
View file @
e0824f17
...
...
@@ -20,7 +20,7 @@ An overview of the four cases described above:
## Git hooks
For historical reasons the gitlab-shell repository also contains
the
The gitlab-shell repository used to also contain
the
Git hooks that allow GitLab to validate Git pushes (e.g. "is this user
allowed to push to this protected branch"). These hooks also trigger
events in GitLab (e.g. to start a CI pipeline after a push).
...
...
@@ -30,17 +30,13 @@ require direct disk access to Git repositories, and that is only
possible on Gitaly servers. It makes no sense to have to install
gitlab-shell on Gitaly servers.
As of GitLab 11.
9
[
the actual Git hooks are in the Gitaly
As of GitLab 11.
10
[
the actual Git hooks are in the Gitaly
repository
](
https://gitlab.com/gitlab-org/gitaly/tree/v1.22.0/ruby/vendor/gitlab-shell/hooks
)
,
but gitlab-shell must still be installed on Gitaly servers because the
hooks rely on configuration data (e.g. the GitLab internal API URL) that
is not yet available in Gitaly itself. Also see the
[
transition
plan
](
https://gitlab.com/gitlab-org/gitaly/issues/1226#note_126519133
)
.
This means that for GitLab 11.9 and up, it is pointless to make changes
to Git hook code in the gitlab-shell repository, because the code that
gets run is in the Gitaly repository instead.
## Code status
[
![pipeline status
](
https://gitlab.com/gitlab-org/gitlab-shell/badges/master/pipeline.svg
)
](https://gitlab.com/gitlab-org/gitlab-shell/commits/master)
...
...
hooks/post-receive
View file @
e0824f17
#!/usr/bin/env ruby
#!/bin/sh
echo
"The gitlab-shell hooks have been migrated to Gitaly, see https://gitlab.com/gitlab-org/gitaly/issues/1226"
exit
1
# This file was placed here by GitLab. It makes sure that your pushed commits
# will be processed properly.
refs
=
$stdin
.
read
key_id
=
ENV
.
delete
(
'GL_ID'
)
gl_repository
=
ENV
[
'GL_REPOSITORY'
]
repo_path
=
Dir
.
pwd
require_relative
'../lib/gitlab_custom_hook'
require_relative
'../lib/hooks_utils'
require_relative
'../lib/gitlab_post_receive'
push_options
=
HooksUtils
.
get_push_options
if
GitlabPostReceive
.
new
(
gl_repository
,
repo_path
,
key_id
,
refs
,
push_options
).
exec
&&
GitlabCustomHook
.
new
(
repo_path
,
key_id
).
post_receive
(
refs
)
exit
0
else
exit
1
end
hooks/pre-receive
View file @
e0824f17
#!/usr/bin/env ruby
#!/bin/sh
echo
"The gitlab-shell hooks have been migrated to Gitaly, see https://gitlab.com/gitlab-org/gitaly/issues/1226"
exit
1
# This file was placed here by GitLab. It makes sure that your pushed commits
# will be processed properly.
refs
=
$stdin
.
read
key_id
=
ENV
.
delete
(
'GL_ID'
)
protocol
=
ENV
.
delete
(
'GL_PROTOCOL'
)
repo_path
=
Dir
.
pwd
gl_repository
=
ENV
[
'GL_REPOSITORY'
]
def
increase_reference_counter
(
gl_repository
,
repo_path
)
result
=
GitlabNet
.
new
.
pre_receive
(
gl_repository
)
result
&&
result
[
'reference_counter_increased'
]
end
require_relative
'../lib/gitlab_custom_hook'
require_relative
'../lib/gitlab_access'
require_relative
'../lib/gitlab_net'
# It's important that on pre-receive `increase_reference_counter` gets executed
# last so that it only runs if everything else succeeded. On post-receive on the
# other hand, we run GitlabPostReceive first because the push is already done
# and we don't want to skip it if the custom hook fails.
if
GitlabAccess
.
new
(
gl_repository
,
repo_path
,
key_id
,
refs
,
protocol
).
exec
&&
GitlabCustomHook
.
new
(
repo_path
,
key_id
).
pre_receive
(
refs
)
&&
increase_reference_counter
(
gl_repository
,
repo_path
)
exit
0
else
exit
1
end
hooks/update
View file @
e0824f17
#!/usr/bin/env ruby
#!/bin/sh
echo
"The gitlab-shell hooks have been migrated to Gitaly, see https://gitlab.com/gitlab-org/gitaly/issues/1226"
exit
1
# This file was placed here by GitLab. It makes sure that your pushed commits
# will be processed properly.
ref_name
=
ARGV
[
0
]
old_value
=
ARGV
[
1
]
new_value
=
ARGV
[
2
]
repo_path
=
Dir
.
pwd
key_id
=
ENV
.
delete
(
'GL_ID'
)
require_relative
'../lib/gitlab_custom_hook'
if
GitlabCustomHook
.
new
(
repo_path
,
key_id
).
update
(
ref_name
,
old_value
,
new_value
)
exit
0
else
exit
1
end
lib/gitlab_access.rb
deleted
100644 → 0
View file @
433cc965
require_relative
'gitlab_init'
require_relative
'gitlab_net'
require_relative
'gitlab_access_status'
require_relative
'gitlab_metrics'
require_relative
'object_dirs_helper'
require
'json'
class
GitlabAccess
class
AccessDeniedError
<
StandardError
;
end
attr_reader
:config
,
:gl_repository
,
:repo_path
,
:changes
,
:protocol
def
initialize
(
gl_repository
,
repo_path
,
actor
,
changes
,
protocol
)
@config
=
GitlabConfig
.
new
@gl_repository
=
gl_repository
@repo_path
=
repo_path
.
strip
@actor
=
actor
@changes
=
changes
.
lines
@protocol
=
protocol
end
def
exec
status
=
GitlabMetrics
.
measure
(
'check-access:git-receive-pack'
)
do
api
.
check_access
(
'git-receive-pack'
,
@gl_repository
,
@repo_path
,
@actor
,
@changes
,
@protocol
,
env:
ObjectDirsHelper
.
all_attributes
.
to_json
)
end
raise
AccessDeniedError
,
status
.
message
unless
status
.
allowed?
true
rescue
GitlabNet
::
ApiUnreachableError
$stderr
.
puts
"GitLab: Failed to authorize your Git request: internal API unreachable"
false
rescue
AccessDeniedError
=>
ex
$stderr
.
puts
"GitLab:
#{
ex
.
message
}
"
false
end
protected
def
api
GitlabNet
.
new
end
end
lib/gitlab_custom_hook.rb
deleted
100644 → 0
View file @
433cc965
require
'open3'
require_relative
'gitlab_init'
require_relative
'gitlab_metrics'
class
GitlabCustomHook
attr_reader
:vars
,
:config
def
initialize
(
repo_path
,
key_id
)
@repo_path
=
repo_path
@vars
=
{
'GL_ID'
=>
key_id
}
@config
=
GitlabConfig
.
new
end
def
pre_receive
(
changes
)
GitlabMetrics
.
measure
(
"pre-receive-hook"
)
do
find_hooks
(
'pre-receive'
).
all?
do
|
hook
|
call_receive_hook
(
hook
,
changes
)
end
end
end
def
post_receive
(
changes
)
GitlabMetrics
.
measure
(
"post-receive-hook"
)
do
find_hooks
(
'post-receive'
).
all?
do
|
hook
|
call_receive_hook
(
hook
,
changes
)
end
end
end
def
update
(
ref_name
,
old_value
,
new_value
)
GitlabMetrics
.
measure
(
"update-hook"
)
do
find_hooks
(
'update'
).
all?
do
|
hook
|
system
(
vars
,
hook
,
ref_name
,
old_value
,
new_value
)
end
end
end
private
def
call_receive_hook
(
hook
,
changes
)
# Prepare the hook subprocess. Attach a pipe to its stdin, and merge
# both its stdout and stderr into our own stdout.
stdin_reader
,
stdin_writer
=
IO
.
pipe
hook_pid
=
spawn
(
vars
,
hook
,
in:
stdin_reader
,
err: :out
)
stdin_reader
.
close
# Submit changes to the hook via its stdin.
begin
IO
.
copy_stream
(
StringIO
.
new
(
changes
),
stdin_writer
)
rescue
Errno
::
EPIPE
# rubocop:disable Lint/HandleExceptions
# It is not an error if the hook does not consume all of its input.
end
# Close the pipe to let the hook know there is no further input.
stdin_writer
.
close
Process
.
wait
(
hook_pid
)
$?
.
success?
end
# lookup hook files in this order:
#
# 1. <repository>.git/custom_hooks/<hook_name> - per project hook
# 2. <repository>.git/custom_hooks/<hook_name>.d/* - per project hooks
# 3. <repository>.git/hooks/<hook_name>.d/* - global hooks
#
def
find_hooks
(
hook_name
)
hook_files
=
[]
# <repository>.git/custom_hooks/<hook_name>
project_custom_hook_file
=
File
.
join
(
@repo_path
,
'custom_hooks'
,
hook_name
)
hook_files
.
push
(
project_custom_hook_file
)
if
File
.
executable?
(
project_custom_hook_file
)
# <repository>.git/custom_hooks/<hook_name>.d/*
project_custom_hooks_dir
=
File
.
join
(
@repo_path
,
'custom_hooks'
,
"
#{
hook_name
}
.d"
)
hook_files
+=
match_hook_files
(
project_custom_hooks_dir
)
# <repository>.git/hooks/<hook_name>.d/* OR <custom_hook_dir>/<hook_name>.d/*
global_custom_hooks_parent
=
config
.
custom_hooks_dir
(
default:
File
.
join
(
@repo_path
,
'hooks'
))
global_custom_hooks_dir
=
File
.
join
(
global_custom_hooks_parent
,
"
#{
hook_name
}
.d"
)
hook_files
+=
match_hook_files
(
global_custom_hooks_dir
)
hook_files
end
# match files from path:
# 1. file must be executable
# 2. file must not match backup file
#
# the resulting list is sorted
def
match_hook_files
(
path
)
return
[]
unless
Dir
.
exist?
(
path
)
Dir
[
"
#{
path
}
/*"
].
select
do
|
f
|
!
f
.
end_with?
(
'~'
)
&&
File
.
executable?
(
f
)
end
.
sort
end
end
lib/gitlab_net.rb
View file @
e0824f17
...
...
@@ -3,7 +3,6 @@ require 'openssl'
require
'json'
require_relative
'gitlab_config'
require_relative
'gitlab_access'
require_relative
'gitlab_lfs_authentication'
require_relative
'http_helper'
...
...
lib/gitlab_post_receive.rb
deleted
100644 → 0
View file @
433cc965
require_relative
'gitlab_init'
require_relative
'gitlab_net'
require_relative
'gitlab_metrics'
require
'json'
require
'base64'
require
'securerandom'
class
GitlabPostReceive
attr_reader
:config
,
:gl_repository
,
:repo_path
,
:changes
,
:jid
def
initialize
(
gl_repository
,
repo_path
,
actor
,
changes
,
push_options
)
@config
=
GitlabConfig
.
new
@gl_repository
=
gl_repository
@repo_path
=
repo_path
.
strip
@actor
=
actor
@changes
=
changes
@push_options
=
push_options
@jid
=
SecureRandom
.
hex
(
12
)
end
def
exec
response
=
GitlabMetrics
.
measure
(
"post-receive"
)
do
api
.
post_receive
(
gl_repository
,
@actor
,
changes
,
@push_options
)
end
return
false
unless
response
print_formatted_alert_message
(
response
[
'broadcast_message'
])
if
response
[
'broadcast_message'
]
print_merge_request_links
(
response
[
'merge_request_urls'
])
if
response
[
'merge_request_urls'
]
puts
response
[
'redirected_message'
]
if
response
[
'redirected_message'
]
puts
response
[
'project_created_message'
]
if
response
[
'project_created_message'
]
print_warnings
(
response
[
'warnings'
])
if
response
[
'warnings'
]
response
[
'reference_counter_decreased'
]
rescue
GitlabNet
::
ApiUnreachableError
false
end
protected
def
api
@api
||=
GitlabNet
.
new
end
def
print_merge_request_links
(
merge_request_urls
)
return
if
merge_request_urls
.
empty?
puts
merge_request_urls
.
each
{
|
mr
|
print_merge_request_link
(
mr
)
}
end
def
print_merge_request_link
(
merge_request
)
message
=
if
merge_request
[
"new_merge_request"
]
"To create a merge request for
#{
merge_request
[
'branch_name'
]
}
, visit:"
else
"View merge request for
#{
merge_request
[
'branch_name'
]
}
:"
end
puts
message
puts
((
" "
*
2
)
+
merge_request
[
"url"
])
puts
end
def
print_warnings
(
warnings
)
message
=
"WARNINGS:
\n
#{
warnings
}
"
print_formatted_alert_message
(
message
)
end
def
print_formatted_alert_message
(
message
)
# A standard terminal window is (at least) 80 characters wide.
total_width
=
80
# Git prefixes remote messages with "remote: ", so this width is subtracted
# from the width available to us.
total_width
-=
"remote: "
.
length
# rubocop:disable Performance/FixedSize
# Our centered text shouldn't start or end right at the edge of the window,
# so we add some horizontal padding: 2 chars on either side.
text_width
=
total_width
-
2
*
2
# Automatically wrap message at text_width (= 68) characters:
# Splits the message up into the longest possible chunks matching
# "<between 0 and text_width characters><space or end-of-line>".
msg_start_idx
=
0
lines
=
[]
while
msg_start_idx
<
message
.
length
parsed_line
=
parse_broadcast_msg
(
message
[
msg_start_idx
..-
1
],
text_width
)
msg_start_idx
+=
parsed_line
.
length
lines
.
push
(
parsed_line
.
strip
)
end
puts
puts
"="
*
total_width
puts
lines
.
each
do
|
line
|
line
.
strip!
# Center the line by calculating the left padding measured in characters.
line_padding
=
[(
total_width
-
line
.
length
)
/
2
,
0
].
max
puts
((
" "
*
line_padding
)
+
line
)
end
puts
puts
"="
*
total_width
end
private
def
parse_broadcast_msg
(
msg
,
text_length
)
msg
||=
""
# just return msg if shorter than or equal to text length
return
msg
if
msg
.
length
<=
text_length
# search for word break shorter than text length
truncate_to_space
=
msg
.
match
(
/\A(.{,
#{
text_length
}
})(?=\s|$)(\s*)/
).
to_s
if
truncate_to_space
.
empty?
# search for word break longer than text length
truncate_to_space
=
msg
.
match
(
/\A\S+/
).
to_s
end
truncate_to_space
end
end
spec/gitlab_access_spec.rb
deleted
100644 → 0
View file @
433cc965
require
'spec_helper'
require
'gitlab_access'
describe
GitlabAccess
do
let
(
:repository_path
)
{
"/home/git/repositories"
}
let
(
:repo_name
)
{
'dzaporozhets/gitlab-ci'
}
let
(
:repo_path
)
{
File
.
join
(
repository_path
,
repo_name
)
+
".git"
}
let
(
:api
)
do
double
(
GitlabNet
).
tap
do
|
api
|
allow
(
api
).
to
receive
(
:check_access
).
and_return
(
GitAccessStatus
.
new
(
true
,
'200'
,
'ok'
,
gl_repository:
'project-1'
,
gl_project_path:
'group/subgroup/project'
,
gl_id:
'user-123'
,
gl_username:
'testuser'
,
git_config_options:
[
'receive.MaxInputSize=10000'
],
gitaly:
nil
,
git_protocol:
'version=2'
))
end
end
subject
do
GitlabAccess
.
new
(
nil
,
repo_path
,
'key-123'
,
'wow'
,
'ssh'
).
tap
do
|
access
|
allow
(
access
).
to
receive
(
:exec_cmd
).
and_return
(
:exec_called
)
allow
(
access
).
to
receive
(
:api
).
and_return
(
api
)
end
end
before
do
allow_any_instance_of
(
GitlabConfig
).
to
receive
(
:repos_path
).
and_return
(
repository_path
)
end
describe
:initialize
do
it
{
expect
(
subject
.
repo_path
).
to
eq
(
repo_path
)
}
it
{
expect
(
subject
.
changes
).
to
eq
([
'wow'
])
}
it
{
expect
(
subject
.
protocol
).
to
eq
(
'ssh'
)
}
end
describe
"#exec"
do
context
"access is granted"
do
it
"returns true"
do
expect
(
subject
.
exec
).
to
be_truthy
end
end
context
"access is denied"
do
before
do
allow
(
api
).
to
receive
(
:check_access
).
and_return
(
GitAccessStatus
.
new
(
false
,
'401'
,
'denied'
,
gl_repository:
nil
,
gl_project_path:
nil
,
gl_id:
nil
,
gl_username:
nil
,
git_config_options:
nil
,
gitaly:
nil
,
git_protocol:
nil
))
end
it
"returns false"
do
expect
(
subject
.
exec
).
to
be_falsey
end
end
context
"API connection fails"
do
before
do
allow
(
api
).
to
receive
(
:check_access
).
and_raise
(
GitlabNet
::
ApiUnreachableError
)
end
it
"returns false"
do
expect
(
subject
.
exec
).
to
be_falsey
end
end
end
end
spec/gitlab_custom_hook_spec.rb
deleted
100644 → 0
View file @
433cc965
# coding: utf-8
require
'spec_helper'
require
'gitlab_custom_hook'
describe
GitlabCustomHook
do
let
(
:original_root_path
)
{
ROOT_PATH
}
let
(
:tmp_repo_path
)
{
File
.
join
(
original_root_path
,
'tmp'
,
'repo.git'
)
}
let
(
:tmp_root_path
)
{
File
.
join
(
original_root_path
,
'tmp'
)
}
let
(
:global_custom_hooks_path
)
{
global_hook_path
(
'custom_global_hooks'
)
}
let
(
:hook_ok
)
{
File
.
join
(
original_root_path
,
'spec'
,
'support'
,
'hook_ok'
)
}
let
(
:hook_fail
)
{
File
.
join
(
original_root_path
,
'spec'
,
'support'
,
'hook_fail'
)
}
let
(
:hook_gl_id
)
{
File
.
join
(
original_root_path
,
'spec'
,
'support'
,
'gl_id_test_hook'
)
}
let
(
:vars
)
{
{
"GL_ID"
=>
"key_1"
}
}
let
(
:old_value
)
{
"old-value"
}
let
(
:new_value
)
{
"new-value"
}
let
(
:ref_name
)
{
"name/of/ref"
}
let
(
:changes
)
{
"
#{
old_value
}
#{
new_value
}
#{
ref_name
}
\n
"
}
let
(
:gitlab_custom_hook
)
{
GitlabCustomHook
.
new
(
tmp_repo_path
,
'key_1'
)
}
def
hook_path
(
path
)
File
.
join
(
tmp_repo_path
,
path
.
split
(
'/'
))
end
def
global_hook_path
(
path
)
File
.
join
(
tmp_root_path
,
path
.
split
(
'/'
))
end
def
create_hook
(
path
,
which
)
FileUtils
.
ln_sf
(
which
,
hook_path
(
path
))
end
# global hooks multiplexed
def
create_global_hooks_d
(
which
,
hook_name
=
'hook'
)
create_hook
(
'hooks/pre-receive.d/'
+
hook_name
,
which
)
create_hook
(
'hooks/update.d/'
+
hook_name
,
which
)
create_hook
(
'hooks/post-receive.d/'
+
hook_name
,
which
)
end
# repo hooks
def
create_repo_hooks
(
which
)
create_hook
(
'custom_hooks/pre-receive'
,
which
)
create_hook
(
'custom_hooks/update'
,
which
)
create_hook
(
'custom_hooks/post-receive'
,
which
)
end
# repo hooks multiplexed
def
create_repo_hooks_d
(
which
,
hook_name
=
'hook'
)
create_hook
(
'custom_hooks/pre-receive.d/'
+
hook_name
,
which
)
create_hook
(
'custom_hooks/update.d/'
+
hook_name
,
which
)
create_hook
(
'custom_hooks/post-receive.d/'
+
hook_name
,
which
)
end
def
cleanup_hook_setup
FileUtils
.
rm_rf
(
File
.
join
(
tmp_repo_path
))
FileUtils
.
rm_rf
(
File
.
join
(
global_custom_hooks_path
))
FileUtils
.
rm_rf
(
File
.
join
(
tmp_root_path
,
'hooks'
))
FileUtils
.
rm_f
(
File
.
join
(
tmp_root_path
,
'config.yml'
))
end
def
expect_call_receive_hook
(
path
)
expect
(
gitlab_custom_hook
)
.
to
receive
(
:call_receive_hook
)
.
with
(
hook_path
(
path
),
changes
)
.
and_call_original
end
def
expect_call_update_hook
(
path
)
expect
(
gitlab_custom_hook
)
.
to
receive
(
:system
)
.
with
(
vars
,
hook_path
(
path
),
ref_name
,
old_value
,
new_value
)
.
and_call_original
end
# setup paths
# <repository>.git/hooks/ - symlink to gitlab-shell/hooks global dir
# <repository>.git/hooks/<hook_name> - executed by git itself, this is gitlab-shell/hooks/<hook_name>
# <repository>.git/hooks/<hook_name>.d/* - global hooks: all executable files (minus editor backup files)
# <repository>.git/custom_hooks/<hook_name> - per project hook (this is already existing behavior)
# <repository>.git/custom_hooks/<hook_name>.d/* - per project hooks
#
# custom hooks are invoked in such way that first failure prevents other scripts being ran
# as global scripts are ran first, failing global skips repo hooks
before
do
cleanup_hook_setup
FileUtils
.
mkdir_p
(
File
.
join
(
tmp_repo_path
,
'custom_hooks'
))
FileUtils
.
mkdir_p
(
File
.
join
(
tmp_root_path
,
'hooks'
))
[
'pre-receive'
,
'update'
,
'post-receive'
].
each
do
|
hook
|
FileUtils
.
mkdir_p
(
File
.
join
(
tmp_repo_path
,
'custom_hooks'
,
"
#{
hook
}
.d"
))
FileUtils
.
mkdir_p
(
File
.
join
(
tmp_root_path
,
'hooks'
,
"
#{
hook
}
.d"
))
end
FileUtils
.
symlink
(
File
.
join
(
tmp_root_path
,
'hooks'
),
File
.
join
(
tmp_repo_path
,
'hooks'
))
FileUtils
.
symlink
(
File
.
join
(
ROOT_PATH
,
'config.yml.example'
),
File
.
join
(
tmp_root_path
,
'config.yml'
))
stub_const
(
'ROOT_PATH'
,
tmp_root_path
)
end
after
do
cleanup_hook_setup
end
context
'with gl_id_test_hook as repo hook'
do
before
do
create_repo_hooks
(
hook_gl_id
)
end
context
'pre_receive hook'
do
it
'passes GL_ID variable to hook'
do
expect
(
gitlab_custom_hook
.
pre_receive
(
changes
)).
to
eq
(
true
)
end
end
context
'post_receive hook'
do
it
'passes GL_ID variable to hook'
do
expect
(
gitlab_custom_hook
.
post_receive
(
changes
)).
to
eq
(
true
)
end
end
context
'update hook'
do
it
'passes GL_ID variable to hook'
do
expect
(
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)).
to
eq
(
true
)
end
end
end
context
'with gl_id_test_hook as global hook'
do
before
do
create_global_hooks_d
(
hook_gl_id
)
end
context
'pre_receive hook'
do
it
'passes GL_ID variable to hook'
do
expect
(
gitlab_custom_hook
.
pre_receive
(
changes
)).
to
eq
(
true
)
end
end
context
'post_receive hook'
do
it
'passes GL_ID variable to hook'
do
expect
(
gitlab_custom_hook
.
post_receive
(
changes
)).
to
eq
(
true
)
end
end
context
'update hook'
do
it
'passes GL_ID variable to hook'
do
expect
(
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)).
to
eq
(
true
)
end
end
end
context
"having no hooks"
do
it
"returns true"
do
expect
(
gitlab_custom_hook
.
pre_receive
(
changes
)).
to
eq
(
true
)
expect
(
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)).
to
eq
(
true
)
expect
(
gitlab_custom_hook
.
post_receive
(
changes
)).
to
eq
(
true
)
end
end
context
"having only successful repo hooks"
do
before
do
create_repo_hooks
(
hook_ok
)
end
it
"returns true"
do
expect
(
gitlab_custom_hook
.
pre_receive
(
changes
)).
to
eq
(
true
)
expect
(
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)).
to
eq
(
true
)
expect
(
gitlab_custom_hook
.
post_receive
(
changes
)).
to
eq
(
true
)
end
end
context
"having both successful repo and global hooks"
do
before
do
create_repo_hooks
(
hook_ok
)
create_global_hooks_d
(
hook_ok
)
end
it
"returns true"
do
expect
(
gitlab_custom_hook
.
pre_receive
(
changes
)).
to
eq
(
true
)
expect
(
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)).
to
eq
(
true
)
expect
(
gitlab_custom_hook
.
post_receive
(
changes
)).
to
eq
(
true
)
end
end
context
"having failing repo and successful global hooks"
do
before
do
create_repo_hooks_d
(
hook_fail
)
create_global_hooks_d
(
hook_ok
)
end
it
"returns false"
do
expect
(
gitlab_custom_hook
.
pre_receive
(
changes
)).
to
eq
(
false
)
expect
(
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)).
to
eq
(
false
)
expect
(
gitlab_custom_hook
.
post_receive
(
changes
)).
to
eq
(
false
)
end
it
"only executes the global hook"
do
expect_call_receive_hook
(
"custom_hooks/pre-receive.d/hook"
)
expect_call_update_hook
(
"custom_hooks/update.d/hook"
)
expect_call_receive_hook
(
"custom_hooks/post-receive.d/hook"
)
gitlab_custom_hook
.
pre_receive
(
changes
)
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)
gitlab_custom_hook
.
post_receive
(
changes
)
end
end
context
"having successful repo but failing global hooks"
do
before
do
create_repo_hooks_d
(
hook_ok
)
create_global_hooks_d
(
hook_fail
)
end
it
"returns false"
do
expect
(
gitlab_custom_hook
.
pre_receive
(
changes
)).
to
eq
(
false
)
expect
(
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)).
to
eq
(
false
)
expect
(
gitlab_custom_hook
.
post_receive
(
changes
)).
to
eq
(
false
)
end
it
"executes the relevant hooks"
do
expect_call_receive_hook
(
"hooks/pre-receive.d/hook"
)
expect_call_receive_hook
(
"custom_hooks/pre-receive.d/hook"
)
expect_call_update_hook
(
"hooks/update.d/hook"
)
expect_call_update_hook
(
"custom_hooks/update.d/hook"
)
expect_call_receive_hook
(
"hooks/post-receive.d/hook"
)
expect_call_receive_hook
(
"custom_hooks/post-receive.d/hook"
)
gitlab_custom_hook
.
pre_receive
(
changes
)
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)
gitlab_custom_hook
.
post_receive
(
changes
)
end
end
context
"executing hooks in expected order"
do
before
do
create_repo_hooks_d
(
hook_ok
,
'01-test'
)
create_repo_hooks_d
(
hook_ok
,
'02-test'
)
create_global_hooks_d
(
hook_ok
,
'03-test'
)
create_global_hooks_d
(
hook_ok
,
'04-test'
)
end
it
"executes hooks in order"
do
expect_call_receive_hook
(
"custom_hooks/pre-receive.d/01-test"
).
ordered
expect_call_receive_hook
(
"custom_hooks/pre-receive.d/02-test"
).
ordered
expect_call_receive_hook
(
"hooks/pre-receive.d/03-test"
).
ordered
expect_call_receive_hook
(
"hooks/pre-receive.d/04-test"
).
ordered
expect_call_update_hook
(
"custom_hooks/update.d/01-test"
).
ordered
expect_call_update_hook
(
"custom_hooks/update.d/02-test"
).
ordered
expect_call_update_hook
(
"hooks/update.d/03-test"
).
ordered
expect_call_update_hook
(
"hooks/update.d/04-test"
).
ordered
expect_call_receive_hook
(
"custom_hooks/post-receive.d/01-test"
).
ordered
expect_call_receive_hook
(
"custom_hooks/post-receive.d/02-test"
).
ordered
expect_call_receive_hook
(
"hooks/post-receive.d/03-test"
).
ordered
expect_call_receive_hook
(
"hooks/post-receive.d/04-test"
).
ordered
gitlab_custom_hook
.
pre_receive
(
changes
)
gitlab_custom_hook
.
update
(
ref_name
,
old_value
,
new_value
)
gitlab_custom_hook
.
post_receive
(
changes
)
end
end
context
"when the custom_hooks_dir config option is set"
do
before
do
allow
(
gitlab_custom_hook
.
config
).
to
receive
(
:custom_hooks_dir
).
and_return
(
global_custom_hooks_path
)
FileUtils
.
mkdir_p
(
File
.
join
(
global_custom_hooks_path
,
"pre-receive.d"
))
FileUtils
.
ln_sf
(
hook_ok
,
File
.
join
(
global_custom_hooks_path
,
"pre-receive.d"
,
"hook"
))
create_global_hooks_d
(
hook_fail
)
end
it
"finds hooks in that directory"
do
expect
(
gitlab_custom_hook
)
.
to
receive
(
:call_receive_hook
)
.
with
(
global_hook_path
(
"custom_global_hooks/pre-receive.d/hook"
),
changes
)
.
and_call_original
expect
(
gitlab_custom_hook
.
pre_receive
(
changes
)).
to
eq
(
true
)
end
it
"does not execute hooks in the default location"
do
expect
(
gitlab_custom_hook
)
.
not_to
receive
(
:call_receive_hook
)
.
with
(
"hooks/pre-receive.d/hook"
,
changes
)
.
and_call_original
gitlab_custom_hook
.
pre_receive
(
changes
)
end
end
end
spec/gitlab_post_receive_spec.rb
deleted
100644 → 0
View file @
433cc965
# coding: utf-8
require
'spec_helper'
require
'gitlab_post_receive'
describe
GitlabPostReceive
do
let
(
:repository_path
)
{
"/home/git/repositories"
}
let
(
:repo_name
)
{
'dzaporozhets/gitlab-ci'
}
let
(
:actor
)
{
'key-123'
}
let
(
:changes
)
{
"123456 789012 refs/heads/tést
\n
654321 210987 refs/tags/tag"
}
let
(
:wrongly_encoded_changes
)
{
changes
.
encode
(
"ISO-8859-1"
).
force_encoding
(
"UTF-8"
)
}
let
(
:base64_changes
)
{
Base64
.
encode64
(
wrongly_encoded_changes
)
}
let
(
:repo_path
)
{
File
.
join
(
repository_path
,
repo_name
)
+
".git"
}
let
(
:gl_repository
)
{
"project-1"
}
let
(
:push_options
)
{
[]
}
let
(
:gitlab_post_receive
)
{
GitlabPostReceive
.
new
(
gl_repository
,
repo_path
,
actor
,
wrongly_encoded_changes
,
push_options
)
}
let
(
:broadcast_message
)
{
"test "
*
10
+
"message "
*
10
}
let
(
:enqueued_at
)
{
Time
.
new
(
2016
,
6
,
23
,
6
,
59
)
}
let
(
:new_merge_request_urls
)
do
[{
'branch_name'
=>
'new_branch'
,
'url'
=>
'http://localhost/dzaporozhets/gitlab-ci/merge_requests/new?merge_request%5Bsource_branch%5D=new_branch'
,
'new_merge_request'
=>
true
}]
end
let
(
:existing_merge_request_urls
)
do
[{
'branch_name'
=>
'feature_branch'
,
'url'
=>
'http://localhost/dzaporozhets/gitlab-ci/merge_requests/1'
,
'new_merge_request'
=>
false
}]
end
before
do
$logger
=
double
(
'logger'
).
as_null_object
# Global vars are bad
allow_any_instance_of
(
GitlabConfig
).
to
receive
(
:repos_path
).
and_return
(
repository_path
)
end
describe
"#exec"
do
let
(
:response
)
{
{
'reference_counter_decreased'
=>
true
}
}
it
'calls the api to notify the execution of the hook'
do
expect_any_instance_of
(
GitlabNet
).
to
receive
(
:post_receive
).
and_return
(
response
)
expect
(
gitlab_post_receive
.
exec
).
to
eq
(
true
)
end
context
'merge request urls and broadcast messages'
do
let
(
:response
)
do
{
'reference_counter_decreased'
=>
true
,
'merge_request_urls'
=>
new_merge_request_urls
,
'broadcast_message'
=>
broadcast_message
}
end
it
'prints the merge request urls and broadcast message'
do
expect_any_instance_of
(
GitlabNet
).
to
receive
(
:post_receive
).
and_return
(
response
)
assert_broadcast_message_printed
(
gitlab_post_receive
)
assert_new_mr_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
.
exec
).
to
eq
(
true
)
end
context
'when contains long url string at end'
do
let
(
:broadcast_message
)
{
"test "
*
10
+
"message "
*
10
+
"https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url"
}
it
'doesnt truncate url'
do
expect_any_instance_of
(
GitlabNet
).
to
receive
(
:post_receive
).
and_return
(
response
)
assert_broadcast_message_printed_keep_long_url_end
(
gitlab_post_receive
)
assert_new_mr_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
.
exec
).
to
eq
(
true
)
end
end
context
'when contains long url string at start'
do
let
(
:broadcast_message
)
{
"https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url "
+
"test "
*
10
+
"message "
*
11
}
it
'doesnt truncate url'
do
expect_any_instance_of
(
GitlabNet
).
to
receive
(
:post_receive
).
and_return
(
response
)
assert_broadcast_message_printed_keep_long_url_start
(
gitlab_post_receive
)
assert_new_mr_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
.
exec
).
to
eq
(
true
)
end
end
context
'when contains long url string in middle'
do
let
(
:broadcast_message
)
{
"test "
*
11
+
"https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url "
+
"message "
*
11
}
it
'doesnt truncate url'
do
expect_any_instance_of
(
GitlabNet
).
to
receive
(
:post_receive
).
and_return
(
response
)
assert_broadcast_message_printed_keep_long_url_middle
(
gitlab_post_receive
)
assert_new_mr_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
.
exec
).
to
eq
(
true
)
end
end
end
context
'when warnings are present'
do
let
(
:response
)
do
{
'reference_counter_decreased'
=>
true
,
'warnings'
=>
'My warning message'
}
end
it
'treats the warning as a broadcast message'
do
expect_any_instance_of
(
GitlabNet
).
to
receive
(
:post_receive
).
and_return
(
response
)
expect
(
gitlab_post_receive
).
to
receive
(
:print_formatted_alert_message
).
with
(
"WARNINGS:
\n
My warning message"
)
expect
(
gitlab_post_receive
.
exec
).
to
eq
(
true
)
end
end
context
'when redirected message available'
do
let
(
:message
)
{
"This is a redirected message"
}
let
(
:response
)
do
{
'reference_counter_decreased'
=>
true
,
'redirected_message'
=>
message
}
end
it
'prints redirected message'
do
expect_any_instance_of
(
GitlabNet
).
to
receive
(
:post_receive
).
and_return
(
response
)
assert_redirected_message_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
.
exec
).
to
eq
(
true
)
end
context
'when project created message is available'
do
let
(
:message
)
{
"This is a created project message"
}
let
(
:response
)
do
{
'reference_counter_decreased'
=>
true
,
'project_created_message'
=>
message
}
end
it
'prints project created message'
do
expect_any_instance_of
(
GitlabNet
).
to
receive
(
:post_receive
).
and_return
(
response
)
assert_project_created_message_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
.
exec
).
to
be
true
end
end
end
end
private
def
assert_new_mr_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"To create a merge request for new_branch, visit:"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" http://localhost/dzaporozhets/gitlab-ci/merge_requests/new?merge_request%5Bsource_branch%5D=new_branch"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
end
def
assert_existing_mr_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"View merge request for feature_branch:"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" http://localhost/dzaporozhets/gitlab-ci/merge_requests/1"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
end
def
assert_broadcast_message_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"========================================================================"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" test test test test test test test test test test message message"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" message message message message message message message message"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"========================================================================"
).
ordered
end
def
assert_redirected_message_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"This is a redirected message"
)
end
def
assert_project_created_message_printed
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"This is a created project message"
)
end
def
assert_broadcast_message_printed_keep_long_url_end
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"========================================================================"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" test test test test test test test test test test message message"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" message message message message message message message message"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"========================================================================"
).
ordered
end
def
assert_broadcast_message_printed_keep_long_url_start
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"========================================================================"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" test test test test test test test test test test message message"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" message message message message message message message message"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" message"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"========================================================================"
).
ordered
end
def
assert_broadcast_message_printed_keep_long_url_middle
(
gitlab_post_receive
)
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"========================================================================"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" test test test test test test test test test test test"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"https://localhost:5000/test/a/really/long/url/that/is/in/the/broadcast/message/do-not-truncate-when-url"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" message message message message message message message message"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
" message message message"
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
ordered
expect
(
gitlab_post_receive
).
to
receive
(
:puts
).
with
(
"========================================================================"
).
ordered
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