Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 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 | |
| 15 | # This is designed to be called by a gerrit hook. It searched new |
| 16 | # patchsets for those from a first time commiter, then posts a helpful |
| 17 | # message welcoming them to the community and explaining the review process |
| 18 | # |
| 19 | # For example, this might be called as follows |
Jeremy Stanley | aaaf1c7 | 2014-03-18 02:14:55 +0000 | [diff] [blame] | 20 | # python welcome_message.py --change Ia1fea1eab3976f1a9cb89ceb3ce1c6c6a7e79c42 |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 21 | # --change-url \ https://review-dev.openstack.org/81 --project gtest-org/test \ |
| 22 | # --branch master --uploader User A. Example (user@example.com) --commit \ |
Jeremy Stanley | aaaf1c7 | 2014-03-18 02:14:55 +0000 | [diff] [blame] | 23 | # 05508ae633852469d2fd7786a3d6f1d06f87055b --patchset 1 patchset-merged \ |
| 24 | # --ssh-user=user --ssh-key=/home/user/.ssh/id_rsa |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 25 | # and if this was the first commit from "user@example.com", a message |
| 26 | # would be posted on review 81. |
| 27 | |
| 28 | |
| 29 | import argparse |
| 30 | import logging |
| 31 | import paramiko |
| 32 | |
| 33 | import jeepyb.gerritdb |
Steve Kowalik | 5c5a9e1 | 2015-08-14 13:56:53 +1000 | [diff] [blame] | 34 | import jeepyb.log as l |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 35 | |
| 36 | BASE_DIR = '/home/gerrit2/review_site' |
| 37 | |
| 38 | logger = logging.getLogger('welcome_reviews') |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 39 | |
| 40 | |
| 41 | def is_newbie(uploader): |
| 42 | """Determine if the owner of the patch is a first-timer.""" |
| 43 | |
| 44 | # Retrieve uploader email |
| 45 | try: |
| 46 | searchkey = uploader[uploader.rindex("(") + 1:-1] |
| 47 | except ValueError: |
| 48 | logger.info('Couldnt get email for %s', uploader) |
| 49 | return False |
| 50 | |
| 51 | # this query looks for all distinct patchsets for the given |
| 52 | # user. If there's only 1, they're a first-timer. |
| 53 | query = """SELECT COUNT(DISTINCT p.change_id + p.patch_set_id) |
| 54 | FROM patch_sets p, account_external_ids a |
| 55 | WHERE a.email_address = %s |
| 56 | AND a.account_id = p.uploader_account_id;""" |
| 57 | |
| 58 | cursor = jeepyb.gerritdb.connect().cursor() |
| 59 | cursor.execute(query, searchkey) |
| 60 | data = cursor.fetchone() |
| 61 | if data: |
Jeremy Stanley | ad63ded | 2014-03-06 23:42:15 +0000 | [diff] [blame] | 62 | if data[0] == 1: |
Tom Fifield | afc6c24 | 2013-12-13 08:50:43 +0800 | [diff] [blame] | 63 | logger.info('We found a newbie: %s', uploader) |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 64 | return True |
| 65 | else: |
| 66 | return False |
| 67 | |
| 68 | |
K Jonathan Harker | 364eb14 | 2014-07-09 17:40:41 -0700 | [diff] [blame] | 69 | def post_message(commit, gerrit_user, gerrit_ssh_key, message_file): |
Jeremy Stanley | aaaf1c7 | 2014-03-18 02:14:55 +0000 | [diff] [blame] | 70 | """Post a welcome message on the patch set specified by the commit.""" |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 71 | |
K Jonathan Harker | 364eb14 | 2014-07-09 17:40:41 -0700 | [diff] [blame] | 72 | default_text = """Thank you for your first contribution to OpenStack. |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 73 | |
| 74 | Your patch will now be tested automatically by OpenStack testing frameworks |
| 75 | and once the automatic tests pass, it will be reviewed by other friendly |
| 76 | developers. They will give you feedback and may require you to refine it. |
| 77 | |
| 78 | People seldom get their patch approved on the first try, so don't be |
| 79 | concerned if requested to make corrections. Feel free to modify your patch |
| 80 | and resubmit a new change-set. |
| 81 | |
| 82 | Patches usually take 3 to 7 days to be reviewed so be patient and be |
Ganesh Narayanan | 380770f | 2015-04-20 21:49:04 -0700 | [diff] [blame] | 83 | available on IRC to ask and answer questions about your work. Also it |
| 84 | takes generally at least a couple of weeks for cores to get around to |
| 85 | reviewing code. The more you participate in the community the more |
| 86 | rewarding it is for you. You may also notice that the more you get to know |
| 87 | people and get to be known, the faster your patches will be reviewed and |
| 88 | eventually approved. Get to know others and become known by doing code |
| 89 | reviews: anybody can do it, and it's a great way to learn the code base. |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 90 | |
| 91 | Thanks again for supporting OpenStack, we look forward to working with you. |
| 92 | |
| 93 | IRC: https://wiki.openstack.org/wiki/IRC |
Jeremy Stanley | 76a1a28 | 2014-12-05 03:30:42 +0000 | [diff] [blame] | 94 | Workflow: http://docs.openstack.org/infra/manual/developers.html |
K Jonathan Harker | 5935b67 | 2014-07-09 16:54:00 -0700 | [diff] [blame] | 95 | Commit Messages: https://wiki.openstack.org/wiki/GitCommitMessages |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 96 | """ |
K Jonathan Harker | 364eb14 | 2014-07-09 17:40:41 -0700 | [diff] [blame] | 97 | |
| 98 | if message_file: |
| 99 | try: |
| 100 | with open(message_file, 'r') as _file: |
| 101 | welcome_text = _file.read() |
| 102 | except (OSError, IOError): |
| 103 | logger.exception("Could not open message file") |
| 104 | welcome_text = default_text |
| 105 | else: |
| 106 | welcome_text = default_text |
| 107 | |
Jeremy Stanley | aaaf1c7 | 2014-03-18 02:14:55 +0000 | [diff] [blame] | 108 | # post the above message, using ssh. |
| 109 | command = ('gerrit review ' |
| 110 | '--message="{message}" {commit}').format( |
| 111 | message=welcome_text, |
| 112 | commit=commit) |
| 113 | logger.info('Welcoming: %s', commit) |
| 114 | ssh = paramiko.SSHClient() |
| 115 | ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
| 116 | ssh.connect('localhost', username=gerrit_user, |
| 117 | key_filename=gerrit_ssh_key, port=29418) |
| 118 | stdin, stdout, stderr = ssh.exec_command(command) |
| 119 | stdout_text = stdout.read() |
| 120 | stderr_text = stderr.read() |
| 121 | ssh.close() |
| 122 | if stdout_text: |
| 123 | logger.debug('stdout: %s' % stdout_text) |
| 124 | if stderr_text: |
| 125 | logger.error('stderr: %s' % stderr_text) |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 126 | |
| 127 | |
| 128 | def main(): |
| 129 | parser = argparse.ArgumentParser() |
| 130 | parser.add_argument('hook') |
| 131 | # common |
| 132 | parser.add_argument('--change', default=None) |
| 133 | parser.add_argument('--change-url', default=None) |
| 134 | parser.add_argument('--project', default=None) |
| 135 | parser.add_argument('--branch', default=None) |
| 136 | parser.add_argument('--commit', default=None) |
Khai Do | 335ef39 | 2014-01-28 20:45:04 -0800 | [diff] [blame] | 137 | parser.add_argument('--topic', default=None) |
Khai Do | bb2eed5 | 2015-04-14 15:17:31 -0700 | [diff] [blame] | 138 | parser.add_argument('--change-owner', default=None) |
Khai Do | 2158c6b | 2015-10-17 07:02:41 -0700 | [diff] [blame] | 139 | # patchset-abandoned |
| 140 | parser.add_argument('--abandoner', default=None) |
| 141 | parser.add_argument('--reason', default=None) |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 142 | # change-merged |
| 143 | parser.add_argument('--submitter', default=None) |
Khai Do | 2158c6b | 2015-10-17 07:02:41 -0700 | [diff] [blame] | 144 | parser.add_argument('--newrev', default=None) |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 145 | # patchset-created |
| 146 | parser.add_argument('--uploader', default=None) |
| 147 | parser.add_argument('--patchset', default=None) |
Khai Do | 335ef39 | 2014-01-28 20:45:04 -0800 | [diff] [blame] | 148 | parser.add_argument('--is-draft', default=None) |
Khai Do | bb2eed5 | 2015-04-14 15:17:31 -0700 | [diff] [blame] | 149 | parser.add_argument('--kind', default=None) |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 150 | # for Welcome Message |
Jeremy Stanley | aaaf1c7 | 2014-03-18 02:14:55 +0000 | [diff] [blame] | 151 | parser.add_argument('--ssh-user', dest='ssh_user', |
| 152 | help='The gerrit welcome message user') |
| 153 | parser.add_argument('--ssh-key', dest='ssh_key', |
| 154 | help='The gerrit welcome message SSH key file') |
K Jonathan Harker | 364eb14 | 2014-07-09 17:40:41 -0700 | [diff] [blame] | 155 | parser.add_argument('--message-file', dest='message_file', default=None, |
| 156 | help='The gerrit welcome message') |
Tom Fifield | afc6c24 | 2013-12-13 08:50:43 +0800 | [diff] [blame] | 157 | # Don't actually post the message |
| 158 | parser.add_argument('--dryrun', dest='dryrun', action='store_true') |
| 159 | parser.add_argument('--no-dryrun', dest='dryrun', action='store_false') |
| 160 | parser.set_defaults(dryrun=False) |
Steve Kowalik | 5c5a9e1 | 2015-08-14 13:56:53 +1000 | [diff] [blame] | 161 | l.setup_logging_arguments(parser) |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 162 | |
| 163 | args = parser.parse_args() |
| 164 | |
Steve Kowalik | 5c5a9e1 | 2015-08-14 13:56:53 +1000 | [diff] [blame] | 165 | l.configure_logging(args) |
James E. Blair | fdc8b5d | 2014-02-10 09:56:28 -0800 | [diff] [blame] | 166 | |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 167 | # they're a first-timer, post the message on 1st patchset |
Jeremy Stanley | aaaf1c7 | 2014-03-18 02:14:55 +0000 | [diff] [blame] | 168 | if is_newbie(args.uploader) and args.patchset == '1' and not args.dryrun: |
K Jonathan Harker | 364eb14 | 2014-07-09 17:40:41 -0700 | [diff] [blame] | 169 | post_message(args.commit, args.ssh_user, args.ssh_key, |
| 170 | args.message_file) |
Tom Fifield | d339347 | 2013-11-28 12:27:56 +1100 | [diff] [blame] | 171 | |
| 172 | if __name__ == "__main__": |
| 173 | main() |