• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / cli / 8047629296

26 Feb 2024 10:49AM CUT coverage: 58.888%. Remained the same
8047629296

push

github

web-flow
fix: update release process to create PR (#1991)

6195 of 10520 relevant lines covered (58.89%)

689.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/internal/db/remote/commit/commit.go
1
package commit
2

3
import (
4
        "context"
5
        _ "embed"
6
        "errors"
7
        "fmt"
8
        "path/filepath"
9

10
        "github.com/jackc/pgconn"
11
        "github.com/jackc/pgerrcode"
12
        "github.com/jackc/pgx/v4"
13
        "github.com/spf13/afero"
14
        "github.com/supabase/cli/internal/db/diff"
15
        "github.com/supabase/cli/internal/db/dump"
16
        "github.com/supabase/cli/internal/migration/list"
17
        "github.com/supabase/cli/internal/migration/repair"
18
        "github.com/supabase/cli/internal/utils"
19
)
20

21
func Run(ctx context.Context, schema []string, config pgconn.Config, fsys afero.Fs) error {
×
22
        // Sanity checks.
×
23
        {
×
24
                if err := utils.AssertDockerIsRunning(ctx); err != nil {
×
25
                        return err
×
26
                }
×
27
                if err := utils.LoadConfigFS(fsys); err != nil {
×
28
                        return err
×
29
                }
×
30
        }
31

32
        if err := utils.RunProgram(ctx, func(p utils.Program, ctx context.Context) error {
×
33
                return run(p, ctx, schema, config, fsys)
×
34
        }); err != nil {
×
35
                return err
×
36
        }
×
37

38
        fmt.Println("Finished " + utils.Aqua("supabase db remote commit") + ".")
×
39
        return nil
×
40
}
41

42
func run(p utils.Program, ctx context.Context, schema []string, config pgconn.Config, fsys afero.Fs) error {
×
43
        // 1. Assert `supabase/migrations` and `schema_migrations` are in sync.
×
44
        p.Send(utils.StatusMsg("Connecting to remote database..."))
×
45
        conn, err := utils.ConnectRemotePostgres(ctx, config)
×
46
        if err != nil {
×
47
                return err
×
48
        }
×
49
        defer conn.Close(context.Background())
×
50
        if err := assertRemoteInSync(ctx, conn, fsys); err != nil {
×
51
                return err
×
52
        }
×
53

54
        // 2. Fetch remote schema changes
55
        if len(schema) == 0 {
×
56
                schema, err = diff.LoadUserSchemas(ctx, conn)
×
57
                if err != nil {
×
58
                        return err
×
59
                }
×
60
        }
61
        timestamp := utils.GetCurrentTimestamp()
×
62
        if err := fetchRemote(p, ctx, schema, timestamp, config, fsys); err != nil {
×
63
                return err
×
64
        }
×
65

66
        // 3. Insert a row to `schema_migrations`
67
        return repair.UpdateMigrationTable(ctx, conn, []string{timestamp}, repair.Applied, false, fsys)
×
68
}
69

70
func fetchRemote(p utils.Program, ctx context.Context, schema []string, timestamp string, config pgconn.Config, fsys afero.Fs) error {
×
71
        path := filepath.Join(utils.MigrationsDir, timestamp+"_remote_commit.sql")
×
72
        // Special case if this is the first migration
×
73
        if migrations, err := list.LoadLocalMigrations(fsys); err != nil {
×
74
                return err
×
75
        } else if len(migrations) == 0 {
×
76
                p.Send(utils.StatusMsg("Committing initial migration on remote database..."))
×
77
                return dump.Run(ctx, path, config, nil, nil, false, false, false, false, false, fsys)
×
78
        }
×
79

80
        w := utils.StatusWriter{Program: p}
×
81
        // Diff remote db (source) & shadow db (target) and write it as a new migration.
×
82
        output, err := diff.DiffDatabase(ctx, schema, config, w, fsys, diff.DiffSchemaMigra)
×
83
        if err != nil {
×
84
                return err
×
85
        }
×
86
        if len(output) == 0 {
×
87
                return errors.New("no schema changes found")
×
88
        }
×
89
        return afero.WriteFile(fsys, path, []byte(output), 0644)
×
90
}
91

92
func assertRemoteInSync(ctx context.Context, conn *pgx.Conn, fsys afero.Fs) error {
×
93
        remoteMigrations, err := list.LoadRemoteMigrations(ctx, conn)
×
94
        if err != nil {
×
95
                var pgErr *pgconn.PgError
×
96
                if !errors.As(err, &pgErr) || pgErr.Code != pgerrcode.UndefinedTable {
×
97
                        return err
×
98
                }
×
99
        }
100
        localMigrations, err := list.LoadLocalMigrations(fsys)
×
101
        if err != nil {
×
102
                return err
×
103
        }
×
104

105
        conflictErr := errors.New("The remote database's migration history is not in sync with the contents of " + utils.Bold(utils.MigrationsDir) + `. Resolve this by:
×
106
- Updating the project from version control to get the latest ` + utils.Bold(utils.MigrationsDir) + `,
×
107
- Pushing unapplied migrations with ` + utils.Aqua("supabase db push") + `,
×
108
- Or failing that, manually editing supabase_migrations.schema_migrations table with ` + utils.Aqua("supabase migration repair") + ".")
×
109
        if len(remoteMigrations) != len(localMigrations) {
×
110
                return conflictErr
×
111
        }
×
112

113
        for i, remoteTimestamp := range remoteMigrations {
×
114
                // LoadLocalMigrations guarantees we always have a match
×
115
                localTimestamp := utils.MigrateFilePattern.FindStringSubmatch(localMigrations[i])[1]
×
116
                if localTimestamp != remoteTimestamp {
×
117
                        return conflictErr
×
118
                }
×
119
        }
120

121
        return nil
×
122
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc