Search code examples
github-actionskeystonejs

Updating the Prisma, GraphQL and DB schemas for a Keystone project in a non-interactive environment


I am building a github action event that is deploying a keystone.js server

When the build is running, the user is being prompted to answer a question

➜  server git:(test-me) npm run build

> [email protected] build
> keystone build

Your Prisma and GraphQL schemas are not up to date
✔ Would you like to update your Prisma and GraphQL schemas? … no

My question is how to config the workflow so that during runtime it will answer yes?

Thanks!


Solution

  • Some background – this all has to do with how Keystone leverages the underlying functionality of Prisma Migrate which is responsible generating and applying database migrations in a Keystone project. That's why a lot of the messages, commands, etc. in this area of the system reference "Prisma". Also, if need to delve deep into migrations, at some point the Prisma's docs will become more more relevant that those of Keystone (which is really just a wrapping the Prisma CLI for these operations).

    So, in this case, it sounds like you're missed the db.useMigrations flag. I'm just going to quote the docs verbatim here as they do a pretty good job of explaining it:

    In development, Keystone will migrate the structure of your database for you in one of two ways depending on how you have configured db.useMigrations:

    • If db.useMigrations is false (the default), Keystone will use Prisma Migrate to update your database so that it matches your schema. It may lose data while updating your database so you should only use this mode in initial development.
    • If db.useMigrations is true, Keystone will use Prisma Migrate to apply any existing migrations and prompt you to create a migration if there was a change to your schema.

    When you are using migrations, the recommended workflow is to have keystone dev generate the migrations for you and apply them automatically in development.

    Commit the migration files to source control, then when you are hosting your app in production, use the keystone prisma migrate deploy command [..] to deploy your migrations before starting Keystone.

    What's happening here (I think) is that you haven't set db.useMigrations to true, so your project just resetting your DB anytime there are changes. That is, every time Keystone starts it's comparing your list schemas with the DB and asking if you want to reset the DB to match, including when it starts up for the first time in production.

    This all happens without generating physical migration files - it just makes changes to the DB directly. It's a super handy way of working early in a project, when you're hacking around locally – you can add/remove/rename/etc. fields and lists without accumulating a series of migrations that step though those changes. The idea is that, as your schema starts to settle down and you want to start deploying, you turn the db.useMigrations flag on and start generating migrations (.sql files that will perform the steps necessary to align your DB with your list schema). These files should be committed to version control (ie. git) and deployed along with the app code.

    In practice, your Keystone config might look like this:

    export default withAuth(
      config({
        db: {
          provider: 'postgresql',
          useMigrations: true,  // <-- Here
          url: DATABASE_URL,
        },
        server: { port: PORT },
        lists,
        session,
      })
    );
    

    Generally, once you project is at the point you'd turn db.useMigrations on, the changes you're making become a bit more methodical so you'd generally leave it set to true. Maybe if you do a major DB overhaul at some point you might have a branch where db.useMigrations is false for a time but, once you're happy with your lists again, you'd set db.useMigrations back to true, use keystone dev to generate a migration, then merging the branch back into main (or master or whatever your main branch is called).

    Also, remember that the automatic migrations are really just suggestions. They're plain SQL so feel free to edit them if you require additional steps to, for example, ensure data isn't lost when fields or lists are renamed.

    You might also want to checkout this related answer where I talk about Keystone deploying migrations in the context of deploying to Heroku.