Skip to content

Commit 64bd54b

Browse files
Changed logic: hooks no longer get the payload as argument, now they get the path to a file holding the payload.
Passing the payload as an argument was too error prone.
1 parent 7a5905d commit 64bd54b

File tree

2 files changed

+47
-21
lines changed

2 files changed

+47
-21
lines changed

README.rst

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,16 @@ following order:
5858
hooks/{event}
5959
hooks/all
6060

61-
The application will pass to the hooks the JSON received as first argument.
62-
Hooks can be written in any scripting language as long as the file is executable
63-
and has a shebang. A simple example in Python could be:
61+
The application will pass to the hooks the path to a JSON file holding the
62+
payload for the request as first argument. The event type will be passed
63+
as second argument. For example:
64+
65+
::
66+
67+
hooks/push-myrepo-master /tmp/sXFHji push
68+
69+
Hooks can be written in any scripting language as long as the file is
70+
executable and has a shebang. A simple example in Python could be:
6471

6572
::
6673

@@ -71,7 +78,8 @@ and has a shebang. A simple example in Python could be:
7178
import sys
7279
import json
7380

74-
payload = json.loads(sys.argv[1])
81+
with open(sys.argv[1], 'r') as jsf:
82+
payload = json.loads(jsf.read())
7583

7684
### Do something with the payload
7785
name = payload['repository']['name']

webhooks.py

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
from hashlib import sha1
2424
from json import loads, dumps
2525
from subprocess import Popen, PIPE
26-
from os import access, X_OK
26+
from tempfile import mkstemp
27+
from os import access, X_OK, remove
2728
from os.path import isfile, abspath, normpath, dirname, join, basename
2829

2930
import requests
@@ -99,31 +100,48 @@ def index():
99100
join(hooks, 'all')
100101
]
101102

103+
# Check permissions
104+
scripts = [s for s in scripts if isfile(s) and access(s, X_OK)]
105+
if not scripts:
106+
return ''
107+
108+
# Save payload to temporal file
109+
_, tmpfile = mkstemp()
110+
with open(tmpfile, 'w') as pf:
111+
pf.write(dumps(payload))
112+
102113
# Run scripts
103114
ran = {}
104115
for s in scripts:
105-
if isfile(s) and access(s, X_OK):
106116

107-
proc = Popen(
108-
[s, dumps(payload)],
109-
shell=True,
110-
stdout=PIPE, stderr=PIPE
111-
)
112-
stdout, stderr = proc.communicate()
117+
proc = Popen(
118+
[s, tmpfile, event],
119+
shell=True,
120+
stdout=PIPE, stderr=PIPE
121+
)
122+
stdout, stderr = proc.communicate()
123+
124+
ran[basename(s)] = {
125+
'returncode': proc.returncode,
126+
'stdout': stdout,
127+
'stderr': stderr,
128+
}
113129

114-
ran[basename(s)] = {
115-
'returncode': proc.returncode,
116-
'stdout': stdout,
117-
'stderr': stderr,
118-
}
130+
# Log errors if a hook failed
131+
if proc.returncode != 0:
132+
logging.error('{} : {} \n{}'.format(
133+
s, proc.returncode, stderr
134+
))
119135

120-
output = ''
136+
# Remove temporal file
137+
remove(tmpfile)
121138

122139
info = config.get('return_scripts_info', False)
123-
if info:
124-
output = dumps(ran, sort_keys=True, indent=4)
125-
logging.debug(output)
140+
if not info:
141+
return ''
126142

143+
output = dumps(ran, sort_keys=True, indent=4)
144+
logging.info(output)
127145
return output
128146

129147

0 commit comments

Comments
 (0)