github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/cataloger/githubactions/parse_workflow.go (about) 1 package githubactions 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 8 "gopkg.in/yaml.v3" 9 10 "github.com/anchore/syft/syft/artifact" 11 "github.com/anchore/syft/syft/file" 12 "github.com/anchore/syft/syft/pkg" 13 "github.com/anchore/syft/syft/pkg/cataloger/generic" 14 ) 15 16 var ( 17 _ generic.Parser = parseWorkflowForActionUsage 18 _ generic.Parser = parseWorkflowForWorkflowUsage 19 ) 20 21 type workflowDef struct { 22 Jobs map[string]workflowJobDef `yaml:"jobs"` 23 } 24 25 type workflowJobDef struct { 26 Uses string `yaml:"uses"` 27 Steps []stepDef `yaml:"steps"` 28 } 29 30 type stepDef struct { 31 Name string `yaml:"name"` 32 Uses string `yaml:"uses"` 33 With struct { 34 Path string `yaml:"path"` 35 Key string `yaml:"key"` 36 } `yaml:"with"` 37 } 38 39 func parseWorkflowForWorkflowUsage(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 40 contents, err := io.ReadAll(reader) 41 if err != nil { 42 return nil, nil, fmt.Errorf("unable to read yaml workflow file: %w", err) 43 } 44 45 var wf workflowDef 46 if err = yaml.Unmarshal(contents, &wf); err != nil { 47 return nil, nil, fmt.Errorf("unable to parse yaml workflow file: %w", err) 48 } 49 50 // we use a collection to help with deduplication before raising to higher level processing 51 pkgs := pkg.NewCollection() 52 53 for _, job := range wf.Jobs { 54 if job.Uses != "" { 55 p := newPackageFromUsageStatement(job.Uses, reader.Location) 56 if p != nil { 57 pkgs.Add(*p) 58 } 59 } 60 } 61 62 return pkgs.Sorted(), nil, nil 63 } 64 65 func parseWorkflowForActionUsage(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 66 contents, err := io.ReadAll(reader) 67 if err != nil { 68 return nil, nil, fmt.Errorf("unable to read yaml workflow file: %w", err) 69 } 70 71 var wf workflowDef 72 if err = yaml.Unmarshal(contents, &wf); err != nil { 73 return nil, nil, fmt.Errorf("unable to parse yaml workflow file: %w", err) 74 } 75 76 // we use a collection to help with deduplication before raising to higher level processing 77 pkgs := pkg.NewCollection() 78 79 for _, job := range wf.Jobs { 80 for _, step := range job.Steps { 81 if step.Uses == "" { 82 continue 83 } 84 p := newPackageFromUsageStatement(step.Uses, reader.Location) 85 if p != nil { 86 pkgs.Add(*p) 87 } 88 } 89 } 90 91 return pkgs.Sorted(), nil, nil 92 }