Skip to content

v0.13.0

Choose a tag to compare

@FabianClemenz FabianClemenz released this 14 Sep 11:08
· 13 commits to main since this release
Immutable release. Only release title and notes can be modified.
6e21f58

erdify 0.13.0 — one ERD generator for every Python schema in your repository.

Warning

Breaking: a run that finds no tables now exits 1 instead of 0 and writes nothing. Pass --allow-empty (or set allow_empty = true under [tool.erdify]) to restore the previous behavior. Details below.

Changed — breaking

  • A run that finds no tables now exits 1 instead of 0, and writes
    nothing. Up to 0.12.3 it warned, wrote a structurally valid but empty
    diagram, and exited 0 — so a CI job that commits the regenerated ERD
    silently replaced a good diagram with an empty one whenever --include
    stopped matching, which a rename or a moved package is enough to cause. The
    overwhelmingly likely cause of zero entities is a misconfiguration, so that
    is now an error.

    Failing before generation means an existing output file is left untouched.

    If an empty schema is a legitimate outcome for your project — everything
    filtered out by --exclude, a --sources filter that matches nothing, a
    schema mid-migration — pass --allow-empty or set allow_empty = true under
    [tool.erdify]. That restores the previous behavior exactly.

Added

  • New documentation page Comparison — erdify next to eralchemy,
    sqlalchemy-schemadisplay, erdantic, django-extensions graph_models and
    DBML/dbdiagram, on the axes that actually differ (live connection, importing
    your code, frameworks covered, runtime dependencies, output formats, CI drift
    gate), including where each alternative is the better choice.
  • New documentation page Python Parsing Limitations — the Python-side
    counterpart to the SQL frontend's "Deferred / Not Supported" table: what the
    AST parser cannot see (runtime-constructed models, non-literal
    __tablename__, __table_args__, composite foreign keys, foreign keys inside
    sa_column, unannotated relationship() assignments) and what to do instead.
  • New documentation page Troubleshooting — symptom-first fixes for models
    not being found, too many entities, missing relationships and missing keys on
    Pydantic/dataclass models.
  • Every documentation page now carries its own description frontmatter, so
    each page gets its own search-engine snippet and social-card subtitle instead
    of repeating site_description.
  • --allow-empty (and allow_empty in [tool.erdify]) opts back in to the
    pre-0.13.0 behavior for an empty result: warn, write the empty diagram, exit
    0. See the breaking change below.
  • erdify now ships .pre-commit-hooks.yaml, so it can be used as a pre-commit
    repository instead of a repo: local / language: system hook that requires
    erdify to be installed in the consumer's environment first. Two ids are
    provided: erdify regenerates the diagram (pre-commit fails the commit when
    the file changed), and erdify-check never writes and exits non-zero when the
    committed diagram has drifted. --check is part of the latter's entry point,
    so overriding args cannot drop it. SQL DDL projects add
    additional_dependencies: ['sqlglot>=25'] rather than using a separate id.
  • The documentation site now renders a social card (og:image) for every page,
    so links shared on chat, social and link-preview surfaces show a real card
    instead of a bare text entry. This enables mkdocs-material's social plugin,
    which pulls in the mkdocs-material[imaging] dependencies and their system
    libraries in the docs workflow.
  • The changelog is published as a page on the documentation site. It includes
    the repository's CHANGELOG.md verbatim via pymdownx.snippets, so there is
    still a single source of truth.
  • Every documentation page now has an edit link back to its source on GitHub
    (content.action.edit; edit_uri was already configured but Material never
    rendered the button without the feature) and previous/next navigation in the
    footer (navigation.footer).

Changed

  • The "No tables found" message now ends with a link to the troubleshooting
    page, which did not exist when the message was written.

  • The Datadog coverage upload is now also skipped for Dependabot. The existing
    fork check covers pull requests from forks, but a Dependabot pull request's
    head branch lives in this repository, and GitHub runs those with Dependabot
    secrets rather than Actions secrets — so the step would have run with an
    empty key and failed the required Tests passed check on every dependency
    bump. The condition matches on the actor: secrets cannot be referenced in an
    if: conditional, and the documented job-level-env workaround would put the
    API key in the environment of every step in the job.

  • SECURITY.md scopes its absolute claims to the core install. "Does not
    execute / import / connect / send" holds for the stdlib-only core; the
    erdify[sql] extra runs third-party code (sqlglot) in your process and is now
    described as its own trust boundary. Added: --output/--inject do write to
    the paths you name, and the rendering step (PlantUML server, Mermaid, browser)
    is outside erdify's control. The response times are stated as what a small
    team aims for rather than a service-level guarantee.

  • docs/usage/ci.md leads with the --check drift gate and presents the
    auto-commit workflow as the alternative, with its trade-off stated. The
    workflow examples keep floating action tags for readability, and a note now
    says so explicitly and tells readers to pin to a SHA in their own repository —
    as erdify's own workflows do.

  • Reduced decorative emoji in SECURITY.md and CONTRIBUTING.md, which people
    reach when something is wrong or when they are trying to get set up.

  • The "No tables found" warning is now actionable: it names the active
    --include patterns, reports how many .py/.sql files were scanned and how
    many matched, and distinguishes "nothing matched the patterns" (the usual
    cause — --include defaults to models.py, so models in e.g. schema.py are
    never seen) from "files matched but held no recognized models".

  • The README now answers "why erdify and not X" right after the feature list,
    with a condensed comparison table and a link to the full one.

  • The README shows its example ERD as a live Mermaid diagram injected with
    erdify --inject instead of a committed PNG — the format the README itself
    advertises as rendering natively on GitHub. A readme-erd pre-commit hook
    runs the same command with --check, so the embedded diagram cannot go stale
    (and it dogfoods both flags on the project's own front page).

  • The README badge row is down from ten to six: PyPI version, Python versions,
    License, Tests, Coverage and a new docs badge. The Linting, Ruff, mypy and
    download badges added rows without adding information a reader acts on.

  • The PyPI project page now links to the documentation site
    (https://erdify.devsuit.io/) instead of the README anchor on GitHub, and
    gains Changelog and Issues links.

  • [tool.ruff] target-version is py311, matching requires-python = ">=3.11"
    instead of contradicting it with py310.

  • The documentation home page now leads with what erdify is, the
    framework-comparison diagram and a three-line install-and-run, instead of
    restating the sidebar. The Comparison, Python Parsing Limitations and
    Troubleshooting pages are in the nav.

  • docs/frameworks/index.md loads its second example image from the repository
    instead of raw.githubusercontent.com, matching the first one on the page.

  • The Mermaid section of docs/usage/output-formats.md shows the .mmd source
    and the rendered diagram in side-by-side tabs; the rendered-only fence never
    showed readers what the file actually contains.

  • The required Tests passed check now fails for a pull request from the
    machine-written badges branch into main (the only base the test workflow
    runs for). GitHub cannot bar a branch from being a pull-request source, and
    such a pull request would otherwise look mergeable while replacing the README
    on main with the branch's own.

  • Test coverage is now uploaded to Datadog Code Coverage from the Linux /
    Python 3.13 matrix leg, with code-coverage.datadog.yaml defining the
    service mapping and 90% total/patch PR gates (matching the existing
    fail_under), and service.datadog.yaml registering erdify in the Datadog
    Software Catalog. The upload is skipped on pull requests from forks, which
    have no access to repository secrets; the workflow deliberately stays on the
    pull_request trigger.

  • The README now carries a coverage badge. Datadog exposes no public badge
    endpoint, so pushes to main publish the percentage as a shields.io endpoint
    payload on the orphan badges branch of this repository, committed by
    github-actions[bot] with the workflow's built-in GITHUB_TOKEN. Pull
    requests never update it. Keeping the payload in the repository rather than in
    a Gist or a third-party badge service means no personal credential is involved
    and the badge survives any contributor leaving.

  • CI now resolves uv to latest-known instead of latest, so the version
    installed in every workflow (including the PyPI publish job) is one whose
    checksum ships with the pinned setup-uv release. New uv versions reach CI
    only through a setup-uv bump, which arrives as a reviewed, cooldown-gated
    Dependabot PR.

  • Dependabot's github-actions version-update group now includes major, so
    major action bumps arrive as a single grouped PR instead of one PR each. The
    uv entry deliberately keeps majors separate, and security updates are
    unaffected in both.


Install: pip install erdify · Docs: https://erdify.devsuit.io/ · Full diff: v0.12.3...v0.13.0