docs: Add Migration docs - #622
Conversation
|
| Project | cot |
| Branch | elijah/migration-docs |
| Testbed | github-ubuntu-latest |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result microseconds (µs) (Result Δ%) | Upper Boundary microseconds (µs) (Limit %) |
|---|---|---|---|
| empty_router/empty_router | 📈 view plot 🚷 view threshold | 11,279.00 µs(+53.70%)Baseline: 7,338.41 µs | 12,807.92 µs (88.06%) |
| json_api/json_api | 📈 view plot 🚷 view threshold | 924.75 µs(-14.18%)Baseline: 1,077.50 µs | 1,368.44 µs (67.58%) |
| nested_routers/nested_routers | 📈 view plot 🚷 view threshold | 848.49 µs(-15.50%)Baseline: 1,004.10 µs | 1,245.23 µs (68.14%) |
| single_root_route/single_root_route | 📈 view plot 🚷 view threshold | 813.19 µs(-15.92%)Baseline: 967.14 µs | 1,208.85 µs (67.27%) |
| single_root_route_burst/single_root_route_burst | 📈 view plot 🚷 view threshold | 16,501.00 µs(-4.94%)Baseline: 17,357.78 µs | 21,685.90 µs (76.09%) |
Codecov Report❌ Patch coverage is
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
This is not a breaking change, right? Then it should be |
| * **`DEPENDENCIES`**: a list of other migrations (including those in other apps) that must run before this one. See [Dependencies](#dependencies) below. | ||
| * **`OPERATIONS`**: the actual list of schema changes this migration performs, applied in order. See [Operations](#operations) below. | ||
|
|
||
| You'll also notice a second struct below the `Migration` impl, prefixed with an underscore (`_Product` above). This is a snapshot of the model as it looked at the time this migration was generated, marked with `model_type = "migration"`. Cot uses these snapshots to work out what changed the next time you run `cot migration make`, by diffing your current models against the latest snapshot on record. You shouldn't need to touch these by hand, they exist purely so future migrations can be generated correctly. |
There was a problem hiding this comment.
This is not the only reason these structures exists. Note that with each migration being run, a given model can have completely different structure. For the custom migrations, this matters: if you use the wrong version of the model, you might end up doing operations that will straight up fail, or, what's even worse, will silently corrupt your data.
In custom migrations, you should only use the snapshot (model_type = "migration") models to ensure the engine will use the correct version of each model. We should also mention this in the custom migrations docs.
seqre
left a comment
There was a problem hiding this comment.
Overall great work, just some suggestions for improvement!
| "{} in {}\n{}", | ||
| err, | ||
| file_info, | ||
| code_block.literal.replace('\n', "\n ") |
There was a problem hiding this comment.
I'm not sure if printing the whole code block makes sense. I'd suggest one of three:
- Print top N lines
- Print only the metadata line with language
- Do not print at all
There was a problem hiding this comment.
I went in the direction of option 1. This change was added because it was technically hard to see where the issue was when the tests failed. The current implementation looks like overkill, but the output does look much better imo:
Caused by:
for `cot-test::doc_code_blocks`, command `/Users/eli/Documents/work/cot/cot/target/debug/deps/doc_code_blocks-f8b5e65a4ded8731 --list --format terse` exited with exit code 101
--- stdout:
--- stderr:
thread 'main' (599490) panicked at cot-test/tests/doc_code_blocks.rs:92:21:
unknown test language: ignore
--> migrations.md:201:1
|
201 | Rollback dry run
202 |
203 | Target:
204 | app: customers
205 | migration: m_0001_initial
|
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---
error: Recipe `test` failed on line 67 with exit code 104
| * **`DEPENDENCIES`**: a list of other migrations (including those in other apps) that must run before this one. See [Dependencies](#dependencies) below. | ||
| * **`OPERATIONS`**: the actual list of schema changes this migration performs, applied in order. See [Operations](#operations) below. | ||
|
|
||
| You'll also notice a second struct below the `Migration` impl, prefixed with an underscore (`_Product` above). This is a snapshot of the model as it looked at the time this migration was generated, marked with `model_type = "migration"`. Cot uses these snapshots to work out what changed the next time you run `cot migration make`, by diffing your current models against the latest snapshot on record. You shouldn't need to touch these by hand, they exist purely so future migrations can be generated correctly. |
There was a problem hiding this comment.
This is a snapshot of the model as it looked at the time this migration was generated
This part is 100% correct, but I'd emphasize here also that that's the Rust representation of what the database table will be after the migration.
| //! | ||
| //! List of migrations for the current app. | ||
| //! | ||
| //! Generated by cot CLI 0.6.0 on 2026-05-27 00:42:36+00:00 |
There was a problem hiding this comment.
Unrelated nit, but I think we should add a note here in the generator that users should not modify this file as there is no point in that.
|
|
||
| If Cot ever detects a cycle in your migration dependencies, it will refuse to run and tell you so, both when generating new migrations and when booting the project. | ||
|
|
||
| ## Rolling back migrations |
There was a problem hiding this comment.
We should wait with merging this until #583 is merged then
|
|
||
| * The full migration name, e.g. `m_0002_add_sku` | ||
| * Just the number, e.g. `0002` | ||
| * The special value `zero`, meaning "roll back everything for this app" |
There was a problem hiding this comment.
I don't like this zero special value, if anything I'd prefer 0 or just having no special cases
There was a problem hiding this comment.
The special case of zero is as a result of making the migration rollback exclusive to the specified migration. I went in this direction for the sake of familiarity with Git/Django(and other systems that require some form of rollback). The special case is typically used if you want to also roll back the initial migration. If we want to take out the special case, we can make the rollback inclusive of the specified migration, i.e migration rollback 0001 will roll back everything, including 0001. I'm not sure if this feels intuitive UX-wise. I'd love to have your opinions on this: @m4tx @seqre
|
|
||
| ## Rolling back migrations | ||
|
|
||
| Rolling back migrations runs through your compiled project binary in the target dir, not the `cot` CLI: |
There was a problem hiding this comment.
We'll need to update this to use the cot CLI once #587 gets merged
| 5, | ||
| ); | ||
|
|
||
| panic!("{err}\n{snippet}"); |
There was a problem hiding this comment.
Could we define a custom error struct (and return Result<(), ThisNewErrorStruct> here) instead of using bespoke logic in-place here? This would allow us to define the fancy printing in just one place in the code and then reuse if needed.
Type of change