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
95 changes: 93 additions & 2 deletions src/commands/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1510,10 +1510,10 @@ async fn ensure_config_initialized(args: &SharedArgs) -> Result<()> {
}

let cwd = std::env::current_dir().context("Unable to get current directory")?;
let railway_file = cwd.join(".railway").join("railway.ts");
if railway_file.exists() {
if find_railway_file(&cwd).is_some() {
return Ok(());
}
let railway_file = cwd.join(".railway").join("railway.ts");

println!();
println!("{}", "Railway configuration is not initialized yet.".bold());
Expand Down Expand Up @@ -1542,6 +1542,22 @@ async fn ensure_config_initialized(args: &SharedArgs) -> Result<()> {
Ok(())
}

fn find_railway_file(start: &Path) -> Option<PathBuf> {
for directory in start.ancestors() {
if directory.file_name().and_then(|name| name.to_str()) == Some(".railway") {
let direct = directory.join("railway.ts");
if direct.is_file() {
return Some(direct);
}
}
let nested = directory.join(".railway").join("railway.ts");
if nested.is_file() {
return Some(nested);
}
}
None
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -1619,6 +1635,31 @@ mod tests {
assert!(outside.exists());
}

#[test]
fn config_discovery_works_from_project_root_and_railway_directory() {
let root = tempfile::tempdir().unwrap();
let railway_dir = root.path().join(".railway");
fs::create_dir_all(&railway_dir).unwrap();
let config = railway_dir.join("railway.ts");
fs::write(&config, "export default {};").unwrap();

assert_eq!(find_railway_file(root.path()), Some(config.clone()));
assert_eq!(find_railway_file(&railway_dir), Some(config));
}

#[test]
fn config_discovery_walks_up_from_nested_project_directories() {
let root = tempfile::tempdir().unwrap();
let railway_dir = root.path().join(".railway");
let nested = root.path().join("src").join("Backend.Api");
fs::create_dir_all(&railway_dir).unwrap();
fs::create_dir_all(&nested).unwrap();
let config = railway_dir.join("railway.ts");
fs::write(&config, "export default {};").unwrap();

assert_eq!(find_railway_file(&nested), Some(config));
}

fn service_resource(
source: serde_json::Value,
deploy: serde_json::Value,
Expand Down Expand Up @@ -1669,6 +1710,56 @@ mod tests {
assert!(!rendered.contains("registryCredentials"));
}

#[test]
fn pull_renderer_preserves_image_resource_limits() {
let resource = service_resource(
json!({ "image": "nginx:latest" }),
json!({
"limitOverride": {
"containers": { "cpu": 2, "memoryBytes": 2_000_000_000_i64 }
}
}),
);

let rendered = render_service_body(
&resource,
&std::collections::BTreeMap::new(),
&std::collections::HashMap::new(),
true,
);

assert!(rendered.contains("source: image(\"nginx:latest\")"));
assert!(rendered.contains("cpu: 2"));
assert!(rendered.contains("memoryBytes: 2000000000"));
}

#[test]
fn pull_renderer_preserves_quoted_bucket_references_when_values_are_visible() {
let mut resource = service_resource(json!({ "image": "nginx:latest" }), json!({}));
resource.variables = Some(
json!({
"InspectionsBucket__BucketName": {
"type": "literal",
"value": "${{inspections_media.BUCKET}}"
}
})
.as_object()
.unwrap()
.clone(),
);

let rendered = render_service_body(
&resource,
&std::collections::BTreeMap::new(),
&std::collections::HashMap::new(),
false,
);

assert!(
rendered.contains("InspectionsBucket__BucketName: \"${{inspections_media.BUCKET}}\"")
);
}

#[test]
fn pull_renderer_preserves_supported_image_auto_updates_only() {
let policy = json!({
Expand Down
18 changes: 17 additions & 1 deletion src/commands/config/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,9 @@ fn resolve_runner(explicit_runner: Option<&str>, cwd: &std::path::Path) -> Resol
};
}

if let Some(runner) = find_project_runner(cwd) {
if let Some(runner) =
find_project_runner(cwd).or_else(|| find_project_runner(&cwd.join(".railway")))
{
return ResolvedRunner {
path: runner.to_string_lossy().to_string(),
source: RunnerSource::ProjectDependency,
Expand Down Expand Up @@ -895,6 +897,20 @@ mod runner_discovery_tests {
path
}

#[test]
fn resolves_a_runner_installed_beside_the_railway_config() {
let root = tempfile::tempdir().unwrap();
fs::create_dir_all(root.path().join(".git")).unwrap();
let railway_dir = root.path().join(".railway");
fs::create_dir_all(&railway_dir).unwrap();
let expected = make_runner(&railway_dir);

let resolved = resolve_runner(None, root.path());

assert_eq!(PathBuf::from(resolved.path), expected);
assert!(matches!(resolved.source, RunnerSource::ProjectDependency));
}

#[test]
fn finds_a_runner_inside_the_repository() {
let root = tempfile::tempdir().unwrap();
Expand Down
Loading