Skip to content

Releases: gmr/pglifecycle

2.0.0-alpha.2

2.0.0-alpha.2 Pre-release
Pre-release

Choose a tag to compare

@gmr gmr released this 01 Sep 18:50
6b596b5

Added

  • deploy accepts the same pg_dump exclusions as pull-T/--exclude-table, -N/--exclude-schema, and --exclude-extension, repeatable and conflicting with --dump. A project pulled with exclusions was previously compared against a full-database snapshot, producing "Skipping dependency on unmanaged ..." warnings and a dump slower than the pull it was compared against (#67).
  • A generated schema reference for all 37 object schemata, rendered from the title and description already carried in schemata/*.yml, so it cannot drift from the contract the loader applies. Each schema is also published resolved as JSON at schemata/<name>.json, so an editor can validate project files against it with a yaml-language-server modeline (#68).
  • Documentation for the gmr/pglifecycle-action GitHub Actions (#68).
  • Table-level column_defaults, so a default on a column an inheritance child only inherits is kept. pg_dump writes those as a standalone ALTER TABLE ONLY ... SET DEFAULT with no matching column entry, and they were silently discarded from the project (#66).
  • Role memberships accept the admin, inherit, and set options as a mapping, not just a bare role name. INHERIT FALSE and ADMIN OPTION were being dropped with a warning (#66).

Changed

  • pull and deploy prompt for a database password themselves instead of leaving it to the client tools. pg_dump, pg_dumpall, and psql now always run with -w and take the password from the environment; -W prompts up front, and a "no password supplied" failure prompts and retries. Where nobody can answer — -w, or a non-interactive stdin — the command fails with a hint naming PGPASSWORD, pgpass, and the terminal (#69).
  • The documentation site matches pglifecycle.com: PostgreSQL blue on warm paper, Space Grotesk headings, IBM Plex for text and code, and dark code blocks in both colour schemes (#68).
  • Every schema $id resolves. All 37 pointed at a pglifecycle.readthedocs.io URL that returns 404, and $schema declared a draft-agnostic URI that validators reject (#68).
  • New dependency: rpassword 7, for reading the password without echo (#69).

Fixed

  • A pulled project containing overloaded functions can be loaded again. The loader keyed the inventory by (type, schema, bare name) while pull writes overloads to f.yaml / f_1.yaml, so build and deploy refused the project outright with Duplicate FUNCTION (#66).
  • Hash partitions validate. The partitions branches gated on for_values_when, which no schema declares, so every hash-partitioned table failed validation and was dropped along with its dependents' edges (#66).
  • Tables and materialized views with toast. storage parameters validate; the property-name pattern rejected the dot (#66).
  • Three more schema branches that gated on properties their object never defines: collation.yml rejected every collation defined by sql: or copy_from:, and index.yml and view.yml gated on table_name and options. A new test walks every bundled schema and fails any oneOf/anyOf/allOf branch that gates on an undeclared property (#66).
  • Storage parameters render as WITH (k=v, ...). The Python implementation emitted the list without the required parentheses and the port was faithful to it, so the first table with storage parameters failed to restore with syntax error at or near "fillfactor" (#66).
  • The role-membership warning fires only for a genuinely unrecognized option. PostgreSQL 16+ always writes INHERIT TRUE and GRANTED BY, so ~600 lines of noise were hiding three real INHERIT FALSE and ten ADMIN OPTION losses (#66).
  • pull and deploy no longer appear to hang forever. The client tools prompt for a password on /dev/tty rather than stdin, and the prompt landed on the line the progress spinner refreshes ten times a second — leaving a 0-byte archive on disk and no backend in pg_stat_activity (#69).

2.0.0-alpha.1

2.0.0-alpha.1 Pre-release
Pre-release

Choose a tag to compare

@gmr gmr released this 01 Sep 03:07
59891bd

Added

  • Support for PostgreSQL 18 table-level NOT NULL constraints, including named constraints and NO INHERIT. Pulling a PG 18 server previously dropped any table whose CREATE TABLE carried one, writing no file and logging only a parse warning (#64, #65).
  • Inheritance support for foreign tables: INHERITS, inherited columns, and table constraints are now pulled, rendered, and reconciled on deploy. An inheriting foreign table previously pulled as name/schema/owner/server/options alone, silently (#65).
  • A published Docker image at ghcr.io/gmr/pglifecycle (amd64 + arm64), built on Alpine with the PostgreSQL 17 client tools that pull, build, and deploy shell out to (#63).

Changed

  • Updated internal dependencies: tree-sitter-postgres from 1.2 to 19.0.0-beta.2 (the PostgreSQL 19 grammar), libpgfmt from 1.2 to 1.3, and libpgdump from 2.1 to 2.2.
  • Deploy renames a NOT NULL constraint in place rather than dropping and recreating it (#65).

Fixed

  • Inherited tables can be restored again. Restore ordering derived edges from foreign keys only, so a child that sorted before its parent failed with relation "..." does not exist (#65).
  • Named NOT NULL constraints keep their name and NO INHERIT flag through a pull/build round trip, instead of collapsing to nullable: false and being auto-renamed on rebuild (#65).
  • Homebrew installs work for this project's unprefixed tags. The formula-update step wrote a hardcoded v into every download URL, pointing brew install pglifecycle at assets that did not exist (#63).
  • The release workflow triggers on release: published rather than created, which never fires for a draft-then-publish release, and verifies the tag matches the Cargo.toml version before building (#63).
  • Identifiers in table-level NOT NULL constraints are quoted (#64).

2.0.0-alpha.0

2.0.0-alpha.0 Pre-release
Pre-release

Choose a tag to compare

@gmr gmr released this 31 Aug 16:41
7211bfb

First release of the Rust rewrite, replacing the Python implementation
(preserved at the python-final tag). The on-disk project format and
the schemata/ contract carry over unchanged, and build output is
deliberately faithful to the Python archives entry-by-entry — the
intentional deviations are enumerated at the top of src/build/mod.rs.

Alpha: the CLI surface and project format are stable enough to use, but
not yet frozen.

Commands

  • pull — database or pg_dump archive → a structured YAML
    project. Parses each entry's DDL through a tree-sitter-postgres CST,
    merges child entries (indexes, constraints, triggers, comments, ACLs)
    into their owning objects, and writes one file per object.
    --update/--prune refresh an existing project in place.
  • build — project → pg_restore -Fc archive.
  • deploy — compare the project against a live database and emit
    the DDL to make the database match. Output-first: the script goes to
    stdout or --output to be applied separately, and destructive
    statements are excluded unless --allow-drop.
  • create — scaffold an empty project.

Coverage

Schemas, tables (including partitions and typed tables), views,
materialized views, sequences, domains, types, functions, aggregates,
operators, casts, collations, conversions, text search objects, event
triggers, publications, subscriptions, tablespaces, foreign data
wrappers, servers, user mappings, foreign tables, and roles, users,
groups with their settings, grants, revocations, and memberships.

Notable in this release

  • Role membership grants are emitted by build (#58), including
    membership in predefined roles such as pg_read_all_data, which can
    only ever be referenced and never created.
  • Role membership modifiers that the project format cannot represent —
    WITH ADMIN OPTION, GRANTED BY, and the REVOKE ... OPTION FOR
    form — are now reported rather than silently dropped (#61).
  • The views: ACL section is emitted, coalesced with tables: since
    PostgreSQL grants on views with TABLE syntax (#62).
  • Foreign objects are pulled, built, and reconciled in deploy
    (#45, #46, #50).
  • Progress indicators and failure diagnostics across all three commands
    (#29, #30, #31, #35), with SQL formatting guarded by a per-statement
    timeout (#33).

Verification

just check (fmt, clippy -D warnings, tests), mkdocs build --strict, and both database gates against PostgreSQL 17 — the
round-trip gate (schema → pull → build → restore → diff) and the three
deploy gates (equivalence, convergence, safety).

Known issue

Cargo.lock pins time 0.3.48 and time-macros 0.2.28, both since
yanked from crates.io. They build and test clean; the bump is deferred
to the next release.