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