@@ -509,19 +509,26 @@ func presentCheckResults(out *ui.UI, report *doctor.Report, valid bool, willReme
509509 ui .Pluralize (len (unpinnedWorkflows ), "workflow" , "workflows" ))
510510 }
511511 }
512- // Separate SHA_AS_REF warnings into direct (aggregate) and transitive (individual).
512+ // Separate SHA_AS_REF warnings into direct (aggregate) and transitive (suppressed).
513+ // TODO: Transitive deps pinned to bare SHAs are silently swallowed for now.
514+ // We need to figure out how to coexist better with composite actions that
515+ // don't use dependency pinning — warning on every transitive dep is noisy
516+ // and not actionable by the consumer. Revisit when we have a story for
517+ // composite action authors to adopt pinning.
513518 var bareSHADeps []string
514519 var otherDetailWarnings []string
515520 for _ , key := range otherWarnings {
516521 wg := warnMap [key ]
517522 f := wg .finding
518523 if f .Category == doctor .CategorySHAAsRef {
519524 isTransitive := f .Dependency != nil && f .ActionRef == nil
520- if isTransitive {
521- otherDetailWarnings = append (otherDetailWarnings , key )
522- } else {
525+ if ! isTransitive {
523526 bareSHADeps = append (bareSHADeps , key )
524527 }
528+ // transitive SHA_AS_REF: silently swallowed (see TODO above)
529+ } else if f .Category == doctor .CategoryValid && f .Severity == doctor .SeverityWarning &&
530+ strings .Contains (f .Remediation , "transitive dependency" ) {
531+ // transitive reachability unknown: silently swallowed (see TODO above)
525532 } else {
526533 otherDetailWarnings = append (otherDetailWarnings , key )
527534 }
@@ -540,41 +547,12 @@ func presentCheckResults(out *ui.UI, report *doctor.Report, valid bool, willReme
540547 wg := warnMap [key ]
541548 f := wg .finding
542549 depKey := f .DepKey ()
543- switch {
544- case f .Category == doctor .CategorySHAAsRef :
545- out .Warning ("%s: transitive dependency pinned to a bare SHA — reachability cannot be verified" , depKey )
546- printTransitiveContext (out , f .ParentNWO , wg .workflows )
547- case f .Category == doctor .CategoryValid && f .Severity == doctor .SeverityWarning :
550+ if f .Category == doctor .CategoryValid && f .Severity == doctor .SeverityWarning {
548551 label := depKey
549552 if label == "" {
550553 label = f .WorkflowPath
551554 }
552- if strings .Contains (f .Remediation , "transitive dependency" ) {
553- out .Warning ("%s: transitive dependency pinned to a bare SHA — reachability cannot be verified" , label )
554- printTransitiveContext (out , f .ParentNWO , wg .workflows )
555- } else {
556- out .Warning ("%s: %s" , label , f .Detail )
557- }
555+ out .Warning ("%s: %s" , label , f .Detail )
558556 }
559557 }
560558}
561-
562- // printTransitiveContext prints ↳ lines for a transitive dep finding.
563- func printTransitiveContext (out * ui.UI , parentNWO string , workflows []string ) {
564- if parentNWO != "" {
565- out .Detail (" ↳ pulled in by %s" , out .Bold (parentNWO ))
566- } else {
567- out .Detail (" ↳ this comes from a composite action's internal dependency" )
568- }
569- if len (workflows ) > 0 {
570- out .Detail (" ↳ in %s" , ui .Pluralize (len (workflows ), "workflow" , "workflows" )+ ": " + formatWorkflowPaths (workflows ))
571- }
572- }
573-
574- // formatWorkflowPaths formats a list of workflow paths for display.
575- func formatWorkflowPaths (paths []string ) string {
576- if len (paths ) <= 3 {
577- return strings .Join (paths , ", " )
578- }
579- return strings .Join (paths [:3 ], ", " ) + fmt .Sprintf (" (+%d more)" , len (paths )- 3 )
580- }
0 commit comments