# Copyright 2022 Google LLC # # 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. # ################################################################################ """Entrypoint for CI into trial_build. This script will get the command from the last PR comment containing "/gcbrun" and pass it to trial_build.py which will build test versions of base-imags, push them and then do test builds using those images.""" import logging import os import sys import github import trial_build TRIGGER_COMMAND = '/gcbrun' def get_comments(pull_request_number): """Returns comments on the GitHub Pull request referenced by |pull_request_number|.""" github_obj = github.Github() repo = github_obj.get_repo('google/oss-fuzz') pull = repo.get_pull(pull_request_number) pull_comments = list(pull.get_comments()) issue = repo.get_issue(pull_request_number) issue_comments = list(issue.get_comments()) # Github only returns comments if from the pull object when a pull request is # open. If it is a draft, it will only return comments from the issue object. return pull_comments + issue_comments def get_latest_gcbrun_command(comments): """Gets the last /gcbrun comment from comments.""" for comment in reversed(comments): # This seems to get comments on code too. body = comment.body command_str = f'{TRIGGER_COMMAND} trial_build.py ' if not body.startswith(command_str): continue if len(body) == len(command_str): return None return body[len(command_str):].strip().split(' ') return None def exec_command_from_github(pull_request_number, branch): """Executes the gcbrun command for trial_build.py in the most recent command on |pull_request_number|.""" comments = get_comments(pull_request_number) command = get_latest_gcbrun_command(comments) logging.info('Command: %s.', command) if command is None: logging.info('Trial build not requested.') return None # Set the branch so that the trial_build builds the projects from the PR # branch. command.append(f' --branch {branch}') logging.info('Command: %s.', command) return trial_build.trial_build_main(command, local_base_build=False) def main(): """Entrypoint for GitHub CI into trial_build.py""" logging.basicConfig(level=logging.INFO) pull_request_number = int(os.environ['PULL_REQUEST_NUMBER']) branch = os.environ['BRANCH'] return 0 if exec_command_from_github(pull_request_number, branch) else 1 if __name__ == '__main__': sys.exit(main())