From 6f072f219fc2483593ecc6d8974f64aef26fcdda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 6 Nov 2024 14:32:07 +0100 Subject: [PATCH] First build --- .bandit.yaml | 2 + .github/dpkg-versions.yaml | 1 + .github/publish.yaml | 6 +- .github/requirements.txt | 1 + .github/workflows/main.yaml | 44 +- .github/workflows/repository-dispatch.yaml | 40 ++ Dockerfile | 3 + README.md | 6 +- config.md | 90 ++-- poetry.lock | 535 ++++++++++++++++++++- pyproject.toml | 8 +- tag_publish/__init__.py | 242 ++++++++++ tag_publish/applications-versions.yaml | 2 + tag_publish/cli.py | 160 +++--- tag_publish/configuration.py | 288 +++++------ tag_publish/lib/docker.py | 20 +- tag_publish/lib/trigger_image_update.py | 36 -- tag_publish/new.py | 64 ++- tag_publish/package-lock.json | 437 ----------------- tag_publish/package.json | 9 - tag_publish/publish.py | 43 +- tag_publish/schema.json | 333 +++++++------ 22 files changed, 1373 insertions(+), 997 deletions(-) create mode 100644 .github/dpkg-versions.yaml create mode 100644 .github/requirements.txt create mode 100644 .github/workflows/repository-dispatch.yaml create mode 100644 Dockerfile create mode 100644 tag_publish/applications-versions.yaml delete mode 100644 tag_publish/lib/trigger_image_update.py delete mode 100644 tag_publish/package-lock.json delete mode 100644 tag_publish/package.json diff --git a/.bandit.yaml b/.bandit.yaml index 1bf9b48..fdeda8f 100644 --- a/.bandit.yaml +++ b/.bandit.yaml @@ -1,2 +1,4 @@ skips: - B101 # Use of assert detected. + - B603 # subprocess call - check for execution of untrusted input. + - B607 # Starting a process with a partial executable path. diff --git a/.github/dpkg-versions.yaml b/.github/dpkg-versions.yaml new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.github/dpkg-versions.yaml @@ -0,0 +1 @@ +{} diff --git a/.github/publish.yaml b/.github/publish.yaml index 5e5b883..af610f0 100644 --- a/.github/publish.yaml +++ b/.github/publish.yaml @@ -4,4 +4,8 @@ pypi: versions: - version_tag - version_branch - - rebuild + packages: + - path: . +docker: + images: + - name: camptocamp/tag-publish diff --git a/.github/requirements.txt b/.github/requirements.txt new file mode 100644 index 0000000..ddf14cc --- /dev/null +++ b/.github/requirements.txt @@ -0,0 +1 @@ +c2cciutils==1.7.1 diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 63cd630..e8492c3 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -16,8 +16,8 @@ env: HAS_SECRETS: ${{ secrets.HAS_SECRETS }} jobs: - main: - name: Continuous integration + pre-commit: + name: Pre commit checks runs-on: ubuntu-24.04 timeout-minutes: 20 if: "!startsWith(github.event.head_commit.message, '[skip ci] ')" @@ -27,17 +27,10 @@ jobs: with: fetch-depth: 0 - - uses: camptocamp/initialise-gopass-summon-action@v2 - with: - ci-gpg-private-key: ${{secrets.CI_GPG_PRIVATE_KEY}} - github-gopass-ci-token: ${{secrets.GOPASS_CI_GITHUB_TOKEN}} - patterns: pypi - if: env.HAS_SECRETS == 'HAS_SECRETS' - - uses: actions/setup-python@v5 with: python-version: '3.13' - - run: python3 -m pip install --requirement=requirements.txt + - run: python3 -m pip install $(grep pre-commit== requirements.txt) - uses: actions/cache@v4 with: @@ -54,18 +47,45 @@ jobs: retention-days: 1 if: failure() + main: + name: Continuous integration + runs-on: ubuntu-24.04 + timeout-minutes: 20 + needs: pre-commit + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: camptocamp/initialise-gopass-summon-action@v2 + with: + ci-gpg-private-key: ${{secrets.CI_GPG_PRIVATE_KEY}} + github-gopass-ci-token: ${{secrets.GOPASS_CI_GITHUB_TOKEN}} + patterns: pypi + if: env.HAS_SECRETS == 'HAS_SECRETS' + + - uses: actions/setup-python@v5 + with: + python-version: '3.13' + - run: python3 -m pip install --requirement=.github/requirements.txt + - run: python3 -m pip install --requirement=requirements.txt + - name: Print the environment run: c2cciutils-env env: GITHUB_EVENT: ${{ toJson(github) }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: poetry install - name: Prospector run: poetry run prospector --die-on-tool-error --output-format=pylint + - run: docker build --tag camptocamp/tag-publish . + - name: Publish - run: tag-publish + run: poetry run tag-publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: git diff --exit-code --patch > /tmp/dpkg-versions.patch || true if: failure() diff --git a/.github/workflows/repository-dispatch.yaml b/.github/workflows/repository-dispatch.yaml new file mode 100644 index 0000000..4faeec4 --- /dev/null +++ b/.github/workflows/repository-dispatch.yaml @@ -0,0 +1,40 @@ +name: Print repository dispatch event + +on: + repository_dispatch: + types: + - published + inputs: + type: + description: The type of the event + required: true + name: + description: The package name + path: + description: The package path + version: + description: The package version + tag: + description: The package tag + repository: + description: The repository name or URL + version_type: + description: The version type + required: true + +jobs: + print: + runs-on: ubuntu-24.04 + name: Print repository dispatch event + timeout-minutes: 10 + + steps: + - name: Print the event + run: | + echo "Event type: ${{ github.event.client_payload.type }}" + echo "Package name: ${{ github.event.client_payload.name }}" + echo "Package path: ${{ github.event.client_payload.path }}" + echo "Package version: ${{ github.event.client_payload.version }}" + echo "Package tag: ${{ github.event.client_payload.tag }}" + echo "Repository: ${{ github.event.client_payload.repository }}" + echo "Version type: ${{ github.event.client_payload.version_type }}" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9c43176 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +FROM ubuntu + +RUN echo Just for a test diff --git a/README.md b/README.md index 2d6b750..f2c369a 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,11 @@ It can also contain the following sentences: See also [GitHub Documentation](https://docs.github.com/en/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository) -## Publishing +## Configuration + +### Dry run + +Dry run publish: `GITHUB_REF=... c2cciutils-publish --dry-run ...` ### To pypi diff --git a/config.md b/config.md index 810ef4e..7826ef9 100644 --- a/config.md +++ b/config.md @@ -7,63 +7,55 @@ _Tag Publish configuration file_ - **`version`** _(object)_: The version configurations. - **`branch_to_version_re`**: Refer to _[#/definitions/version_transform](#definitions/version_transform)_. - **`tag_to_version_re`**: Refer to _[#/definitions/version_transform](#definitions/version_transform)_. -- **`docker`**: Refer to _[#/definitions/publish_docker](#definitions/publish_docker)_. -- **`pypi`**: Refer to _[#/definitions/publish_pypi](#definitions/publish_pypi)_. -- **`helm`**: Refer to _[#/definitions/publish_helm](#definitions/publish_helm)_. +- **`docker`**: Refer to _[#/definitions/docker](#definitions/docker)_. +- **`pypi`**: Refer to _[#/definitions/pypi](#definitions/pypi)_. +- **`helm`**: Refer to _[#/definitions/helm](#definitions/helm)_. +- **`dispatch`** _(array)_: Default: `[{}]`. + - **Items** _(object)_: Send a dispatch event to an other repository. Default: `{}`. + - **`repository`** _(string)_: The repository name to be triggered. Default: `"camptocamp/argocd-gs-gmf-apps"`. + - **`event-type`** _(string)_: The event type to be triggered. Default: `"published"`. ## Definitions -- **`publish_docker`**: The configuration used to publish on Docker. - - **One of** - - _object_: The configuration used to publish on Docker. - - **`latest`** _(boolean)_: Publish the latest version on tag latest. Default: `true`. - - **`images`** _(array)_: List of images to be published. - - **Items** _(object)_ - - **`group`** _(string)_: The image is in the group, should be used with the --group option of tag-publish script. Default: `"default"`. - - **`name`** _(string)_: The image name. - - **`tags`** _(array)_: The tag name, will be formatted with the version=, the image with version=latest should be present when we call the tag-publish script. Default: `["{version}"]`. - - **Items** _(string)_ - - **`repository`** _(object)_: The repository where we should publish the images. Can contain additional properties. Default: `{"github": {"server": "ghcr.io", "versions": ["version_tag", "version_branch", "rebuild"]}, "dockerhub": {}}`. - - **Additional properties** _(object)_ - - **`server`** _(string)_: The server URL. - - **`versions`** _(array)_: The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script. Default: `["version_tag", "version_branch", "rebuild", "feature_branch"]`. - - **Items** _(string)_ - - **`dispatch`**: Send a dispatch event to an other repository. Default: `{}`. - - **One of** - - _object_: Send a dispatch event to an other repository. - - **`repository`** _(string)_: The repository name to be triggered. Default: `"camptocamp/argocd-gs-gmf-apps"`. - - **`event-type`** _(string)_: The event type to be triggered. Default: `"image-update"`. - - : Must be: `false`. - - **`snyk`** _(object)_: Checks the published images with Snyk. - - **`monitor_args`**: The arguments to pass to the Snyk container monitor command. Default: `["--app-vulns"]`. - - **One of** - - _array_ - - **Items** _(string)_ - - : Must be: `false`. - - **`test_args`**: The arguments to pass to the Snyk container test command. Default: `["--app-vulns", "--severity-threshold=critical"]`. - - **One of** - - _array_ - - **Items** _(string)_ - - : Must be: `false`. - - : Must be: `false`. -- **`publish_pypi`**: Configuration to publish on pypi. Default: `{}`. - - **One of** - - _object_: Configuration to publish on pypi. - - **`packages`** _(array)_: The configuration of packages that will be published. - - **Items** _(object)_: The configuration of package that will be published. - - **`group`** _(string)_: The image is in the group, should be used with the --group option of tag-publish script. Default: `"default"`. - - **`path`** _(string)_: The path of the pypi package. - - **`build_command`** _(array)_: The command used to do the build. - - **Items** _(string)_ - - **`versions`** _(array)_: The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script. +- **`docker`** _(object)_: The configuration used to publish on Docker. + - **`latest`** _(boolean)_: Publish the latest version on tag latest. Default: `true`. + - **`images`** _(array)_: List of images to be published. + - **Items** _(object)_ + - **`group`** _(string)_: The image is in the group, should be used with the --group option of tag-publish script. Default: `"default"`. + - **`name`** _(string)_: The image name. + - **`tags`** _(array)_: The tag name, will be formatted with the version=, the image with version=latest should be present when we call the tag-publish script. Default: `["{version}"]`. - **Items** _(string)_ - - : Must be: `false`. -- **`publish_helm`**: Configuration to publish Helm charts on GitHub release. + - **`repository`** _(object)_: The repository where we should publish the images. Can contain additional properties. Default: `{"github": {"server": "ghcr.io", "versions": ["version_tag", "version_branch", "rebuild"]}, "dockerhub": {}}`. + - **Additional properties** _(object)_ + - **`server`** _(string)_: The server URL. + - **`versions`** _(array)_: The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script. Default: `["version_tag", "version_branch", "rebuild", "feature_branch"]`. + - **Items** _(string)_ + - **`snyk`** _(object)_: Checks the published images with Snyk. + - **`monitor_args`**: The arguments to pass to the Snyk container monitor command. Default: `["--app-vulns"]`. + - **One of** + - _array_ + - **Items** _(string)_ + - : Must be: `false`. + - **`test_args`**: The arguments to pass to the Snyk container test command. Default: `["--app-vulns", "--severity-threshold=critical"]`. + - **One of** + - _array_ + - **Items** _(string)_ + - : Must be: `false`. +- **`pypi`** _(object)_: Configuration to publish on pypi. + - **`packages`** _(array)_: The configuration of packages that will be published. + - **Items** _(object)_: The configuration of package that will be published. + - **`group`** _(string)_: The image is in the group, should be used with the --group option of tag-publish script. Default: `"default"`. + - **`path`** _(string)_: The path of the pypi package. Default: `"."`. + - **`build_command`** _(array)_: The command used to do the build. + - **Items** _(string)_ + - **`versions`** _(array)_: The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script. Default: `["version_tag"]`. + - **Items** _(string)_ +- **`helm`**: Configuration to publish Helm charts on GitHub release. - **One of** - _object_: Configuration to publish on Helm charts on GitHub release. - **`folders`** _(array)_: The folders that will be published. - **Items** _(string)_ - - **`versions`** _(array)_: The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script. + - **`versions`** _(array)_: The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script. Default: `["version_tag"]`. - **Items** _(string)_ - : Must be: `false`. - **`version_transform`** _(array)_: A version transformer definition. diff --git a/poetry.lock b/poetry.lock index 4c5a9c5..1e7e42a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -11,6 +11,23 @@ files = [ {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] +[[package]] +name = "application-download" +version = "0.0.1.dev3" +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"}, +] + +[package.dependencies] +jsonschema-validator-new = ">=0.0.0,<1.0.0" +PyYAML = ">=6.0.0,<7.0.0" +requests = ">=2.0.0,<3.0.0" +"ruamel.yaml" = ">=0.0.0,<1.0.0" + [[package]] name = "astroid" version = "3.3.5" @@ -25,6 +42,25 @@ files = [ [package.dependencies] typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} +[[package]] +name = "attrs" +version = "24.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + [[package]] name = "backports-tarfile" version = "1.2.0" @@ -179,6 +215,17 @@ files = [ [package.dependencies] pycparser = "*" +[[package]] +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + [[package]] name = "charset-normalizer" version = "3.4.0" @@ -304,6 +351,20 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "configupdater" +version = "3.2" +description = "Parser like ConfigParser but for updating configuration files" +optional = false +python-versions = ">=3.6" +files = [ + {file = "ConfigUpdater-3.2-py2.py3-none-any.whl", hash = "sha256:0f65a041627d7693840b4dd743581db4c441c97195298a29d075f91b79539df2"}, + {file = "ConfigUpdater-3.2.tar.gz", hash = "sha256:9fdac53831c1b062929bf398b649b87ca30e7f1a735f3fbf482072804106306b"}, +] + +[package.extras] +testing = ["flake8", "pytest", "pytest-cov", "pytest-randomly", "pytest-xdist", "sphinx"] + [[package]] name = "cryptography" version = "43.0.3" @@ -353,6 +414,25 @@ ssh = ["bcrypt (>=3.1.5)"] test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] +[[package]] +name = "debian-inspector" +version = "31.1.0" +description = "Utilities to parse Debian package, copyright and control files." +optional = false +python-versions = ">=3.7" +files = [ + {file = "debian_inspector-31.1.0-py3-none-any.whl", hash = "sha256:77dfeb34492dd49d8593d4f7146ffa3f71fca703737824e09d7472e0eafca567"}, + {file = "debian_inspector-31.1.0.tar.gz", hash = "sha256:ebcfbc17064f10bd3b6d2122cdbc97b71a494af0ebbafaf9a8ceadfe8b164f99"}, +] + +[package.dependencies] +attrs = ">=19.2,<20.1.0 || >20.1.0" +chardet = ">=3.0.0" + +[package.extras] +docs = ["Sphinx (>=5.0.2)", "doc8 (>=0.11.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-reredirects (>=0.1.2)", "sphinx-rtd-dark-mode (>=1.3.0)", "sphinx-rtd-theme (>=1.0.0)", "sphinxcontrib-apidoc (>=0.3.0)"] +testing = ["aboutcode-toolkit (>=7.0.2)", "black", "commoncode", "isort", "pycodestyle (>=2.8.0)", "pytest (>=6,!=7.0.0)", "pytest-xdist (>=2)", "twine"] + [[package]] name = "defusedxml" version = "0.7.1" @@ -364,6 +444,23 @@ files = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] +[[package]] +name = "deprecated" +version = "1.2.14" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, +] + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] + [[package]] name = "dill" version = "0.3.9" @@ -483,6 +580,20 @@ dev = ["build", "bump (>=1.3.2)", "id[lint,test]"] lint = ["bandit", "interrogate", "mypy", "ruff (<0.4.2)", "types-requests"] test = ["coverage[toml]", "pretend", "pytest", "pytest-cov"] +[[package]] +name = "identify" +version = "2.6.1" +description = "File identification library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"}, + {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"}, +] + +[package.extras] +license = ["ukkonen"] + [[package]] name = "idna" version = "3.10" @@ -607,6 +718,68 @@ files = [ test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] trio = ["async_generator", "trio"] +[[package]] +name = "json5" +version = "0.9.25" +description = "A Python implementation of the JSON5 data format." +optional = false +python-versions = ">=3.8" +files = [ + {file = "json5-0.9.25-py3-none-any.whl", hash = "sha256:34ed7d834b1341a86987ed52f3f76cd8ee184394906b6e22a1e0deb9ab294e8f"}, + {file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"}, +] + +[[package]] +name = "jsonschema" +version = "4.23.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2024.10.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.9" +files = [ + {file = "jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf"}, + {file = "jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "jsonschema-validator-new" +version = "0.1.0" +description = "Tool to validate files against a JSON Schema" +optional = false +python-versions = ">=3.8,<4" +files = [ + {file = "jsonschema_validator_new-0.1.0-py3-none-any.whl", hash = "sha256:f93e1a4ca92079f28fbad2b43a1733b5d51c6cc4c7fd327689a63a90b77cf4ff"}, + {file = "jsonschema_validator_new-0.1.0.tar.gz", hash = "sha256:deac226a3288222e9f1eb73267e496e33a598270529b31629f2407620a6dde37"}, +] + +[package.dependencies] +jsonschema = "*" +requests = "*" +"ruamel.yaml" = "*" + [[package]] name = "keyring" version = "25.5.0" @@ -721,6 +894,27 @@ files = [ {file = "more_itertools-10.5.0-py3-none-any.whl", hash = "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef"}, ] +[[package]] +name = "multi-repo-automation" +version = "1.4.1" +description = "Library for automation updates on multiple repositories." +optional = false +python-versions = ">=3.9" +files = [ + {file = "multi_repo_automation-1.4.1-py3-none-any.whl", hash = "sha256:300f299fa4d1e11aa4865f0308afa3a1bcd54a467a2a88b8191166e2b51a9608"}, + {file = "multi_repo_automation-1.4.1.tar.gz", hash = "sha256:d0f2ecc88489ec04b667790490827c5f09c9f21bc6615a41e85d71b41ebb69ac"}, +] + +[package.dependencies] +configupdater = "*" +identify = "*" +json5 = "*" +PyYAML = "*" +requests = "*" +"ruamel.yaml" = "*" +security_md = "*" +tomlkit = "*" + [[package]] name = "mypy" version = "1.13.0" @@ -1113,6 +1307,25 @@ files = [ {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, ] +[[package]] +name = "pygithub" +version = "2.4.0" +description = "Use the full Github API v3" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyGithub-2.4.0-py3-none-any.whl", hash = "sha256:81935aa4bdc939fba98fee1cb47422c09157c56a27966476ff92775602b9ee24"}, + {file = "pygithub-2.4.0.tar.gz", hash = "sha256:6601e22627e87bac192f1e2e39c6e6f69a43152cfb8f307cee575879320b3051"}, +] + +[package.dependencies] +Deprecated = "*" +pyjwt = {version = ">=2.4.0", extras = ["crypto"]} +pynacl = ">=1.4.0" +requests = ">=2.14.0" +typing-extensions = ">=4.0.0" +urllib3 = ">=1.26.0" + [[package]] name = "pygments" version = "2.18.0" @@ -1127,6 +1340,26 @@ files = [ [package.extras] windows-terminal = ["colorama (>=0.4.6)"] +[[package]] +name = "pyjwt" +version = "2.9.0" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, + {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, +] + +[package.dependencies] +cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""} + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + [[package]] name = "pylint" version = "3.3.1" @@ -1217,6 +1450,32 @@ files = [ [package.dependencies] pylint = ">=1.7" +[[package]] +name = "pynacl" +version = "1.5.0" +description = "Python binding to the Networking and Cryptography (NaCl) library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"}, + {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"}, + {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"}, + {file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"}, + {file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"}, + {file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"}, +] + +[package.dependencies] +cffi = ">=1.4.1" + +[package.extras] +docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] +tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] + [[package]] name = "pyproject-hooks" version = "1.2.0" @@ -1343,6 +1602,21 @@ Pygments = ">=2.5.1" [package.extras] md = ["cmarkgfm (>=0.8.0)"] +[[package]] +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + [[package]] name = "requests" version = "2.32.3" @@ -1428,6 +1702,186 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.1 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "rpds-py" +version = "0.20.1" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a649dfd735fff086e8a9d0503a9f0c7d01b7912a333c7ae77e1515c08c146dad"}, + {file = "rpds_py-0.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f16bc1334853e91ddaaa1217045dd7be166170beec337576818461268a3de67f"}, + {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14511a539afee6f9ab492b543060c7491c99924314977a55c98bfa2ee29ce78c"}, + {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3ccb8ac2d3c71cda472b75af42818981bdacf48d2e21c36331b50b4f16930163"}, + {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c142b88039b92e7e0cb2552e8967077e3179b22359e945574f5e2764c3953dcf"}, + {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f19169781dddae7478a32301b499b2858bc52fc45a112955e798ee307e294977"}, + {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13c56de6518e14b9bf6edde23c4c39dac5b48dcf04160ea7bce8fca8397cdf86"}, + {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:925d176a549f4832c6f69fa6026071294ab5910e82a0fe6c6228fce17b0706bd"}, + {file = "rpds_py-0.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:78f0b6877bfce7a3d1ff150391354a410c55d3cdce386f862926a4958ad5ab7e"}, + {file = "rpds_py-0.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3dd645e2b0dcb0fd05bf58e2e54c13875847687d0b71941ad2e757e5d89d4356"}, + {file = "rpds_py-0.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4f676e21db2f8c72ff0936f895271e7a700aa1f8d31b40e4e43442ba94973899"}, + {file = "rpds_py-0.20.1-cp310-none-win32.whl", hash = "sha256:648386ddd1e19b4a6abab69139b002bc49ebf065b596119f8f37c38e9ecee8ff"}, + {file = "rpds_py-0.20.1-cp310-none-win_amd64.whl", hash = "sha256:d9ecb51120de61e4604650666d1f2b68444d46ae18fd492245a08f53ad2b7711"}, + {file = "rpds_py-0.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:762703bdd2b30983c1d9e62b4c88664df4a8a4d5ec0e9253b0231171f18f6d75"}, + {file = "rpds_py-0.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0b581f47257a9fce535c4567782a8976002d6b8afa2c39ff616edf87cbeff712"}, + {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:842c19a6ce894493563c3bd00d81d5100e8e57d70209e84d5491940fdb8b9e3a"}, + {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42cbde7789f5c0bcd6816cb29808e36c01b960fb5d29f11e052215aa85497c93"}, + {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c8e9340ce5a52f95fa7d3b552b35c7e8f3874d74a03a8a69279fd5fca5dc751"}, + {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ba6f89cac95c0900d932c9efb7f0fb6ca47f6687feec41abcb1bd5e2bd45535"}, + {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a916087371afd9648e1962e67403c53f9c49ca47b9680adbeef79da3a7811b0"}, + {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:200a23239781f46149e6a415f1e870c5ef1e712939fe8fa63035cd053ac2638e"}, + {file = "rpds_py-0.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:58b1d5dd591973d426cbb2da5e27ba0339209832b2f3315928c9790e13f159e8"}, + {file = "rpds_py-0.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6b73c67850ca7cae0f6c56f71e356d7e9fa25958d3e18a64927c2d930859b8e4"}, + {file = "rpds_py-0.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d8761c3c891cc51e90bc9926d6d2f59b27beaf86c74622c8979380a29cc23ac3"}, + {file = "rpds_py-0.20.1-cp311-none-win32.whl", hash = "sha256:cd945871335a639275eee904caef90041568ce3b42f402c6959b460d25ae8732"}, + {file = "rpds_py-0.20.1-cp311-none-win_amd64.whl", hash = "sha256:7e21b7031e17c6b0e445f42ccc77f79a97e2687023c5746bfb7a9e45e0921b84"}, + {file = "rpds_py-0.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:36785be22066966a27348444b40389f8444671630063edfb1a2eb04318721e17"}, + {file = "rpds_py-0.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:142c0a5124d9bd0e2976089484af5c74f47bd3298f2ed651ef54ea728d2ea42c"}, + {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbddc10776ca7ebf2a299c41a4dde8ea0d8e3547bfd731cb87af2e8f5bf8962d"}, + {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:15a842bb369e00295392e7ce192de9dcbf136954614124a667f9f9f17d6a216f"}, + {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be5ef2f1fc586a7372bfc355986226484e06d1dc4f9402539872c8bb99e34b01"}, + {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbcf360c9e3399b056a238523146ea77eeb2a596ce263b8814c900263e46031a"}, + {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecd27a66740ffd621d20b9a2f2b5ee4129a56e27bfb9458a3bcc2e45794c96cb"}, + {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0b937b2a1988f184a3e9e577adaa8aede21ec0b38320d6009e02bd026db04fa"}, + {file = "rpds_py-0.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6889469bfdc1eddf489729b471303739bf04555bb151fe8875931f8564309afc"}, + {file = "rpds_py-0.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:19b73643c802f4eaf13d97f7855d0fb527fbc92ab7013c4ad0e13a6ae0ed23bd"}, + {file = "rpds_py-0.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3c6afcf2338e7f374e8edc765c79fbcb4061d02b15dd5f8f314a4af2bdc7feb5"}, + {file = "rpds_py-0.20.1-cp312-none-win32.whl", hash = "sha256:dc73505153798c6f74854aba69cc75953888cf9866465196889c7cdd351e720c"}, + {file = "rpds_py-0.20.1-cp312-none-win_amd64.whl", hash = "sha256:8bbe951244a838a51289ee53a6bae3a07f26d4e179b96fc7ddd3301caf0518eb"}, + {file = "rpds_py-0.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6ca91093a4a8da4afae7fe6a222c3b53ee4eef433ebfee4d54978a103435159e"}, + {file = "rpds_py-0.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b9c2fe36d1f758b28121bef29ed1dee9b7a2453e997528e7d1ac99b94892527c"}, + {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f009c69bc8c53db5dfab72ac760895dc1f2bc1b62ab7408b253c8d1ec52459fc"}, + {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6740a3e8d43a32629bb9b009017ea5b9e713b7210ba48ac8d4cb6d99d86c8ee8"}, + {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32b922e13d4c0080d03e7b62991ad7f5007d9cd74e239c4b16bc85ae8b70252d"}, + {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe00a9057d100e69b4ae4a094203a708d65b0f345ed546fdef86498bf5390982"}, + {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49fe9b04b6fa685bd39237d45fad89ba19e9163a1ccaa16611a812e682913496"}, + {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa7ac11e294304e615b43f8c441fee5d40094275ed7311f3420d805fde9b07b4"}, + {file = "rpds_py-0.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aa97af1558a9bef4025f8f5d8c60d712e0a3b13a2fe875511defc6ee77a1ab7"}, + {file = "rpds_py-0.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:483b29f6f7ffa6af845107d4efe2e3fa8fb2693de8657bc1849f674296ff6a5a"}, + {file = "rpds_py-0.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37fe0f12aebb6a0e3e17bb4cd356b1286d2d18d2e93b2d39fe647138458b4bcb"}, + {file = "rpds_py-0.20.1-cp313-none-win32.whl", hash = "sha256:a624cc00ef2158e04188df5e3016385b9353638139a06fb77057b3498f794782"}, + {file = "rpds_py-0.20.1-cp313-none-win_amd64.whl", hash = "sha256:b71b8666eeea69d6363248822078c075bac6ed135faa9216aa85f295ff009b1e"}, + {file = "rpds_py-0.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5b48e790e0355865197ad0aca8cde3d8ede347831e1959e158369eb3493d2191"}, + {file = "rpds_py-0.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3e310838a5801795207c66c73ea903deda321e6146d6f282e85fa7e3e4854804"}, + {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249280b870e6a42c0d972339e9cc22ee98730a99cd7f2f727549af80dd5a963"}, + {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e79059d67bea28b53d255c1437b25391653263f0e69cd7dec170d778fdbca95e"}, + {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b431c777c9653e569986ecf69ff4a5dba281cded16043d348bf9ba505486f36"}, + {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da584ff96ec95e97925174eb8237e32f626e7a1a97888cdd27ee2f1f24dd0ad8"}, + {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a0629ec053fc013808a85178524e3cb63a61dbc35b22499870194a63578fb9"}, + {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fbf15aff64a163db29a91ed0868af181d6f68ec1a3a7d5afcfe4501252840bad"}, + {file = "rpds_py-0.20.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:07924c1b938798797d60c6308fa8ad3b3f0201802f82e4a2c41bb3fafb44cc28"}, + {file = "rpds_py-0.20.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4a5a844f68776a7715ecb30843b453f07ac89bad393431efbf7accca3ef599c1"}, + {file = "rpds_py-0.20.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:518d2ca43c358929bf08f9079b617f1c2ca6e8848f83c1225c88caeac46e6cbc"}, + {file = "rpds_py-0.20.1-cp38-none-win32.whl", hash = "sha256:3aea7eed3e55119635a74bbeb80b35e776bafccb70d97e8ff838816c124539f1"}, + {file = "rpds_py-0.20.1-cp38-none-win_amd64.whl", hash = "sha256:7dca7081e9a0c3b6490a145593f6fe3173a94197f2cb9891183ef75e9d64c425"}, + {file = "rpds_py-0.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b41b6321805c472f66990c2849e152aff7bc359eb92f781e3f606609eac877ad"}, + {file = "rpds_py-0.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a90c373ea2975519b58dece25853dbcb9779b05cc46b4819cb1917e3b3215b6"}, + {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16d4477bcb9fbbd7b5b0e4a5d9b493e42026c0bf1f06f723a9353f5153e75d30"}, + {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84b8382a90539910b53a6307f7c35697bc7e6ffb25d9c1d4e998a13e842a5e83"}, + {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4888e117dd41b9d34194d9e31631af70d3d526efc363085e3089ab1a62c32ed1"}, + {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5265505b3d61a0f56618c9b941dc54dc334dc6e660f1592d112cd103d914a6db"}, + {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e75ba609dba23f2c95b776efb9dd3f0b78a76a151e96f96cc5b6b1b0004de66f"}, + {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1791ff70bc975b098fe6ecf04356a10e9e2bd7dc21fa7351c1742fdeb9b4966f"}, + {file = "rpds_py-0.20.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d126b52e4a473d40232ec2052a8b232270ed1f8c9571aaf33f73a14cc298c24f"}, + {file = "rpds_py-0.20.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c14937af98c4cc362a1d4374806204dd51b1e12dded1ae30645c298e5a5c4cb1"}, + {file = "rpds_py-0.20.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3d089d0b88996df627693639d123c8158cff41c0651f646cd8fd292c7da90eaf"}, + {file = "rpds_py-0.20.1-cp39-none-win32.whl", hash = "sha256:653647b8838cf83b2e7e6a0364f49af96deec64d2a6578324db58380cff82aca"}, + {file = "rpds_py-0.20.1-cp39-none-win_amd64.whl", hash = "sha256:fa41a64ac5b08b292906e248549ab48b69c5428f3987b09689ab2441f267d04d"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a07ced2b22f0cf0b55a6a510078174c31b6d8544f3bc00c2bcee52b3d613f74"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:68cb0a499f2c4a088fd2f521453e22ed3527154136a855c62e148b7883b99f9a"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa3060d885657abc549b2a0f8e1b79699290e5d83845141717c6c90c2df38311"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95f3b65d2392e1c5cec27cff08fdc0080270d5a1a4b2ea1d51d5f4a2620ff08d"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2cc3712a4b0b76a1d45a9302dd2f53ff339614b1c29603a911318f2357b04dd2"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d4eea0761e37485c9b81400437adb11c40e13ef513375bbd6973e34100aeb06"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f5179583d7a6cdb981151dd349786cbc318bab54963a192692d945dd3f6435d"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fbb0ffc754490aff6dabbf28064be47f0f9ca0b9755976f945214965b3ace7e"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a94e52537a0e0a85429eda9e49f272ada715506d3b2431f64b8a3e34eb5f3e75"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:92b68b79c0da2a980b1c4197e56ac3dd0c8a149b4603747c4378914a68706979"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:93da1d3db08a827eda74356f9f58884adb254e59b6664f64cc04cdff2cc19b0d"}, + {file = "rpds_py-0.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:754bbed1a4ca48479e9d4182a561d001bbf81543876cdded6f695ec3d465846b"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ca449520e7484534a2a44faf629362cae62b660601432d04c482283c47eaebab"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:9c4cb04a16b0f199a8c9bf807269b2f63b7b5b11425e4a6bd44bd6961d28282c"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb63804105143c7e24cee7db89e37cb3f3941f8e80c4379a0b355c52a52b6780"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:55cd1fa4ecfa6d9f14fbd97ac24803e6f73e897c738f771a9fe038f2f11ff07c"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f8f741b6292c86059ed175d80eefa80997125b7c478fb8769fd9ac8943a16c0"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fc212779bf8411667234b3cdd34d53de6c2b8b8b958e1e12cb473a5f367c338"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ad56edabcdb428c2e33bbf24f255fe2b43253b7d13a2cdbf05de955217313e6"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a3a1e9ee9728b2c1734f65d6a1d376c6f2f6fdcc13bb007a08cc4b1ff576dc5"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e13de156137b7095442b288e72f33503a469aa1980ed856b43c353ac86390519"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:07f59760ef99f31422c49038964b31c4dfcfeb5d2384ebfc71058a7c9adae2d2"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:59240685e7da61fb78f65a9f07f8108e36a83317c53f7b276b4175dc44151684"}, + {file = "rpds_py-0.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:83cba698cfb3c2c5a7c3c6bac12fe6c6a51aae69513726be6411076185a8b24a"}, + {file = "rpds_py-0.20.1.tar.gz", hash = "sha256:e1791c4aabd117653530dccd24108fa03cc6baf21f58b950d0a73c3b3b29a350"}, +] + +[[package]] +name = "ruamel-yaml" +version = "0.18.6" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"}, + {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"}, +] + +[package.dependencies] +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} + +[package.extras] +docs = ["mercurial (>5.7)", "ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.12" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +optional = false +python-versions = ">=3.9" +files = [ + {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5"}, + {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969"}, + {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df"}, + {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76"}, + {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6"}, + {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd"}, + {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da"}, + {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28"}, + {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6"}, + {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e"}, + {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e"}, + {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52"}, + {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642"}, + {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2"}, + {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4"}, + {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb"}, + {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632"}, + {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d"}, + {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c"}, + {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd"}, + {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31"}, + {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680"}, + {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5"}, + {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4"}, + {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a"}, + {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475"}, + {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef"}, + {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6"}, + {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf"}, + {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1"}, + {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6"}, + {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3"}, + {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:fc4b630cd3fa2cf7fce38afa91d7cfe844a9f75d7f0f36393fa98815e911d987"}, + {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bc5f1e1c28e966d61d2519f2a3d451ba989f9ea0f2307de7bc45baa526de9e45"}, + {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a0e060aace4c24dcaf71023bbd7d42674e3b230f7e7b97317baf1e953e5b519"}, + {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2f1c3765db32be59d18ab3953f43ab62a761327aafc1594a2a1fbe038b8b8a7"}, + {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d85252669dc32f98ebcd5d36768f5d4faeaeaa2d655ac0473be490ecdae3c285"}, + {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e143ada795c341b56de9418c58d028989093ee611aa27ffb9b7f609c00d813ed"}, + {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-win32.whl", hash = "sha256:beffaed67936fbbeffd10966a4eb53c402fafd3d6833770516bf7314bc6ffa12"}, + {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-win_amd64.whl", hash = "sha256:040ae85536960525ea62868b642bdb0c2cc6021c9f9d507810c0c604e66f5a7b"}, + {file = "ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f"}, +] + [[package]] name = "secretstorage" version = "3.3.3" @@ -1659,6 +2113,85 @@ h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + [[package]] name = "zipp" version = "3.20.2" @@ -1681,4 +2214,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4.0" -content-hash = "ef4f65da1d058e9d892ff8182d8e8d38a5ef9f20ca3435cd344ae35221598570" +content-hash = "bb870a867f40e1c77c5e26b9cf2123cc78b891e9d823d48763c02065b7994c3b" diff --git a/pyproject.toml b/pyproject.toml index 931fdc5..5f9fc60 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,8 +56,8 @@ include = [ exclude = ["tag_publish/node_modules/**/test"] [tool.poetry.scripts] -tag_publish = "tag_publish.cli:main" -tag_publish_new = "tag_publish.new:main" +tag-publish = "tag_publish.cli:main" +tag-publish-new = "tag_publish.new:main" [tool.poetry.dependencies] python = ">=3.9,<4.0" @@ -66,6 +66,10 @@ twine = "5.1.1" PyYAML = "6.0.2" id = "1.4.0" security-md = "0.2.3" +application-download = "0.0.1.dev3" +PyGithub = "2.4.0" +debian-inspector = "31.1.0" +multi-repo-automation = "1.4.1" [tool.poetry.group.dev.dependencies] prospector = { version = "1.12.1", extras = ["with-bandit", "with-mypy", "with-pyroma"] } diff --git a/tag_publish/__init__.py b/tag_publish/__init__.py index e4c29cb..631a86c 100644 --- a/tag_publish/__init__.py +++ b/tag_publish/__init__.py @@ -1,3 +1,245 @@ """ Tag Publish main module. """ + +import os.path +import re +import subprocess # nosec +from re import Match, Pattern +from typing import Any, Optional, TypedDict, cast + +import github +import requests +import ruamel.yaml +import security_md + +import tag_publish.configuration + +VersionTransform = TypedDict( + "VersionTransform", + { + # The from regular expression + "from": Pattern[str], + # The expand regular expression: https://docs.python.org/3/library/re.html#re.Match.expand + "to": str, + }, + total=False, +) + + +class GH: + """GitHub helper class.""" + + def __init__(self) -> None: + """Initialize the GitHub helper class.""" + token = os.environ["GITHUB_TOKEN"] + self.auth = github.Auth.Token(token) + self.github = github.Github(auth=self.auth) + self.repo = self.github.get_repo(os.environ["GITHUB_REPOSITORY"]) + self.default_branch = self.repo.default_branch + + +def get_security_md(gh: GH) -> security_md.Security: + """ + Get the SECURITY.md file. + + Arguments: + gh: The GitHub helper + + """ + security_file = gh.repo.get_contents("SECURITY.md") + assert isinstance(security_file, github.ContentFile.ContentFile) + return security_md.Security(security_file.decoded_content.decode("utf-8")) + + +def merge(default_config: Any, config: Any) -> Any: + """ + Deep merge the dictionaries (on dictionaries only, not on arrays). + + Arguments: + default_config: The default config that will be applied + config: The base config, will be modified + + """ + if not isinstance(default_config, dict) or not isinstance(config, dict): + return config + + for key in default_config: + if key not in config: + config[key] = default_config[key] + else: + merge(default_config[key], config[key]) + return config + + +def get_config(gh: GH) -> tag_publish.configuration.Configuration: + """ + Get the configuration, with project and auto detections. + """ + config: tag_publish.configuration.Configuration = {} + if os.path.exists("ci/config.yaml"): + with open("ci/config.yaml", encoding="utf-8") as open_file: + yaml_ = ruamel.yaml.YAML() + config = yaml_.load(open_file) + + merge( + { + "version": { + "tag_to_version_re": [ + {"from": r"([0-9]+.[0-9]+.[0-9]+)", "to": r"\1"}, + ], + "branch_to_version_re": [ + {"from": r"([0-9]+.[0-9]+)", "to": r"\1"}, + {"from": gh.default_branch, "to": gh.default_branch}, + ], + } + }, + config, + ) + + return config + + +def get_value(matched: Optional[Match[str]], config: Optional[VersionTransform], value: str) -> str: + """ + Get the final value. + + `match`, `config` and `value` are the result of `match`. + + The `config` should have a `to` key with an expand template. + + Arguments: + matched: The matched object to a regular expression + config: The result of `compile` + value: The default value on returned no match + + Return the value + + """ + return matched.expand(config.get("to", r"\1")) if matched is not None and config is not None else value + + +def compile_re( + config: tag_publish.configuration.VersionTransform, prefix: str = "" +) -> list[VersionTransform]: + """ + Compile the from as a regular expression of a dictionary of the config list. + + to be used with convert and match + + Arguments: + config: The transform config + prefix: The version prefix + + Return the compiled transform config. + + """ + result = [] + for conf in config: + new_conf = cast(VersionTransform, dict(conf)) + + from_re = conf.get("from", r"(.*)") + if from_re[0] == "^": + from_re = from_re[1:] + if from_re[-1] != "$": + from_re += "$" + from_re = f"^{re.escape(prefix)}{from_re}" + + new_conf["from"] = re.compile(from_re) + result.append(new_conf) + return result + + +def match( + value: str, config: list[VersionTransform] +) -> tuple[Optional[Match[str]], Optional[VersionTransform], str]: + """ + Get the matched version. + + Arguments: + --------- + value: That we want to match with + config: The result of `compile` + + Returns the re match object, the matched config and the value as a tuple + On no match it returns None, value + + """ + for conf in config: + matched = conf["from"].match(value) + if matched is not None: + return matched, conf, value + return None, None, value + + +def does_match(value: str, config: list[VersionTransform]) -> bool: + """ + Check if the version match with the config patterns. + + Arguments: + --------- + value: That we want to match with + config: The result of `compile` + + Returns True it it does match else False + + """ + matched, _, _ = match(value, config) + return matched is not None + + +def check_response(response: requests.Response, raise_for_status: bool = True) -> Any: + """ + Check the response and raise an exception if it's not ok. + + Also print the X-Ratelimit- headers to get information about the rate limiting. + """ + for header in response.headers: + if header.lower().startswith("x-ratelimit-"): + print(f"{header}: {response.headers[header]}") + if raise_for_status: + response.raise_for_status() + + +def add_authorization_header(headers: dict[str, str]) -> dict[str, str]: + """ + Add the Authorization header needed to be authenticated on GitHub. + + Arguments: + headers: The headers + + Return the headers (to be chained) + + """ + try: + token = os.environ["GITHUB_TOKEN"].strip() + headers["Authorization"] = f"Bearer {token}" + return headers + except FileNotFoundError: + return headers + + +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 "SNYK_ORG" in env: + subprocess.run([snyk_bin, "config", "set", f"org={env['SNYK_ORG']}"], check=True, env=env) + + return snyk_bin, env + + +class PublishedPayload(TypedDict, total=False): + """ + The payload to send to the dispatch event. + """ + + type: str + name: str + path: str + version: str + tag: str + repository: str + version_type: str + id: int diff --git a/tag_publish/applications-versions.yaml b/tag_publish/applications-versions.yaml new file mode 100644 index 0000000..1ee744e --- /dev/null +++ b/tag_publish/applications-versions.yaml @@ -0,0 +1,2 @@ +# https://docs.renovatebot.com/modules/datasource/#github-releases-datasource +helm/chart-releaser: v1.6.1 # github-releases diff --git a/tag_publish/cli.py b/tag_publish/cli.py index e5c3aa5..bfde520 100644 --- a/tag_publish/cli.py +++ b/tag_publish/cli.py @@ -5,14 +5,17 @@ """ import argparse +import json import os +import os.path +import random import re import subprocess # nosec import sys from re import Match from typing import Optional, cast -import requests +import application_download.cli import security_md import yaml @@ -21,8 +24,6 @@ import tag_publish.lib.docker import tag_publish.lib.oidc import tag_publish.publish -import tag_publish.scripts.download_applications -from tag_publish.scripts.trigger_image_update import dispatch def match(tpe: str, base_re: str) -> Optional[Match[str]]: @@ -86,7 +87,8 @@ def main() -> None: ) args = parser.parse_args() - config = tag_publish.get_config() + github = tag_publish.GH() + config = tag_publish.get_config(github) # Describe the kind of release we do: rebuild (specified with --type), version_tag, version_branch, # feature_branch, feature_tag (for pull request) @@ -166,55 +168,51 @@ def main() -> None: else: print(f"Create release type {version_type}: {version}") + github = tag_publish.GH() + success = True + published_payload: list[tag_publish.PublishedPayload] = [] + pypi_config = cast( - tag_publish.configuration.PublishPypiConfig, - config.get("publish", {}).get("pypi", {}) if config.get("publish", {}).get("pypi", False) else {}, + tag_publish.configuration.Pypi, + config.get("pypi", {}) if config.get("pypi", False) else {}, ) if pypi_config: if pypi_config["packages"]: tag_publish.lib.oidc.pypi_login() for package in pypi_config["packages"]: - if ( - package.get("group", tag_publish.configuration.PUBLISH_PIP_PACKAGE_GROUP_DEFAULT) - == args.group - ): - publish = version_type in pypi_config.get("versions", []) + if package.get("group", tag_publish.configuration.PIP_PACKAGE_GROUP_DEFAULT) == args.group: + publish = version_type in pypi_config.get( + "versions", tag_publish.configuration.PYPI_VERSIONS_DEFAULT + ) + path = package.get("path", tag_publish.configuration.PYPI_PACKAGE_PATH_DEFAULT) if args.dry_run: - print( - f"{'Publishing' if publish else 'Checking'} " - f"'{package.get('path')}' to pypi, skipping (dry run)" - ) + print(f"{'Publishing' if publish else 'Checking'} '{path}' to pypi, skipping (dry run)") else: - success &= tag_publish.publish.pip(package, version, version_type, publish) + success &= tag_publish.publish.pip(package, version, version_type, publish, github) + published_payload.append( + { + "type": "pypi", + "path": "path", + "version": version, + "version_type": version_type, + } + ) docker_config = cast( - tag_publish.configuration.PublishDockerConfig, - config.get("publish", {}).get("docker", {}) if config.get("publish", {}).get("docker", False) else {}, + tag_publish.configuration.Docker, + config.get("docker", {}) if config.get("docker", False) else {}, ) if docker_config: - full_repo = tag_publish.get_repository() - full_repo_split = full_repo.split("/") - master_branch, _ = tag_publish.get_master_branch(full_repo_split) security_text = "" if local: with open("SECURITY.md", encoding="utf-8") as security_file: security_text = security_file.read() + security = security_md.Security(security_text) else: - security_response = requests.get( - f"https://raw.githubusercontent.com/{full_repo}/{master_branch}/SECURITY.md", - headers=tag_publish.add_authorization_header({}), - timeout=int(os.environ.get("C2CCIUTILS_TIMEOUT", "30")), - ) - tag_publish.check_response(security_response, False) - if security_response.ok: - security_text = security_response.text - elif security_response.status_code != 404: - print(f"::error:: {security_response.status_code} {security_response.text}") - sys.exit(1) - - security = security_md.Security(security_text) + security = tag_publish.get_security_md(github) + version_index = security.version_index alternate_tag_index = security.alternate_tag_index @@ -247,13 +245,8 @@ def main() -> None: images_snyk: set[str] = set() versions = args.docker_versions.split(",") if args.docker_versions else [version] for image_conf in docker_config.get("images", []): - if ( - image_conf.get("group", tag_publish.configuration.PUBLISH_DOCKER_IMAGE_GROUP_DEFAULT) - == args.group - ): - for tag_config in image_conf.get( - "tags", tag_publish.configuration.PUBLISH_DOCKER_IMAGE_TAGS_DEFAULT - ): + if image_conf.get("group", tag_publish.configuration.DOCKER_IMAGE_GROUP_DEFAULT) == args.group: + for tag_config in image_conf.get("tags", tag_publish.configuration.DOCKER_IMAGE_TAGS_DEFAULT): tag_src = tag_config.format(version="latest") image_source = f"{image_conf['name']}:{tag_src}" images_src.add(image_source) @@ -277,21 +270,17 @@ def main() -> None: check=True, ) - tags_calendar = [] for name, conf in { **cast( - dict[str, tag_publish.configuration.PublishDockerRepository], + dict[str, tag_publish.configuration.DockerRepository], tag_publish.configuration.DOCKER_REPOSITORY_DEFAULT, ), **docker_config.get("repository", {}), }.items(): for docker_version in versions: - tag_dst = tag_config.format(version=docker_version) - if tag_dst not in tags_calendar: - tags_calendar.append(tag_dst) if version_type in conf.get( "versions", - tag_publish.configuration.PUBLISH_DOCKER_REPOSITORY_VERSIONS_DEFAULT, + tag_publish.configuration.DOCKER_REPOSITORY_VERSIONS_DEFAULT, ): tags = [ tag_config.format(version=alt_tag) @@ -306,24 +295,19 @@ def main() -> None: ) else: success &= tag_publish.publish.docker( - conf, name, image_conf, tag_src, tags, images_full + conf, + name, + image_conf, + tag_src, + tags, + images_full, + version_type, + published_payload, ) if args.dry_run: sys.exit(0) - dispatch_config = docker_config.get("dispatch", {}) - if dispatch_config is not False and images_full: - dispatch( - dispatch_config.get( - "repository", tag_publish.configuration.DOCKER_DISPATCH_REPOSITORY_DEFAULT - ), - dispatch_config.get( - "event-type", tag_publish.configuration.DOCKER_DISPATCH_EVENT_TYPE_DEFAULT - ), - images_full, - ) - snyk_exec, env = tag_publish.snyk_exec() for image in images_snyk: print(f"::group::Snyk check {image}") @@ -333,7 +317,7 @@ def main() -> None: if version_type in ("version_branch", "version_tag"): monitor_args = docker_config.get("snyk", {}).get( "monitor_args", - tag_publish.configuration.PUBLISH_DOCKER_SNYK_MONITOR_ARGS_DEFAULT, + tag_publish.configuration.DOCKER_SNYK_MONITOR_ARGS_DEFAULT, ) if monitor_args is not False: subprocess.run( # pylint: disable=subprocess-run-check @@ -349,7 +333,7 @@ def main() -> None: env=env, ) test_args = docker_config.get("snyk", {}).get( - "test_args", tag_publish.configuration.PUBLISH_DOCKER_SNYK_TEST_ARGS_DEFAULT + "test_args", tag_publish.configuration.DOCKER_SNYK_TEST_ARGS_DEFAULT ) snyk_error = False if test_args is not False: @@ -406,24 +390,23 @@ def main() -> None: success = False helm_config = cast( - tag_publish.configuration.PublishHelmConfig, - config.get("publish", {}).get("helm", {}) if config.get("publish", {}).get("helm", False) else {}, + tag_publish.configuration.HelmConfig, + config.get("helm", {}) if config.get("helm", False) else {}, ) - if helm_config and helm_config["folders"] and version_type in helm_config.get("versions", []): - tag_publish.scripts.download_applications.download_tag_publish_applications("helm/chart-releaser") - - owner, repo = full_repo_split + if ( + helm_config + and helm_config["folders"] + and version_type in helm_config.get("versions", tag_publish.configuration.HELM_VERSIONS_DEFAULT) + ): + application_download.cli.download_application("helm/chart-releaser") + + owner = github.repo.owner.login + repo = github.repo.name commit_sha = ( subprocess.run(["git", "rev-parse", "HEAD"], check=True, stdout=subprocess.PIPE) .stdout.strip() .decode() ) - token = ( - os.environ["GITHUB_TOKEN"].strip() - if "GITHUB_TOKEN" in os.environ - else tag_publish.gopass("gs/ci/github/token/gopass") - ) - assert token is not None if version_type == "version_branch": last_tag = ( subprocess.run( @@ -449,7 +432,36 @@ def main() -> None: version = ".".join(versions) for folder in helm_config["folders"]: + token = os.environ["GITHUB_TOKEN"] success &= tag_publish.publish.helm(folder, version, owner, repo, commit_sha, token) + published_payload.append( + { + "type": "helm", + "path": folder, + "version": version, + "version_type": version_type, + } + ) + + config = tag_publish.get_config(tag_publish.GH()) + + for published in published_payload: + for dispatch_config in config.get("dispatch", []): + repository = dispatch_config.get("repository") + event_type = dispatch_config.get( + "event-type", tag_publish.configuration.DISPATCH_EVENT_TYPE_DEFAULT + ) + + id_ = random.randint(1, 100000) # nosec # noqa: S311 + published["id"] = id_ + + if repository: + print(f"Triggering {event_type}:{id_} on {repository} with {json.dumps(published)}") + github_repo = github.github.get_repo(repository) + else: + print(f"Triggering {event_type}:{id_} with {json.dumps(published)}") + github_repo = github.repo + github_repo.create_repository_dispatch(event_type, published) # type: ignore[arg-type] if not success: sys.exit(1) diff --git a/tag_publish/configuration.py b/tag_publish/configuration.py index 1c38955..899b75f 100644 --- a/tag_publish/configuration.py +++ b/tag_publish/configuration.py @@ -19,57 +19,84 @@ class Configuration(TypedDict, total=False): The version configurations """ - docker: "PublishDocker" + docker: "Docker" """ - Publish Docker. + Docker. The configuration used to publish on Docker - - Aggregation type: oneOf - Subtype: "PublishDockerConfig" """ - pypi: "PublishPypi" + pypi: "Pypi" """ - publish pypi. + pypi. Configuration to publish on pypi - - default: - {} - - Aggregation type: oneOf - Subtype: "PublishPypiConfig" """ - helm: "PublishHelm" + helm: "Helm" """ - publish helm. + helm. Configuration to publish Helm charts on GitHub release Aggregation type: oneOf - Subtype: "PublishHelmConfig" + Subtype: "HelmConfig" + """ + + dispatch: List["DispatchConfig"] + """ + Dispatch. + + default: + - {} """ DISPATCH_CONFIG_DEFAULT: Dict[str, Any] = {} -""" Default value of the field path 'Publish Docker config dispatch oneof0' """ +""" Default value of the field path 'Dispatch item' """ + + +DISPATCH_DEFAULT = [{}] +""" Default value of the field path 'configuration dispatch' """ -DOCKER_DISPATCH_EVENT_TYPE_DEFAULT = "image-update" +DISPATCH_EVENT_TYPE_DEFAULT = "published" """ Default value of the field path 'dispatch config event-type' """ -DOCKER_DISPATCH_REPOSITORY_DEFAULT = "camptocamp/argocd-gs-gmf-apps" +DISPATCH_REPOSITORY_DEFAULT = "camptocamp/argocd-gs-gmf-apps" """ Default value of the field path 'dispatch config repository' """ +DOCKER_IMAGE_GROUP_DEFAULT = "default" +""" Default value of the field path 'Docker image group' """ + + +DOCKER_IMAGE_TAGS_DEFAULT = ["{version}"] +""" Default value of the field path 'Docker image tags' """ + + +DOCKER_LATEST_DEFAULT = True +""" Default value of the field path 'Docker latest' """ + + DOCKER_REPOSITORY_DEFAULT = { "github": {"server": "ghcr.io", "versions": ["version_tag", "version_branch", "rebuild"]}, "dockerhub": {}, } -""" Default value of the field path 'Publish Docker config repository' """ +""" Default value of the field path 'Docker repository' """ + + +DOCKER_REPOSITORY_VERSIONS_DEFAULT = ["version_tag", "version_branch", "rebuild", "feature_branch"] +""" Default value of the field path 'Docker repository versions' """ + + +DOCKER_SNYK_MONITOR_ARGS_DEFAULT = ["--app-vulns"] +""" Default value of the field path 'Docker snyk monitor_args' """ + + +DOCKER_SNYK_TEST_ARGS_DEFAULT = ["--app-vulns", "--severity-threshold=critical"] +""" Default value of the field path 'Docker snyk test_args' """ # | dispatch config. @@ -81,90 +108,43 @@ class Configuration(TypedDict, total=False): DispatchConfig = TypedDict( "DispatchConfig", { - # | Docker dispatch repository. + # | Dispatch repository. # | # | The repository name to be triggered # | # | default: camptocamp/argocd-gs-gmf-apps "repository": str, - # | Docker dispatch event type. + # | Dispatch event type. # | # | The event type to be triggered # | - # | default: image-update + # | default: published "event-type": str, }, total=False, ) -PUBLISH_DOCKER_IMAGE_GROUP_DEFAULT = "default" -""" Default value of the field path 'Publish Docker image group' """ - - -PUBLISH_DOCKER_IMAGE_TAGS_DEFAULT = ["{version}"] -""" Default value of the field path 'Publish Docker image tags' """ - - -PUBLISH_DOCKER_LATEST_DEFAULT = True -""" Default value of the field path 'Publish Docker config latest' """ - - -PUBLISH_DOCKER_REPOSITORY_VERSIONS_DEFAULT = ["version_tag", "version_branch", "rebuild", "feature_branch"] -""" Default value of the field path 'Publish Docker repository versions' """ - - -PUBLISH_DOCKER_SNYK_MONITOR_ARGS_DEFAULT = ["--app-vulns"] -""" Default value of the field path 'Publish Docker config snyk monitor_args' """ - - -PUBLISH_DOCKER_SNYK_TEST_ARGS_DEFAULT = ["--app-vulns", "--severity-threshold=critical"] -""" Default value of the field path 'Publish Docker config snyk test_args' """ - - -PUBLISH_PIP_PACKAGE_GROUP_DEFAULT = "default" -""" Default value of the field path 'publish pypi package group' """ - - -PUBLISH_PYPI_CONFIG_DEFAULT: Dict[str, Any] = {} -""" Default value of the field path 'publish pypi oneof0' """ - - -PUBLISH_PYPI_DEFAULT: Dict[str, Any] = {} -""" Default value of the field path 'publish_pypi' """ - - -PublishDocker = Union["PublishDockerConfig", Literal[False]] -""" -Publish Docker. - -The configuration used to publish on Docker - -Aggregation type: oneOf -Subtype: "PublishDockerConfig" -""" - - -class PublishDockerConfig(TypedDict, total=False): +class Docker(TypedDict, total=False): """ - Publish Docker config. + Docker. The configuration used to publish on Docker """ latest: bool """ - Publish Docker latest. + Docker latest. Publish the latest version on tag latest default: True """ - images: List["PublishDockerImage"] + images: List["DockerImage"] """ List of images to be published """ - repository: Dict[str, "PublishDockerRepository"] + repository: Dict[str, "DockerRepository"] """ Docker repository. @@ -180,27 +160,16 @@ class PublishDockerConfig(TypedDict, total=False): - rebuild """ - dispatch: Union["DispatchConfig", "_PublishDockerConfigDispatchOneof1"] - """ - Send a dispatch event to an other repository - - default: - {} - - Aggregation type: oneOf - Subtype: "DispatchConfig" - """ - - snyk: "_PublishDockerConfigSnyk" + snyk: "_DockerSnyk" """ Checks the published images with Snyk """ -class PublishDockerImage(TypedDict, total=False): - """Publish Docker image.""" +class DockerImage(TypedDict, total=False): + """Docker image.""" group: str """ - Publish Docker image group. + Docker image group. The image is in the group, should be used with the --group option of tag-publish script @@ -212,7 +181,7 @@ class PublishDockerImage(TypedDict, total=False): tags: List[str] """ - publish docker image tags. + docker image tags. The tag name, will be formatted with the version=, the image with version=latest should be present when we call the tag-publish script @@ -221,15 +190,15 @@ class PublishDockerImage(TypedDict, total=False): """ -class PublishDockerRepository(TypedDict, total=False): - """Publish Docker repository.""" +class DockerRepository(TypedDict, total=False): + """Docker repository.""" server: str """ The server URL """ versions: List[str] """ - Publish Docker repository versions. + Docker repository versions. The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script @@ -241,20 +210,24 @@ class PublishDockerRepository(TypedDict, total=False): """ -PublishHelm = Union["PublishHelmConfig", Literal[False]] +HELM_VERSIONS_DEFAULT = ["version_tag"] +""" Default value of the field path 'helm config versions' """ + + +Helm = Union["HelmConfig", Literal[False]] """ -publish helm. +helm. Configuration to publish Helm charts on GitHub release Aggregation type: oneOf -Subtype: "PublishHelmConfig" +Subtype: "HelmConfig" """ -class PublishHelmConfig(TypedDict, total=False): +class HelmConfig(TypedDict, total=False): """ - publish helm config. + helm config. Configuration to publish on Helm charts on GitHub release """ @@ -263,50 +236,59 @@ class PublishHelmConfig(TypedDict, total=False): """ The folders that will be published """ versions: List[str] - """ The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script """ + """ + helm versions. + The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script -PublishPypi = Union["PublishPypiConfig", "_PublishPypiOneof1"] -""" -publish pypi. + default: + - version_tag + """ -Configuration to publish on pypi -default: - {} +PIP_PACKAGE_GROUP_DEFAULT = "default" +""" Default value of the field path 'pypi package group' """ -Aggregation type: oneOf -Subtype: "PublishPypiConfig" -""" + +PYPI_PACKAGE_PATH_DEFAULT = "." +""" Default value of the field path 'pypi package path' """ -class PublishPypiConfig(TypedDict, total=False): +PYPI_VERSIONS_DEFAULT = ["version_tag"] +""" Default value of the field path 'pypi versions' """ + + +class Pypi(TypedDict, total=False): """ - publish pypi config. + pypi. Configuration to publish on pypi - - default: - {} """ - packages: List["PublishPypiPackage"] + packages: List["PypiPackage"] """ The configuration of packages that will be published """ versions: List[str] - """ The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script """ + """ + pypi versions. + + The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script + default: + - version_tag + """ -class PublishPypiPackage(TypedDict, total=False): + +class PypiPackage(TypedDict, total=False): """ - publish pypi package. + pypi package. The configuration of package that will be published """ group: str """ - Publish pip package group. + pip package group. The image is in the group, should be used with the --group option of tag-publish script @@ -314,7 +296,13 @@ class PublishPypiPackage(TypedDict, total=False): """ path: str - """ The path of the pypi package """ + """ + pypi package path. + + The path of the pypi package + + default: . + """ build_command: List[str] """ The command used to do the build """ @@ -350,47 +338,28 @@ class Version(TypedDict, total=False): """ -_PUBLISH_DOCKER_CONFIG_DISPATCH_DEFAULT: Dict[str, Any] = {} -""" Default value of the field path 'Publish Docker config dispatch' """ - - -_PUBLISH_DOCKER_CONFIG_DISPATCH_ONEOF1_DEFAULT: Dict[str, Any] = {} -""" Default value of the field path 'Publish Docker config dispatch oneof1' """ - - -_PUBLISH_DOCKER_SNYK_MONITOR_ARGS_ONEOF0_DEFAULT = ["--app-vulns"] -""" Default value of the field path 'Publish Docker Snyk monitor args oneof0' """ +_DOCKER_SNYK_MONITOR_ARGS_ONEOF0_DEFAULT = ["--app-vulns"] +""" Default value of the field path 'Docker Snyk monitor args oneof0' """ -_PUBLISH_DOCKER_SNYK_MONITOR_ARGS_ONEOF1_DEFAULT = ["--app-vulns"] -""" Default value of the field path 'Publish Docker Snyk monitor args oneof1' """ +_DOCKER_SNYK_MONITOR_ARGS_ONEOF1_DEFAULT = ["--app-vulns"] +""" Default value of the field path 'Docker Snyk monitor args oneof1' """ -_PUBLISH_DOCKER_SNYK_TEST_ARGS_ONEOF0_DEFAULT = ["--app-vulns", "--severity-threshold=critical"] -""" Default value of the field path 'Publish Docker Snyk test args oneof0' """ +_DOCKER_SNYK_TEST_ARGS_ONEOF0_DEFAULT = ["--app-vulns", "--severity-threshold=critical"] +""" Default value of the field path 'Docker Snyk test args oneof0' """ -_PUBLISH_DOCKER_SNYK_TEST_ARGS_ONEOF1_DEFAULT = ["--app-vulns", "--severity-threshold=critical"] -""" Default value of the field path 'Publish Docker Snyk test args oneof1' """ +_DOCKER_SNYK_TEST_ARGS_ONEOF1_DEFAULT = ["--app-vulns", "--severity-threshold=critical"] +""" Default value of the field path 'Docker Snyk test args oneof1' """ -_PUBLISH_PYPI_ONEOF1_DEFAULT: Dict[str, Any] = {} -""" Default value of the field path 'publish pypi oneof1' """ - - -_PublishDockerConfigDispatchOneof1 = Literal[False] -""" -default: - {} -""" - - -class _PublishDockerConfigSnyk(TypedDict, total=False): +class _DockerSnyk(TypedDict, total=False): """Checks the published images with Snyk""" - monitor_args: Union["_PublishDockerSnykMonitorArgsOneof0", "_PublishDockerSnykMonitorArgsOneof1"] + monitor_args: Union["_DockerSnykMonitorArgsOneof0", "_DockerSnykMonitorArgsOneof1"] """ - Publish Docker Snyk monitor args. + Docker Snyk monitor args. The arguments to pass to the Snyk container monitor command @@ -400,9 +369,9 @@ class _PublishDockerConfigSnyk(TypedDict, total=False): Aggregation type: oneOf """ - test_args: Union["_PublishDockerSnykTestArgsOneof0", "_PublishDockerSnykTestArgsOneof1"] + test_args: Union["_DockerSnykTestArgsOneof0", "_DockerSnykTestArgsOneof1"] """ - Publish Docker Snyk test args. + Docker Snyk test args. The arguments to pass to the Snyk container test command @@ -414,21 +383,21 @@ class _PublishDockerConfigSnyk(TypedDict, total=False): """ -_PublishDockerSnykMonitorArgsOneof0 = List[str] +_DockerSnykMonitorArgsOneof0 = List[str] """ default: - --app-vulns """ -_PublishDockerSnykMonitorArgsOneof1 = Literal[False] +_DockerSnykMonitorArgsOneof1 = Literal[False] """ default: - --app-vulns """ -_PublishDockerSnykTestArgsOneof0 = List[str] +_DockerSnykTestArgsOneof0 = List[str] """ default: - --app-vulns @@ -436,7 +405,7 @@ class _PublishDockerConfigSnyk(TypedDict, total=False): """ -_PublishDockerSnykTestArgsOneof1 = Literal[False] +_DockerSnykTestArgsOneof1 = Literal[False] """ default: - --app-vulns @@ -444,13 +413,6 @@ class _PublishDockerConfigSnyk(TypedDict, total=False): """ -_PublishPypiOneof1 = Literal[False] -""" -default: - {} -""" - - _VersionTransformItem = TypedDict( "_VersionTransformItem", { diff --git a/tag_publish/lib/docker.py b/tag_publish/lib/docker.py index df2237b..51255b6 100644 --- a/tag_publish/lib/docker.py +++ b/tag_publish/lib/docker.py @@ -9,8 +9,6 @@ import yaml from debian_inspector.version import Version -import tag_publish.configuration - def get_dpkg_packages_versions( image: str, @@ -26,8 +24,6 @@ def get_dpkg_packages_versions( Where `debian_11` corresponds on last path element for 'Debian 11' from https://repology.org/repositories/statistics """ - dpkg_configuration = tag_publish.get_config().get("dpkg", {}) - os_release = {} try: os_release_process = subprocess.run( @@ -85,15 +81,13 @@ def get_dpkg_packages_versions( if version is None: print(f"Error: Missing version for package {package}") else: - if package not in dpkg_configuration.get("ignored_packages", []): - package = dpkg_configuration.get("packages_mapping", {}).get(package, package) - if package in package_version and version != package_version[package]: - print( - f"The package {package} has different version " - f"({package_version[package]} != {version})" - ) - if package not in ("base-files",): - package_version[package] = version + if package in package_version and version != package_version[package]: + print( + f"The package {package} has different version " + f"({package_version[package]} != {version})" + ) + if package not in ("base-files",): + package_version[package] = version package = value version = None if name == "Version" and version is None: diff --git a/tag_publish/lib/trigger_image_update.py b/tag_publish/lib/trigger_image_update.py deleted file mode 100644 index cb71893..0000000 --- a/tag_publish/lib/trigger_image_update.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 - -""" -Trigger an image update on the argocd repository. -""" - -import os.path -import random -import subprocess # nosec - -import requests - - -def dispatch(repository: str, event_type: str, images_full: list[str]) -> None: - """ - Trigger an image update on the argocd repository. - """ - id_ = random.randint(1, 100000) # nosec # noqa: S311 - print(f"Triggering {event_type}:{id_} on {repository} with {','.join(images_full)}") - - response = requests.post( - f"https://api.github.com/repos/{repository}/dispatches", - headers={ - "Content-Type": "application/json2", - "Accept": "application/vnd.github.v3+json", - "Authorization": "token " - + subprocess.run( - ["gopass", "show", "gs/ci/github/token/gopass"], check=True, stdout=subprocess.PIPE - ) - .stdout.decode() - .strip(), - }, - json={"event_type": event_type, "client_payload": {"name": " ".join(images_full), "id": id_}}, - timeout=int(os.environ.get("C2CCIUTILS_TIMEOUT", "30")), - ) - response.raise_for_status() diff --git a/tag_publish/new.py b/tag_publish/new.py index d0962d6..f5b2f8a 100644 --- a/tag_publish/new.py +++ b/tag_publish/new.py @@ -7,9 +7,18 @@ import subprocess # nosec import multi_repo_automation as mra -import ruamel +import ruamel.yaml +import security_md -import tag_publish + +def _get_default_branch() -> str: + """Get the default branch name.""" + return subprocess.run( + ["gh", "repo", "view", "--json", "defaultBranchRef", "--jq", ".defaultBranchRef.name"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ).stdout.strip() def main() -> None: @@ -54,6 +63,12 @@ def main() -> None: "--upstream-supported-until", help="The date until the version is supported upstream", ) + args_parser.add_argument( + "--remote", + default="origin", + help="The remote to push the branch", + ) + arguments = args_parser.parse_args() # Get the repo information e.g.: @@ -73,13 +88,13 @@ def main() -> None: check=True, ).stdout.strip() + default_branch = _get_default_branch() + # Checkout the master branch - subprocess.run(["git", "checkout", repo.get("master_branch", "master")], check=True) + subprocess.run(["git", "checkout", default_branch], check=True) # Pull it from origin - subprocess.run( - ["git", "pull", repo.get("remote", "origin"), repo.get("master_branch", "master")], check=True - ) + subprocess.run(["git", "pull", arguments, default_branch], check=True) # Push it to a new stabilization branch if arguments.version: @@ -104,10 +119,18 @@ def main() -> None: # # # Do the changes for the new version # # # - remotes = [r for r in mra.run(["git", "remote"], stdout=subprocess.PIPE).stdout.split() if r != ""] + remotes = [ + r + for r in subprocess.run( + ["git", "remote"], stdout=subprocess.PIPE, encoding="utf-8", check=True + ).stdout.split() + if r != "" + ] remote_branches = [ b.strip()[len("remotes/") :] - for b in mra.run(["git", "branch", "--all"], stdout=subprocess.PIPE).stdout.split() + for b in subprocess.run( + ["git", "branch", "--all"], stdout=subprocess.PIPE, encoding="utf-8", check=True + ).stdout.split() if b != "" and b.strip().startswith("remotes/") ] if "upstream" in remotes: @@ -117,14 +140,14 @@ def main() -> None: else: remote_branches = ["/".join(b.split("/")[1:]) for b in remote_branches] - config = tag_publish.get_config() - branch_re = tag_publish.compile_re(config["version"].get("branch_to_version_re", [])) - branches_match = [tag_publish.match(b, branch_re) for b in remote_branches] - version_branch = {m.groups()[0] if m.groups() else b: b for m, c, b in branches_match if m is not None} + if os.path.exists("SECURITY.md"): + with open("SECURITY.md", encoding="utf-8") as security_file: + security_text = security_file.read() + security = security_md.Security(security_text) - stabilization_branches = [ - version_branch.get(version, version) for version in mra.get_stabilization_versions(repo) - ] + stabilization_branches = security.branches() + else: + stabilization_branches = [] modified_files = [] if version: @@ -132,8 +155,8 @@ def main() -> None: if os.path.exists("SECURITY.md"): modified_files.append("SECURITY.md") - with mra.Edit("SECURITY.md") as security_md: - security_md_lines = security_md.data.split("\n") + with mra.Edit("SECURITY.md") as security_md_file: + security_md_lines = security_md_file.data.split("\n") index = -1 for i, line in enumerate(security_md_lines): if line.startswith("| "): @@ -143,11 +166,11 @@ def main() -> None: if arguments.upstream_supported_until: new_line += f" {arguments.upstream_supported_until} |" - security_md.data = "\n".join( + security_md_file.data = "\n".join( [*security_md_lines[: index + 1], new_line, *security_md_lines[index + 1 :]] ) - stabilization_branches_with_master = [*stabilization_branches, repo.get("master_branch", "master")] + stabilization_branches_with_master = [*stabilization_branches, default_branch] for labels in mra.gh_json("label", ["name"], "list"): if ( @@ -237,7 +260,8 @@ def main() -> None: subprocess.run(["git", "checkout", old_branch_name, "--"], check=True) if url: - subprocess.run([mra.get_browser(), url], check=True) + pr_number = url.rsplit("/", 1)[-1] + mra.gh("browse", pr_number) else: mra.gh("browse") diff --git a/tag_publish/package-lock.json b/tag_publish/package-lock.json deleted file mode 100644 index f1557bc..0000000 --- a/tag_publish/package-lock.json +++ /dev/null @@ -1,437 +0,0 @@ -{ - "name": "c2ccicheck", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "c2ccicheck", - "version": "1.0.0", - "dependencies": { - "snyk": "1.1294.0" - } - }, - "node_modules/@sentry-internal/tracing": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.119.2.tgz", - "integrity": "sha512-V2W+STWrafyGJhQv3ulMFXYDwWHiU6wHQAQBShsHVACiFaDrJ2kPRet38FKv4dMLlLlP2xN+ss2e5zv3tYlTiQ==", - "license": "MIT", - "dependencies": { - "@sentry/core": "7.119.2", - "@sentry/types": "7.119.2", - "@sentry/utils": "7.119.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/core": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz", - "integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==", - "license": "MIT", - "dependencies": { - "@sentry/types": "7.119.2", - "@sentry/utils": "7.119.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/integrations": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.119.2.tgz", - "integrity": "sha512-dCuXKvbUE3gXVVa696SYMjlhSP6CxpMH/gl4Jk26naEB8Xjsn98z/hqEoXLg6Nab73rjR9c/9AdKqBbwVMHyrQ==", - "license": "MIT", - "dependencies": { - "@sentry/core": "7.119.2", - "@sentry/types": "7.119.2", - "@sentry/utils": "7.119.2", - "localforage": "^1.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/node": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.119.2.tgz", - "integrity": "sha512-TPNnqxh+Myooe4jTyRiXrzrM2SH08R4+nrmBls4T7lKp2E5R/3mDSe/YTn5rRcUt1k1hPx1NgO/taG0DoS5cXA==", - "license": "MIT", - "dependencies": { - "@sentry-internal/tracing": "7.119.2", - "@sentry/core": "7.119.2", - "@sentry/integrations": "7.119.2", - "@sentry/types": "7.119.2", - "@sentry/utils": "7.119.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/types": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz", - "integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/utils": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz", - "integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==", - "license": "MIT", - "dependencies": { - "@sentry/types": "7.119.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "license": "MIT" - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "license": "MIT" - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "license": "BSD-3-Clause", - "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "license": "MIT" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "license": "ISC" - }, - "node_modules/lie": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", - "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", - "license": "MIT", - "dependencies": { - "immediate": "~3.0.5" - } - }, - "node_modules/localforage": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", - "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", - "license": "Apache-2.0", - "dependencies": { - "lie": "3.1.1" - } - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "license": "BSD-3-Clause", - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "license": "MIT" - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/snyk": { - "version": "1.1294.0", - "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.1294.0.tgz", - "integrity": "sha512-4RBj3Lfccz5+6L2Kw9bt7icF+ex3antwt9PkSl2oEulI7mgqvc8VUFLnezg8c6PY60IPM9DrSSmNjXBac10I3Q==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@sentry/node": "^7.36.0", - "global-agent": "^3.0.0" - }, - "bin": { - "snyk": "bin/snyk" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause" - }, - "node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/tag_publish/package.json b/tag_publish/package.json deleted file mode 100644 index 001faa2..0000000 --- a/tag_publish/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "c2ccicheck", - "version": "1.0.0", - "description": "", - "author": "", - "dependencies": { - "snyk": "1.1294.0" - } -} diff --git a/tag_publish/publish.py b/tag_publish/publish.py index 433e7ac..9a9aa1d 100644 --- a/tag_publish/publish.py +++ b/tag_publish/publish.py @@ -8,6 +8,7 @@ import re import subprocess # nosec import sys +from typing import Optional import ruamel import tomllib @@ -16,7 +17,11 @@ def pip( - package: tag_publish.configuration.PublishPypiPackage, version: str, version_type: str, publish: bool + package: tag_publish.configuration.PypiPackage, + version: str, + version_type: str, + publish: bool, + github: tag_publish.GH, ) -> bool: """ Publish to pypi. @@ -27,6 +32,7 @@ def pip( version_branch, feature_branch, feature_tag (for pull request) publish: If False only check the package package: The package configuration + github: The GitHub helper """ print(f"::group::{'Publishing' if publish else 'Checking'} '{package.get('path')}' to pypi") @@ -37,10 +43,8 @@ def pip( env = {} env["VERSION"] = version env["VERSION_TYPE"] = version_type - full_repo = tag_publish.get_repository() - full_repo_split = full_repo.split("/") - master_branch, _ = tag_publish.get_master_branch(full_repo_split) - is_master = master_branch == version + default_branch = github.repo.default_branch + is_master = default_branch == version env["IS_MASTER"] = "TRUE" if is_master else "FALSE" cwd = os.path.abspath(package.get("path", ".")) @@ -103,12 +107,14 @@ def pip( def docker( - config: tag_publish.configuration.PublishDockerRepository, + config: tag_publish.configuration.DockerRepository, name: str, - image_config: tag_publish.configuration.PublishDockerImage, + image_config: tag_publish.configuration.DockerImage, tag_src: str, dst_tags: list[str], images_full: list[str], + version_type: str, + published: Optional[list[tag_publish.PublishedPayload]] = None, ) -> bool: """ Publish to a Docker registry. @@ -126,6 +132,9 @@ def docker( tag_src: The source tag (usually latest) dst_tags: Publish using the provided tags images_full: The list of published images (with tag), used to build the dispatch event + version_type: Describe the kind of release we do: rebuild (specified using --type), version_tag, + version_branch, feature_branch, feature_tag (for pull request) + published: The list of published artifacts to be filled """ print( @@ -149,6 +158,16 @@ def docker( check=True, ) new_images_full.append(f"{config['server']}/{image_config['name']}:{tag}") + if published is not None: + published.append( + { + "type": "docker", + "repository": config["server"], + "name": image_config["name"], + "tag": tag, + "version_type": version_type, + } + ) else: for tag in dst_tags: if tag_src != tag: @@ -161,6 +180,16 @@ def docker( ], check=True, ) + if published is not None: + published.append( + { + "type": "docker", + "repository": "docker.io", + "name": image_config["name"], + "tag": tag, + "version_type": version_type, + } + ) new_images_full.append(f"{image_config['name']}:{tag}") for image in new_images_full: diff --git a/tag_publish/schema.json b/tag_publish/schema.json index 0e827aa..1cf3309 100644 --- a/tag_publish/schema.json +++ b/tag_publish/schema.json @@ -6,204 +6,165 @@ "description": "Tag Publish configuration file", "additionalProperties": false, "definitions": { - "publish_docker": { - "title": "Publish Docker", + "docker": { + "title": "Docker", "description": "The configuration used to publish on Docker", - "oneOf": [ - { - "title": "Publish Docker config", - "description": "The configuration used to publish on Docker", - "type": "object", - "properties": { - "latest": { - "description": "Publish the latest version on tag latest", - "title": "Publish Docker latest", - "default": true, - "type": "boolean" - }, - "images": { - "description": "List of images to be published", - "type": "array", - "items": { - "title": "Publish Docker image", - "type": "object", - "properties": { - "group": { - "description": "The image is in the group, should be used with the --group option of tag-publish script", - "title": "Publish Docker image group", - "default": "default", - "type": "string" - }, - "name": { - "description": "The image name", - "type": "string" - }, - "tags": { - "description": "The tag name, will be formatted with the version=, the image with version=latest should be present when we call the tag-publish script", - "title": "publish docker image tags", - "type": "array", - "default": ["{version}"], - "items": { - "type": "string" - } - } + "type": "object", + "properties": { + "latest": { + "description": "Publish the latest version on tag latest", + "title": "Docker latest", + "default": true, + "type": "boolean" + }, + "images": { + "description": "List of images to be published", + "type": "array", + "items": { + "title": "Docker image", + "type": "object", + "properties": { + "group": { + "description": "The image is in the group, should be used with the --group option of tag-publish script", + "title": "Docker image group", + "default": "default", + "type": "string" + }, + "name": { + "description": "The image name", + "type": "string" + }, + "tags": { + "description": "The tag name, will be formatted with the version=, the image with version=latest should be present when we call the tag-publish script", + "title": "docker image tags", + "type": "array", + "default": ["{version}"], + "items": { + "type": "string" } } + } + } + }, + "repository": { + "title": "Docker repository", + "description": "The repository where we should publish the images", + "default": { + "github": { + "server": "ghcr.io", + "versions": ["version_tag", "version_branch", "rebuild"] }, - "repository": { - "title": "Docker repository", - "description": "The repository where we should publish the images", - "default": { - "github": { - "server": "ghcr.io", - "versions": ["version_tag", "version_branch", "rebuild"] - }, - "dockerhub": {} + "dockerhub": {} + }, + "type": "object", + "additionalProperties": { + "title": "Docker repository", + "type": "object", + "properties": { + "server": { + "description": "The server URL", + "type": "string" }, - "type": "object", - "additionalProperties": { - "title": "Publish Docker repository", - "type": "object", - "properties": { - "server": { - "description": "The server URL", - "type": "string" - }, - "versions": { - "description": "The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script", - "title": "Publish Docker repository versions", - "type": "array", - "default": ["version_tag", "version_branch", "rebuild", "feature_branch"], - "items": { - "type": "string" - } - } + "versions": { + "description": "The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script", + "title": "Docker repository versions", + "type": "array", + "default": ["version_tag", "version_branch", "rebuild", "feature_branch"], + "items": { + "type": "string" } } - }, - "dispatch": { - "description": "Send a dispatch event to an other repository", - "default": {}, + } + } + }, + "snyk": { + "description": "Checks the published images with Snyk", + "type": "object", + "properties": { + "monitor_args": { + "description": "The arguments to pass to the Snyk container monitor command", + "title": "Docker Snyk monitor args", + "default": ["--app-vulns"], "oneOf": [ { - "type": "object", - "title": "dispatch config", - "description": "Send a dispatch event to an other repository", - "properties": { - "repository": { - "title": "Docker dispatch repository", - "description": "The repository name to be triggered", - "default": "camptocamp/argocd-gs-gmf-apps", - "type": "string" - }, - "event-type": { - "title": "Docker dispatch event type", - "description": "The event type to be triggered", - "default": "image-update", - "type": "string" - } + "type": "array", + "items": { + "type": "string" } }, { "const": false } ] }, - "snyk": { - "description": "Checks the published images with Snyk", - "type": "object", - "properties": { - "monitor_args": { - "description": "The arguments to pass to the Snyk container monitor command", - "title": "Publish Docker Snyk monitor args", - "default": ["--app-vulns"], - "oneOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { "const": false } - ] + "test_args": { + "description": "The arguments to pass to the Snyk container test command", + "title": "Docker Snyk test args", + "default": ["--app-vulns", "--severity-threshold=critical"], + "oneOf": [ + { + "type": "array", + "items": { + "type": "string" + } }, - "test_args": { - "description": "The arguments to pass to the Snyk container test command", - "title": "Publish Docker Snyk test args", - "default": ["--app-vulns", "--severity-threshold=critical"], - "oneOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { "const": false } - ] - } - } + { "const": false } + ] } } - }, - { "const": false } - ] + } + } }, - "publish_pypi": { - "title": "publish pypi", + "pypi": { + "title": "pypi", "description": "Configuration to publish on pypi", - "default": {}, - "oneOf": [ - { - "title": "publish pypi config", - "description": "Configuration to publish on pypi", - "type": "object", - "properties": { - "packages": { - "description": "The configuration of packages that will be published", - "type": "array", - "items": { - "title": "publish pypi package", - "description": "The configuration of package that will be published", - "type": "object", - "properties": { - "group": { - "description": "The image is in the group, should be used with the --group option of tag-publish script", - "title": "Publish pip package group", - "default": "default", - "type": "string" - }, - "path": { - "description": "The path of the pypi package", - "type": "string" - }, - "build_command": { - "description": "The command used to do the build", - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "versions": { - "description": "The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script", - "type": "array", - "items": { + "type": "object", + "properties": { + "packages": { + "description": "The configuration of packages that will be published", + "type": "array", + "items": { + "title": "pypi package", + "description": "The configuration of package that will be published", + "type": "object", + "properties": { + "group": { + "description": "The image is in the group, should be used with the --group option of tag-publish script", + "title": "pip package group", + "default": "default", "type": "string" + }, + "path": { + "title": "pypi package path", + "description": "The path of the pypi package", + "type": "string", + "default": "." + }, + "build_command": { + "description": "The command used to do the build", + "type": "array", + "items": { + "type": "string" + } } } } }, - { - "const": false + "versions": { + "title": "pypi versions", + "description": "The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script", + "type": "array", + "default": ["version_tag"], + "items": { + "type": "string" + } } - ] + } }, - "publish_helm": { - "title": "publish helm", + "helm": { + "title": "helm", "description": "Configuration to publish Helm charts on GitHub release", "oneOf": [ { - "title": "publish helm config", + "title": "helm config", "description": "Configuration to publish on Helm charts on GitHub release", "type": "object", "properties": { @@ -215,8 +176,10 @@ } }, "versions": { + "title": "helm versions", "description": "The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script", "type": "array", + "default": ["version_tag"], "items": { "type": "string" } @@ -257,8 +220,34 @@ "tag_to_version_re": { "$ref": "#/definitions/version_transform" } } }, - "docker": { "$ref": "#/definitions/publish_docker" }, - "pypi": { "$ref": "#/definitions/publish_pypi" }, - "helm": { "$ref": "#/definitions/publish_helm" } + "docker": { "$ref": "#/definitions/docker" }, + "pypi": { "$ref": "#/definitions/pypi" }, + "helm": { "$ref": "#/definitions/helm" }, + "dispatch": { + "title": "Dispatch", + "type": "array", + "default": [{}], + + "items": { + "title": "dispatch config", + "description": "Send a dispatch event to an other repository", + "default": {}, + "type": "object", + "properties": { + "repository": { + "title": "Dispatch repository", + "description": "The repository name to be triggered", + "default": "camptocamp/argocd-gs-gmf-apps", + "type": "string" + }, + "event-type": { + "title": "Dispatch event type", + "description": "The event type to be triggered", + "default": "published", + "type": "string" + } + } + } + } } }