diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8ceeaf0..a92237a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,9 @@ +--- version: 2 + + updates: -- package-ecosystem: "pip" - directory: "/" - schedule: - interval: "weekly" + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..43dba8f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,39 @@ +--- +name: Tests + + +on: + push: + branches: + - main + pull_request: + branches: + - "*" + + +jobs: + build: + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v3 + + # Use GitHub's Docker registry to cache intermediate layers + - run: echo ${{ secrets.GITHUB_TOKEN }} | docker login docker.pkg.github.com + -u $GITHUB_ACTOR --password-stdin + - run: docker pull docker.pkg.github.com/$GITHUB_REPOSITORY/aleph-message-build-cache + || true + + - name: Build the Docker image + run: | + git fetch --tags + docker build . -t aleph-message:${GITHUB_REF##*/} -f Dockerfile --cache-from=docker.pkg.github.com/$GITHUB_REPOSITORY/aleph-message-build-cache + + - name: Cache the image on GitHub's repository + run: docker tag aleph-message:${GITHUB_REF##*/} docker.pkg.github.com/$GITHUB_REPOSITORY/aleph-message-build-cache + && docker push docker.pkg.github.com/$GITHUB_REPOSITORY/aleph-message-build-cache + || true + + - name: Test that aleph_message is correctly installed + run: |- + docker run aleph-message:${GITHUB_REF##*/} python -c "from aleph_message import parse_message" diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml new file mode 100644 index 0000000..3adf330 --- /dev/null +++ b/.github/workflows/code-quality.yml @@ -0,0 +1,35 @@ +--- +name: Tests + + +on: + push: + branches: + - main + pull_request: + branches: + - "*" + + +jobs: + code-quality: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cache/pip + ~/.local/share/hatch/env/virtual/ + key: ${GITHUB_JOB}-${{ hashFiles('pyproject.toml') }} + restore-keys: | + ${GITHUB_JOB} + + - run: | + python3 -m venv /tmp/venv + /tmp/venv/bin/python -m pip install --upgrade pip hatch coverage + + - run: /tmp/venv/bin/hatch run linting:all diff --git a/.github/workflows/pytests.yml b/.github/workflows/pytests.yml new file mode 100644 index 0000000..c1a641c --- /dev/null +++ b/.github/workflows/pytests.yml @@ -0,0 +1,45 @@ +--- +name: Tests + + +on: + push: + branches: + - main + pull_request: + branches: + - "*" + + +jobs: + tests: + strategy: + fail-fast: false + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + os: [ubuntu-22.04, ubuntu-24.04] + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cache/pip + ~/.local/share/hatch/env/virtual/ + key: ${{ runner.os }}-${GITHUB_JOB}-${{ hashFiles('pyproject.toml') }} + restore-keys: | + ${{ runner.os }}-${GITHUB_JOB} + + - run: | + python3 -m venv /tmp/venv + /tmp/venv/bin/python -m pip install --upgrade pip hatch coverage + + - run: /tmp/venv/bin/hatch run testing:cov + + - uses: codecov/codecov-action@v4.0.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: aleph-im/aleph-message diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index b0412e0..0000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Tests - -on: - push: - pull_request: - branches: - - main - -jobs: - build: - runs-on: ubuntu-20.04 - - steps: - - uses: actions/checkout@v3 - - # Use GitHub's Docker registry to cache intermediate layers - - run: echo ${{ secrets.GITHUB_TOKEN }} | docker login docker.pkg.github.com -u $GITHUB_ACTOR --password-stdin - - run: docker pull docker.pkg.github.com/$GITHUB_REPOSITORY/aleph-message-build-cache || true - - - name: Build the Docker image - run: | - git fetch --prune --unshallow --tags - docker build . -t aleph-message:${GITHUB_REF##*/} -f Dockerfile --cache-from=docker.pkg.github.com/$GITHUB_REPOSITORY/aleph-message-build-cache - - - name: Cache the image on GitHub's repository - run: docker tag aleph-message:${GITHUB_REF##*/} docker.pkg.github.com/$GITHUB_REPOSITORY/aleph-message-build-cache && docker push docker.pkg.github.com/$GITHUB_REPOSITORY/aleph-message-build-cache || true - - - name: Test with black in the Docker image - run: | - docker run aleph-message:${GITHUB_REF##*/} black --check aleph_message - - - name: Test with ruff in the Docker image - run: | - docker run aleph-message:${GITHUB_REF##*/} ruff check aleph_message - - - name: Pytest in the Docker image - run: | - docker run aleph-message:${GITHUB_REF##*/} pytest -vv --cov aleph_message - - - name: MyPy in the Docker image - run: | - docker run aleph-message:${GITHUB_REF##*/} mypy aleph_message --install-types --non-interactive --check-untyped-defs --ignore-missing-imports diff --git a/Dockerfile b/Dockerfile index 44f9492..ab0a24b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,7 @@ -FROM ubuntu:20.04 +FROM python:3.12 RUN apt-get update && apt-get install -y python3-pip -RUN pip install pytest requests types-requests pytest-cov mypy twine typing-extensions +RUN pip install types-requests mypy twine typing-extensions hatch COPY . /opt/aleph-message WORKDIR /opt/aleph-message -RUN pip install -e . -RUN pip install mypy ruff black \ No newline at end of file +RUN pip install . diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index c3c2909..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,9 +0,0 @@ -recursive-include aleph_message *.py -recursive-include aleph_message *.json - -include aleph_message/py.typed -include LICENSE -include pytest.ini -include test.sh -include Dockerfile -include .dockerignore diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..03ca350 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,164 @@ +[build-system] +build-backend = "hatchling.build" + +requires = [ "hatch-vcs", "hatchling" ] + +[project] +name = "aleph-message" +description = "Aleph.im message specification" +readme = "README.md" +license = { file = "LICENSE" } +authors = [ + { name = "Hugo Herter", email = "git@hugoherter.com" }, +] +requires-python = ">=3" +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: System :: Distributed Computing", +] +dynamic = [ "version" ] +dependencies = [ + "pydantic>=1.10.5,<2", + "typing-extensions>=4.5", +] +urls.Documentation = "https://aleph.im/" +urls.Homepage = "https://github.com/aleph-im/aleph-message" + +[tool.hatch.metadata] +allow-direct-references = true + +[tool.hatch.version] +source = "vcs" + +[tool.hatch.build.targets.wheel] +packages = [ + "Dockerfile", + "LICENSE", + "pyproject.toml", + "README.md", + "aleph_message", +] + +[tool.hatch.build.targets.sdist] +include = [ + "Dockerfile", + "LICENSE", + "pyproject.toml", + "README.md", + "aleph_message", +] + +[tool.hatch.envs.testing] +dependencies = [ + "requests", + "rich", + "pytest==8.0.1", + "pytest-cov==4.1.0", +] + +# XXX see https://github.com/aleph-im/pyaleph/blob/main/.github/workflows/pyaleph-ci.yml +[tool.hatch.envs.testing.scripts] +test = "pytest -v {args:.}" +test-cov = "pytest -v --cov {args:.}" +cov-report = [ + "- coverage combine", + "coverage report", +] +cov = [ + "test-cov", + "cov-report", +] + +[tool.hatch.envs.linting] +detached = true +dependencies = [ + "black==24.2.0", + "mypy==1.2.0", + "mypy-extensions==1.0.0", + "ruff==0.4.8", + "isort==5.13.2", + "check-sdist==0.1.3", + "yamlfix==1.16.1", + "pyproject-fmt==2.2.1", + "types-requests", + "typing-extensions", +] + +[tool.hatch.envs.linting.scripts] +typing = "mypy --config-file=pyproject.toml {args:} ./aleph_message/" +style = [ + "ruff check {args:.}", + "black --check --diff {args:} ./aleph_message/", + "isort --check-only --profile black {args:} ./aleph_message/", + "yamlfix --check .", + "pyproject-fmt --check pyproject.toml", +] +sdist = "check-sdist --inject-junk" +fmt = [ + "black {args:} ./aleph_message/", + "ruff check --fix {args:.} ./aleph_message/", + "isort --profile black {args:} ./aleph_message/", + "yamlfix .", + "pyproject-fmt pyproject.toml", + "style", +] +all = [ + "style", + "typing", + "sdist", +] + +[tool.isort] +profile = "black" + +[tool.check-sdist] +git-only = [ + "tests", + "docs", + "deployment", + ".coveragerc", + ".dockerignore", + "shell.nix", +] +default-ignore = true + +[tool.pytest] +markers = [ + "slow: marks tests as slow (deselect with '-m \"not slow\"')", +] + +[tool.coverage.run] +branch = true +parallel = true +source = [ + "aleph_message/", +] +omit = [ + "*/site-packages/*", +] + +[tool.coverage.paths] +source = [ + "aleph_message/", +] +omit = [ + "*/site-packages/*", +] + +[tool.mypy] +show_column_numbers = true +install_types = true +ignore_missing_imports = true + +[tool.yamlfix] +sequence_style = "keep_style" +preserve_quotes = true +whitelines = 1 +section_whitelines = 2 diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 7617853..0000000 --- a/pytest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -markers = - slow: marks tests as slow (deselect with '-m "not slow"') diff --git a/setup.py b/setup.py deleted file mode 100644 index 1c4cce1..0000000 --- a/setup.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -"""Aleph Message - Python library for the Aleph.im message specification -(c) 2022 OKESO for Aleph.im -""" - -import os -import re - - -def get_version(): - version_file = os.path.join("aleph_message", "__init__.py") - initfile_lines = open(version_file, "rt").readlines() - version = r"^__version__ = ['\"]([^'\"]*)['\"]" - - for line in initfile_lines: - mo = re.search(version, line, re.M) - if mo: - return mo.group(1) - raise RuntimeError(f"Unable to find version string in {version_file}.") - - -from setuptools import setup - -# allow setup.py to be run from any path -os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) - -with open("README.md") as file: - long_description = file.read() - -setup( - name="aleph-message", - version=get_version(), - description="Aleph.im message specification ", - long_description=long_description, - long_description_content_type="text/markdown", - author="Hugo Herter", - author_email="git@hugoherter.com", - url="https://github.com/aleph-im/aleph-message", - packages=[ - "aleph_message", - "aleph_message.models", - "aleph_message.models.execution", - ], - package_data={ - "aleph_message": ["py.typed"], - "aleph_message.models": ["py.typed"], - "aleph_message.models.execution": ["py.typed"], - }, - data_files=[], - install_requires=[ - "pydantic>=1.10.5,<2.0.0", - "typing_extensions>=4.5.0", - ], - license="MIT", - platform="any", - keywords="aleph.im message validation specification", - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Programming Language :: Python :: 3", - "Intended Audience :: Developers", - "Topic :: System :: Distributed Computing", - ], -) diff --git a/test.sh b/test.sh deleted file mode 100755 index 28d382b..0000000 --- a/test.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -set -euf - -podman build --loglevel 3 -t aleph-message . -podman run --rm -ti -v $(pwd)/aleph_message:/opt/aleph_message aleph-message pytest -vv -podman run --rm -ti -v $(pwd)/aleph_message:/opt/aleph_message aleph-message mypy --ignore-missing-imports aleph_message