on main help sign in
Remove autocompletion of first migration

For Reshape to work with an existing database, the first migration shouldn't autocomplete as then there can't be a zero-downtime deployment. The user should instead use `--complete` if they don't care about zero-downtime, for example when setting up a dev or CI environment. We should update the `--complete` flag to apply and complete each migration one by one for efficiency.

commit3a4f0f7f9ae7bf41664a909b8ea8b11234c04896 authorfabianlindfors <fabian@flapplabs.se> dateTue 1 Feb 2022, 09:50 (5 years ago) parent8888557
3 files changed+13−24
README.md+2−2 src/lib.rs+8−22 tests/common.rs+3
README.md+2−2
@@ -117,10 +117,10 @@ db.execute(reshape_schema_query)
117117To create your new `users` table, run:
118118
119119```bash
120−reshape migrate
120+reshape migrate --complete
121121```
122122
123−As this is the first migration, Reshape will automatically complete it. For subsequent migrations, you will need to first run `reshape migrate`, roll out your application and then complete the migration using `reshape complete`.
123+We use the `--complete` flag to automatically complete the migration. During a production deployment, you should first first run `reshape migrate` followed by `reshape complete` once your application has been fully rolled out.
124124
125125If nothing else is specified, Reshape will try to connect to a Postgres database running on `localhost` using `postgres` as both username and password. See [Connection options](#connection-options) for details on how to change the connection settings.
126126
src/lib.rs+8−22
@@ -160,7 +160,6 @@ fn migrate(
160160 // with the already applied ones stored in the state. This will throw an error if the
161161 // two sets of migrations don't agree, for example if a new migration has been added
162162 // in between two existing ones.
163− let current_migration = state::current_migration(db)?;
164163 let remaining_migrations = state::remaining_migrations(db, migrations)?;
165164 if remaining_migrations.is_empty() {
166165 println!("No migrations left to apply");
@@ -252,27 +251,14 @@ fn migrate(
252251 state.in_progress(remaining_migrations);
253252 state.save(db).context("failed to save in-progress state")?;
254253
255− // If we started from a blank slate, we can finish the migration immediately
256− if current_migration.is_none() {
257− println!("Automatically completing migrations\n");
258− complete(db, state).context("failed to automatically complete migrations")?;
259−
260− println!("Migrations complete:");
261− println!(
262− " - Run '{}' from your application to use the latest schema",
263− schema_query_for_migration(&target_migration)
264− );
265− } else {
266− println!("Migrations have been applied and the new schema is ready for use:");
267− println!(
268− " - Run '{}' from your application to use the latest schema",
269− schema_query_for_migration(&target_migration)
270− );
271− println!(
272− " - Run 'reshape complete' once your application has been updated and the previous schema is no longer in use"
273− );
274− }
275−
254+ println!("Migrations have been applied and the new schema is ready for use:");
255+ println!(
256+ " - Run '{}' from your application to use the latest schema",
257+ schema_query_for_migration(&target_migration)
258+ );
259+ println!(
260+ " - Run 'reshape complete' once your application has been updated and the previous schema is no longer in use"
261+ );
276262 Ok(())
277263}
278264
tests/common.rs+3
@@ -128,6 +128,9 @@ impl Test<'_> {
128128 .simple_query(&reshape::schema_query_for_migration(&first_migration.name))
129129 .unwrap();
130130
131+ // Automatically complete first migration
132+ self.reshape.complete().unwrap();
133+
131134 // Run setup function
132135 if let Some(after_first_fn) = self.after_first_fn {
133136 print_subheading("Running setup and first checks");