@@ -801,6 +801,24 @@ func DeduplicateRuntimeSetupStepsFromCustomSteps(customSteps string, runtimeRequ
801801
802802 log .Printf ("Deduplicating runtime setup steps from custom steps (%d runtimes)" , len (runtimeRequirements ))
803803
804+ // Extract version comments from uses lines before unmarshaling
805+ // This is necessary because YAML treats "# comment" as a comment, not part of the value
806+ // Format: "uses: action@sha # v1.0.0" -> after unmarshal, only "action@sha" remains
807+ versionComments := make (map [string ]string ) // key: action@sha, value: # v1.0.0
808+ lines := strings .Split (customSteps , "\n " )
809+ for _ , line := range lines {
810+ trimmed := strings .TrimSpace (line )
811+ if strings .HasPrefix (trimmed , "uses:" ) && strings .Contains (trimmed , " # " ) {
812+ // Extract the uses value and version comment
813+ parts := strings .SplitN (trimmed , " # " , 2 )
814+ if len (parts ) == 2 {
815+ usesValue := strings .TrimSpace (strings .TrimPrefix (parts [0 ], "uses:" ))
816+ versionComment := " # " + parts [1 ]
817+ versionComments [usesValue ] = versionComment
818+ }
819+ }
820+ }
821+
804822 // Parse custom steps YAML
805823 var stepsWrapper map [string ]any
806824 if err := yaml .Unmarshal ([]byte (customSteps ), & stepsWrapper ); err != nil {
@@ -965,10 +983,32 @@ func DeduplicateRuntimeSetupStepsFromCustomSteps(customSteps string, runtimeRequ
965983
966984 // Convert back to YAML
967985 stepsWrapper ["steps" ] = filteredSteps
986+
987+ // Restore version comments to steps that have them
988+ // This must be done before marshaling
989+ for i , step := range filteredSteps {
990+ if stepMap , ok := step .(map [string ]any ); ok {
991+ if usesVal , hasUses := stepMap ["uses" ]; hasUses {
992+ if usesStr , ok := usesVal .(string ); ok {
993+ if versionComment , hasComment := versionComments [usesStr ]; hasComment {
994+ // Add the version comment back
995+ stepMap ["uses" ] = usesStr + versionComment
996+ filteredSteps [i ] = stepMap
997+ }
998+ }
999+ }
1000+ }
1001+ }
1002+
9681003 deduplicatedYAML , err := yaml .Marshal (stepsWrapper )
9691004 if err != nil {
9701005 return customSteps , runtimeRequirements , fmt .Errorf ("failed to marshal deduplicated workflow steps to YAML. Step deduplication removes duplicate runtime setup actions (like actions/setup-node) from custom steps to avoid conflicts when automatic runtime detection adds them. This optimization ensures runtime setup steps appear before custom steps. Error: %w" , err )
9711006 }
9721007
973- return string (deduplicatedYAML ), filteredRequirements , nil
1008+ // Remove quotes from uses values with version comments
1009+ // The YAML marshaller quotes strings containing # (for inline version comments)
1010+ // but GitHub Actions expects unquoted uses values
1011+ deduplicatedStr := unquoteUsesWithComments (string (deduplicatedYAML ))
1012+
1013+ return deduplicatedStr , filteredRequirements , nil
9741014}
0 commit comments