From fcfc8580ea9b2b0de31e7e2f38e6e76a7d64f29d Mon Sep 17 00:00:00 2001 From: lovetox Date: Thu, 21 Apr 2022 00:16:40 +0200 Subject: Add CI deploy script --- .ci/deploy.py | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 .ci/deploy.py (limited to '.ci') diff --git a/.ci/deploy.py b/.ci/deploy.py new file mode 100644 index 0000000..584e180 --- /dev/null +++ b/.ci/deploy.py @@ -0,0 +1,150 @@ +from typing import Any, Iterator + +import os +import json +import functools +from shutil import make_archive +from ftplib import FTP_TLS +from pathlib import Path + +import requests +from rich.console import Console + + +PackageT = tuple[dict[str, Any], Path] +ManifestT = dict[str, Any] +PackageIndexT = dict[str, Any] + + +FTP_URL = 'panoramix.gajim.org' +FTP_USER = os.environ['FTP_USER'] +FTP_PASS = os.environ['FTP_PASS'] + +REPOSITORY_FOLDER = 'plugins/master' +PACKAGE_INDEX_URL = 'https://ftp.gajim.org/plugins/master/package_index.json' +REPO_ROOT = Path(__file__).parent.parent +BUILD_PATH = REPO_ROOT / 'build' + + +REQUIRED_KEYS = { + 'authors', + 'description', + 'homepage', + 'name', + 'platforms', + 'requirements', + 'short_name', + 'version' +} + + +console = Console() + + +def ftp_connection(func: Any) -> Any: + @functools.wraps(func) + def func_wrapper(*args: Any) -> None: + ftp = FTP_TLS(FTP_URL, FTP_USER, FTP_PASS) + console.print('Successfully connected to', FTP_URL) + func(ftp, *args) + ftp.quit() + console.print('Quit') + return + return func_wrapper + + +def is_manifest_valid(manifest: ManifestT) -> bool: + manifest_keys = set(manifest.keys()) + return REQUIRED_KEYS.issubset(manifest_keys) + + +def download_package_index() -> ManifestT: + console.print('Download package index') + r = requests.get(PACKAGE_INDEX_URL) + r.raise_for_status() + index = r.json() + return index + + +def iter_manifests() -> Iterator[PackageT]: + for path in REPO_ROOT.rglob('manifest.json'): + with path.open() as f: + manifest = json.load(f) + yield manifest, path.parent + + +def find_plugins_to_publish(index: PackageIndexT) -> list[PackageT]: + packages_to_publish: list[PackageT] = [] + for manifest, path in iter_manifests(): + if not is_manifest_valid(manifest): + exit('Invalid manifest found') + + short_name = manifest['short_name'] + version = manifest['version'] + + try: + index['plugins'][short_name][version] + except KeyError: + packages_to_publish.append((manifest, path)) + console.print('Found package to publish:', path.stem) + + return packages_to_publish + + +def get_release_zip_name(manifest: ManifestT) -> str: + short_name = manifest['short_name'] + version = manifest['version'] + return f'{short_name}_{version}' + + +def get_dir_list(ftp: FTP_TLS) -> set[str]: + return {x[0] for x in ftp.mlsd()} + + +def upload_file(ftp: FTP_TLS, + filepath: Path) -> None: + + name = filepath.name + console.print('Upload file', name) + with open(filepath, 'rb') as f: + ftp.storbinary('STOR ' + name, f) + + +def create_release_folder(ftp: FTP_TLS, + packages_to_publish: list[PackageT]) -> None: + + folders = {manifest['short_name'] for manifest, _ in packages_to_publish} + dir_list = get_dir_list(ftp) + missing_folders = folders - dir_list + for folder in missing_folders: + ftp.mkd(folder) + + +@ftp_connection +def deploy(ftp: FTP_TLS, packages_to_publish: list[PackageT]) -> None: + ftp.cwd(REPOSITORY_FOLDER) + create_release_folder(ftp, packages_to_publish) + + for manifest, path in packages_to_publish: + package_name = manifest['short_name'] + zip_name = get_release_zip_name(manifest) + zip_path = BUILD_PATH / f'{zip_name}.zip' + image_path = path / f'{package_name}.png' + + make_archive(str(BUILD_PATH / zip_name), 'zip', path) + + ftp.cwd(package_name) + upload_file(ftp, zip_path) + upload_file(ftp, image_path) + ftp.cwd('..') + + console.print('Deployed', package_name) + + +if __name__ == '__main__': + index = download_package_index() + packages_to_publish = find_plugins_to_publish(index) + if not packages_to_publish: + console.print('No new packages deployed') + else: + deploy(packages_to_publish) -- cgit v1.2.3