feat(migrate): add standalone schema migration binary
Runs the SeaORM entity-first schema sync (db::schema::sync_schema) as a one-shot app; disables auto_migrate to avoid double execution. Add make migrate / make check-migrate targets.
zhenyi committed
Added app/migrate/src/main.rs app/migrate/src/main.rs +47 −0 View app/migrate/src/main.rs
@@ -0,0 +1,47 @@
1use config::ConfigLoader;
2use db::conn::Db;
3use db::schema::sync_schema;
4use tracing::info;
5
6const DEFAULT_LOG_FILTER: &str = "info,migrate=debug,db=debug";
7
8#[tokio::main]
9async fn main() {
10 if let Err(e) = run().await {
11 eprintln!("migrate: fatal: {e}");
12 std::process::exit(1);
13 }
14}
15
16async fn run() -> Result<(), Box<dyn std::error::Error>> {
17 let mut loader = ConfigLoader::new();
18 let mut args = std::env::args().skip(1);
19 while let Some(arg) = args.next() {
20 match arg.as_str() {
21 "--config" => {
22 let path = args.next().ok_or("--config requires a path argument")?;
23 loader = loader.config_file(path);
24 }
25 other => {
26 return Err(
27 format!("unknown argument: {other} (usage: migrate [--config <path>])").into(),
28 );
29 }
30 }
31 }
32
33 let mut app = loader.load()?;
34 app.obs = app.obs.with_app_defaults("migrate", DEFAULT_LOG_FILTER);
35 let _obs = obs::init(&app.obs)?;
36
37 let mut db_cfg = app.db.clone();
38 db_cfg.auto_migrate = false;
39 let db = Db::from_config(&db_cfg).await?;
40
41 info!("running schema migration");
42 sync_schema(db.primary_connection()).await?;
43 info!("schema migration completed");
44
45 db.close().await;
46 Ok(())
47}
Added app/migrate/Cargo.toml app/migrate/Cargo.toml +16 −0 View app/migrate/Cargo.toml
@@ -0,0 +1,16 @@
1[package]
2name = "migrate"
3version.workspace = true
4edition.workspace = true
5authors.workspace = true
6categories.workspace = true
7keywords.workspace = true
8repository.workspace = true
9homepage.workspace = true
10
11[dependencies]
12config.workspace = true
13db.workspace = true
14obs.workspace = true
15tokio.workspace = true
16tracing.workspace = true
Modified Cargo.lock Cargo.lock +11 −0 View Cargo.lock
@@ -4846,6 +4846,17 @@
48464846]
48474847
48484848[[package]]
4849name = "migrate"
4850version = "1.94.0"
4851dependencies = [
4852 "config 1.94.0",
4853 "db",
4854 "obs",
4855 "tokio",
4856 "tracing",
4857]
4858
4859[[package]]
48494860name = "mime"
48504861version = "0.3.17"
48514862source = "registry+https://github.com/rust-lang/crates.io-index"
Modified Cargo.toml Cargo.toml +2 −1 View Cargo.toml
@@ -48,6 +48,7 @@
4848 "app/mails",
4949 "app/gitpro",
5050 "app/githook",
51 "app/migrate",
5152 "agent/llm",
5253 "agent/lprovider"
5354]
@@ -90,7 +91,7 @@
9091tokio = { version = "1.53.1", features = ["full"] }
9192sea-orm = { version = "2.0.1", features = ["sqlx-all","runtime-tokio","with-time","with-uuid"]}
9293serde = { version = "1.0.229", features = ["derive"] }
93time = { version = "0.3", features = ["serde", "macros", "formatting"] }
94time = { version = "0.3", features = ["serde", "serde-human-readable", "macros", "formatting"] }
9495uuid = { version = "1", features = ["v7", "serde"] }
9596lombok = "0.4.0"
9697log = "0.4"
Modified Makefile Makefile +8 −0 View Makefile
@@ -227,6 +227,14 @@
227227build-mails:
228228 cargo build -p mails
229229
230.PHONY: check-migrate
231check-migrate:
232 cargo check -p migrate
233
234.PHONY: migrate
235migrate:
236 cargo run -p migrate
237
230238.PHONY: check-mails
231239check-mails:
232240 cargo check -p mails