Skip to content

Commit a19a6cf

Browse files
authored
Fix some issues with github triggers (#253)
Fixes #246
1 parent 9d30645 commit a19a6cf

File tree

1 file changed

+76
-58
lines changed

1 file changed

+76
-58
lines changed

src/github/trigger/trigger.py

Lines changed: 76 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from requests.adapters import HTTPAdapter
1212
from urllib3.util.retry import Retry
1313

14-
from flask import Response, request, g
14+
from flask import request, g, jsonify
1515
from pyinfraboxutils.ibflask import app
1616

1717
from pyinfraboxutils import get_env, get_logger
@@ -23,8 +23,7 @@
2323
logger = get_logger("github")
2424

2525
def res(status, message):
26-
Response.status = status
27-
return {"message": message}
26+
return jsonify({"message": message}), status
2827

2928
def remove_ref(ref):
3029
return "/".join(ref.split("/")[2:])
@@ -189,7 +188,7 @@ def create_push(self, c, repository, branch, tag):
189188

190189
if not result:
191190
status_url = repository['statuses_url'].format(sha=c['id'])
192-
result = self.execute('''
191+
self.execute('''
193192
INSERT INTO "commit" (
194193
id, message, repository_id, timestamp,
195194
author_name, author_email, author_username,
@@ -200,7 +199,7 @@ def create_push(self, c, repository, branch, tag):
200199
%s, %s, %s,
201200
%s, %s, %s,
202201
%s, %s, %s)
203-
RETURNING id
202+
ON CONFLICT DO NOTHING
204203
''', [c['id'],
205204
c['message'],
206205
repo_id,
@@ -215,7 +214,7 @@ def create_push(self, c, repository, branch, tag):
215214
branch,
216215
project_id,
217216
tag,
218-
status_url])
217+
status_url], fetch=False)
219218

220219
build_id = self.create_build(commit_id, project_id)
221220
clone_url = repository['clone_url']
@@ -297,24 +296,29 @@ def handle_pull_request(self, event):
297296
return res(200, 'no token')
298297

299298

300-
commits = get_commits(event['pull_request']['commits_url'], token)
299+
for _ in range(0, 3):
300+
commits = get_commits(event['pull_request']['commits_url'], token)
301+
hc = None
302+
for commit in commits:
303+
if commit['sha'] == event['pull_request']['head']['sha']:
304+
hc = commit
305+
break
301306

302-
hc = None
303-
for commit in commits:
304-
if commit['sha'] == event['pull_request']['head']['sha']:
305-
hc = commit
306-
break
307+
if not hc:
308+
# We might receive the pr event before the push event.
309+
# this may lead to a situation that we cannot yet
310+
# find the actual commit. Wait some time and retry.
311+
eventlet.sleep(1)
307312

308313
if not hc:
309314
logger.error('Head commit not found: %s', event['pull_request']['head']['sha'])
310-
logger.error(json.dumps(commits, indent=4))
311315
return res(500, 'Internal Server Error')
312316

313317
is_fork = event['pull_request']['head']['repo']['fork']
314318

315319
result = self.execute('''
316320
SELECT id FROM pull_request WHERE project_id = %s and github_pull_request_id = %s
317-
''', [repo_id, event['pull_request']['id']])
321+
''', [project_id, event['pull_request']['id']])
318322

319323
if not result:
320324
result = self.execute('''
@@ -327,13 +331,8 @@ def handle_pull_request(self, event):
327331
event['pull_request']['html_url']
328332
])
329333
pr_id = result[0][0]
330-
331-
result = self.execute('''
332-
SELECT id
333-
FROM "commit"
334-
WHERE id = %s
335-
AND project_id = %s
336-
''', [hc['sha'], project_id])
334+
else:
335+
pr_id = result[0][0]
337336

338337
committer_login = None
339338
if hc.get('committer', None):
@@ -362,48 +361,67 @@ def handle_pull_request(self, event):
362361
author_name = author.get('name', 'unkown')
363362
author_date = author.get('date', datetime.now())
364363

365-
if not result:
366-
result = self.execute('''
367-
INSERT INTO "commit" (
368-
id, message, repository_id, timestamp,
369-
author_name, author_email, author_username,
370-
committer_name, committer_email, committer_username, url, project_id,
371-
branch, pull_request_id, github_status_url)
372-
VALUES (%s, %s, %s,
373-
%s, %s, %s,
374-
%s, %s, %s,
375-
%s, %s, %s,
376-
%s, %s, %s)
377-
RETURNING id
378-
''', [hc['sha'], hc['commit']['message'],
379-
repo_id, author_date, author_name,
380-
author_email, author_login,
381-
hc['commit']['committer']['name'],
382-
hc['commit']['committer']['email'],
383-
committer_login, hc['html_url'], project_id, branch, pr_id,
384-
event['pull_request']['statuses_url']])
385-
else:
364+
commit_id = hc['sha']
365+
result = self.execute('''
366+
SELECT id
367+
FROM "commit"
368+
WHERE id = %s
369+
AND project_id = %s
370+
''', [commit_id, project_id])
371+
372+
if result:
386373
if event['action'] == 'opened':
387374
return res(200, 'build already triggered')
388375

389-
commit_id = result[0][0]
390-
391-
if self.has_active_build(commit_id, project_id):
392-
return res(200, 'build already triggered')
393-
394-
build_id = self.create_build(commit_id, project_id)
395-
396-
clone_url = event['repository']['clone_url']
397-
398-
if event['repository']['private']:
399-
clone_url = event['repository']['ssh_url']
400-
401-
self.create_job(event['pull_request']['head']['sha'],
402-
clone_url,
403-
build_id, project_id, None, env=env, fork=is_fork)
376+
self.execute('''
377+
INSERT INTO "commit" (
378+
id, message, repository_id, timestamp,
379+
author_name, author_email, author_username,
380+
committer_name, committer_email, committer_username, url, project_id,
381+
branch, pull_request_id, github_status_url)
382+
VALUES (%s, %s, %s,
383+
%s, %s, %s,
384+
%s, %s, %s,
385+
%s, %s, %s,
386+
%s, %s, %s)
387+
ON CONFLICT ON CONSTRAINT commit_pkey DO UPDATE
388+
SET pull_request_id = %s
389+
''', [hc['sha'], hc['commit']['message'],
390+
repo_id, author_date, author_name,
391+
author_email, author_login,
392+
hc['commit']['committer']['name'],
393+
hc['commit']['committer']['email'],
394+
committer_login, hc['html_url'], project_id, branch, pr_id,
395+
event['pull_request']['statuses_url'], pr_id], fetch=False)
396+
397+
# Abort jobs which are still running on the same PR
398+
self.execute('''
399+
INSERT INTO abort
400+
SELECT j.id, null
401+
FROM job j
402+
JOIN build b
403+
ON b.id = j.build_id
404+
JOIN commit c
405+
ON b.commit_id = c.id
406+
AND b.project_id = c.project_id
407+
WHERE
408+
c.pull_request_id = %s AND
409+
j.state in ('queued', 'scheduled', 'running') AND
410+
c.id != %s
411+
''', [pr_id, commit_id], fetch=False)
412+
413+
if not self.has_active_build(commit_id, project_id):
414+
build_id = self.create_build(commit_id, project_id)
415+
clone_url = event['repository']['clone_url']
416+
417+
if event['repository']['private']:
418+
clone_url = event['repository']['ssh_url']
419+
420+
self.create_job(event['pull_request']['head']['sha'],
421+
clone_url,
422+
build_id, project_id, None, env=env, fork=is_fork)
404423

405424
g.db.commit()
406-
407425
return res(200, 'ok')
408426

409427

0 commit comments

Comments
 (0)