Skip to content

docs: Add Migration docs - #622

Open
ElijahAhianyo wants to merge 11 commits into
masterfrom
elijah/migration-docs
Open

docs: Add Migration docs#622
ElijahAhianyo wants to merge 11 commits into
masterfrom
elijah/migration-docs

Conversation

@ElijahAhianyo

@ElijahAhianyo ElijahAhianyo commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Refactor / cleanup
  • Performance improvement
  • Other (describe above)

@github-actions github-actions Bot added the A-docs Area: Documentation label Jul 27, 2026
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

🐰 Bencher Report

Projectcot
Branchelijah/migration-docs
Testbedgithub-ubuntu-latest
Click to view all benchmark results
BenchmarkLatencyBenchmark 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%)
🐰 View full continuous benchmarking report in Bencher

@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 23 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cot-test/src/utils.rs 0.00% 23 Missing ⚠️
Flag Coverage Δ
rust 90.20% <0.00%> (-0.10%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cot-macros/src/lib.rs 94.84% <ø> (ø)
cot-test/src/lib.rs 76.76% <ø> (ø)
cot/src/db/migrations.rs 83.47% <ø> (ø)
cot-test/src/utils.rs 0.00% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions Bot added C-lib Crate: cot (main library crate) C-macros Crate: cot-macros labels Jul 27, 2026
@ElijahAhianyo
ElijahAhianyo marked this pull request as ready for review July 27, 2026 16:44
@ElijahAhianyo
ElijahAhianyo requested review from m4tx and seqre July 27, 2026 16:46
@m4tx

m4tx commented Jul 27, 2026

Copy link
Copy Markdown
Member

This is not a breaking change, right? Then it should be docs, not docs!.

@ElijahAhianyo ElijahAhianyo changed the title docs!: Add Migration docs docs: Add Migration docs Jul 27, 2026
Comment thread docs/databases/migrations.md Outdated
* **`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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created #623 to improve this.

@seqre seqre left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall great work, just some suggestions for improvement!

Comment thread cot-test/tests/doc_code_blocks.rs Outdated
"{} in {}\n{}",
err,
file_info,
code_block.literal.replace('\n', "\n ")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if printing the whole code block makes sense. I'd suggest one of three:

  1. Print top N lines
  2. Print only the metadata line with language
  3. Do not print at all

@ElijahAhianyo ElijahAhianyo Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread docs/databases/migrations.md Outdated
Comment thread docs/databases/migrations.md Outdated
Comment thread docs/databases/migrations.md Outdated
* **`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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/databases/migrations.md Outdated

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this zero special value, if anything I'd prefer 0 or just having no special cases

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need to update this to use the cot CLI once #587 gets merged

@ElijahAhianyo
ElijahAhianyo requested review from m4tx and seqre July 31, 2026 00:56
5,
);

panic!("{err}\n{snippet}");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread docs/databases/migrations.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-docs Area: Documentation C-lib Crate: cot (main library crate) C-macros Crate: cot-macros

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants