diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 1641bdd..c100993 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -35,6 +35,10 @@ datasourceTemplate: 'python-version', depNameTemplate: 'python', }, + { + fileMatch: ['^tag_publish/versions.yaml$'], + matchStrings: ['(?.*): (?.*) # (?.*)'], + }, ], packageRules: [ /** Automerge the patch, the minor and the dev dependency */ diff --git a/poetry.lock b/poetry.lock index bdbd27c..bc74ec3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -12,14 +12,14 @@ files = [ ] [[package]] -name = "application-download" -version = "0.0.1.dev3" +name = "applications-download" +version = "0.7.1" description = "Tools used to publish Python packages, Docker images and Helm charts for GitHub tag and branch" optional = false python-versions = ">=3.9" files = [ - {file = "application_download-0.0.1.dev3-py3-none-any.whl", hash = "sha256:89662f68d327ccd39c499947c58861ec0c94f648de471fd173d8df53dae25069"}, - {file = "application_download-0.0.1.dev3.tar.gz", hash = "sha256:bc7d894bab6f87d6e822c717eecdc169489e3dc2a61ce8ab7de26a785b40bb57"}, + {file = "applications_download-0.7.1-py3-none-any.whl", hash = "sha256:cb4c1a686d8b2522b3b3fe4632a8305cef59f31a02dfd7e5588292d58dc8f917"}, + {file = "applications_download-0.7.1.tar.gz", hash = "sha256:b385e3c88fb41fd50121ae67e3c69f58613dc252e501e6aff6aea4c4698b1f98"}, ] [package.dependencies] @@ -2214,4 +2214,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4.0" -content-hash = "a30510453c99db72224432d0d8d9a084af11aef2983452005a7fabfa0702868e" +content-hash = "ce93a305b88c95fc0e0250164a73ef4793a6a8b6b724a2b94242717a374f9249" diff --git a/pyproject.toml b/pyproject.toml index bbd0480..9bb44b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,7 +66,8 @@ twine = "5.1.1" PyYAML = "6.0.2" id = "1.4.0" security-md = "0.2.3" -application-download = "0.0.1.dev3" +applications-download = "0.7.1" +jsonschema-validator-new = "0.1.0" PyGithub = "2.5.0" debian-inspector = "31.1.0" multi-repo-automation = "1.4.1" diff --git a/tag_publish/__init__.py b/tag_publish/__init__.py index b087b57..0eaf8b3 100644 --- a/tag_publish/__init__.py +++ b/tag_publish/__init__.py @@ -2,17 +2,21 @@ Tag Publish main module. """ +import json import os.path +import pkgutil import re import subprocess # nosec from re import Match, Pattern -from typing import Any, Optional, TypedDict, cast +from typing import Any, Optional, TypedDict, TypeVar, cast -import application_download.cli +import applications_download import github +import jsonschema_validator import requests import ruamel.yaml import security_md +import yaml import tag_publish.configuration @@ -94,9 +98,14 @@ def get_config(gh: GH) -> tag_publish.configuration.Configuration: """ config: tag_publish.configuration.Configuration = {} if os.path.exists(".github/publish.yaml"): + schema_data = pkgutil.get_data("tag_publish", "schema.json") + assert schema_data is not None + schema = json.loads(schema_data) + with open(".github/publish.yaml", encoding="utf-8") as open_file: yaml_ = ruamel.yaml.YAML() config = yaml_.load(open_file) + jsonschema_validator.validate(".github/publish.yaml", cast(dict[str, Any], config), schema) merge( { @@ -235,17 +244,36 @@ def add_authorization_header(headers: dict[str, str]) -> dict[str, str]: return headers +BINARY_FILENAME = TypeVar("BINARY_FILENAME", str, Optional[str]) + + +def download_application(application_name: str, binary_filename: BINARY_FILENAME = None) -> BINARY_FILENAME: + """ + Download the application if necessary, with the included version. + """ + binary_full_filename = ( + os.path.expanduser(os.path.join("~", ".local", "bin", binary_filename)) if binary_filename else None + ) + + if not os.path.exists(binary_full_filename) if binary_full_filename else True: + applications = applications_download.load_applications(None) + versions_data = pkgutil.get_data("tag_publish", "versions.yaml") + assert versions_data is not None + versions = yaml.safe_load(versions_data) + applications_download.download_applications( + applications, {application_name: versions[application_name]} + ) + + return binary_full_filename + + def snyk_exec() -> tuple[str, dict[str, str]]: """Get the Snyk cli executable path.""" env = {**os.environ} env["FORCE_COLOR"] = "true" - snyk_bin = os.path.expanduser(os.path.join("~", ".local", "bin", "snyk")) - if not os.path.exists(snyk_bin): - folder = os.path.expanduser(os.path.join("~", ".config", "application_download")) - if not os.path.exists(folder): - os.makedirs(folder) - application_download.cli.download_application("snyk/cli") + snyk_bin = download_application("snyk/cli", "snyk") + assert snyk_bin is not None if "SNYK_TOKEN" not in env: env["SNYK_TOKEN"] = subprocess.run( diff --git a/tag_publish/cli.py b/tag_publish/cli.py index 7fc8bf5..4720732 100644 --- a/tag_publish/cli.py +++ b/tag_publish/cli.py @@ -15,7 +15,6 @@ from re import Match from typing import Optional, cast -import application_download.cli import security_md import yaml @@ -219,7 +218,7 @@ def _handle_pypi_publish( if "packages" in pypi_config: tag_publish.lib.oidc.pypi_login() - for package in pypi_config["packages"]: + for package in pypi_config.get("packages", []): if package.get("group", tag_publish.configuration.PIP_PACKAGE_GROUP_DEFAULT) == group: publish = version_type in pypi_config.get( "versions", tag_publish.configuration.PYPI_VERSIONS_DEFAULT @@ -466,7 +465,7 @@ def _handle_helm_publish( if helm_config.get("folders") and version_type in helm_config.get( "versions", tag_publish.configuration.HELM_VERSIONS_DEFAULT ): - application_download.cli.download_application("helm/chart-releaser") + tag_publish.download_application("helm/chart-releaser") owner = github.repo.owner.login repo = github.repo.name diff --git a/tag_publish/applications-versions.yaml b/tag_publish/versions.yaml similarity index 100% rename from tag_publish/applications-versions.yaml rename to tag_publish/versions.yaml