- Cargo workspace with hiy-server (axum 0.7 + sqlx SQLite + tokio) - SQLite schema: apps, deploys, env_vars (inline migrations, no daemon) - Background build worker: sequential queue, streams stdout/stderr to DB - REST API: CRUD for apps, deploys, env vars; GitHub webhook with HMAC-SHA256 - SSE endpoint for live build log streaming - Monospace HTMX-free dashboard: app list + per-app detail, log viewer, env editor - builder/build.sh: clone/pull → detect strategy (Dockerfile/buildpack/static) → docker build → swap container → update Caddy via admin API → prune images - infra/docker-compose.yml + Dockerfile.server for local dev (no Pi needed) - proxy/Caddyfile: auto-HTTPS off for local, comment removed for production - .env.example Compiles clean (zero warnings). Run locally: cp .env.example .env && cargo run --bin hiy-server https://claude.ai/code/session_01FKCW3FDjNFj6jve4niMFXH
55 lines
1.4 KiB
Rust
55 lines
1.4 KiB
Rust
use axum::{
|
|
extract::{Path, State},
|
|
http::StatusCode,
|
|
Json,
|
|
};
|
|
|
|
use crate::{
|
|
models::{EnvVar, SetEnvVar},
|
|
AppState,
|
|
};
|
|
|
|
pub async fn list(
|
|
State(s): State<AppState>,
|
|
Path(app_id): Path<String>,
|
|
) -> Result<Json<Vec<EnvVar>>, StatusCode> {
|
|
let vars = sqlx::query_as::<_, EnvVar>(
|
|
"SELECT * FROM env_vars WHERE app_id = ? ORDER BY key",
|
|
)
|
|
.bind(&app_id)
|
|
.fetch_all(&s.db)
|
|
.await
|
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
|
Ok(Json(vars))
|
|
}
|
|
|
|
pub async fn set(
|
|
State(s): State<AppState>,
|
|
Path(app_id): Path<String>,
|
|
Json(payload): Json<SetEnvVar>,
|
|
) -> Result<StatusCode, StatusCode> {
|
|
sqlx::query(
|
|
"INSERT INTO env_vars (app_id, key, value) VALUES (?, ?, ?)
|
|
ON CONFLICT(app_id, key) DO UPDATE SET value = excluded.value",
|
|
)
|
|
.bind(&app_id)
|
|
.bind(&payload.key)
|
|
.bind(&payload.value)
|
|
.execute(&s.db)
|
|
.await
|
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
|
Ok(StatusCode::NO_CONTENT)
|
|
}
|
|
|
|
pub async fn remove(
|
|
State(s): State<AppState>,
|
|
Path((app_id, key)): Path<(String, String)>,
|
|
) -> Result<StatusCode, StatusCode> {
|
|
sqlx::query("DELETE FROM env_vars WHERE app_id = ? AND key = ?")
|
|
.bind(&app_id)
|
|
.bind(&key)
|
|
.execute(&s.db)
|
|
.await
|
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
|
Ok(StatusCode::NO_CONTENT)
|
|
}
|