def __init__(self, update: Update, context: CallbackContext, args: list[str]): """Init twrpdtgen project class.""" super().__init__(update, context, args) parser = CIParser(prog="/ci twrpdtgen") parser.set_output(self.update.message.reply_text) parser.add_argument('url', help='URL of the image') self.parsed_args = parser.parse_args(args)
def __init__(self, update: Update, context: CallbackContext, args: list[str]): super().__init__(update, context, args) parser = CIParser(prog="/ci") parser.set_output(self.update.message.reply_text) parser.add_argument('device', help='device codename') parser.add_argument('-ic', '--installclean', help='make installclean before building', action='store_true') parser.add_argument('-c', '--clean', help='make clean before building', action='store_true') parser.set_defaults(clean=False, installclean=False) self.parsed_args = parser.parse_args(args)
def ci(update: Update, context: CallbackContext): if not user_is_admin(update.message.from_user.id): update.message.reply_text("Error: You are not authorized to use CI function of this bot.\n" "Ask to who host this bot to add you to the authorized people list") return if get_config("CI_CHANNEL_ID") == "": update.message.reply_text("Error: CI channel or user ID not defined") LOGE("CI channel or user ID not defined") return parser = CIParser(prog="/ci") parser.set_output(update.message.reply_text) parser.add_argument('project', help='CI project', nargs='?', default=None,) parser.add_argument('-s', '--status', action='store_true', help='show queue status') args, project_args = parser.parse_known_args(context.args) if args.status: update.message.reply_text(queue_manager.get_formatted_queue_list()) return if args.project is None: parser.error("Please specify a project") try: project_class = import_module(f"homebot.modules.ci.projects.{args.project}", package="Project").Project except ModuleNotFoundError: update.message.reply_text(f"Error: Project script not found") return except Exception as e: text = "Error: Error while importing project:" text += format_exception(e) update.message.reply_text(text) LOGE(text) return try: project = project_class(update, context, project_args) except Exception as e: text = "Error: Project class initialization failed:\n" text += format_exception(e) update.message.reply_text(text) LOGE(text) return workflow = Workflow(project) queue_manager.put(workflow) update.message.reply_text("Workflow added to the queue") LOGI("Workflow added to the queue")
def ci_build(update, context): parser = CIParser(prog="/ci AOSP") parser.set_output(update.message.reply_text) parser.add_argument('project', help='AOSP project') parser.add_argument('device', help='device codename') parser.add_argument('-ic', '--installclean', help='make installclean before building', action='store_true') parser.add_argument('-c', '--clean', help='make clean before building', action='store_true') parser.set_defaults(clean=False, installclean=False) try: args_passed = update.message.text.split(' ', 2)[2].split() except IndexError: args_passed = "" args = parser.parse_args(args_passed) project_module = import_module( 'homebot.modules.ci.projects.aosp.projects.' + args.project, package="*") projects_dir = Path(get_config("CI_MAIN_DIR")) project_dir = projects_dir / (project_module.project + "-" + project_module.version) out_dir = project_dir / "out" device_out_dir = out_dir / "target" / "product" / args.device if args.clean is True: clean_type = "clean" elif args.installclean is True: clean_type = "installclean" else: clean_type = "none" message_id = context.bot.send_message( get_config("CI_CHANNEL_ID"), make_ci_post(project_module, args.device, "Building", None)).message_id process = Popen([ bot_path / "modules" / "ci" / "projects" / "aosp" / "tools" / "building.sh", "--project", project_module.project + "-" + project_module.version, "--name", project_module.project + " " + project_module.version, "--android_version", project_module.android_version, "--lunch_prefix", project_module.lunch_prefix, "--lunch_suffix", project_module.lunch_suffix, "--build_target", project_module.build_target, "--artifacts", project_module.artifacts, "--device", args.device, "--main_dir", get_config("CI_MAIN_DIR"), "--clean", clean_type ], stdout=PIPE, stderr=PIPE, universal_newlines=True) _, _ = process.communicate() context.bot.edit_message_text(chat_id=get_config("CI_CHANNEL_ID"), message_id=message_id, text=make_ci_post( project_module, args.device, error_code.get( process.returncode, "Build failed: Unknown error"), None)) if needs_logs_upload.get(process.returncode, False) != False: log_file = open( project_dir / needs_logs_upload.get(process.returncode), "rb") context.bot.send_document(get_config("CI_CHANNEL_ID"), log_file) log_file.close() if get_config("CI_UPLOAD_ARTIFACTS") != "true": return build_result = error_code.get(process.returncode, "Build failed: Unknown error") artifacts = { artifact: "On queue" for artifact in list(device_out_dir.glob(project_module.artifacts)) } context.bot.edit_message_text(chat_id=get_config("CI_CHANNEL_ID"), message_id=message_id, text=make_ci_post( project_module, args.device, build_result, create_artifacts_list(artifacts))) for artifact in artifacts: artifacts[artifact] = "Uploading" context.bot.edit_message_text(chat_id=get_config("CI_CHANNEL_ID"), message_id=message_id, text=make_ci_post( project_module, args.device, build_result, create_artifacts_list(artifacts))) result = upload( artifact, Path(project_module.project_type) / args.device / project_module.project / project_module.android_version) if result is True: artifacts[artifact] = "Upload successful" else: artifacts[artifact] = "Upload failed" context.bot.edit_message_text(chat_id=get_config("CI_CHANNEL_ID"), message_id=message_id, text=make_ci_post( project_module, args.device, build_result, create_artifacts_list(artifacts)))
def ci_build(update: Update, context: CallbackContext): # Parse arguments parser = CIParser(prog="/ci aosp") parser.set_output(update.message.reply_text) parser.add_argument('project', help='AOSP project') parser.add_argument('device', help='device codename') parser.add_argument('-ic', '--installclean', help='make installclean before building', action='store_true') parser.add_argument('-c', '--clean', help='make clean before building', action='store_true') parser.add_argument('-g', '--gapped', help='make gapped build', action='store_true') parser.set_defaults(clean=False, installclean=False, gapped=False) try: args_passed = update.message.text.split(' ', 2)[2].split() except IndexError: args_passed = [] args = parser.parse_args(args_passed) # Import project project: AOSPProject project = import_module( f"homebot.modules.ci.projects.aosp.projects.{args.project}", package="*").project project_dir = Path( f"{get_config('CI_MAIN_DIR')}/{project.name}-{project.version}") device_out_dir = project_dir / "out" / "target" / "product" / args.device if args.clean is True: clean_type = "clean" elif args.installclean is True: clean_type = "installclean" else: clean_type = "none" message_id = update_ci_post(context, None, project, args.device, "Building", gapped=args.gapped) command = [ bot_path / "modules" / "ci" / "projects" / "aosp" / "tools" / "building.sh", "--sources", project_dir, "--lunch_prefix", project.lunch_prefix, "--lunch_suffix", project.lunch_suffix, "--build_target", project.build_target, "--clean", clean_type, "--gapped", str(args.gapped), "--device", args.device ] last_edit = datetime.now() process = subprocess.Popen(command, encoding="UTF-8", stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while True: output = process.stdout.readline() if output == '' and process.poll() is not None: break if not output: continue now = datetime.now() if (now - last_edit).seconds < 300: continue result = re.search(r"\[ +([0-9]+% [0-9]+/[0-9]+)\]", output.strip()) if result is None: continue result_split = str(result.group(1)).split() if len(result_split) != 2: continue percentage, targets = re.split(" +", result.group(1)) update_ci_post(context, message_id, project, args.device, f"Building: {percentage} ({targets})", gapped=args.gapped) last_edit = now returncode = process.poll() # Process return code build_result = ERROR_CODES.get(returncode, "Build failed: Unknown error") update_ci_post(context, message_id, project, args.device, build_result, gapped=args.gapped) needs_logs_upload = NEEDS_LOGS_UPLOAD.get(returncode, False) if needs_logs_upload != False: log_file = open(project_dir / needs_logs_upload, "rb") context.bot.send_document(get_config("CI_CHANNEL_ID"), log_file) log_file.close() if returncode != SUCCESS or get_config("CI_UPLOAD_ARTIFACTS") != "true": return # Upload artifacts try: uploader = Uploader() except Exception as e: update_ci_post(context, message_id, project, args.device, f"{build_result}\n" f"Upload failed: {type(e)}: {e}", gapped=args.gapped) return artifacts = Artifacts(device_out_dir, project.artifacts) update_ci_post(context, message_id, project, args.device, build_result, artifacts=artifacts, gapped=args.gapped) for artifact in artifacts.artifacts: artifact.status = STATUS_UPLOADING update_ci_post(context, message_id, project, args.device, build_result, artifacts=artifacts, gapped=args.gapped) try: uploader.upload( artifact, Path(project.category) / args.device / project.name / project.android_version) except Exception as e: artifact.status = f"{STATUS_NOT_UPLOADED}: {type(e)}: {e}" else: artifact.status = STATUS_UPLOADED update_ci_post(context, message_id, project, args.device, build_result, artifacts=artifacts, gapped=args.gapped)