#!/usr/bin/env vpython3 # Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. # # Use of this source code is governed by a BSD-style license # that can be found in the LICENSE file in the root of the source # tree. An additional intellectual property rights grant can be found # in the file PATENTS. All contributing project authors may # be found in the AUTHORS file in the root of the source tree. """Script to auto-update the WebRTC source version in call/version.cc""" import argparse import datetime import logging import os import re import subprocess import sys UPDATE_BRANCH_NAME = 'webrtc_version_update' SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) CHECKOUT_SRC_DIR = os.path.realpath( os.path.join(SCRIPT_DIR, os.pardir, os.pardir)) NOTIFY_EMAIL = 'webrtc-trooper@webrtc.org' def _remove_previous_update_branch(): active_branch, branches = _get_branches() if active_branch == UPDATE_BRANCH_NAME: active_branch = 'main' if UPDATE_BRANCH_NAME in branches: logging.info('Removing previous update branch (%s)', UPDATE_BRANCH_NAME) subprocess.check_call(['git', 'checkout', active_branch]) subprocess.check_call(['git', 'branch', '-D', UPDATE_BRANCH_NAME]) logging.info('No branch to remove') def _get_last_author(): """Returns a string with the author of the last commit.""" author = subprocess.check_output( ['git', 'log', '-1', '--pretty=format:"%an"'], universal_newlines=True).splitlines() return author def _get_branches(): """Returns a tuple (active, branches). 'active' is a string with name of the currently active branch, while 'branches' is the list of all branches. """ lines = subprocess.check_output(['git', 'branch'], universal_newlines=True).splitlines() branches = [] active = '' for line in lines: if '*' in line: # The assumption is that the first char will always be the '*'. active = line[1:].strip() branches.append(active) else: branch = line.strip() if branch: branches.append(branch) return active, branches def _create_update_branch(): logging.info('Creating update branch: %s', UPDATE_BRANCH_NAME) subprocess.check_call(['git', 'checkout', '-b', UPDATE_BRANCH_NAME]) def _update_webrtc_version(filename): with open(filename, 'rb') as file: content = file.read().decode('utf-8') date = datetime.datetime.utcnow() # pylint: disable=line-too-long new_content = re.sub( r'WebRTC source stamp [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}', r'WebRTC source stamp %02d-%02d-%02dT%02d:%02d:%02d' % (date.year, date.month, date.day, date.hour, date.minute, date.second), content, flags=re.MULTILINE) # pylint: enable=line-too-long with open(filename, 'wb') as file: file.write(new_content.encode('utf-8')) def _is_tree_clean(): stdout = subprocess.check_output(['git', 'status', '--porcelain'], universal_newlines=True) if len(stdout) == 0: return True return False def _local_commit(): logging.info('Committing changes locally.') date = datetime.datetime.utcnow() msg = ('Update WebRTC code version (%02d-%02d-%02dT%02d:%02d:%02d).' '\n\nBug: None') msg = msg % (date.year, date.month, date.day, date.hour, date.minute, date.second) subprocess.check_call(['git', 'add', '--update', '.']) subprocess.check_call(['git', 'commit', '-m', msg]) def _upload_cl(commit_queue_mode): """Upload the committed changes as a changelist to Gerrit. commit_queue_mode: - 2: Submit to commit queue. - 1: Run trybots but do not submit to CQ. - 0: Skip CQ, upload only. """ cmd = [ 'git', 'cl', 'upload', '--force', '--bypass-hooks', '--bypass-watchlist' ] if commit_queue_mode >= 2: logging.info('Sending the CL to the CQ...') cmd.extend(['-o', 'label=Bot-Commit+1']) cmd.extend(['-o', 'label=Commit-Queue+2']) cmd.extend(['--send-mail', '--cc', NOTIFY_EMAIL]) elif commit_queue_mode >= 1: logging.info('Starting CQ dry run...') cmd.extend(['-o', 'label=Commit-Queue+1']) subprocess.check_call(cmd) def main(): logging.basicConfig(level=logging.INFO) parser = argparse.ArgumentParser() parser.add_argument('--clean', action='store_true', default=False, help='Removes any previous local update branch.') opts = parser.parse_args() if opts.clean: _remove_previous_update_branch() if _get_last_author() == 'webrtc-version-updater': logging.info('Last commit is a version change, skipping CL.') return 0 version_filename = os.path.join(CHECKOUT_SRC_DIR, 'call', 'version.cc') _create_update_branch() _update_webrtc_version(version_filename) if _is_tree_clean(): logging.info('No WebRTC version change detected, skipping CL.') else: _local_commit() logging.info('Uploading CL...') _upload_cl(2) return 0 if __name__ == '__main__': sys.exit(main())