blob: a949cf20e74411da1fcb46bea7d528024482c860 [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
20# python welcome_message.py -change Ia1fea1eab3976f1a9cb89ceb3ce1c6c6a7e79c42
21# --change-url \ https://review-dev.openstack.org/81 --project gtest-org/test \
22# --branch master --uploader User A. Example (user@example.com) --commit \
23# 05508ae633852469d2fd7786a3d6f1d06f87055b --patchset 1 patchset-merged user \
24# ~/.ssh/id_rsa
25# 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
34
35BASE_DIR = '/home/gerrit2/review_site'
36
37logger = logging.getLogger('welcome_reviews')
38logger.setLevel(logging.INFO)
39
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:
62 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
69def post_message(change_id, gerrit_user, gerrit_ssh_key):
70 """Post a welcome message on the patch set specified by the change_id."""
71
72 welcome_text = """Thank you for your first contribution to OpenStack.
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
83 available on IRC to ask and answer questions about your work. The more you
84 participate in the community the more rewarding it is for you. You may also
85 notice that the more you get to know people and get to be known, the faster
86 your patches will be reviewed and eventually approved. Get to know others
87 and become known by doing code reviews: anybody can do it, and it's a
88 great way to learn the code base.
89
90 Thanks again for supporting OpenStack, we look forward to working with you.
91
92 IRC: https://wiki.openstack.org/wiki/IRC
93 Workflow: https://wiki.openstack.org/wiki/Gerrit_Workflow
94 """
95 # get the patch_id
96 query = """SELECT change_id FROM patch_sets WHERE change_id = %s;"""
97
98 cursor = jeepyb.gerritdb.connect().cursor()
99 cursor.execute(query, change_id)
100 data = cursor.fetchone()
101 if data[0]:
102 # post the above message, using ssh.
103 command = ('gerrit review '
104 '--message="{message}" {patch_id}').format(
105 message=welcome_text,
106 patch_id=data)
107 logger.info('Welcoming: %s', data[0])
108 ssh = paramiko.SSHClient()
109 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
110 ssh.connect('localhost', username=gerrit_user,
111 key_filename=gerrit_ssh_key, port=29418)
112 stdin, stdout, stderr = ssh.exec_command(command)
113
114 else:
115 logger.info('Unable to find patch_id for change_id=%s', change_id)
116
117
118def main():
119 parser = argparse.ArgumentParser()
120 parser.add_argument('hook')
121 # common
122 parser.add_argument('--change', default=None)
123 parser.add_argument('--change-url', default=None)
124 parser.add_argument('--project', default=None)
125 parser.add_argument('--branch', default=None)
126 parser.add_argument('--commit', default=None)
Khai Do335ef392014-01-28 20:45:04 -0800127 parser.add_argument('--topic', default=None)
Tom Fifieldd3393472013-11-28 12:27:56 +1100128 # change-merged
129 parser.add_argument('--submitter', default=None)
130 # patchset-created
131 parser.add_argument('--uploader', default=None)
132 parser.add_argument('--patchset', default=None)
Khai Do335ef392014-01-28 20:45:04 -0800133 parser.add_argument('--is-draft', default=None)
Tom Fifieldd3393472013-11-28 12:27:56 +1100134 # for Welcome Message
135 parser.add_argument('user', help='The gerrit admin user')
136 parser.add_argument('ssh_key', help='The gerrit admin SSH key file')
Tom Fifieldafc6c242013-12-13 08:50:43 +0800137 # Don't actually post the message
138 parser.add_argument('--dryrun', dest='dryrun', action='store_true')
139 parser.add_argument('--no-dryrun', dest='dryrun', action='store_false')
140 parser.set_defaults(dryrun=False)
Tom Fifieldd3393472013-11-28 12:27:56 +1100141
142 args = parser.parse_args()
143
144 # they're a first-timer, post the message on 1st patchset
Tom Fifieldafc6c242013-12-13 08:50:43 +0800145 if is_newbie(args.uploader) and args.patchset == 1 and not args.dryrun:
Tom Fifieldd3393472013-11-28 12:27:56 +1100146 post_message(args.change, args.user, args.ssh_key)
147
148if __name__ == "__main__":
149 main()