Gerrit Project Builder Tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

welcome_message.py 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #!/usr/bin/env python
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. # This is designed to be called by a gerrit hook. It searched new
  15. # patchsets for those from a first time commiter, then posts a helpful
  16. # message welcoming them to the community and explaining the review process
  17. #
  18. # For example, this might be called as follows
  19. # python welcome_message.py --change Ia1fea1eab3976f1a9cb89ceb3ce1c6c6a7e79c42
  20. # --change-url \ https://review-dev.openstack.org/81 --project gtest-org/test \
  21. # --branch master --uploader User A. Example (user@example.com) --commit \
  22. # 05508ae633852469d2fd7786a3d6f1d06f87055b --patchset 1 patchset-merged \
  23. # --ssh-user=user --ssh-key=/home/user/.ssh/id_rsa
  24. # and if this was the first commit from "user@example.com", a message
  25. # would be posted on review 81.
  26. import argparse
  27. import logging
  28. import paramiko
  29. import jeepyb.gerritdb
  30. import jeepyb.log as l
  31. BASE_DIR = '/home/gerrit2/review_site'
  32. logger = logging.getLogger('welcome_reviews')
  33. def is_newbie(uploader):
  34. """Determine if the owner of the patch is a first-timer."""
  35. # Retrieve uploader email
  36. try:
  37. searchkey = uploader[uploader.rindex("(") + 1:-1]
  38. except ValueError:
  39. logger.info('Couldnt get email for %s', uploader)
  40. return False
  41. # this query looks for all distinct patchsets for the given
  42. # user. If there's only 1, they're a first-timer.
  43. query = """SELECT COUNT(DISTINCT p.change_id + p.patch_set_id)
  44. FROM patch_sets p, account_external_ids a
  45. WHERE a.email_address = %s
  46. AND a.account_id = p.uploader_account_id;"""
  47. cursor = jeepyb.gerritdb.connect().cursor()
  48. cursor.execute(query, searchkey)
  49. data = cursor.fetchone()
  50. if data:
  51. if data[0] == 1:
  52. logger.info('We found a newbie: %s', uploader)
  53. return True
  54. else:
  55. return False
  56. def post_message(commit, gerrit_user, gerrit_ssh_key, message_file):
  57. """Post a welcome message on the patch set specified by the commit."""
  58. default_text = """Thank you for your first contribution to OpenStack.
  59. Your patch will now be tested automatically by OpenStack testing frameworks
  60. and once the automatic tests pass, it will be reviewed by other friendly
  61. developers. They will give you feedback and may require you to refine it.
  62. People seldom get their patch approved on the first try, so don't be
  63. concerned if requested to make corrections. Feel free to modify your patch
  64. and resubmit a new change-set.
  65. Patches usually take 3 to 7 days to be reviewed so be patient and be
  66. available on IRC to ask and answer questions about your work. Also it
  67. takes generally at least a couple of weeks for cores to get around to
  68. reviewing code. The more you participate in the community the more
  69. rewarding it is for you. You may also notice that the more you get to know
  70. people and get to be known, the faster your patches will be reviewed and
  71. eventually approved. Get to know others and become known by doing code
  72. reviews: anybody can do it, and it's a great way to learn the code base.
  73. Thanks again for supporting OpenStack, we look forward to working with you.
  74. IRC: https://wiki.openstack.org/wiki/IRC
  75. Workflow: https://docs.openstack.org/infra/manual/developers.html
  76. Commit Messages: https://wiki.openstack.org/wiki/GitCommitMessages
  77. """
  78. if message_file:
  79. try:
  80. with open(message_file, 'r') as _file:
  81. welcome_text = _file.read()
  82. except (OSError, IOError):
  83. logger.exception("Could not open message file")
  84. welcome_text = default_text
  85. else:
  86. welcome_text = default_text
  87. # post the above message, using ssh.
  88. command = ('gerrit review '
  89. '--message="{message}" {commit}').format(
  90. message=welcome_text,
  91. commit=commit)
  92. logger.info('Welcoming: %s', commit)
  93. ssh = paramiko.SSHClient()
  94. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  95. ssh.connect('localhost', username=gerrit_user,
  96. key_filename=gerrit_ssh_key, port=29418)
  97. stdin, stdout, stderr = ssh.exec_command(command)
  98. stdout_text = stdout.read()
  99. stderr_text = stderr.read()
  100. ssh.close()
  101. if stdout_text:
  102. logger.debug('stdout: %s' % stdout_text)
  103. if stderr_text:
  104. logger.error('stderr: %s' % stderr_text)
  105. def main():
  106. parser = argparse.ArgumentParser()
  107. parser.add_argument('hook')
  108. # common
  109. parser.add_argument('--change', default=None)
  110. parser.add_argument('--change-url', default=None)
  111. parser.add_argument('--project', default=None)
  112. parser.add_argument('--branch', default=None)
  113. parser.add_argument('--commit', default=None)
  114. parser.add_argument('--topic', default=None)
  115. parser.add_argument('--change-owner', default=None)
  116. # patchset-abandoned
  117. parser.add_argument('--abandoner', default=None)
  118. parser.add_argument('--reason', default=None)
  119. # change-merged
  120. parser.add_argument('--submitter', default=None)
  121. parser.add_argument('--newrev', default=None)
  122. # patchset-created
  123. parser.add_argument('--uploader', default=None)
  124. parser.add_argument('--patchset', default=None)
  125. parser.add_argument('--is-draft', default=None)
  126. parser.add_argument('--kind', default=None)
  127. # for Welcome Message
  128. parser.add_argument('--ssh-user', dest='ssh_user',
  129. help='The gerrit welcome message user')
  130. parser.add_argument('--ssh-key', dest='ssh_key',
  131. help='The gerrit welcome message SSH key file')
  132. parser.add_argument('--message-file', dest='message_file', default=None,
  133. help='The gerrit welcome message')
  134. # Don't actually post the message
  135. parser.add_argument('--dryrun', dest='dryrun', action='store_true')
  136. parser.add_argument('--no-dryrun', dest='dryrun', action='store_false')
  137. parser.set_defaults(dryrun=False)
  138. l.setup_logging_arguments(parser)
  139. args = parser.parse_args()
  140. l.configure_logging(args)
  141. # they're a first-timer, post the message on 1st patchset
  142. if is_newbie(args.uploader) and args.patchset == '1' and not args.dryrun:
  143. post_message(args.commit, args.ssh_user, args.ssh_key,
  144. args.message_file)
  145. if __name__ == "__main__":
  146. main()