Allow github trigger to match on branches/refs

Change-Id: If33d5566813f08704db2ed6983541eec31c96a55
diff --git a/doc/source/triggers.rst b/doc/source/triggers.rst
index d8c7ee8..07b18ab 100644
--- a/doc/source/triggers.rst
+++ b/doc/source/triggers.rst
@@ -128,6 +128,11 @@
 
     *push* - head reference updated (pushed to branch)
 
+  **branch**
+  The branch associated with the event. Example: ``master``.  This
+  field is treated as a regular expression, and multiple branches may
+  be listed. Used for ``pull-request`` events.
+
   **comment**
   This is only used for ``pull_request`` ``comment`` events.  It accepts a list
   of regexes that are searched for in the comment string. If any of these
@@ -143,8 +148,10 @@
   ``unlabeled`` action when a label with name ``do not test`` is removed from
   the pull request.
 
-  Additionally a ``push`` event can be configured, with an
-  associated ``ref`` represented as a regex to match branches or tags.
+  Additionally a ``push`` event can be configured, with an ``ref`` field. This
+  field is treated as a regular expression and multiple refs may be listed.
+  Github always sends full ref name, eg. ``refs/tags/bar`` and this string is
+  matched against the regexp.
 
 GitHub Configuration
 ~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/fixtures/layouts/basic-github.yaml b/tests/fixtures/layouts/basic-github.yaml
index 53f0c0f..709fd02 100644
--- a/tests/fixtures/layouts/basic-github.yaml
+++ b/tests/fixtures/layouts/basic-github.yaml
@@ -8,6 +8,7 @@
             - opened
             - changed
             - reopened
+          branch: '^master$'
         - event: pull_request
           action: comment
           comment: 'test me'
diff --git a/tests/fixtures/layouts/push-tag-github.yaml b/tests/fixtures/layouts/push-tag-github.yaml
index 814068f..54683e9 100644
--- a/tests/fixtures/layouts/push-tag-github.yaml
+++ b/tests/fixtures/layouts/push-tag-github.yaml
@@ -4,7 +4,7 @@
     trigger:
       github:
         - event: push
-          ref: ^refs/heads/.*$
+          ref: '^refs/heads/master$'
 
 - pipeline:
     name: tag
diff --git a/tests/unit/test_github_driver.py b/tests/unit/test_github_driver.py
index 967a226..3f567d2 100644
--- a/tests/unit/test_github_driver.py
+++ b/tests/unit/test_github_driver.py
@@ -54,6 +54,16 @@
         self.assertEqual(A.number, zuulvars['change'])
         self.assertEqual(A.head_sha, zuulvars['patchset'])
         self.assertEqual(1, len(A.comments))
+        self.assertEqual(2, len(self.history))
+
+        # test_pull_unmatched_branch_event(self):
+        self.create_branch('org/project', 'unmatched_branch')
+        B = self.fake_github.openFakePullRequest(
+            'org/project', 'unmatched_branch', 'B')
+        self.fake_github.emitEvent(B.getPullRequestOpenedEvent())
+        self.waitUntilSettled()
+
+        self.assertEqual(2, len(self.history))
 
     @simple_layout('layouts/basic-github.yaml', driver='github')
     def test_comment_event(self):
@@ -113,6 +123,18 @@
 
         self.assertEqual('SUCCESS',
                          self.getJobFromHistory('project-post').result)
+        self.assertEqual(1, len(self.history))
+
+        # test unmatched push event
+        old_sha = random_sha1()
+        new_sha = random_sha1()
+        self.fake_github.emitEvent(
+            self.fake_github.getPushEvent('org/project',
+                                          'refs/heads/unmatched_branch',
+                                          old_sha, new_sha))
+        self.waitUntilSettled()
+
+        self.assertEqual(1, len(self.history))
 
     @simple_layout('layouts/labeling-github.yaml', driver='github')
     def test_labels(self):
diff --git a/zuul/driver/github/githubtrigger.py b/zuul/driver/github/githubtrigger.py
index 629609e..541c783 100644
--- a/zuul/driver/github/githubtrigger.py
+++ b/zuul/driver/github/githubtrigger.py
@@ -22,29 +22,26 @@
     name = 'github'
     log = logging.getLogger("zuul.trigger.GithubTrigger")
 
-    def _toList(self, item):
-        if not item:
-            return []
-        if isinstance(item, list):
-            return item
-        return [item]
-
     def getEventFilters(self, trigger_config):
+        def toList(item):
+            if not item:
+                return []
+            if isinstance(item, list):
+                return item
+            return [item]
+
         efilters = []
-        for trigger in self._toList(trigger_config):
-            types = trigger.get('event', None)
-            actions = trigger.get('action')
-            refs = trigger.get('refs')
-            comments = self._toList(trigger.get('comment'))
-            labels = trigger.get('label')
-            unlabels = trigger.get('unlabel')
-            f = EventFilter(trigger=self,
-                            types=self._toList(types),
-                            actions=self._toList(actions),
-                            refs=self._toList(refs),
-                            comments=self._toList(comments),
-                            labels=self._toList(labels),
-                            unlabels=self._toList(unlabels))
+        for trigger in toList(trigger_config):
+            f = EventFilter(
+                trigger=self,
+                types=toList(trigger['event']),
+                actions=toList(trigger.get('action')),
+                branches=toList(trigger.get('branch')),
+                refs=toList(trigger.get('ref')),
+                comments=toList(trigger.get('comment')),
+                labels=toList(trigger.get('label')),
+                unlabels=toList(trigger.get('unlabel'))
+            )
             efilters.append(f)
 
         return efilters
@@ -62,6 +59,7 @@
             toList(v.Any('pull_request',
                          'push')),
         'action': toList(str),
+        'branch': toList(str),
         'ref': toList(str),
         'comment': toList(str),
         'label': toList(str),