Skip to content

Commit

Permalink
feat(action): add check for package versions
Browse files Browse the repository at this point in the history
  • Loading branch information
pchorus committed Apr 15, 2024
1 parent fc98d53 commit 2add0f2
Show file tree
Hide file tree
Showing 14 changed files with 477 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: CI

on: [ push ]

jobs:
lint-and-test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- uses: moneymeets/action-setup-python-poetry@master

- uses: moneymeets/moneymeets-composite-actions/lint-python@master

- run: poetry run python -m pytest --cov --cov-fail-under=45
45 changes: 45 additions & 0 deletions .idea/watcherTasks.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions .run/invalid_package_versions.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="invalid_package_versions" type="PythonConfigurationType" factoryName="Python">
<module name="action-setup-python-poetry" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="SDK_NAME" value="Python 3.12" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="invalid_package_versions.runner" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="true" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ runs:
cache: ${{ inputs.poetry_cache_enabled == 'true' && 'poetry' || ''}}
cache-dependency-path: ${{ inputs.poetry_cache_enabled == 'true' && format('{0}/poetry.lock', inputs.working_directory) || ''}}

- run: python ${{ github.action_path }}/invalid-package-versions.py
shell: bash
working-directory: ${{ inputs.working_directory }}

- run: |
if [ "$(echo ${{ steps.detect-versions.outputs.poetry-version }} | cut -c1-4)" == "1.5." ]; then
poetry lock --check
Expand Down
Empty file.
41 changes: 41 additions & 0 deletions invalid_package_versions/runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import itertools
import sys
import tomllib
from pathlib import Path
from typing import Sequence

IGNORE_PACKAGES = ("boto3",)


def get_version(version: str | dict) -> str | None:
return version if isinstance(version, str) else version.get("version")


def get_invalid_package_versions(pyproject_data: dict) -> Sequence[tuple[str, str]]:
poetry_data = pyproject_data["tool"]["poetry"]

return tuple(
(package, version_str)
for package, version in (
*poetry_data["dependencies"].items(),
*poetry_data["dev-dependencies"].items(),
*itertools.chain.from_iterable(
(group["dependencies"].items() for _, group in poetry_data.get("group", {}).items()),
),
)
if package not in IGNORE_PACKAGES
and (version_str := get_version(version)) not in ("*", None)
and not version_str.startswith("~")
)


def run():
if invalid_versions := get_invalid_package_versions(
pyproject_data=tomllib.loads(Path("pyproject.toml").read_text()),
):
print(f"Invalid package versions found in pyproject.toml: {invalid_versions}")
sys.exit(1)


if __name__ == "__main__":
sys.exit(run())
Empty file.
34 changes: 34 additions & 0 deletions invalid_package_versions/tests/data/pyproject_mock_invalid.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[tool.poetry]
name = "test-project"
version = "0.1.0"
description = "Testing only"
authors = ["moneymeets GmbH <service@moneymeets.com>"]


[tool.poetry.scripts]
merge_checks_runner = 'invalid_package_versions.runner:run'


[tool.poetry.dependencies]
python = ">=3.12"
boto3 = ">=1.26.148"


[tool.poetry.dev-dependencies]
pytest = ">=8"
pytest-cov = "*"

ruff = "*"


[tool.poetry.group.test-group-1.dependencies]
test-package-1 = ">=1"


[tool.poetry.group.test-group-2.dependencies]
test-package-2 = ">=1"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
34 changes: 34 additions & 0 deletions invalid_package_versions/tests/data/pyproject_mock_valid.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[tool.poetry]
name = "test-project"
version = "0.1.0"
description = "Testing only"
authors = ["moneymeets GmbH <service@moneymeets.com>"]


[tool.poetry.scripts]
merge_checks_runner = 'invalid_package_versions.runner:run'


[tool.poetry.dependencies]
python = "~3.12"
boto3 = ">=1.26.148"


[tool.poetry.dev-dependencies]
pytest = "*"
pytest-cov = "*"

ruff = "*"


[tool.poetry.group.test-group-1.dependencies]
test-package-1 = "*"


[tool.poetry.group.test-group-2.dependencies]
test-package-2 = "*"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import tomllib
from pathlib import Path
from unittest import TestCase

from invalid_package_versions.runner import get_invalid_package_versions

TEST_DATA_DIR = Path(__file__).parent / "data"


class GetInvalidPackageVersionsTest(TestCase):
valid_pyproject_toml = tomllib.loads((TEST_DATA_DIR / "pyproject_mock_valid.toml").read_text())
invalid_pyproject_toml = tomllib.loads((TEST_DATA_DIR / "pyproject_mock_invalid.toml").read_text())

def test_get_invalid_package_versions_success(self):
self.assertEqual((), get_invalid_package_versions(self.valid_pyproject_toml))

def test_get_invalid_package_versions_failed(self):
self.assertEqual(
(
("python", ">=3.12"),
("pytest", ">=8"),
("test-package-1", ">=1"),
("test-package-2", ">=1"),
),
get_invalid_package_versions(self.invalid_pyproject_toml),
)
12 changes: 12 additions & 0 deletions invalid_package_versions/tests/test_get_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from unittest import TestCase

from invalid_package_versions.runner import get_version


class GetVersionTest(TestCase):
def test_get_version_success(self):
self.assertEqual("*", get_version("*"))
self.assertEqual("*", get_version({"version": "*"}))

def test_get_version_failed(self):
self.assertEqual(None, get_version({}))
Loading

0 comments on commit 2add0f2

Please sign in to comment.