Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,459 changes: 1,041 additions & 418 deletions Cargo.lock

Large diffs are not rendered by default.

20 changes: 9 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,30 @@ libvault-core = "0.1.0"
#====
anyhow = "1.0.103"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.150"
serde_json = "1.0.151"
serde_urlencoded = "0.7"
tracing = "0.1.44"
tracing-subscriber = "0.3.23"
tracing-appender = "0.2.5"
thiserror = "2.0.18"
clap = "4.6.1"
thiserror = "2.0.19"
clap = "4.6.4"

#====
tokio = "1.52.3"
tokio = "1.53.1"
tokio-stream = "0.1.18"
tokio-util = "0.7.18"
tokio-util = "0.7.19"
async-trait = "0.1.89"
async-stream = "0.3.6"
async-recursion = "1.1.1"
futures = "0.3.32"
futures-util = "0.3.32"
axum = { version = "0.8.9", features = ["macros", "json"] }
axum-extra = "0.12.6"
russh = "0.61.2"
russh = "0.62.3"
tower-http = "0.7.0"
tower = "0.5.3"
tower-sessions = { version = "0.15", features = ["memory-store"] }
time = { version = "0.3.51", features = ["serde"] }
time = { version = "0.3.54", features = ["serde"] }
lettre = { version = "0.11", default-features = false, features = [
"builder",
"smtp-transport",
Expand All @@ -77,8 +77,8 @@ lettre = { version = "0.11", default-features = false, features = [
"rustls-platform-verifier",
] }
#====
sea-orm = "1.1.20"
sea-orm-migration = "1.1.20"
sea-orm = "2.0.0"
sea-orm-migration = "2.0.0"

#====
rand = "0.10.2"
Expand All @@ -94,10 +94,8 @@ hmac = "0.13"
idgenerator = "2.0.0"
config = "0.15.25"
reqwest = "0.13.4"
lazy_static = "1.5.0"
uuid = "1.23.5"
regex = "1.13.0"
ed25519-dalek = "2.2.0"
ctrlc = "3.5.2"
cedar-policy = "4.11.2"
secp256k1 = "0.31.1"
Expand Down
14 changes: 13 additions & 1 deletion ceres/src/model/admin.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde::Serialize;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;

#[derive(Serialize, ToSchema)]
Expand All @@ -10,3 +10,15 @@ pub struct IsAdminResponse {
pub struct AdminListResponse {
pub admins: Vec<String>,
}

/// Request body for generating `.mega_cedar.json` content from admin usernames.
#[derive(Debug, Deserialize, ToSchema)]
pub struct GenerateCedarRequest {
pub admins: Vec<String>,
}

/// Response containing generated `.mega_cedar.json` content.
#[derive(Serialize, ToSchema)]
pub struct GenerateCedarResponse {
pub content: String,
}
13 changes: 7 additions & 6 deletions ceres/src/model/webhook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use utoipa::ToSchema;
pub struct CreateWebhookRequest {
pub target_url: String,
pub secret: String,
/// Event types: "cl.created", "cl.updated", "cl.merged", "cl.closed", "cl.reopened", "cl.comment.created", "*"
/// Event types: "cl_created", "cl_updated", "cl_merged", "cl_closed", "cl_reopened", "cl_comment_created", "all"
pub event_types: Vec<String>,
pub path_filter: Option<String>,
pub active: Option<bool>,
Expand Down Expand Up @@ -39,7 +39,7 @@ impl From<WebhookWithEventTypes> for WebhookResponse {
event_types: value
.event_types
.into_iter()
.map(|e| e.to_value())
.map(|e| e.to_value().value.into_owned())
.collect(),
path_filter: m.path_filter,
active: m.active,
Expand All @@ -52,7 +52,8 @@ impl From<WebhookWithEventTypes> for WebhookResponse {
pub fn parse_webhook_event_types(raw: Vec<String>) -> Result<Vec<WebhookEventTypeEnum>, String> {
raw.into_iter()
.map(|s| {
WebhookEventTypeEnum::try_from_value(&s).map_err(|_| format!("invalid event type: {s}"))
WebhookEventTypeEnum::try_from(s.as_str())
.map_err(|_| format!("invalid event type: {s}"))
})
.collect()
}
Expand All @@ -66,7 +67,7 @@ mod tests {

#[test]
fn parse_webhook_event_types_accepts_known_values() {
let parsed = parse_webhook_event_types(vec!["cl.created".to_string(), "all".to_string()])
let parsed = parse_webhook_event_types(vec!["cl_created".to_string(), "all".to_string()])
.expect("valid event types");
assert_eq!(parsed.len(), 2);
assert_eq!(parsed[0], WebhookEventTypeEnum::ClCreated);
Expand All @@ -75,7 +76,7 @@ mod tests {

#[test]
fn parse_webhook_event_types_rejects_unknown_values() {
let err = parse_webhook_event_types(vec!["not.a.real.event".to_string()])
let err = parse_webhook_event_types(vec!["not_a_real_event".to_string()])
.expect_err("invalid event type");
assert!(err.contains("invalid event type"));
}
Expand Down Expand Up @@ -104,7 +105,7 @@ mod tests {
let response = WebhookResponse::from(value);
assert_eq!(response.id, 42);
assert_eq!(response.target_url, "https://example.com/hook");
assert_eq!(response.event_types, vec!["cl.created".to_string()]);
assert_eq!(response.event_types, vec!["cl_created".to_string()]);
assert_eq!(response.path_filter.as_deref(), Some("/project"));
assert!(response.active);
}
Expand Down
21 changes: 20 additions & 1 deletion jupiter-migrate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,30 @@ After schema changes, regenerate callisto entities (adjust connection URL for yo
sea-orm-cli generate entity \
-u postgres://postgres:postgres@localhost:5432/mono \
-o jupiter/callisto/src \
--with-serde both
--with-serde both \
--entity-format dense
```

Review generated diffs in `jupiter/callisto/src/` before committing.

**Do not edit CLI-generated entity files** for polymorphic/link joins or `Model::new` helpers — those live only in `entity_ext/`. Regenerating must overwrite table models cleanly.

**After every regen:**

1. Re-add `pub mod entity_ext;` to `jupiter/callisto/src/mod.rs` (codegen overwrites this file).
2. Keep `sea_orm_active_enums.rs` webhook variant names readable (`ClCreated`, not CLI-mangled names). `rs_type = "Enum"` is correct for SeaORM 2.0 — call sites that need a string use `to_value().value` or `TryFrom<&str>`.
3. Leave `entity_ext/` alone — it owns:
- `Model::new` helpers and ID utilities
- Polymorphic / link-based `Relation` + `Related` (no DB FKs), including:
- `item_labels` / `item_assignees`: dual `belongs_to` on `item_id` → `mega_cl` and `mega_issue`
- `mega_cl` / `mega_issue`: `has_many` labels (via), assignees, conversations
- `mega_conversation`: link joins to CL/Issue; `has_many` reactions
- `reactions`: `belongs_to` conversation
- `mega_code_review_thread`: `belongs_to` `mega_cl` on `link`
- `label`: `has_many` `item_labels`

Join call sites that need those relations use `callisto::entity_ext::<table>::Relation`, not the generated entity `Relation`.

## Library API

```rust
Expand Down
1 change: 1 addition & 0 deletions jupiter-migrate/src/migration/m20250314_025943_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl MigrationTrait for Migration {
DatabaseBackend::Sqlite | DatabaseBackend::MySql => {
// Do not create enum in sqlite
}
_ => {}
}

manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl MigrationTrait for Migration {
}

DatabaseBackend::Sqlite => {}
_ => {}
}

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ impl MigrationTrait for Migration {
.await?;
}
DatabaseBackend::Sqlite | DatabaseBackend::MySql => {}
_ => {}
}

manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl MigrationTrait for Migration {
.await?;
}
DatabaseBackend::Sqlite | DatabaseBackend::MySql => {}
_ => {}
}

manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ impl MigrationTrait for Migration {
.await?;
}
DatabaseBackend::Sqlite | DatabaseBackend::MySql => {}
_ => {}
}

Ok(())
Expand All @@ -43,6 +44,7 @@ impl MigrationTrait for Migration {
.await?;
}
DatabaseBackend::Sqlite | DatabaseBackend::MySql => {}
_ => {}
}

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,22 @@ impl MigrationTrait for Migration {

manager
.get_connection()
.execute(Statement::from_string(
.execute_raw(Statement::from_string(
manager.get_database_backend(),
"ALTER TABLE access_token RENAME COLUMN user_id TO username".to_owned(),
))
.await?;

manager
.get_connection()
.execute(Statement::from_string(
.execute_raw(Statement::from_string(
manager.get_database_backend(),
"ALTER TABLE ssh_keys RENAME COLUMN user_id TO username".to_owned(),
))
.await?;
}
DatabaseBackend::Sqlite => {}
_ => {}
}

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impl MigrationTrait for Migration {
.await?;
}
DatabaseBackend::Sqlite => {}
_ => {}
}

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ impl MigrationTrait for Migration {
.await?;
}
DatabaseBackend::MySql | DatabaseBackend::Sqlite => {}
_ => {}
}

manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ impl MigrationTrait for Migration {
.await?;
}
DatabaseBackend::MySql | DatabaseBackend::Sqlite => {}
_ => {}
}

manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ impl MigrationTrait for Migration {
.await?;
}
DatabaseBackend::Sqlite | DatabaseBackend::MySql => {}
_ => {}
}

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl MigrationTrait for Migration {
manager.get_database_backend(),
r#"ALTER TYPE "check_type_enum" RENAME VALUE 'mr_sync' TO 'cl_sync';"#,
);
manager.get_connection().execute(rename_stmt).await?;
manager.get_connection().execute_raw(rename_stmt).await?;
}
Ok(())
}
Expand All @@ -25,7 +25,7 @@ impl MigrationTrait for Migration {
manager.get_database_backend(),
r#"ALTER TYPE "check_type_enum" RENAME VALUE 'cl_sync' TO 'mr_sync';"#,
);
manager.get_connection().execute(rollback_stmt).await?;
manager.get_connection().execute_raw(rollback_stmt).await?;
}
Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ impl MigrationTrait for Migration {
.await?;
}
DatabaseBackend::MySql | DatabaseBackend::Sqlite => {}
_ => {}
}

manager
Expand Down
63 changes: 32 additions & 31 deletions jupiter-migrate/src/migration/m20251119_145041_add_draft_status.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
use sea_orm_migration::{prelude::*, sea_orm::DatabaseBackend};

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let backend = manager.get_database_backend();

match backend {
DatabaseBackend::Postgres => {
manager
.get_connection()
.execute_unprepared(
r#"ALTER TYPE merge_status_enum ADD VALUE IF NOT EXISTS 'draft';"#,
)
.await?;
}
DatabaseBackend::Sqlite | DatabaseBackend::MySql => {}
}

Ok(())
}

async fn down(&self, _: &SchemaManager) -> Result<(), DbErr> {
// Note: PostgreSQL does not support removing enum values directly
// This migration cannot be fully reversed without recreating the enum
Ok(())
}
}
use sea_orm_migration::{prelude::*, sea_orm::DatabaseBackend};

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let backend = manager.get_database_backend();

match backend {
DatabaseBackend::Postgres => {
manager
.get_connection()
.execute_unprepared(
r#"ALTER TYPE merge_status_enum ADD VALUE IF NOT EXISTS 'draft';"#,
)
.await?;
}
DatabaseBackend::Sqlite | DatabaseBackend::MySql => {}
_ => {}
}

Ok(())
}

async fn down(&self, _: &SchemaManager) -> Result<(), DbErr> {
// Note: PostgreSQL does not support removing enum values directly
// This migration cannot be fully reversed without recreating the enum
Ok(())
}
}
Loading
Loading