blob: 096832da5659ba51d208b1f8f23ffc60c359459d [file] [log] [blame]
Tom Fifieldd3393472013-11-28 12:27:56 +11001#!/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 Stanleyaaaf1c72014-03-18 02:14:55 +000020# python welcome_message.py --change Ia1fea1eab3976f1a9cb89ceb3ce1c6c6a7e79c42
Tom Fifieldd3393472013-11-28 12:27:56 +110021# --change-url \ https://review-dev.openstack.org/81 --project gtest-org/test \
22# --branch master --uploader User A. Example (user@example.com) --commit \
Jeremy Stanleyaaaf1c72014-03-18 02:14:55 +000023# 05508ae633852469d2fd7786a3d6f1d06f87055b --patchset 1 patchset-merged \
24# --ssh-user=user --ssh-key=/home/user/.ssh/id_rsa
Tom Fifieldd3393472013-11-28 12:27:56 +110025# and if this was the first commit from "user@example.com", a message
26# would be posted on review 81.
27
28
29import argparse
30import logging
31import paramiko
32
33import jeepyb.gerritdb
Steve Kowalik5c5a9e12015-08-14 13:56:53 +100034import jeepyb.log as l
Tom Fifieldd3393472013-11-28 12:27:56 +110035
36BASE_DIR = '/home/gerrit2/review_site'
37
38logger = logging.getLogger('welcome_reviews')
Tom Fifieldd3393472013-11-28 12:27:56 +110039
40
41def 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 Stanleyad63ded2014-03-06 23:42:15 +000062 if data[0] == 1:
Tom Fifieldafc6c242013-12-13 08:50:43 +080063 logger.info('We found a newbie: %s', uploader)
Tom Fifieldd3393472013-11-28 12:27:56 +110064 return True
65 else:
66 return False
67
68
K Jonathan Harker364eb142014-07-09 17:40:41 -070069def post_message(commit, gerrit_user, gerrit_ssh_key, message_file):
Jeremy Stanleyaaaf1c72014-03-18 02:14:55 +000070 """Post a welcome message on the patch set specified by the commit."""
Tom Fifieldd3393472013-11-28 12:27:56 +110071
K Jonathan Harker364eb142014-07-09 17:40:41 -070072 default_text = """Thank you for your first contribution to OpenStack.
Tom Fifieldd3393472013-11-28 12:27:56 +110073
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 Narayanan380770f2015-04-20 21:49:04 -070083 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 Fifieldd3393472013-11-28 12:27:56 +110090
91 Thanks again for supporting OpenStack, we look forward to working with you.
92
93 IRC: https://wiki.openstack.org/wiki/IRC
Jeremy Stanley76a1a282014-12-05 03:30:42 +000094 Workflow: http://docs.openstack.org/infra/manual/developers.html
K Jonathan Harker5935b672014-07-09 16:54:00 -070095 Commit Messages: https://wiki.openstack.org/wiki/GitCommitMessages
Tom Fifieldd3393472013-11-28 12:27:56 +110096 """
K Jonathan Harker364eb142014-07-09 17:40:41 -070097
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 Stanleyaaaf1c72014-03-18 02:14:55 +0000108 # 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 Fifieldd3393472013-11-28 12:27:56 +1100126
127
128def 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 Do335ef392014-01-28 20:45:04 -0800137 parser.add_argument('--topic', default=None)
Khai Dobb2eed52015-04-14 15:17:31 -0700138 parser.add_argument('--change-owner', default=None)
Khai Do2158c6b2015-10-17 07:02:41 -0700139 # patchset-abandoned
140 parser.add_argument('--abandoner', default=None)
141 parser.add_argument('--reason', default=None)
Tom Fifieldd3393472013-11-28 12:27:56 +1100142 # change-merged
143 parser.add_argument('--submitter', default=None)
Khai Do2158c6b2015-10-17 07:02:41 -0700144 parser.add_argument('--newrev', default=None)
Tom Fifieldd3393472013-11-28 12:27:56 +1100145 # patchset-created
146 parser.add_argument('--uploader', default=None)
147 parser.add_argument('--patchset', default=None)
Khai Do335ef392014-01-28 20:45:04 -0800148 parser.add_argument('--is-draft', default=None)
Khai Dobb2eed52015-04-14 15:17:31 -0700149 parser.add_argument('--kind', default=None)
Tom Fifieldd3393472013-11-28 12:27:56 +1100150 # for Welcome Message
Jeremy Stanleyaaaf1c72014-03-18 02:14:55 +0000151 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 Harker364eb142014-07-09 17:40:41 -0700155 parser.add_argument('--message-file', dest='message_file', default=None,
156 help='The gerrit welcome message')
Tom Fifieldafc6c242013-12-13 08:50:43 +0800157 # 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 Kowalik5c5a9e12015-08-14 13:56:53 +1000161 l.setup_logging_arguments(parser)
Tom Fifieldd3393472013-11-28 12:27:56 +1100162
163 args = parser.parse_args()
164
Steve Kowalik5c5a9e12015-08-14 13:56:53 +1000165 l.configure_logging(args)
James E. Blairfdc8b5d2014-02-10 09:56:28 -0800166
Tom Fifieldd3393472013-11-28 12:27:56 +1100167 # they're a first-timer, post the message on 1st patchset
Jeremy Stanleyaaaf1c72014-03-18 02:14:55 +0000168 if is_newbie(args.uploader) and args.patchset == '1' and not args.dryrun:
K Jonathan Harker364eb142014-07-09 17:40:41 -0700169 post_message(args.commit, args.ssh_user, args.ssh_key,
170 args.message_file)
Tom Fifieldd3393472013-11-28 12:27:56 +1100171
172if __name__ == "__main__":
173 main()