Skip to content

Support for squashing migrations for trunk based development workflows #5714

@jasonkuhrt

Description

@jasonkuhrt

Our team is thinking about how to adopt an ideal (but simple) migration workflow.

We already practice trunk based development on our application.

This means we branch of trunk, make changes, create a pull-request, iterate (multiple commits) with a preview deploy for that branch, then once done, squash-merge the work into trunk where it appears as a single commit of work. The merge into trunk kicks off a production deployment (with automated tests of course).

The way we see adopting Prisma into this workflow right now:

  1. Commits should have max 1 migration. This is for simplicity. We can't think why a commit should have multiple migrations since a commit is an atomic deployable unit. E.g. there will never be a deployment of "half of a commit".

  2. On branches, eventually, migrations should be deployed to the preview database by CI runs triggered by the git push. But for now we're ok doing manual migration deploys via the CLI right before pushing the commit.

  3. A branch has many commits but as mentioned before we want trunk to represent the work as one commit. This can lead to a situation where the resulting 1 trunk commit will have more than 1 migration, violating our number 1 workflow rule. Therefore squash-merging a PR we will locally delete all the migrations introduced by the branch and then re-create just one migration. We'll commit+push that to the branch and then squash merge it (if we're being pick, probably way for the branch preview deploy yet again one last time etc. but in practice we'll probably skip this).

This issue is a feature request for step 3 above.

It would be great if instead of doing this manually:

Therefore squash-merging a PR we will locally delete all the migrations introduced by the branch and then re-create just one migration.

We could have tooling to do this. Literally that initially seems to translate to:

prisma migrate squash --from <name> --to <name>

But actually we would love to introduce a PR bot that adds the commits to the branch for us, thus keeping the PR continually in a ready-for-trunk-merge state (respective to our number 1 rule above).

That would require us to:

  1. Find out the migrations that have been introduced on this branch
  2. Tell Prisma to squash merge them all

Thus this form would be advantageous to us:

prisma migrate squash --from <name>

This way we would just look for the oldest migration introduced in the branch, then let Prisma infer to squash up and including the latest migration.

I don't know if it would be appropriate for Prisma to including support for discovering the migrations introduced by a git branch over its base... This would involve getting cozy with git internally which is probably going to far in scope here, e.g.:

prisma migrate list --from-current-branch

And thus, e.g.:

prisma migrate squash --from $(prisma migrate list --json --from-current-branch | jq '[0]')

That said, as a user, having prisma migrate list --from-current-branch would greatly lower the bar for me to implement my automation. I would avoid having to:

  • Think about/Get familiar with how migrations are ordered on disc

  • Script/learn git, especially the nuances of branches, finding their parents, then diffing from state of their parents, blah blah blah

  • handling edge cases (like when a branch introduces prisma, no migrations history to diff on parent branch)

Hmm... I guess, for us, while squash is a necessary ingredient here, it alone doesn't really save us effort/time/thinking than our current manual approach:

Therefore squash-merging a PR we will locally delete all the migrations introduced by the branch and then re-create just one migration.

Its only once we get the PR CI automation going that things become 💯

Finally, a point raised by @albertoperdomo on slack, the challenges introduced by human edits to migration files for squash logic.

My assumption right now as a user is that if I go manually edit a migration I am giving up being able to squash it later.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions