From fc7fb85d57165546b96676af2f8f5658a269a616 Mon Sep 17 00:00:00 2001 From: Dima Gerasimov Date: Wed, 20 May 2026 23:48:32 +0100 Subject: [PATCH] chore: update all ci files --- .github/workflows/main.yml | 51 ++++++++++++++++------------------ LICENSE.txt => LICENSE | 0 mypy.ini | 8 +++--- pyproject.toml | 28 +++++++++---------- ruff.toml | 12 ++++++++ src/dron/launchd.py | 2 +- src/dron/launchd_wrapper.py | 3 +- src/dron/notify/ntfy_common.py | 3 +- src/dron/systemd.py | 4 +-- 9 files changed, 58 insertions(+), 53 deletions(-) rename LICENSE.txt => LICENSE (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2a9e346..3452b67 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,23 +40,19 @@ jobs: # continue-on-error: ${{ matrix.platform == 'windows-latest' }} steps: - # ugh https://github.com/actions/toolkit/blob/main/docs/commands.md#path-manipulation - - run: echo "$HOME/.local/bin" >> $GITHUB_PATH - - uses: actions/checkout@v6 with: submodules: recursive fetch-depth: 0 # nicer to have all git history when debugging/for tests - - uses: actions/setup-python@v6 + - uses: astral-sh/setup-uv@v8.1.0 with: python-version: ${{ matrix.python-version }} - - - uses: astral-sh/setup-uv@v7 - with: - enable-cache: false # we don't have lock files, so can't use them as cache key + enable-cache: false # we don't have lock files during initial CI checkout, so can't use them as cache key - uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true # restrict to the user who kicked off pipeline if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} # explicit bash command is necessary for Windows CI runner, otherwise it thinks it's cmd... @@ -66,7 +62,7 @@ jobs: CI_MYPY_COVERAGE: ${{ matrix.platform == 'ubuntu-latest' && '--cobertura-xml-report .coverage.mypy' || '' }} - if: matrix.platform == 'ubuntu-latest' # no need to compute coverage for other platforms - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@v6 with: fail_ci_if_error: true # default false token: ${{ secrets.CODECOV_TOKEN }} @@ -77,7 +73,7 @@ jobs: pypi: # Do not run it for PRs/cron schedule etc. # NOTE: release tags are guarded by on: push: tags on the top. - if: github.event_name == 'push' && (startsWith(github.event.ref, 'refs/tags/') || (github.event.ref == format('refs/heads/{0}', github.event.repository.master_branch))) + if: github.event_name == 'push' && (github.ref_type == 'tag' || github.ref_name == github.event.repository.master_branch) # Ugh, I tried using matrix or something to explicitly generate only test pypi or prod pypi pipelines. # But github actions is so shit, it's impossible to do any logic at all, e.g. doesn't support conditional matrix, if/else statements for variables etc. @@ -88,30 +84,31 @@ jobs: permissions: # necessary for Trusted Publishing id-token: write - + env: + # always deploy merged master to test pypi + # always deploy tags to release pypi + TARGET: ${{ github.ref_type == 'tag' && 'pypi' || 'testpypi' }} + environment: + # for "deployments" tab on github + # sadly can't reuse env.TARGET here... + name: ${{ github.ref_type == 'tag' && 'pypi' || 'testpypi' }} + url: https://${{ github.ref_type == 'tag' && 'pypi.org' || 'test.pypi.org' }}/project/${{ steps.meta.outputs.pypi_name }}/ steps: - # ugh https://github.com/actions/toolkit/blob/main/docs/commands.md#path-manipulation - - run: echo "$HOME/.local/bin" >> $GITHUB_PATH - - uses: actions/checkout@v6 with: submodules: recursive fetch-depth: 0 # pull all commits to correctly infer vcs version - - uses: actions/setup-python@v6 + - uses: astral-sh/setup-uv@v8.1.0 with: python-version: '3.12' + enable-cache: false # we don't have lock files during initial CI checkout, so can't use them as cache key - - uses: astral-sh/setup-uv@v7 - with: - enable-cache: false # we don't have lock files, so can't use them as cache key + - name: 'release ${{ steps.meta.outputs.pypi_name }} to ${{ env.TARGET }}' + run: .ci/release ${{ env.TARGET == 'testpypi' && '--use-test-pypi' || '' }} - - name: 'release to test pypi' - # always deploy merged master to test pypi - if: github.event.ref == format('refs/heads/{0}', github.event.repository.master_branch) - run: .ci/release --use-test-pypi - - - name: 'release to prod pypi' - # always deploy tags to release pypi - if: startsWith(github.event.ref, 'refs/tags/') - run: .ci/release + - id: meta + shell: bash + run: | + pypi_name=$(unzip -p dist/*.whl '*.dist-info/METADATA' | awk '/^Name:/ {print $2; exit}') + echo "pypi_name=$pypi_name" >> "$GITHUB_OUTPUT" diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/mypy.ini b/mypy.ini index 7b1e535..28c255d 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,18 +1,18 @@ [mypy] pretty = True show_error_context = True -show_column_numbers = True show_error_end = True -check_untyped_defs = True - # see https://mypy.readthedocs.io/en/stable/error_code_list2.html +## NOTE: strict implies all of these.. will gradually move onto it +strict = False +check_untyped_defs = True warn_redundant_casts = True strict_equality = True warn_unused_ignores = True +## enable_error_code = deprecated,redundant-expr,possibly-undefined,truthy-bool,truthy-iterable,ignore-without-code,unused-awaitable - # an example of suppressing # [mypy-my.config.repos.pdfannots.pdfannots] # ignore_errors = True diff --git a/pyproject.toml b/pyproject.toml index 6b817b1..03e05ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,18 +14,14 @@ dependencies = [ "dbus-python; platform_system != 'Darwin'", # dbus interface to systemd ] requires-python = ">=3.12" -# FIXME dbus -## these need to be set if you're planning to upload to pypi +## these are only useful for pypi description = "What if cron and systemd had a baby?" -license = {file = "LICENSE.txt"} -authors = [ - {name = "Dima Gerasimov (@karlicoss)", email = "karlicoss@gmail.com"}, -] -maintainers = [ - {name = "Dima Gerasimov (@karlicoss)", email = "karlicoss@gmail.com"}, -] -[project.urls] +license = {file = "LICENSE"} +authors = [{name = "Dima Gerasimov (@karlicoss)", email = "karlicoss@gmail.com"}] +maintainers = [{name = "Dima Gerasimov (@karlicoss)", email = "karlicoss@gmail.com"}] + +[project.urls] # pypi will fetch some github stats/link, so somewhat useful Homepage = "https://github.com/karlicoss/dron" ## @@ -36,6 +32,7 @@ notify-telegram = [ # see https://github.com/rahiel/telegram-send/issues/115#issuecomment-1368728425 "telegram-send>=0.37", ] + [dependency-groups] testing = [ "pytest>=9", # need version 9 for proper namespace package support @@ -44,16 +41,14 @@ testing = [ "dron[notify-telegram]", ] typecheck = [ - { include-group = "testing" }, "mypy", "lxml", # for mypy html coverage - "ty>=0.0.3", + "ty>=0.0.38", "types-tabulate", -] -[project.scripts] -dron = "dron.__main__:main" + { include-group = "testing" }, +] [build-system] @@ -70,3 +65,6 @@ source = "vcs" [tool.hatch.version.raw-options] version_scheme = "python-simplified-semver" local_scheme = "dirty-tag" + +[project.scripts] +dron = "dron.__main__:main" diff --git a/ruff.toml b/ruff.toml index af5467f..29b0d67 100644 --- a/ruff.toml +++ b/ruff.toml @@ -5,6 +5,7 @@ lint.extend-select = [ ] lint.ignore = [ + "CPY", # copyright headers "D", # annoying nags about docstrings "N", # pep naming "TCH", # type checking rules, mostly just suggests moving imports under TYPE_CHECKING @@ -16,6 +17,9 @@ lint.ignore = [ "EM" , # suggests assigning all exception messages into a variable first... pretty annoying ### too opinionated style checks + "E203", # whitespace before , -- sometimes used for readability, and ruff format should cover it anyway + "E221", # multiple spaces before operator -- also covered by ruff format + "E266", # too many leading '#' for block comment -- sometimes genuinely useful for visual separation "E501", # too long lines "E731", # assigning lambda instead of using def "E741", # Ambiguous variable name: `l` @@ -63,6 +67,8 @@ lint.ignore = [ "RET504", # unnecessary assignment before returning -- that can be useful for readability "RET505", # unnecessary else after return -- can hurt readability + "PLC1901", # suggests using `if string` instead of `strinig == ""` -- dumb. + "PLW0603", # global variable update.. we usually know why we are doing this "PLW2901", # for loop variable overwritten, usually this is intentional @@ -96,4 +102,10 @@ lint.ignore = [ ## "PLC0415", # "imports should be at the top level" -- not realistic + + "RUF067", # `__init__` module should only contain docstrings and re-exports -- might be nice to aim for, but dunno +] + + +extend-exclude = [ ] diff --git a/src/dron/launchd.py b/src/dron/launchd.py index 67a71b9..ba50629 100644 --- a/src/dron/launchd.py +++ b/src/dron/launchd.py @@ -123,7 +123,7 @@ def plist( # maybe we just want bash -c in this case, dunno how to implement properly raise RuntimeError(command) # too ambiguous? else: # must be an actual sequence of path-like things - cmd = tuple(map(str, command)) # ty: ignore[invalid-argument-type] # see https://github.com/astral-sh/ty/issues/2087 + cmd = tuple(map(str, command)) del command mschedule = '' diff --git a/src/dron/launchd_wrapper.py b/src/dron/launchd_wrapper.py index 9897dbb..aabad01 100755 --- a/src/dron/launchd_wrapper.py +++ b/src/dron/launchd_wrapper.py @@ -19,8 +19,7 @@ PYCACHE_PATH = Path('~/.cache/pycache').expanduser() -# ty doesn't support NoReturn yet, see https://github.com/astral-sh/ty/issues/180 -def main() -> NoReturn: # ty: ignore[invalid-return-type] +def main() -> NoReturn: p = argparse.ArgumentParser() p.add_argument('--notify', action='append') p.add_argument('--job', required=True) diff --git a/src/dron/notify/ntfy_common.py b/src/dron/notify/ntfy_common.py index ddcbc14..6fd8331 100644 --- a/src/dron/notify/ntfy_common.py +++ b/src/dron/notify/ntfy_common.py @@ -9,8 +9,7 @@ from typing import NoReturn -# ty doesn't support NoReturn yet, see https://github.com/astral-sh/ty/issues/180 -def run_ntfy(*, job: str, backend: str) -> NoReturn: # ty: ignore[invalid-return-type] +def run_ntfy(*, job: str, backend: str) -> NoReturn: # TODO not sure what to do with --stdin arg here? # could probably use last N lines of log or something # TODO get last logs here? diff --git a/src/dron/systemd.py b/src/dron/systemd.py index 46ac3bb..948ff46 100644 --- a/src/dron/systemd.py +++ b/src/dron/systemd.py @@ -236,7 +236,7 @@ def _sd(s: str) -> str: class BusManager: def __init__(self) -> None: # unused-ignore because on macos there is no dbus (but this code is still running mypy on CI) - from dbus import ( # type: ignore[import-untyped,import-not-found,unused-ignore] + from dbus import ( # type: ignore[import-untyped,import-not-found,unused-ignore] # ty: ignore[unresolved-import] Interface, SessionBus, ) @@ -309,7 +309,7 @@ def test_managed_units() -> None: # dbus.exceptions.DBusException: org.freedesktop.DBus.Error.BadAddress: Address does not contain a colon # todo maybe don't need it anymore with 20.04 circleci? if 'CI' not in os.environ: - cmd_monitor.callback(n=1, once=True, command=True, rate=True) # type: ignore[misc] + cmd_monitor.callback(n=1, once=True, command=True, rate=True) # type: ignore[misc] # ty: ignore[call-non-callable] def skip_if_no_systemd() -> None: