HH-448: enforce PostgreSQL E2E gate (#87)

* HH-448 enforce PostgreSQL E2E gate

* HH-448 fail CI when concurrency test is missing

---------

Co-authored-by: Rogee <rogee@ipao.vip>
This commit is contained in:
Rogee
2026-08-21 20:00:41 +08:00
committed by GitHub
co-authored by rogee
parent cf263d10b4
commit 7e3872170f
3 changed files with 105 additions and 32 deletions
+23 -29
View File
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"os"
"strings"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
@@ -38,12 +39,9 @@ func RunMigrations(dbURL string, migrationsPath string) error {
}
func runMigrations(dbURL string, migrationsPath string) error {
m, err := migrate.New(
fmt.Sprintf("file://%s", migrationsPath),
dbURL,
)
m, err := newMigrate(dbURL, migrationsPath)
if err != nil {
return fmt.Errorf("failed to create migrate instance: %w", err)
return err
}
defer m.Close()
@@ -95,12 +93,9 @@ func withSanitizedPQEnvironment(fn func() error) error {
// MigrateSteps applies N migration steps (positive = up, negative = down).
func MigrateSteps(dbURL string, migrationsPath string, steps int) error {
m, err := migrate.New(
fmt.Sprintf("file://%s", migrationsPath),
dbURL,
)
m, err := newMigrate(dbURL, migrationsPath)
if err != nil {
return fmt.Errorf("failed to create migrate instance: %w", err)
return err
}
defer m.Close()
@@ -116,16 +111,9 @@ func MigrateSteps(dbURL string, migrationsPath string, steps int) error {
// RollbackMigrations rolls back all migrations (drops all tables).
func RollbackMigrations(dbURL string, migrationsPath string) error {
if migrationsPath == "" {
return errors.New("migrations path is required")
}
m, err := migrate.New(
fmt.Sprintf("file://%s", migrationsPath),
dbURL,
)
m, err := newMigrate(dbURL, migrationsPath)
if err != nil {
return fmt.Errorf("failed to create migrate instance: %w", err)
return err
}
defer m.Close()
@@ -142,12 +130,9 @@ func RollbackMigrations(dbURL string, migrationsPath string) error {
// ForceVersion sets the migration version to a specific number, clearing dirty state.
// Use this to recover from a partially-applied migration.
func ForceVersion(dbURL string, migrationsPath string, version int) error {
m, err := migrate.New(
fmt.Sprintf("file://%s", migrationsPath),
dbURL,
)
m, err := newMigrate(dbURL, migrationsPath)
if err != nil {
return fmt.Errorf("failed to create migrate instance: %w", err)
return err
}
defer m.Close()
@@ -161,12 +146,9 @@ func ForceVersion(dbURL string, migrationsPath string, version int) error {
// CurrentVersion returns the current migration version and whether the DB is in a dirty state.
// When no migrations have been applied (version 0), returns (0, false, nil) instead of an error.
func CurrentVersion(dbURL string, migrationsPath string) (uint, bool, error) {
m, err := migrate.New(
fmt.Sprintf("file://%s", migrationsPath),
dbURL,
)
m, err := newMigrate(dbURL, migrationsPath)
if err != nil {
return 0, false, fmt.Errorf("failed to create migrate instance: %w", err)
return 0, false, err
}
defer m.Close()
@@ -181,3 +163,15 @@ func CurrentVersion(dbURL string, migrationsPath string) (uint, bool, error) {
return version, dirty, nil
}
func newMigrate(dbURL, migrationsPath string) (*migrate.Migrate, error) {
if strings.TrimSpace(migrationsPath) == "" {
return nil, errors.New("migration path must not be empty")
}
m, err := migrate.New(fmt.Sprintf("file://%s", migrationsPath), dbURL)
if err != nil {
return nil, fmt.Errorf("failed to create migrate instance: %w", err)
}
return m, nil
}
+19
View File
@@ -7,6 +7,25 @@ import (
"github.com/stretchr/testify/require"
)
func TestMigrationCommandsRejectBlankPath(t *testing.T) {
tests := map[string]func() error{
"run": func() error { return RunMigrations("invalid-url", " \t") },
"steps": func() error { return MigrateSteps("invalid-url", " \t", 1) },
"rollback": func() error { return RollbackMigrations("invalid-url", " \t") },
"force": func() error { return ForceVersion("invalid-url", " \t", 1) },
"version": func() error {
_, _, err := CurrentVersion("invalid-url", " \t")
return err
},
}
for name, run := range tests {
t.Run(name, func(t *testing.T) {
require.EqualError(t, run(), "migration path must not be empty")
})
}
}
func TestWithSanitizedPQEnvironment(t *testing.T) {
t.Setenv("PGSERVICE", "local-service")
t.Setenv("PGSERVICEFILE", "/tmp/pg_service.conf")