-
Notifications
You must be signed in to change notification settings - Fork 887
feat(scripts): add script to check schema between migrations #13037
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- migrations: allow passing in a custom migrate.FS - gen/dump: extract some functions to dbtestutil - scripts: write script to test migrations
if err != nil { | ||
panic(err) | ||
} | ||
|
||
for _, sed := range []string{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
review: moved to dbtestutil.normalizeDump
|
||
err = migrations.Up(db) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
hasPGDump := false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
review: moved to dbtestutil.PGDumpSchemaOnly
schema = regexp.MustCompile(`(?im)^(--.*)$`).ReplaceAll(schema, []byte{}) | ||
// Public is implicit in the schema. | ||
schema = regexp.MustCompile(`(?im)( |::|'|\()public\.`).ReplaceAll(schema, []byte(`$1`)) | ||
// Remove database settings. | ||
schema = regexp.MustCompile(`(?im)^(SET.*;)`).ReplaceAll(schema, []byte(``)) | ||
// Remove select statements | ||
schema = regexp.MustCompile(`(?im)^(SELECT.*;)`).ReplaceAll(schema, []byte(``)) | ||
// Removes multiple newlines. | ||
schema = regexp.MustCompile(`(?im)\n{3,}`).ReplaceAll(schema, []byte("\n\n")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
review: we could pre-compile these but we've already lost enough readability by using regexen IMO
_, _ = buf.WriteRune('\n') | ||
// PGDumpSchemaOnly is for use by gen/dump only. | ||
// It runs pg_dump against dbURL and sets a consistent timezone and encoding. | ||
func PGDumpSchemaOnly(dbURL string) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
review: I wanted to DRY this up with PGDump
but it would have been more fiddly than I'd have liked.
func pgDump(dbURL string) ([]byte, error) { | ||
// PGDump runs pg_dump against dbURL and returns the output. | ||
// It is used by DumpOnFailure(). | ||
func PGDump(dbURL string) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
review: Pre-emptively exported in case other packages find it useful.
func Up(db *sql.DB) error { | ||
return UpWithFS(db, migrations) | ||
} | ||
|
||
// UpWithFS runs SQL migrations in the given fs. | ||
func UpWithFS(db *sql.DB, migs fs.FS) (retErr error) { | ||
_, m, err := setup(db, migs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
review: this make it possible to test arbitrary migration versions
|
||
func makeMigrateFS(version string) (fs.FS, error) { | ||
// Export the migrations from the requested version to a zip archive | ||
out, err := exec.Command("git", "archive", "--format=zip", version, "coderd/database/migrations").CombinedOutput() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you want to go native, I bet you can find a library for git
too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, there's https://github.com/go-git/go-git but I'm happy to just shell out here for now.
// 2. Checks out $NEW_VERSION and runs migrations. | ||
// 3. Compares database schema post-migrate to that in VCS. | ||
// If any diffs are found, exits with an error. | ||
func main() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who/what/when is going to run this script? The hidden question is: can somebody forget to run it and there will be a disaster?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Point 👍 I need to add this to the CI workflow so it gets run on each commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, it makes more sense to integrate with the script Mathias is working on. I'll add a Makefile target at least for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is in a good shape so feel free to merge it 👍
Will add to a GH workflow in a separate PR |
migrate.Up
When run on the problematic commit with the gappy migrations:
When run on the subsequent commit that fixed it: