···3636 Event StringList `yaml:"event"`
3737 Branch StringList `yaml:"branch"` // required for pull_request; for push, either branch or tag must be specified
3838 Tag StringList `yaml:"tag"` // optional; only applies to push events
3939+ Paths StringList `yaml:"paths"` // optional; only run if any changed file matches a glob pattern
3940 }
40414142 CloneOpts struct {
···9394}
94959596// if any of the constraints on a workflow is true, return true
9696-func (w *Workflow) Match(trigger tangled.Pipeline_TriggerMetadata) (bool, error) {
9797+func (w *Workflow) Match(trigger tangled.Pipeline_TriggerMetadata, changedFiles []string) (bool, error) {
9798 // manual triggers always run the workflow
9899 if trigger.Manual != nil {
99100 return true, nil
···101102102103 // if not manual, run through the constraint list and see if any one matches
103104 for _, c := range w.When {
104104- matched, err := c.Match(trigger)
105105+ matched, err := c.Match(trigger, changedFiles)
105106 if err != nil {
106107 return false, err
107108 }
···118119 return false, nil
119120}
120121121121-func (c *Constraint) Match(trigger tangled.Pipeline_TriggerMetadata) (bool, error) {
122122+func (c *Constraint) Match(trigger tangled.Pipeline_TriggerMetadata, changedFiles []string) (bool, error) {
122123 match := true
123124124125 // manual triggers always pass this constraint
···147148 match = match && matched
148149 }
149150151151+ // apply paths filter: if specified, at least one changed file must match
152152+ if len(c.Paths) > 0 {
153153+ matched, err := matchesAnyFile(changedFiles, c.Paths)
154154+ if err != nil {
155155+ return false, err
156156+ }
157157+ match = match && matched
158158+ }
159159+150160 return match, nil
161161+}
162162+163163+// matchesAnyFile returns true if any file in files matches any of the glob patterns.
164164+func matchesAnyFile(files []string, patterns []string) (bool, error) {
165165+ for _, f := range files {
166166+ matched, err := matchesPattern(f, patterns)
167167+ if err != nil {
168168+ return false, err
169169+ }
170170+ if matched {
171171+ return true, nil
172172+ }
173173+ }
174174+ return false, nil
151175}
152176153177func (c *Constraint) MatchRef(ref string) (bool, error) {