@@ -591,6 +591,84 @@ func retrieveConfigFromCache(orgId uint, repoFullName string) (string, *digger_c
591
591
return repoCache .DiggerYmlStr , & config , & projectsGraph , & taConfig , nil
592
592
}
593
593
594
+ // GetDiggerConfigForBranchWithFallback attempts to load config from the specified branch,
595
+ // and falls back to the target branch if the branch doesn't exist and shouldFallback is true
596
+ func GetDiggerConfigForBranchWithFallback (gh utils.GithubClientProvider , installationId int64 , repoFullName string , repoOwner string , repoName string , cloneUrl string , branch string , targetBranch string , shouldFallback bool , changedFiles []string , taConfig * tac.AtlantisConfig ) (string , * github2.GithubService , * digger_config.DiggerConfig , graph.Graph [string , digger_config.Project ], error ) {
597
+ slog .Info ("Attempting to get Digger config for branch with fallback" ,
598
+ "repoFullName" , repoFullName ,
599
+ "primaryBranch" , branch ,
600
+ "targetBranch" , targetBranch ,
601
+ "shouldFallback" , shouldFallback ,
602
+ )
603
+
604
+ ghService , _ , err := utils .GetGithubService (gh , installationId , repoFullName , repoOwner , repoName )
605
+ if err != nil {
606
+ return "" , nil , nil , nil ,fmt .Errorf ("error getting github service" )
607
+ }
608
+
609
+ // Try the primary branch first
610
+ diggerYmlStr , ghService , config , dependencyGraph , err := GetDiggerConfigForBranch (
611
+ gh , installationId , repoFullName , repoOwner , repoName , cloneUrl , branch , changedFiles , taConfig ,
612
+ )
613
+
614
+ actualBranchUsed := branch
615
+
616
+ if err != nil {
617
+ // Check if it's a "branch not found" error
618
+ errMsg := err .Error ()
619
+ isBranchNotFound := strings .Contains (errMsg , "Remote branch" ) && strings .Contains (errMsg , "not found" ) ||
620
+ strings .Contains (errMsg , "couldn't find remote ref" ) ||
621
+ strings .Contains (errMsg , "exit status 128" )
622
+
623
+ if isBranchNotFound && branch != targetBranch && shouldFallback {
624
+ slog .Warn ("Branch not found and fallback enabled, falling back to target branch" ,
625
+ "missingBranch" , branch ,
626
+ "targetBranch" , targetBranch ,
627
+ "repoFullName" , repoFullName ,
628
+ "originalError" , err ,
629
+ )
630
+
631
+ // Try the target branch as fallback
632
+ var fallbackErr error
633
+ diggerYmlStr , ghService , config , dependencyGraph , fallbackErr = GetDiggerConfigForBranch (
634
+ gh , installationId , repoFullName , repoOwner , repoName , cloneUrl , targetBranch , changedFiles , taConfig ,
635
+ )
636
+
637
+ if fallbackErr != nil {
638
+ slog .Error ("Fallback to target branch also failed" ,
639
+ "targetBranch" , targetBranch ,
640
+ "repoFullName" , repoFullName ,
641
+ "fallbackError" , fallbackErr ,
642
+ )
643
+ return "" , nil , nil , nil , fmt .Errorf ("failed to load config from branch '%s' (branch not found) and fallback to target branch '%s' also failed: %v" , branch , targetBranch , fallbackErr )
644
+ }
645
+
646
+ slog .Info ("Successfully loaded config from target branch" ,
647
+ "targetBranch" , targetBranch ,
648
+ "repoFullName" , repoFullName ,
649
+ )
650
+
651
+ actualBranchUsed = targetBranch
652
+ } else {
653
+ // Either not a branch-not-found error, or fallback is disabled
654
+ if isBranchNotFound && ! shouldFallback {
655
+ slog .Info ("Branch not found but fallback is disabled" ,
656
+ "missingBranch" , branch ,
657
+ "repoFullName" , repoFullName ,
658
+ )
659
+ }
660
+ return "" , nil , nil , nil , err
661
+ }
662
+ }
663
+
664
+ slog .Info ("Config loaded successfully" ,
665
+ "repoFullName" , repoFullName ,
666
+ "branchUsed" , actualBranchUsed ,
667
+ )
668
+
669
+ return diggerYmlStr , ghService , config , dependencyGraph , nil
670
+ }
671
+
594
672
// TODO: Refactor this func to receive ghService as input
595
673
func getDiggerConfigForPR (gh utils.GithubClientProvider , orgId uint , prLabels []string , installationId int64 , repoFullName string , repoOwner string , repoName string , cloneUrl string , prNumber int ) (string , * github2.GithubService , * digger_config.DiggerConfig , graph.Graph [string , digger_config.Project ], * string , * string , []string , error ) {
596
674
slog .Info ("Getting Digger config for PR" ,
@@ -616,7 +694,8 @@ func getDiggerConfigForPR(gh utils.GithubClientProvider, orgId uint, prLabels []
616
694
}
617
695
618
696
var prBranch string
619
- prBranch , prCommitSha , _ , _ , err := ghService .GetBranchName (prNumber )
697
+ var targetBranch string
698
+ prBranch , prCommitSha , targetBranch , _ , err := ghService .GetBranchName (prNumber )
620
699
if err != nil {
621
700
slog .Error ("Error getting branch name for PR" ,
622
701
"prNumber" , prNumber ,
@@ -626,10 +705,20 @@ func getDiggerConfigForPR(gh utils.GithubClientProvider, orgId uint, prLabels []
626
705
return "" , nil , nil , nil , nil , nil , nil , fmt .Errorf ("error getting branch name" )
627
706
}
628
707
708
+ // Target branch must be available - no fallback to repo default
709
+ if targetBranch == "" {
710
+ slog .Error ("PR target branch is empty" ,
711
+ "prNumber" , prNumber ,
712
+ "repoFullName" , repoFullName ,
713
+ )
714
+ return "" , nil , nil , nil , nil , nil , nil , fmt .Errorf ("PR target branch is empty for PR #%d" , prNumber )
715
+ }
716
+
629
717
slog .Debug ("Retrieved PR details" ,
630
718
"prNumber" , prNumber ,
631
719
"branch" , prBranch ,
632
720
"commitSha" , prCommitSha ,
721
+ "targetBranch" , targetBranch ,
633
722
)
634
723
635
724
changedFiles , err := ghService .GetChangedFiles (prNumber )
@@ -684,15 +773,39 @@ func getDiggerConfigForPR(gh utils.GithubClientProvider, orgId uint, prLabels []
684
773
slog .Info ("Loading config from repository" ,
685
774
"repoFullName" , repoFullName ,
686
775
"branch" , prBranch ,
776
+ "targetBranch" , targetBranch ,
687
777
"prNumber" , prNumber ,
688
778
)
689
779
690
- diggerYmlStr , ghService , config , dependencyGraph , err := GetDiggerConfigForBranch (gh , installationId , repoFullName , repoOwner , repoName , cloneUrl , prBranch , changedFiles , taConfig )
780
+ // Check if PR is merged to determine if we should fallback
781
+ shouldFallback := false
782
+ isMerged , err := ghService .IsMerged (prNumber )
783
+ if err != nil {
784
+ slog .Warn ("Could not check PR merge status, will not enable fallback" ,
785
+ "prNumber" , prNumber ,
786
+ "repoFullName" , repoFullName ,
787
+ "error" , err ,
788
+ )
789
+ } else {
790
+ shouldFallback = isMerged
791
+ slog .Debug ("PR merge status checked" ,
792
+ "prNumber" , prNumber ,
793
+ "isMerged" , isMerged ,
794
+ "shouldFallback" , shouldFallback ,
795
+ )
796
+ }
797
+
798
+ // Use the fallback method with merge-based fallback logic
799
+ diggerYmlStr , ghService , config , dependencyGraph , err := GetDiggerConfigForBranchWithFallback (
800
+ gh , installationId , repoFullName , repoOwner , repoName , cloneUrl ,
801
+ prBranch , targetBranch , shouldFallback , changedFiles , taConfig ,
802
+ )
691
803
if err != nil {
692
804
slog .Error ("Error loading Digger config from repository" ,
693
805
"prNumber" , prNumber ,
694
806
"repoFullName" , repoFullName ,
695
807
"branch" , prBranch ,
808
+ "targetBranch" , targetBranch ,
696
809
"error" , err ,
697
810
)
698
811
return "" , nil , nil , nil , nil , nil , nil , fmt .Errorf ("error loading digger.yml: %v" , err )
0 commit comments