#!/usr/bin/env python3 # SPDX-License-Identifier: BSD-2-Clause # # SPDX-FileCopyrightText: 2023 KDE e.V. # SPDX-FileContributor: Ingo Klöcker import logging import os import sys from pathlib import Path from sftpnotary import config, projects, util from sftpnotary.exceptions import Error from sftpnotary.microsoftstoreclient import PublishOnMicrosoftStoreJob log = logging.getLogger("publishonmicrosoftstore") def parseCommandLine(): import argparse parser = argparse.ArgumentParser(description="Submit an app to the Microsoft Store") # debug options parser.add_argument("-v", "--verbose", action="count", default=0, help="increase the verbosity") parser.add_argument("--config", required=True, help="the configuration to use; required") parser.add_argument("appxuploadFile", help="the .appxupload file to submit") options = parser.parse_args() return options def logTaskLog(logFile: Path): log.info("Logs of remote signing:") with open(logFile, "r", encoding="utf-8") as f: for line in f: log.info(line.rstrip()) def submitAppx(appx: Path, projectPath: str, branch: str) -> bool: with util.connectToSftpServer() as sftp: job = PublishOnMicrosoftStoreJob( sftp, appxFilePath=appx, token=os.environ.get("CI_JOB_TOKEN"), projectPath=projectPath, branch=branch, ) try: job.start() job.waitForCompletion() except Exception as e: # or more specific exception log.error("Error: PublishOnMicrosoftStoreJob failed", exc_info=e) for logFile in job.logFiles: if logFile.name == "task.log": logTaskLog(logFile) if not job.success: log.error("Error: Submitting the APPX failed") return job.success def main() -> int: options = parseCommandLine() config.loadConfig(options.config) util.setUpClientLogging(log, options.verbose) projectSettingsLocation = config.settings.get("General", "ProjectSettings", "microsoftstorepublisher-projects.yaml") util.loadProjectSettings( projectSettingsLocation, relativeTo=Path(options.config).absolute().parent, ) # Ignore merge request pipelines if os.environ.get("CI_PIPELINE_SOURCE") == "merge_request_event": log.info("Merge request pipelines are not cleared for publishing. Skipping.") return 0 # Check if it makes sense to attempt publishing the APPX projectPath = os.environ["CI_PROJECT_PATH"] branch = os.environ["CI_COMMIT_REF_NAME"] if not projects.settings.exists(projectPath, branch): log.info( f"""Branch '{branch}' of project '{projectPath}' is not cleared for publishing. Skipping.\n You can clear it by adding the branch to {projectSettingsLocation}""" ) return 0 success = submitAppx(Path(options.appxuploadFile), projectPath, branch) return 0 if success else 1 if __name__ == "__main__": try: sys.exit(main()) except Error as e: print("Error: %s" % e, file=sys.stderr) sys.exit(1)