gerrit-to-github-bot/gerrit_to_github_issues/cli.py
Ian Howell 727e8eb44d Integrate with the github project board
Implement a feature allowing the bot to move issues around on the
project board:
* When a change's commit message includes "WIP" or "DNM",
  the issue will be moved to the "In Progress" column.
* When a change's commit message does *not* include "WIP" or "DNM",
  assume that the change is ready for review, and move it to the
  "Submitted on Gerrit" column.
2020-04-30 14:24:26 -05:00

95 lines
5.3 KiB
Python

# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import logging
import os
import sys
from gerrit_to_github_issues import errors
from gerrit_to_github_issues.engine import update
LOG_FORMAT = '%(asctime)s %(levelname)-8s %(name)s:' \
'%(funcName)s [%(lineno)3d] %(message)s' # noqa
LOG = logging.getLogger(__name__)
def validate(namespace: argparse.Namespace):
arg_dict = vars(namespace)
if not ((arg_dict['github_user'] and arg_dict['github_password']) or arg_dict['github_token']):
raise errors.GithubConfigurationError
return arg_dict
def main():
parser = argparse.ArgumentParser(
prog='gerrit-to-github-issues',
usage='synchronizes GitHub Issues with new changes found in Gerrit',
description='This script evaluates the following logic on open changes from Gerrit:\n'
'1. Check for and extract an issue tag (i.e. "[#3]") from the open change\'s commit message.\n'
'2. Check associated Github Issue for a link to the change. If no such link exists, comment it.\n'
'3. If the associated issue was closed, re-open it and comment on it describing why it was '
're-opened and a link to the Gerrit change that was found.\n'
'4. If the Gerrit change\'s commit message contains a "WIP" or "DNM" tag, add the "wip" label '
'to the issue, remove other process labels (e.g. "ready for review"), and move the issue '
'to the "In Progress" column of the project board.\n'
'5. If no "WIP" or "DNM" tag is found in the change\'s commit message, add the "ready for review" '
'label to the issue, remove other process labels (e.g "wip"), and move the issue '
'to the "Submitted on Gerrit" column of the project board.',
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument('-g', '--gerrit-url', action='store', required=True, type=str,
default=os.getenv('GERRIT_URL', default=None), help='Target Gerrit URL.')
parser.add_argument('-a', '--change-age', action='store', required=False, type=str,
default=None,
help='Specifies how far in the past to search for changes in Gerrit. '
'See https://gerrit-review.googlesource.com/Documentation/user-search.html#age for more '
'details.')
parser.add_argument('--skip-approvals', action='store_true', required=False, default=False,
help='Skips evaluation of change approvals to be written to the bot comments.')
parser.add_argument('-u', '--github-user', action='store', required=False, type=str,
default=os.getenv('GITHUB_USER', default=None),
help='Username to use for GitHub Issues integration. Defaults to GITHUB_USER in '
'environmental variables. Must be used with a password.')
parser.add_argument('-p', '--github-password', action='store', required=False, type=str,
default=os.getenv('GITHUB_PW', default=None),
help='Password to use for GitHub Issues integration. Defaults to GITHUB_PW in '
'environmental variables. Must be used with a username.')
parser.add_argument('-t', '--github-token', action='store', required=False, type=str,
default=os.getenv('GITHUB_TOKEN', default=None),
help='Token to use for GitHub Issues integration. Defaults to GITHUB_TOKEN in '
'environmental variables. This will be preferred over a username/password.')
parser.add_argument('-v', '--verbose', action='store_true', required=False,
default=False, help='Enabled DEBUG level logging.')
parser.add_argument('--log-file', action='store', required=False, type=str,
help='Specifies a file to output logs to. Defaults to `sys.stdout`.')
parser.add_argument('gerrit_repo_name', action='store', type=str, help='Target Gerrit repo.')
parser.add_argument('github_repo_name', action='store', type=str, help='Target Github repo.')
parser.add_argument('github_project_id', action='store', type=int, help='Target Github project board ID.')
ns = parser.parse_args()
args = validate(ns)
verbose = args.pop('verbose')
log_file = args.pop('log_file')
log_settings = {
'format': LOG_FORMAT,
}
if verbose:
log_settings['level'] = logging.DEBUG
else:
log_settings['level'] = logging.INFO
if log_file:
log_settings['filename'] = log_file
else:
log_settings['stream'] = sys.stdout
logging.basicConfig(**log_settings)
update(**args)