Skip to content

Commit ead1241

Browse files
Josh Calderdcousens
andauthored
Adds CLI flags to dev build and start to change what is built and run (#8046)
Co-authored-by: Daniel Cousens <[email protected]> Co-authored-by: Daniel Cousens <[email protected]>
1 parent 0fada1b commit ead1241

File tree

23 files changed

+597
-367
lines changed

23 files changed

+597
-367
lines changed

.changeset/plenty-hairs-share.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@keystone-6/core': major
3+
---
4+
5+
Adds additional flags to the `keystone dev`, `keystone build` and `keystone start` CLI commands

docs/components/docs/Navigation.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,9 @@ export function DocsNavigation() {
205205
<NavItem href="/docs/guides/overview">Overview</NavItem>
206206
<NavItem href="/docs/guides/cli">Command Line</NavItem>
207207
<NavItem href="/docs/guides/relationships">Relationships</NavItem>
208-
<NavItem href="/docs/guides/choosing-a-database">
209-
Choosing a Database <Badge look="success">New</Badge>
208+
<NavItem href="/docs/guides/choosing-a-database">Choosing a Database</NavItem>
209+
<NavItem href="/docs/guides/database-migration">
210+
Database Migration <Badge look="success">New</Badge>
210211
</NavItem>
211212
<NavItem href="/docs/guides/filters">
212213
Query Filters <Badge look="success">Updated</Badge>

docs/pages/blog/mysql-support.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ authorHandle: "https://twitter.com/flexdinesh"
77
metaImageUrl: ""
88
---
99

10-
We've added support for MySQL to Keystone's list of database providers, bringing the total number of supported database types to three.
10+
We've added support for MySQL to Keystone's list of database providers, bringing the total number of supported database types to three.
1111

1212
Here's an example `db.config` to work with MySQL database.
1313

@@ -16,7 +16,6 @@ export default config({
1616
db: {
1717
provider: 'mysql',
1818
url: 'mysql://dbuser:dbpass@localhost:5432/keystone',
19-
useMigrations: true,
2019
idField: { kind: 'uuid' },
2120
},
2221
...

docs/pages/docs/config/config.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ These database types are powered by their corresponding Prisma database provider
6464
- `url`: The connection URL for your database
6565
- `onConnect`: which takes a [`KeystoneContext`](../context/overview) object, and lets perform any actions you might need at startup, such as data seeding
6666
- `enableLogging` (default: `false`): Enable logging from the Prisma client.
67-
- `useMigrations` (default: `false`): Determines whether to use migrations or automatically force-update the database with the latest schema and potentially lose data.
6867
- `idField` (default: `{ kind: "cuid" }`): The kind of id field to use, it can be one of: `cuid`, `uuid` or `autoincrement`.
6968
This can also be customised at the list level `db.idField`.
7069
If you are using `autoincrement`, you can also specify `type: 'BigInt'` on PostgreSQL and MySQL to use BigInts.
@@ -82,7 +81,6 @@ export default config({
8281
onConnect: async context => { /* ... */ },
8382
// Optional advanced configuration
8483
enableLogging: true,
85-
useMigrations: true,
8684
idField: { kind: 'uuid' },
8785
shadowDatabaseUrl: 'postgres://dbuser:dbpass@localhost:5432/shadowdb'
8886
},
@@ -100,7 +98,6 @@ export default config({
10098
onConnect: async context => { /* ... */ },
10199
// Optional advanced configuration
102100
enableLogging: true,
103-
useMigrations: true,
104101
idField: { kind: 'uuid' },
105102
},
106103
/* ... */
@@ -117,7 +114,6 @@ export default config({
117114
onConnect: async context => { /* ... */ },
118115
// Optional advanced configuration
119116
enableLogging: true,
120-
useMigrations: true,
121117
idField: { kind: 'uuid' },
122118
},
123119
/* ... */

docs/pages/docs/guides/cli.md

Lines changed: 87 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,36 @@ $ keystone [command]
1414
1515
Commands
1616
dev start the project in development mode (default)
17-
postinstall generate client APIs and types (optional)
18-
build build the project (must be done before using start)
19-
start start the project in production mode
17+
postinstall build the project (for development, optional)
18+
build build the project (required by \`keystone start\`)
19+
start start the project
2020
prisma run Prisma CLI commands safely
21+
telemetry sets telemetry preference (enable/disable/status)
22+
{% if $nextRelease %}
23+
24+
Options
25+
--fix (postinstall) @deprecated
26+
do build the graphql or prisma schemas, don't validate them
27+
28+
--frozen (build)
29+
don't build the graphql or prisma schemas, only validate them
30+
31+
--no-db-push (dev)
32+
don't push any updates of your Prisma schema to your database
33+
34+
--no-prisma (build, dev)
35+
don't build or validate the prisma schema
36+
37+
--no-server (dev)
38+
don't start the express server
39+
40+
--no-ui (build, dev, start)
41+
don't build and serve the AdminUI
42+
43+
--with-migrations (start)
44+
trigger prisma to run migrations as part of startup
45+
{% /if %}
46+
2147
```
2248

2349
{% hint kind="tip" %}
@@ -31,16 +57,24 @@ We recommend adding the following scripts to your project's `package.json` file:
3157
```json
3258
{
3359
"scripts": {
60+
{% if $nextRelease %}
61+
"build": "keystone build",
62+
"dev": "keystone dev",
63+
"postinstall": "keystone postinstall",
64+
"generate": "keystone prisma migrate dev",
65+
"start": "keystone start --with-migrations",
66+
{% else / %}
3467
"deploy": "keystone build && keystone prisma migrate deploy",
3568
"dev": "keystone dev",
3669
"postinstall": "keystone postinstall",
3770
"start": "keystone start"
71+
{% /if %}
3872
}
3973
}
4074
```
4175

4276
{% hint kind="tip" %}
43-
Note: the deploy script above assumes you are using migrations
77+
Note: Depending on where you are deploying the `prisma migrate deploy` step might be better in the `build` or as a separate step altogether.
4478
{% /hint %}
4579

4680
Read on below for more details about each command, and see [bringing it all together](#bringing-it-all-together) for more details (including some important caveats) about how that "deploy" command works.
@@ -57,12 +91,28 @@ This is the command you use to start Keystone for local development. It will:
5791
- Generate and apply database migrations based on your Keystone Schema
5892
- Start the local dev server, which hosts the GraphQL API and Admin UI
5993

60-
{% hint kind="warn" %}
61-
Keystone does not currently watch your local files for changes. If you update the config, schema or any other files in your keystone project you'll need to restart the server.
62-
{% /hint %}
94+
{% if $nextRelease %}
95+
### dev flags
96+
97+
- `--no-db-push` - Don't push any updates of your Prisma schema to your database
98+
- `--no-prisma` - Don't build or validate the prisma schema
99+
- `--no-server` - Don't start the express server, will still watch for changes and update the Admin UI and schema files
100+
- `--no-ui` - Don't build and serve the AdminUI
101+
{% /if %}
63102

64103
### About database migrations
65104

105+
{% if $nextRelease %}
106+
When using `keystone dev` the default behaviour is for Keystone to update your database to match your schema using Prisma Migrate. This behaviour is great for the rapid iteration of a schema, but can be modified in the following ways:
107+
108+
- Running `keystone dev --no-db-push` - This will skip the dev migration step and not perform any checks on your database to ensure it matches your schema. This can be useful if you have an existing database or want to handle all migrations yourself. Be aware that this may lead to GraphQL runtime errors if a table or table column is unavailable.
109+
110+
See [`prisma` command](#prisma) below for more information on database migrations.
111+
112+
{% hint kind="tip" %}
113+
Be careful of running `keystone dev` while pointing to a production database as this can cause data loss.
114+
{% /hint %}
115+
{% else /%}
66116
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`:
67117

68118
- 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.
@@ -75,6 +125,7 @@ Commit the migration files to source control, then when you are hosting your app
75125
{% hint kind="tip" %}
76126
We strongly recommend enabling migrations if you are going to run your app in production. Not doing so risks data loss.
77127
{% /hint %}
128+
{% /if %}
78129

79130
### Resetting the database
80131

@@ -95,6 +146,11 @@ This is mainly useful early in a project's development lifecycle, when you want
95146
```bash
96147
$ keystone postinstall
97148
```
149+
{% if $nextRelease %}
150+
{% hint kind="tip" %}
151+
Note: `postinstall` is an alias for `keystone build --no-ui --frozen` we recommend switching to this `build` command
152+
{% /hint %}
153+
{% /if %}
98154

99155
Keystone generates several files that your app may depend on, including the Node.js API and TypeScript definitions.
100156

@@ -109,6 +165,11 @@ While the recommended way to fix this problem is to start your app using `keysto
109165
```bash
110166
$ keystone postinstall --fix
111167
```
168+
{% if $nextRelease %}
169+
{% hint kind="tip" %}
170+
Note: `postinstall --fix` is an alias for `keystone build --no-ui` we recommend switching to this `build` command
171+
{% /hint %}
172+
{% /if %}
112173

113174
## build
114175

@@ -118,7 +179,14 @@ $ keystone build
118179

119180
This command generates the files needed for Keystone to start in **production** mode. You should run it during the build phase of your production deployment.
120181

121-
It will also validate that the generated files you should have committed to source control are in sync with your Keystone Schema (see `postinstall` above).
182+
It will also validate that the generated files you should have committed to source control are in sync with your Keystone Schema.
183+
{% if $nextRelease %}
184+
185+
### build flags
186+
- `--frozen` - Don't update the graphql or prisma schemas, only validate them, exits with error if the schemas don't match what keystone would generate.
187+
- `--no-prisma` - Don't build or validate the prisma schema
188+
- `--no-ui` - Don't build the AdminUI
189+
{% /if %}
122190

123191
## start
124192

@@ -129,6 +197,12 @@ $ keystone start
129197
This command starts Keystone in **production** mode. It requires a build to have been generated (see `build` above).
130198

131199
It will not generate or apply any database migrations - these should be run during the **build** or **release** phase of your production deployment.
200+
{% if $nextRelease %}
201+
202+
### start flags
203+
- `--with-migrations` - Trigger prisma to run migrations as part of startup
204+
- `--no-ui` - Don't serve the AdminUI
205+
{% /if %}
132206

133207
## prisma
134208

@@ -191,6 +265,11 @@ Start Keystone in production mode:
191265
```bash
192266
yarn keystone start
193267
```
268+
{% if $nextRelease %}
269+
{% hint kind="tip" %}
270+
Note: To run migrations before you start Keystone use `keystone start --with-migrations`
271+
{% /hint %}
272+
{% /if %}
194273

195274
#### Notes
196275

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
title: "Database Migration"
3+
description: "Learn how to get your production database ready using Keystone's migration"
4+
---
5+
6+
Before running `keystone start` with a production database, you will first need to ensure the database has all the tables and fields that keystone requires. To make this easier keystone can generate the required migration files to store alongside your code, and then run these migrations against your production database.
7+
8+
## Prisma Migrate
9+
10+
Keystone uses Prisma's built-in migration feature, this works by generating `.sql` files into a `./migrations` at the root of your project (ie beside your `keystone.ts` file) and then running those migration files against your production database. For detailed information on how Prisma Migrate works see the [Prisma Migrate docs](https://www.prisma.io/docs/concepts/components/prisma-migrate).
11+
12+
## Running `keystone dev`
13+
14+
By default running `keystone dev` will force push your schema to the database set using `db.url` in your `keystone.ts` file.
15+
16+
{% if $nextRelease %}
17+
## Skipping dev DB push
18+
19+
If you want to look after all migrations, including in dev, yourself you can run `keystone dev --no-db-push` this will not perform the default force push in dev leaving you to perform migrations as you like.
20+
21+
{% hint kind="tip" %}
22+
Running `keystone dev --no-db-push` will return GraphQL runtime errors if tables and/or columns that Keystone requires are not present in the database.
23+
{% /hint %}
24+
25+
## Keystone Prisma Migrate CLI
26+
27+
Keystone offers the following three commonly used commands through Prisma to help manage your migrations.
28+
- `keystone prisma migrate generate` - Generates the migration files to run to set up your production database - these files should be committed to source control and accessible by the `deploy` step. This command is helpful if you want to either leave `keystone dev` as the default behaviour for rapid schema iteration and generate the migrations once you are ready to submit a PR.
29+
- `keystone prisma migrate deploy` - Runs the generated migrations - this command can only be run after a `build` step, and is generally run in the deploy step of your app or before running `keystone start`.
30+
- `keystone start --with-migrations` - Runs the generated migrations then starts Keystone.
31+
{% /if %}
32+
## Prisma CLI
33+
34+
The primary reason you'll need to use the Prisma CLI in your Keystone project is to work with Prisma Migrate.
35+
36+
As you start working with more sophisticated migration scenarios, you'll probably also need to use the [`migrate resolve`](https://www.prisma.io/docs/reference/api-reference/command-reference/#migrate-resolve) and [`migrate status`](https://www.prisma.io/docs/reference/api-reference/command-reference/#migrate-status) commands.
37+
38+
While Keystone abstracts much of the Prisma workflow for you, we strongly recommend you familiarise yourself with the Prisma Migrate CLI commands when you are managing your application in production.
39+
40+
41+
{% related-content %}
42+
{% well
43+
heading="Getting Started with create-keystone-app"
44+
href="/docs/getting-started" %}
45+
How to use Keystone's CLI app to standup a new local project with an Admin UI & the GraphQL Playground.
46+
{% /well %}
47+
{% well
48+
heading="Command Line Guide"
49+
href="/docs/guides/cli" %}
50+
Learn how to use Keystone's command line interface (CLI) to develop, build, and deploy your Keystone projects.
51+
{% /well %}
52+
{% /related-content %}

examples/document-field-customisation/keystone-server/keystone.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import { Context, TypeInfo } from '.keystone/types';
66

77
const db: KeystoneConfig<TypeInfo>['db'] = {
88
provider: 'sqlite',
9-
// You should use migrations in production environments
10-
useMigrations: false,
119
url: process.env.DATABASE_URL || 'file:./database.db',
1210
async onConnect(context: Context) {
1311
if (process.argv.includes('--seed-database')) {

examples/e2e-boilerplate/keystone-server/keystone.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import { Context, TypeInfo } from '.keystone/types';
66

77
const db: KeystoneConfig<TypeInfo>['db'] = {
88
provider: 'sqlite',
9-
// You should use migrations in production environments
10-
useMigrations: false,
119
url: process.env.DATABASE_URL || 'file:./database.db',
1210
async onConnect(context: Context) {
1311
if (process.argv.includes('--seed-database')) {

examples/feature-boilerplate/keystone.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import { Context, TypeInfo } from '.keystone/types';
66

77
const db: KeystoneConfig<TypeInfo>['db'] = {
88
provider: 'sqlite',
9-
// You should use migrations in production environments
10-
useMigrations: false,
119
url: process.env.DATABASE_URL || 'file:./database.db',
1210
async onConnect(context: Context) {
1311
if (process.argv.includes('--seed-database')) {

packages/core/src/artifacts.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -108,25 +108,28 @@ export async function validateCommittedArtifacts(
108108
return 'prisma';
109109
}
110110
})();
111-
if (outOfDateSchemas) {
112-
const message = {
113-
both: 'Your Prisma and GraphQL schemas are not up to date',
114-
graphql: 'Your GraphQL schema is not up to date',
115-
prisma: 'Your Prisma schema is not up to date',
116-
}[outOfDateSchemas];
117-
console.log(message);
118-
const term = {
119-
both: 'Prisma and GraphQL schemas',
120-
prisma: 'Prisma schema',
121-
graphql: 'GraphQL schema',
122-
}[outOfDateSchemas];
123-
if (shouldPrompt && (await confirmPrompt(`Would you like to update your ${term}?`))) {
124-
await writeCommittedArtifacts(artifacts, cwd);
125-
} else {
126-
console.log(`Please run keystone postinstall --fix to update your ${term}`);
127-
throw new ExitError(1);
128-
}
111+
if (!outOfDateSchemas) return;
112+
113+
const message = {
114+
both: 'Your Prisma and GraphQL schemas are not up to date',
115+
graphql: 'Your GraphQL schema is not up to date',
116+
prisma: 'Your Prisma schema is not up to date',
117+
}[outOfDateSchemas];
118+
console.log(message);
119+
120+
const which = {
121+
both: 'Prisma and GraphQL schemas',
122+
prisma: 'Prisma schema',
123+
graphql: 'GraphQL schema',
124+
}[outOfDateSchemas];
125+
126+
if (shouldPrompt && (await confirmPrompt(`Replace the ${which}?`))) {
127+
await writeCommittedArtifacts(artifacts, cwd);
128+
return;
129129
}
130+
131+
console.log(`Use keystone dev to update the ${which}`);
132+
throw new ExitError(1);
130133
}
131134

132135
export async function writeCommittedArtifacts(artifacts: CommittedArtifacts, cwd: string) {

0 commit comments

Comments
 (0)