blob: 3f813869b4520a3b6b1a60b83dfb002772c4af06 [file] [log] [blame]
Monty Taylorf45f6ca2012-05-01 17:11:48 -04001#!/usr/bin/env python
2# Copyright (c) 2012 OpenStack, LLC.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16# This script is designed to expire old code reviews that have not been touched
17# using the following rules:
Jonathan Harker450b1a12015-01-06 15:38:19 -050018# 1. if negative comment and no recent activity, expire
Monty Taylorf45f6ca2012-05-01 17:11:48 -040019
Monty Taylor061919f2013-06-02 11:35:42 -040020import argparse
Monty Taylorf45f6ca2012-05-01 17:11:48 -040021import json
22import logging
Monty Taylor061919f2013-06-02 11:35:42 -040023import paramiko
Monty Taylorf45f6ca2012-05-01 17:11:48 -040024
Monty Taylor96ca93b2020-03-24 13:00:16 -050025import jeepyb.log
Steve Kowalik5c5a9e12015-08-14 13:56:53 +100026
Monty Taylorda3bada2012-11-22 09:38:22 -080027logger = logging.getLogger('expire_reviews')
Monty Taylorf45f6ca2012-05-01 17:11:48 -040028
Monty Taylorf45f6ca2012-05-01 17:11:48 -040029
Russell Bryantf98a3a42013-06-25 15:45:52 -040030def expire_patch_set(ssh, patch_id, patch_subject):
Monty Taylor96ca93b2020-03-24 13:00:16 -050031 message = ("Code review expired due to no recent activity"
32 " after a negative review. It can be restored using"
33 " the 'Restore Change' button under the Patch Set"
34 " on the web interface.")
Jeremy Stanley4e5ca4c2012-12-21 17:18:34 +000035 command = ('gerrit review --abandon '
Monty Taylorda3bada2012-11-22 09:38:22 -080036 '--message="{message}" {patch_id}').format(
37 message=message,
38 patch_id=patch_id)
Monty Taylorf45f6ca2012-05-01 17:11:48 -040039
Monty Taylorda3bada2012-11-22 09:38:22 -080040 logger.info('Expiring: %s - %s: %s', patch_id, patch_subject, message)
41 stdin, stdout, stderr = ssh.exec_command(command)
42 if stdout.channel.recv_exit_status() != 0:
43 logger.error(stderr.read())
Monty Taylorf45f6ca2012-05-01 17:11:48 -040044
Monty Taylorf45f6ca2012-05-01 17:11:48 -040045
Monty Taylorda3bada2012-11-22 09:38:22 -080046def main():
Monty Taylorf45f6ca2012-05-01 17:11:48 -040047
Monty Taylorda3bada2012-11-22 09:38:22 -080048 parser = argparse.ArgumentParser()
49 parser.add_argument('user', help='The gerrit admin user')
50 parser.add_argument('ssh_key', help='The gerrit admin SSH key file')
Jonathan Harker450b1a12015-01-06 15:38:19 -050051 parser.add_argument('--age', dest='age', default='1w',
52 help='The minimum age of a review to expire')
Monty Taylor96ca93b2020-03-24 13:00:16 -050053 jeepyb.log.setup_logging_arguments(parser)
Monty Taylorda3bada2012-11-22 09:38:22 -080054 options = parser.parse_args()
Monty Taylor96ca93b2020-03-24 13:00:16 -050055 jeepyb.log.configure_logging(options)
Monty Taylorf45f6ca2012-05-01 17:11:48 -040056
Monty Taylorda3bada2012-11-22 09:38:22 -080057 GERRIT_USER = options.user
58 GERRIT_SSH_KEY = options.ssh_key
Jonathan Harker450b1a12015-01-06 15:38:19 -050059 EXPIRY_AGE = options.age
Monty Taylorf45f6ca2012-05-01 17:11:48 -040060
Monty Taylorda3bada2012-11-22 09:38:22 -080061 logger.info('Starting expire reviews')
62 logger.info('Connecting to Gerrit')
63
64 ssh = paramiko.SSHClient()
65 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
66 ssh.connect('localhost', username=GERRIT_USER,
67 key_filename=GERRIT_SSH_KEY, port=29418)
68
Monty Taylorda3bada2012-11-22 09:38:22 -080069 # Query all reviewed with no activity for 1 week
70 logger.info('Searching no activity on negative review for 1 week')
71 stdin, stdout, stderr = ssh.exec_command(
72 'gerrit query --current-patch-set --all-approvals'
Jonathan Harker450b1a12015-01-06 15:38:19 -050073 ' --format JSON status:reviewed age:' + EXPIRY_AGE)
Monty Taylorda3bada2012-11-22 09:38:22 -080074
75 for line in stdout:
76 row = json.loads(line)
Ramy Asselinc3a62192016-01-13 16:49:53 -080077 if 'rowCount' not in row and 'open' in row and row['open']:
Monty Taylorda3bada2012-11-22 09:38:22 -080078 # Search for negative approvals
79 for approval in row['currentPatchSet']['approvals']:
Jeremy Stanleyd8c51c62013-07-15 14:51:56 +000080 if approval['value'] in ('-1', '-2'):
Monty Taylorda3bada2012-11-22 09:38:22 -080081 expire_patch_set(ssh,
82 row['currentPatchSet']['revision'],
Russell Bryantf98a3a42013-06-25 15:45:52 -040083 row['subject'])
Monty Taylorda3bada2012-11-22 09:38:22 -080084 break
85
86 logger.info('End expire review')
Jeremy Stanley06efb062013-04-15 20:18:16 +000087
Monty Taylor96ca93b2020-03-24 13:00:16 -050088
Jeremy Stanley06efb062013-04-15 20:18:16 +000089if __name__ == "__main__":
90 main()