def hook(id): hook = Hook.query.get_or_404(id) payload = json.loads(request.data) if set(payload.keys()) == {'zen', 'hook_id'}: # http://developer.github.com/webhooks/#ping-event if hook.gh_id != payload['hook_id']: return 'Wrong hook URL', 400 else: return 'OK' ref_and_sha = get_ref_and_sha(payload) if not ref_and_sha: return 'Failed to fetch ref and commit from payload', 400 ref, sha = ref_and_sha gh_commit = hook.project.gh.git_commit(sha) build = hook.project.builds.filter( Build.gh_commit_ref == ref, Build.gh_commit_sha == gh_commit.sha).first() if not build: build = Build( project=hook.project, status='enqueued', gh_commit_ref=ref, gh_commit_sha=gh_commit.sha, gh_commit_author=gh_commit.author['name'], gh_commit_message=gh_commit.message) build.calculate_number() db.session.add(build) hook_call = HookCall( hook=hook, build=build, gh_payload=payload) db.session.add(hook_call) try: db.session.commit() except sqlalchemy.exc.IntegrityError: # Commit may fail due to "unique_ref_and_sha_within_project" # constraint on Build or "unique_hook_call_within_build" on # HookCall. It means that GitHub called this hook twice # (for example, on push and pull request sync events) # at the same time and Build and HookCall has been just # committed by another transaction. db.session.rollback() return 'OK' tasks.do_job.delay(hook_call_id=hook_call.id) return 'OK'
def test_calculate_number(self): build_1 = Build( project=self.project, gh_commit_sha='a' * 40, gh_commit_author='aromanovich', gh_commit_message='ok', gh_commit_ref='master', status='enqueued') build_1.calculate_number() db.session.add(build_1) db.session.commit() build_2 = Build( project=self.project, gh_commit_sha='b' * 40, gh_commit_author='aromanovich', gh_commit_message='ok', gh_commit_ref='master', status='enqueued') build_2.calculate_number() db.session.add(build_2) db.session.commit() assert build_1.number == 1 assert build_2.number == 2
def hook(id): def need_skip_build(gh_commit, payload): search_string = gh_commit.message if 'pull_request' in payload: pr_title = payload['pull_request']['title'] or '' pr_body = payload['pull_request']['body'] or '' search_string += pr_title + pr_body skip_regexp = re.compile('\[ci\s+skip\]|\[skip\s+ci\]|skip_ci|ci_skip', re.IGNORECASE) if skip_regexp.search(search_string): return True else: return False hook = Hook.query.get_or_404(id) payload = json.loads(request.data) if set(payload.keys()) == {'zen', 'hook_id'}: # http://developer.github.com/webhooks/#ping-event if hook.gh_id != payload['hook_id']: return 'Wrong hook URL', 400 else: return 'OK' ref_and_sha = get_ref_and_sha(payload) if not ref_and_sha: return 'Failed to fetch ref and commit from payload', 400 ref, sha = ref_and_sha gh_commit = hook.project.gh.git_commit(sha) # Skip build if message contains si skip pattern if need_skip_build(gh_commit, payload): return 'OK' build = hook.project.builds.filter( Build.gh_commit_ref == ref, Build.gh_commit_sha == gh_commit.sha).first() if not build: build = Build(project=hook.project, status='enqueued', gh_commit_ref=ref, gh_commit_sha=gh_commit.sha, gh_commit_author=gh_commit.author['name'], gh_commit_message=gh_commit.message) build.calculate_number() db.session.add(build) hook_call = HookCall(hook=hook, build=build, gh_payload=payload) db.session.add(hook_call) try: db.session.commit() except sqlalchemy.exc.IntegrityError: # Commit may fail due to "unique_ref_and_sha_within_project" # constraint on Build or "unique_hook_call_within_build" on # HookCall. It means that GitHub called this hook twice # (for example, on push and pull request sync events) # at the same time and Build and HookCall has been just # committed by another transaction. db.session.rollback() return 'OK' tasks.do_job.delay(hook_call_id=hook_call.id) return 'OK'
def hook(id): def need_skip_build(gh_commit, payload): search_string = gh_commit.message if "pull_request" in payload: pr_title = payload["pull_request"]["title"] or "" pr_body = payload["pull_request"]["body"] or "" search_string += pr_title + pr_body skip_regexp = re.compile("\[ci\s+skip\]|\[skip\s+ci\]|skip_ci|ci_skip", re.IGNORECASE) if skip_regexp.search(search_string): return True else: return False hook = Hook.query.get_or_404(id) payload = json.loads(request.data) if set(payload.keys()) == {"zen", "hook_id"}: # http://developer.github.com/webhooks/#ping-event if hook.gh_id != payload["hook_id"]: return "Wrong hook URL", 400 else: return "OK" ref_and_sha = get_ref_and_sha(payload) if not ref_and_sha: return "Failed to fetch ref and commit from payload", 400 ref, sha = ref_and_sha gh_commit = hook.project.gh.git_commit(sha) # Skip build if message contains si skip pattern if need_skip_build(gh_commit, payload): return "OK" build = hook.project.builds.filter(Build.gh_commit_ref == ref, Build.gh_commit_sha == gh_commit.sha).first() if not build: build = Build( project=hook.project, status="enqueued", gh_commit_ref=ref, gh_commit_sha=gh_commit.sha, gh_commit_author=gh_commit.author["name"], gh_commit_message=gh_commit.message, ) build.calculate_number() db.session.add(build) hook_call = HookCall(hook=hook, build=build, gh_payload=payload) db.session.add(hook_call) try: db.session.commit() except sqlalchemy.exc.IntegrityError: # Commit may fail due to "unique_ref_and_sha_within_project" # constraint on Build or "unique_hook_call_within_build" on # HookCall. It means that GitHub called this hook twice # (for example, on push and pull request sync events) # at the same time and Build and HookCall has been just # committed by another transaction. db.session.rollback() return "OK" tasks.do_job.delay(hook_call_id=hook_call.id) return "OK"