push.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/opt/mcfi/venv/bin/python3
  2. #
  3. # This is a script for notifying the forge when PUSH happens. It's called after
  4. # a "git push" by the post-receive hook.
  5. from pygit2 import Repository
  6. import os, requests, sys
  7. if len(sys.argv) != 4:
  8. print(sys.argv[0] + ': Bad input arguments.')
  9. exit()
  10. # ENV variable set by Git
  11. GIT_DIR = os.environ['GIT_DIR']
  12. # ENV variable set by the webserver (HTTPD) when it authenticated the user
  13. # before allowing to push content via HTTPS. Probably empty if pushed via
  14. # SSH.
  15. # TODO check if SSH sets any kind of "USER" variable
  16. REMOTE_USER = os.environ['REMOTE_USER']
  17. # Arguments passed from the git post-receive hook
  18. oldrev = sys.argv[1]
  19. newrev = sys.argv[2]
  20. refname = sys.argv[3]
  21. # Get absolute path. By default Git chdir to repository's .git folder.
  22. repository_path = os.path.abspath(GIT_DIR)
  23. # Split at the second / from the right and remove .git.
  24. # Example: /var/lib/gitolite3/repositories/zplus/repo.git => zplus/repo
  25. repository_name = '/'.join(repository_path.rsplit('/', 2)[-2:])[:-4]
  26. repository = Repository(repository_path)
  27. # Retrieve a Git object.
  28. # https://www.pygit2.org/objects.html
  29. commit = repository.get(newrev)
  30. # Collect commits
  31. commits = []
  32. while True:
  33. if commit.id.__str__() == oldrev:
  34. break
  35. commits.append({
  36. 'id': commit.id.__str__(),
  37. 'author': {
  38. 'name': commit.author.name,
  39. 'email': commit.author.email,
  40. 'time': commit.author.time
  41. },
  42. 'committer': {
  43. 'name': commit.committer.name,
  44. 'email': commit.committer.email,
  45. 'time': commit.committer.time
  46. },
  47. 'message': commit.message,
  48. 'commit_time': commit.commit_time
  49. })
  50. if commit.parents is None or len(commit.parents) == 0:
  51. break
  52. commit = commit.parents[0]
  53. # Callback the local forge to notify the git push
  54. requests.post('http://localhost:9000/git-hooks-post-receive', json={
  55. 'REMOTE_USER': REMOTE_USER,
  56. 'GIT_DIR': GIT_DIR,
  57. 'oldrev': oldrev,
  58. 'newrev': newrev,
  59. 'refname': refname,
  60. 'repository_name': repository_name,
  61. 'commits': commits })