package database import ( "embed" "errors" "fmt" "log/slog" "github.com/golang-migrate/migrate/v4" _ "github.com/golang-migrate/migrate/v4/database/postgres" "github.com/golang-migrate/migrate/v4/source/iofs" ) //go:embed migrations/*.sql var migrationsFS embed.FS // RunMigrations runs all pending database migrations func RunMigrations(databaseURL string, logger *slog.Logger) error { logger.Info("running database migrations") // Create source driver from embedded files source, err := iofs.New(migrationsFS, "migrations") if err != nil { return fmt.Errorf("failed to create migration source: %w", err) } // Create migrate instance m, err := migrate.NewWithSourceInstance("iofs", source, databaseURL) if err != nil { return fmt.Errorf("failed to create migrate instance: %w", err) } defer m.Close() // Run migrations if err := m.Up(); err != nil { if errors.Is(err, migrate.ErrNoChange) { logger.Info("no new migrations to apply") return nil } return fmt.Errorf("failed to run migrations: %w", err) } // Get current version version, dirty, err := m.Version() if err != nil && !errors.Is(err, migrate.ErrNilVersion) { logger.Warn("failed to get migration version", "error", err) } else { logger.Info("migrations complete", "version", version, "dirty", dirty) } return nil }