@@ -562,21 +562,22 @@ User: "deploy this service"
562562 // Build deployment config request
563563 // Derive dockerfile path and build context from DockerfileInfo
564564 //
565- // IMPORTANT: Paths are relative to the ANALYZED directory (args.path), NOT the project root .
566- // This matches the manual wizard behavior when you run `sync-ctl deploy` from a subdirectory .
565+ // IMPORTANT: Paths must be relative to the REPO ROOT for Cloud Runner .
566+ // Cloud Runner clones the GitHub repo and builds from there .
567567 //
568- // Example: User's local structure might be:
569- // /local/project/services/contact-intelligence/Dockerfile
570- // But the GitHub repo might have:
571- // /Dockerfile (at root)
568+ // Example: User analyzes path="services/contact-intelligence" which has a Dockerfile.
569+ // The GitHub repo structure is:
570+ // repo-root/
571+ // services/
572+ // contact-intelligence/
573+ // Dockerfile
572574 //
573- // When user specifies path="services/contact-intelligence", we analyze that dir and find
574- // Dockerfile there. The paths sent to cloud runner should be:
575- // dockerfile: "Dockerfile", context: "."
576- // NOT:
577- // dockerfile: "services/contact-intelligence/Dockerfile", context: "services/contact-intelligence"
575+ // Cloud Runner needs:
576+ // dockerfile: "services/contact-intelligence/Dockerfile"
577+ // context: "services/contact-intelligence"
578578 //
579- // This is because the GitHub repo structure may differ from local structure.
579+ // NOT:
580+ // dockerfile: "Dockerfile", context: "." (would look at repo root)
580581 let ( dockerfile_path, build_context) = analysis. docker_analysis
581582 . as_ref ( )
582583 . and_then ( |d| d. dockerfiles . first ( ) )
@@ -587,27 +588,44 @@ User: "deploy this service"
587588 . unwrap_or_else ( || "Dockerfile" . to_string ( ) ) ;
588589
589590 // Derive dockerfile's directory relative to analysis_path
590- // This gives us the path relative to what we analyzed, NOT the project root
591591 let analysis_relative_dir = df. path . parent ( )
592592 . and_then ( |p| p. strip_prefix ( & analysis_path) . ok ( ) )
593593 . map ( |p| p. to_string_lossy ( ) . to_string ( ) )
594594 . unwrap_or_default ( ) ;
595595
596- // Build paths relative to the analyzed directory
597- // DO NOT prepend args.path - the repo structure may differ from local structure
598- if analysis_relative_dir. is_empty ( ) {
599- // Dockerfile is at the root of the analyzed directory
600- // dockerfile: "Dockerfile", context: "."
601- ( dockerfile_name, "." . to_string ( ) )
596+ // Build paths relative to REPO ROOT by prepending args.path (the subdirectory)
597+ // This ensures Cloud Runner finds the Dockerfile in the cloned repo
598+ let subpath = args. path . as_deref ( ) . unwrap_or ( "" ) ;
599+
600+ if subpath. is_empty ( ) {
601+ // Analyzing repo root - use paths as-is
602+ if analysis_relative_dir. is_empty ( ) {
603+ ( dockerfile_name, "." . to_string ( ) )
604+ } else {
605+ ( format ! ( "{}/{}" , analysis_relative_dir, dockerfile_name) , analysis_relative_dir)
606+ }
602607 } else {
603- // Dockerfile is in a subdirectory of the analyzed directory
604- // dockerfile: "subdir/Dockerfile", context: "subdir"
605- ( format ! ( "{}/{}" , analysis_relative_dir, dockerfile_name) , analysis_relative_dir)
608+ // Analyzing a subdirectory - prepend subpath to make repo-root-relative
609+ if analysis_relative_dir. is_empty ( ) {
610+ // Dockerfile at root of analyzed subdir
611+ // e.g., subpath="services/contact-intelligence" -> dockerfile="services/contact-intelligence/Dockerfile"
612+ ( format ! ( "{}/{}" , subpath, dockerfile_name) , subpath. to_string ( ) )
613+ } else {
614+ // Dockerfile in nested dir within analyzed subdir
615+ // e.g., subpath="services", analysis_relative_dir="contact-intelligence"
616+ let full_context = format ! ( "{}/{}" , subpath, analysis_relative_dir) ;
617+ ( format ! ( "{}/{}" , full_context, dockerfile_name) , full_context)
618+ }
606619 }
607620 } )
608621 . unwrap_or_else ( || {
609- // No dockerfile found - default to root
610- ( "Dockerfile" . to_string ( ) , "." . to_string ( ) )
622+ // No dockerfile found - use subpath as context if provided, else root
623+ let subpath = args. path . as_deref ( ) . unwrap_or ( "" ) ;
624+ if subpath. is_empty ( ) {
625+ ( "Dockerfile" . to_string ( ) , "." . to_string ( ) )
626+ } else {
627+ ( format ! ( "{}/Dockerfile" , subpath) , subpath. to_string ( ) )
628+ }
611629 } ) ;
612630
613631 tracing:: debug!(
0 commit comments