Changelog
=========

v0.8.0 (2026-07-22)
-------------------

Improvements
~~~~~~~~~~~~

- Add ``ci.sh`` to run the full local gate suite in order (``uv sync``,
  ``ruff format``, ``ruff check``, ``ty``, ``mypy``, ``pyright``, and
  ``pytest``), each with its own exit code for easy diagnosis.

- Add ``ci-matrix.sh`` to run an import smoke check and the test suite
  across every supported interpreter (Python 3.9 through 3.13), pulling
  any missing interpreters via uv.

- Adopt ``ruff format`` (single-quote style) and expand the ``ruff check``
  lint ruleset for consistent formatting and stricter linting.

- Add ``ty`` and ``pyright`` (strict mode) as type-checking gates alongside
  ``mypy --strict`` with ``warn_unreachable`` enabled.

Bug Fixes
~~~~~~~~~

- Fix ``patatt.gpg-bin`` configuration handling in ``set_bin_paths()``,
  which asserted on the wrong variable and could never apply a configured
  gpg binary path.

- Fix multi-value config handling in ``get_config_from_git()``, which
  discarded all but the last value of a repeated key (e.g. multiple
  ``patatt.keyringsrc`` entries) instead of collecting them all.

- Fix a subprocess hang when signing or verifying with gpg. gpg spawns
  daemon children (``gpg-agent``, ``scdaemon``) that inherit the captured
  stdout/stderr pipes; a lingering daemon (from a revoked key or a
  misconfigured smartcard) kept the pipe open so the read never reached
  EOF and the call blocked forever, even after gpg itself had exited.
  Redirect subprocess output through temporary files instead of pipes so
  the call returns as soon as the command exits.

v0.7.1 (2026-04-10)
-------------------

Bug Fixes
~~~~~~~~~

- Fix ``user.signingkey`` handling for SSH keys by checking
  ``gpg.format`` to determine the key type, instead of always
  assuming OpenPGP.

- Make ``install-hook`` work correctly in git submodules by using
  ``git rev-parse --git-dir`` instead of assuming ``.git``.

- Fix compatibility with Python versions before 3.13 by using the
  older ``Generator`` type syntax in test fixtures.

- Fix typo in package classifier metadata.

Thanks
~~~~~~

- Bingwu Zhang
- Uwe Kleine-König

v0.7.0 (2026-01-02)
-------------------

New Features
~~~~~~~~~~~~

- Add privacy-preserving by-hash keyring lookup. When standard key lookup
  fails, patatt now falls back to looking up keys at a SHA256 hash-based
  path (``by-hash/XX/YYY...``), avoiding exposure of email addresses in
  directory structures.

- Add comprehensive Sphinx documentation for ReadTheDocs hosting at
  https://patatt.docs.kernel.org

- Add PEP 561 compliance with ``py.typed`` marker for better IDE and
  type checker support.

- Add docstrings to all public classes and functions for improved IDE
  integration.

Improvements
~~~~~~~~~~~~

- Convert path handling to use ``pathlib.Path`` for cleaner code and
  better cross-platform compatibility.

- Refactor codebase to pass ``mypy --strict`` type checking.

- Add pytest test framework with unit tests.

- Use walrus operator for cleaner assign-and-check patterns.

- Improve SSH signing failure messages for better debugging.

- Hook now refuses to run on cover letter templates.

Bug Fixes
~~~~~~~~~

- Fix validation for OpenPGP signatures without embedded public key data.

- Fix compatibility with Python versions before 3.12 (avoid ``@deprecated``
  decorator).

- Fix subprocess file descriptor leak.

- Avoid spuriously reading git config in certain conditions.

- Fix non-writable GNUPGHOME handling.

- Fix header line splitting at 75 characters instead of 78.

Thanks
~~~~~~

- Paul Moore
- Tamir Duberstein

v0.6.3 (2023-01-25)
-------------------

- Fix header line splitting at 75 characters instead of 78.

v0.6.2 (2022-08-25)
-------------------

- Better fix for non-writable GNUPGHOME handling.

v0.6.1 (2022-08-25)
-------------------

- Use NamedTemporaryFile for GPG keyring creation to fix issues with
  non-writable GNUPGHOME.

v0.6.0 (2022-08-22)
-------------------

- Initial stable release with support for ed25519, OpenPGP, and OpenSSH
  signature algorithms.
