mirror of
https://github.com/Xevion/dynamic-preauth.git
synced 2025-12-05 23:14:53 -06:00
feat: dynamic deployment id fetching in debug mode for development
This commit is contained in:
15
src/main.rs
15
src/main.rs
@@ -111,7 +111,11 @@ async fn handle_socket(session_id: u32, websocket: WebSocket) {
|
||||
// Create the executable message first, borrow issues
|
||||
let executable_message = OutgoingMessage::Executables {
|
||||
executables: store.executable_json(),
|
||||
build_log: if store.build_logs.is_some() { Some("/build-logs".to_string()) } else { None },
|
||||
build_log: if store.build_logs.is_some() {
|
||||
Some("/build-logs".to_string())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
};
|
||||
|
||||
let session = store
|
||||
@@ -403,12 +407,19 @@ async fn main() {
|
||||
// Check if we are deployed on Railway
|
||||
let is_railway = env::var("RAILWAY_PROJECT_ID").is_ok();
|
||||
if is_railway {
|
||||
// In debug mode, we might not have RAILWAY_DEPLOYMENT_ID set
|
||||
let deployment_id = if cfg!(debug_assertions) {
|
||||
env::var("RAILWAY_DEPLOYMENT_ID").unwrap_or_else(|_| "latest".to_string())
|
||||
} else {
|
||||
env::var("RAILWAY_DEPLOYMENT_ID").unwrap()
|
||||
};
|
||||
|
||||
let build_logs_url = format!(
|
||||
"https://railway.com/project/{}/service/{}?environmentId={}&id={}#build",
|
||||
env::var("RAILWAY_PROJECT_ID").unwrap(),
|
||||
env::var("RAILWAY_SERVICE_ID").unwrap(),
|
||||
env::var("RAILWAY_ENVIRONMENT_ID").unwrap(),
|
||||
env::var("RAILWAY_DEPLOYMENT_ID").unwrap()
|
||||
deployment_id
|
||||
);
|
||||
|
||||
tracing::info!("Build logs available here: {}", build_logs_url);
|
||||
|
||||
102
src/railway.rs
102
src/railway.rs
@@ -26,6 +26,21 @@ struct BuildLogEntry {
|
||||
timestamp: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct DeploymentNode {
|
||||
id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct DeploymentEdge {
|
||||
node: DeploymentNode,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct DeploymentsConnection {
|
||||
edges: Vec<DeploymentEdge>,
|
||||
}
|
||||
|
||||
fn strip_ansi_codes(text: &str) -> String {
|
||||
// Simple regex to remove ANSI escape sequences
|
||||
let re = regex::Regex::new(r"\x1b\[[0-9;]*[a-zA-Z]").unwrap();
|
||||
@@ -50,9 +65,92 @@ fn should_stop_at_message(message: &str) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
async fn fetch_latest_deployment_id() -> Result<String> {
|
||||
let token = env::var("RAILWAY_TOKEN")?;
|
||||
let service_id = env::var("RAILWAY_SERVICE_ID")?;
|
||||
let project_id = env::var("RAILWAY_PROJECT_ID")?;
|
||||
let environment_id = env::var("RAILWAY_ENVIRONMENT_ID")?;
|
||||
|
||||
let query = r#"
|
||||
query deployments($input: DeploymentListInput!, $first: Int) {
|
||||
deployments(input: $input, first: $first) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let variables = serde_json::json!({
|
||||
"input": {
|
||||
"projectId": project_id,
|
||||
"serviceId": service_id,
|
||||
"environmentId": environment_id,
|
||||
"status": {"in": ["SUCCESS", "DEPLOYING", "SLEEPING", "BUILDING"]}
|
||||
},
|
||||
"first": 1
|
||||
});
|
||||
|
||||
let request = GraphQLRequest {
|
||||
query: query.to_string(),
|
||||
variables,
|
||||
};
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let response = client
|
||||
.post("https://backboard.railway.app/graphql/v2")
|
||||
.header("Authorization", format!("Bearer {}", token))
|
||||
.json(&request)
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
let response_text = response.text().await?;
|
||||
let graphql_response: GraphQLResponse = serde_json::from_str(&response_text)?;
|
||||
|
||||
if let Some(errors) = graphql_response.errors {
|
||||
let error_messages: Vec<String> = errors.iter().map(|e| e.message.clone()).collect();
|
||||
return Err(anyhow::anyhow!(
|
||||
"GraphQL errors: {}",
|
||||
error_messages.join(", ")
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(data) = graphql_response.data {
|
||||
if let Some(deployments_value) = data.get("deployments") {
|
||||
if let Ok(deployments) =
|
||||
serde_json::from_value::<DeploymentsConnection>(deployments_value.clone())
|
||||
{
|
||||
if let Some(first_edge) = deployments.edges.first() {
|
||||
return Ok(first_edge.node.id.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(anyhow::anyhow!(
|
||||
"No deployments found or unexpected response structure"
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn fetch_build_logs() -> Result<crate::models::BuildLogs> {
|
||||
let token = env::var("RAILWAY_TOKEN")?;
|
||||
let deployment_id = env::var("RAILWAY_DEPLOYMENT_ID")?;
|
||||
|
||||
// Get deployment ID - in debug mode, fetch latest if not specified
|
||||
let deployment_id = if cfg!(debug_assertions) {
|
||||
match env::var("RAILWAY_DEPLOYMENT_ID") {
|
||||
Ok(id) => id,
|
||||
Err(_) => {
|
||||
tracing::debug!(
|
||||
"No RAILWAY_DEPLOYMENT_ID specified in debug mode, fetching latest deployment"
|
||||
);
|
||||
fetch_latest_deployment_id().await?
|
||||
}
|
||||
}
|
||||
} else {
|
||||
env::var("RAILWAY_DEPLOYMENT_ID")?
|
||||
};
|
||||
|
||||
let query = r#"
|
||||
query buildLogs($deploymentId: String!, $endDate: DateTime, $filter: String, $limit: Int, $startDate: DateTime) {
|
||||
@@ -142,7 +240,7 @@ pub async fn fetch_build_logs() -> Result<crate::models::BuildLogs> {
|
||||
filtered_logs.push(formatted_entry);
|
||||
}
|
||||
|
||||
// Add Railway URL header to the logs
|
||||
// Add Railway URL header to the logs
|
||||
let railway_url = format!(
|
||||
"Railway Build Logs: https://railway.com/project/{}/service/{}?environmentId={}&id={}#build\n\n",
|
||||
env::var("RAILWAY_PROJECT_ID").unwrap_or_default(),
|
||||
|
||||
Reference in New Issue
Block a user