Skip to content

Ship transaction-free bundles by default - #6

Merged
lemuelroberto merged 2 commits into
emfga:mainfrom
lemuelroberto:feat/no-transaction-bundles
Sep 30, 2026
Merged

lemuelroberto merged 2 commits into
emfga:mainfrom
lemuelroberto:feat/no-transaction-bundles

Conversation

@lemuelroberto

Copy link
Copy Markdown
Member

Why

Release bundles carried one BEGIN;/COMMIT; pair per script section
(30 pairs in the all-in bundle). That makes them impossible to embed
where the caller already owns the transaction — a migration tool
(Kysely, Flyway, Liquibase…) runs each migration inside one, and the
bundle's first COMMIT; ended it halfway through. pgtle-wrap.sh
already worked around the same problem for CREATE EXTENSION by
grepping the lines out.

What changes

  • sql/ carries no transaction control. The plain artifacts are what
    the sources say and run inside the caller's transaction (psql -1,
    a migration, CREATE EXTENSION).
  • Every artifact gets a -tx twin with exactly one BEGIN; and
    one COMMIT; around the whole bundle, for a bare psql -f.
  • pgtle-wrap.sh wraps the plain files unchanged and refuses input
    that controls transactions (e.g. a -tx file).
  • build-release.sh refuses a BEGIN;/COMMIT; line in sql/; CI now
    runs it on every PR.
  • The release smoke job installs each plain artifact between BEGIN
    and ROLLBACK and asserts no cel schema survives (a stray
    COMMIT; fails it), then installs it with --single-transaction,
    then installs the -tx twin with a bare psql -f.
  • docs/INSTALL.md documents both shapes and a "Inside a migration
    tool" section. Version bumped to 0.0.2.

Verified locally

  • docker compose up -d --wait + go vet ./... + go test ./...: ok.
  • The smoke job script, extracted from release.yml: ok for
    cel4postgres and cel4postgres-core, both shapes. With a COMMIT;
    injected at top level of the plain bundle it fails with
    "committed on its own".
  • The pg_tle job script for all and core ext_strings: ok.

Release

After merge, the 0.0.2 release is the manual Release workflow.
fga4postgres will vendor the published cel4postgres--0.0.2.sql.

Every sql/ script opened and committed its own transactions, so a
release bundle carried dozens of top-level BEGIN;/COMMIT; pairs. That
made the bundle impossible to embed where someone else already owns
the transaction: a migration tool runs each migration inside one, and
the bundle's first COMMIT; ended it halfway through, leaving the rest
to run in autocommit. pg_tle hit the same wall, which is why
pgtle-wrap.sh stripped those lines with grep before wrapping.

The sources now carry no transaction control, and the plain artifacts
are what the sources say. The caller picks the boundary: psql -1, a
migration's transaction, or CREATE EXTENSION. For a bare psql -f that
should still be all or nothing, every artifact gets a -tx twin holding
exactly one BEGIN; and one COMMIT; around the whole bundle, rather
than one pair per script section.

Nothing in the scripts depended on a commit between sections: the
all-in bundle installs inside a single transaction and a rollback
leaves no cel schema behind. The release smoke job now proves exactly
that for each plain artifact, and build-release.sh, which CI runs,
refuses a BEGIN; or COMMIT; line that finds its way back into sql/.
The artifact set changed shape: plain files lost their transaction
control and -tx twins were added. A consumer pinning 0.0.1 must not
receive files that behave differently under the same name.
@lemuelroberto
lemuelroberto merged commit 431f212 into emfga:main Sep 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant