Skip to content

feat!: Add support for rolling back migrations#583

Open
ElijahAhianyo wants to merge 13 commits into
masterfrom
elijah/migrations-rollback
Open

feat!: Add support for rolling back migrations#583
ElijahAhianyo wants to merge 13 commits into
masterfrom
elijah/migrations-rollback

Conversation

@ElijahAhianyo

@ElijahAhianyo ElijahAhianyo commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Related issue or discussion

fixes #547

Description

This allows rolling back migrations to the specified migration file.

Assuming the project has the following migration files in its migration dir:

├── migrations
 │   └── m_0001_initial.rs
 |   └── m_0002_second.rs

./target/debug/foo migration rollback m_0001_initial

The above command will roll back(unapply) the m_0002_second file, leaving m_0001_initial applied.
Alternatively, the migration file number can be used for convenience:

./target/debug/foo migration rollback 0001

Migrations are currently tied to a crate(the crate name is used), which means rolling back a migration in a project that imports apps from external crates will implicitly (and only) rollback migrations in the current project/crate. This might change when support for workspaces is added

As a bonus, this PR also adds CLI Group tasks as a means to group nested related subcommands under a parent subcommand:

Eg.

     use async_trait::async_trait;
     use clap::{ArgMatches, Command};
     use cot::cli::{Cli, CliTask, CliTaskGroup};
     use cot::project::WithConfig;
     use cot::{Bootstrapper, Project};
    
     struct Frobnicate;
    
     #[async_trait(?Send)]
     impl CliTask for Frobnicate {
         fn subcommand(&self) -> Command {
             Command::new("frobnicate")
                  .about("Test frobnicate command")

         }
    
         async fn execute(
             &mut self,
             _matches: &ArgMatches,
             _bootstrapper: Bootstrapper<WithConfig>,
         ) -> cot::Result<()> {
             println!("Frobnicating...");
    
             Ok(())
         }
     }
    
     struct MyProject;
     impl Project for MyProject {
         fn register_tasks(&self, cli: &mut Cli) {
             let mut group_command = CliTaskGroup::new("foo").about("Foo related commands");
             group_command.add_task(Frobnicate);
             cli.add_task(group_command);
        }
   }

Results in the following

eli@Elijahs-MacBook-Pro forms % ../../target/debug/newproject foo --help
Foo related commands

Usage: newproject foo [OPTIONS] <COMMAND>

Commands:
  frobnicate  Test frobnicate command
  help        Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help

Type of change

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

@github-actions github-actions Bot added A-deps Area: Dependencies C-lib Crate: cot (main library crate) labels Jun 2, 2026
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

🐰 Bencher Report

Branchelijah/migrations-rollback
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
5,490.80 µs
(-10.98%)Baseline: 6,168.10 µs
7,754.14 µs
(70.81%)
json_api/json_api📈 view plot
🚷 view threshold
919.35 µs
(-14.94%)Baseline: 1,080.84 µs
1,322.26 µs
(69.53%)
nested_routers/nested_routers📈 view plot
🚷 view threshold
847.31 µs
(-15.25%)Baseline: 999.76 µs
1,202.64 µs
(70.45%)
single_root_route/single_root_route📈 view plot
🚷 view threshold
812.91 µs
(-15.53%)Baseline: 962.36 µs
1,165.95 µs
(69.72%)
single_root_route_burst/single_root_route_burst📈 view plot
🚷 view threshold
17,852.00 µs
(+1.01%)Baseline: 17,674.11 µs
21,077.68 µs
(84.70%)
🐰 View full continuous benchmarking report in Bencher

@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.51969% with 19 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cot/src/db/migrations.rs 90.00% 9 Missing and 8 partials ⚠️
cot/src/cli.rs 97.26% 2 Missing ⚠️
Flag Coverage Δ
rust 90.20% <92.51%> (+0.03%) ⬆️

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

Files with missing lines Coverage Δ
cot/src/db/migrations/sorter.rs 93.59% <100.00%> (+0.12%) ⬆️
cot/src/utils/graph.rs 98.76% <100.00%> (+0.04%) ⬆️
cot/src/cli.rs 86.73% <97.26%> (+3.47%) ⬆️
cot/src/db/migrations.rs 84.97% <90.00%> (+1.52%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ElijahAhianyo ElijahAhianyo marked this pull request as ready for review June 9, 2026 20:46
@ElijahAhianyo ElijahAhianyo requested review from m4tx and seqre June 9, 2026 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-deps Area: Dependencies C-lib Crate: cot (main library crate)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add command to rollback migration

1 participant