packages feed

keiro-migrations 0.17.0.0 → 0.18.0.0

raw patch · 4 files changed

+64/−18 lines, 4 filesdep +unixdep ~ephemeral-pgPVP ok

version bump matches the API change (PVP)

Dependencies added: unix

Dependency ranges changed: ephemeral-pg

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -6,6 +6,17 @@  ## [Unreleased] +## 0.18.0.0 — 2026-09-20+++### Other Changes++- Both test suites require `ephemeral-pg >=0.3.1 && <0.4` and start their+  clusters under a stable per-user temporary root. The legacy suite uses+  `withCachedConfig` in place of its hand-rolled `startCached`/`finally`+  bracket. No migration payload changed, so no recorded checksum moves and no+  ledger fixup is required.+ ## 0.17.0.0 — 2026-09-17  ### Other Changes
keiro-migrations.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: keiro-migrations-version: 0.17.0.0+version: 0.18.0.0 synopsis: Schema migrations for keiro description:   Embedded PostgreSQL schema migrations and a migration runner for the Keiro@@ -410,7 +410,7 @@     bytestring >=0.11 && <0.13,     containers >=0.6 && <0.8,     directory >=1.3 && <1.4,-    ephemeral-pg >=0.2 && <0.3,+    ephemeral-pg >=0.3.1 && <0.4,     filepath >=1.4 && <1.6,     hasql >=1.10 && <1.11,     hspec >=2.10 && <2.12,@@ -420,6 +420,7 @@     pg-migrate-import-codd ^>=1.1.0.0,     pg-migrate-test-support ^>=1.1.0.0,     text >=2.0 && <2.2,+    unix >=2.8 && <2.9,  test-suite keiro-migrations-legacy-test   import: common@@ -443,7 +444,7 @@     containers,     contravariant-extras,     directory,-    ephemeral-pg >=0.2,+    ephemeral-pg >=0.3.1 && <0.4,     filepath,     generic-lens >=2.2 && <2.4,     hasql >=1.10 && <1.11,@@ -456,4 +457,5 @@     temporary,     text >=2.0 && <2.2,     time >=1.12 && <1.15,+    unix >=2.8 && <2.9,     vector >=0.13 && <0.14,
test-legacy/Main.hs view
@@ -9,16 +9,17 @@ import Codd.Types (ConnectionString, SchemaAlgo (..), SchemaSelection (..), SqlSchema (..), TxnIsolationLvl (..), singleTryPolicy) import Contravariant.Extras (contrazip3) import Control.Concurrent.Async (concurrently)-import Control.Exception (finally) import Control.Monad (filterM) import Data.Attoparsec.Text (endOfInput, parseOnly) import Data.Int (Int32) import Data.List (isSuffixOf, sort)+import Data.Monoid (Last (..)) import Data.Text (Text) import Data.Text qualified as T import Data.Text.IO qualified as TIO import Data.Time (UTCTime (..), fromGregorian, secondsToDiffTime) import EphemeralPg qualified as Pg+import EphemeralPg.Config qualified as Pg.Config import Hasql.Connection.Settings qualified as Conn import Hasql.Decoders qualified as D import Hasql.Encoders qualified as E@@ -40,27 +41,36 @@     verifySchema,   ) import Keiro.Migrations.New (migrationFileName, migrationSlug, newMigrationFile)-import System.Directory (doesDirectoryExist, doesFileExist, listDirectory)+import System.Directory (createDirectoryIfMissing, doesDirectoryExist, doesFileExist, listDirectory) import System.FilePath (takeFileName) import System.IO.Temp (withSystemTempDirectory)+import System.Posix.User (getEffectiveUserID) import Test.Hspec  -- | Pin the ephemeral PostgreSQL superuser to the fixed name @keiro@ so the -- captured snapshot identity (roles, database owner, per-object owners) is -- deterministic across machines and CI rather than the local OS username. This is -- the portability fix for the strict drift gate.-keiroPgConfig :: Pg.Config-keiroPgConfig = Pg.defaultConfig {Pg.user = "keiro"}+keiroPgConfig :: IO Pg.Config+keiroPgConfig = withStableRoot Pg.defaultConfig {Pg.Config.user = "keiro"} +-- | Give @config@ a stable, per-user temporary root, so ephemeral-pg's startup+-- sweep reclaims clusters abandoned by earlier killed runs instead of searching a+-- per-session @$TMPDIR@. Must match the root in @Keiro.Test.Postgres@+-- (keiro-test-support) so every Keiro suite shares it.+withStableRoot :: Pg.Config -> IO Pg.Config+withStableRoot config = do+  uid <- getEffectiveUserID+  let root = "/tmp/ephpg-keiro-" <> show uid+  createDirectoryIfMissing True root+  pure config {Pg.temporaryRoot = Last (Just root)}+ -- | Start a cached ephemeral server whose PostgreSQL superuser is the fixed--- name @keiro@. Mirrors 'Pg.withCached' but pins the user; 'Pg.withCachedConfig'--- is not exported, so we use 'Pg.startCached' + 'finally'.+-- name @keiro@. Mirrors 'Pg.withCached' but pins the user. withKeiroPg :: (Pg.Database -> IO a) -> IO (Either Pg.StartError a) withKeiroPg action = do-  started <- Pg.startCached keiroPgConfig Pg.defaultCacheConfig-  case started of-    Left err -> pure (Left err)-    Right db -> Right <$> (action db `finally` Pg.stop db)+  config <- keiroPgConfig+  Pg.withCachedConfig config Pg.defaultCacheConfig action  main :: IO () main =
test/Main.hs view
@@ -14,6 +14,7 @@ import Data.List.NonEmpty (NonEmpty (..)) import Data.List.NonEmpty qualified as NonEmpty import Data.Map.Strict qualified as Map+import Data.Monoid (Last (..)) import Data.Set qualified as Set import Data.Text (Text) import Data.Text qualified as Text@@ -29,8 +30,9 @@     planDescription,   ) import Database.PostgreSQL.Migrate.Internal qualified as Migrate.Internal-import Database.PostgreSQL.Migrate.Test (withMigratedDatabase)+import Database.PostgreSQL.Migrate.Test (MigratedDatabaseError, withMigratedDatabaseConfig) import EphemeralPg qualified as Pg+import EphemeralPg.Config qualified as Pg.Config import Hasql.Connection qualified as Connection import Hasql.Connection.Settings qualified as Settings import Hasql.Decoders qualified as Decoders@@ -46,9 +48,10 @@ import Kiroku.Store.Migrations.History.Codd qualified as Kiroku.Codd import Lint import Numeric qualified-import System.Directory (doesDirectoryExist, doesFileExist, listDirectory)+import System.Directory (createDirectoryIfMissing, doesDirectoryExist, doesFileExist, listDirectory) import System.Environment (lookupEnv) import System.FilePath (takeExtension, (</>))+import System.Posix.User (getEffectiveUserID) import Test.Hspec  main :: IO ()@@ -1347,12 +1350,32 @@ importOutcomes :: HistoryImportReport -> [HistoryImportOutcome] importOutcomes HistoryImportReport {importResults} = importOutcome <$> toList importResults -keiroPgConfig :: Pg.Config-keiroPgConfig = Pg.defaultConfig {Pg.user = "keiro"}+-- | Give @config@ a stable, per-user temporary root, so ephemeral-pg's startup+-- sweep reclaims clusters abandoned by earlier killed runs instead of searching a+-- per-session @$TMPDIR@. Must match the root in @Keiro.Test.Postgres@+-- (keiro-test-support) so every Keiro suite shares it.+withStableRoot :: Pg.Config -> IO Pg.Config+withStableRoot config = do+  uid <- getEffectiveUserID+  let root = "/tmp/ephpg-keiro-" <> show uid+  createDirectoryIfMissing True root+  pure config {Pg.temporaryRoot = Last (Just root)} +keiroPgConfig :: IO Pg.Config+keiroPgConfig = withStableRoot Pg.defaultConfig {Pg.Config.user = "keiro"}++withMigratedDatabase ::+  MigrationPlan ->+  (Connection.Connection -> IO value) ->+  IO (Either MigratedDatabaseError value)+withMigratedDatabase plan callback = do+  config <- withStableRoot Pg.defaultConfig+  withMigratedDatabaseConfig config defaultRunOptions plan callback+ withKeiroPg :: (Pg.Database -> IO ()) -> IO () withKeiroPg action = do-  started <- Pg.startCached keiroPgConfig Pg.defaultCacheConfig+  config <- keiroPgConfig+  started <- Pg.startCached config Pg.defaultCacheConfig   case started of     Left startError -> expectationFailure (show startError)     Right database -> action database `finally` Pg.stop database