Repository: buildbot/buildbot

Issue:
_matches_any_tag missing from BuildStartEndStatusGenerator
The [_matches_any_tag function](https://github.com/buildbot/buildbot/blob/e630745771a8bd03a2084d03ea8e43547d3dff4b/master/buildbot/reporters/generators/build.py#L82) is missing from the BuildStartEndStatusGenerator. This causes failures when you try to filter the builders using the tag with GitHubStatusPush and this generator.

```
buildbot_1           | 2021-01-21 13:51:23+0000 [-] Got exception when handling reporter events
buildbot_1           | 	Traceback (most recent call last):
buildbot_1           | 	  File "/usr/lib/python3.8/site-packages/twisted/internet/defer.py", line 1475, in gotResult
buildbot_1           | 	    _inlineCallbacks(r, g, status)
buildbot_1           | 	  File "/usr/lib/python3.8/site-packages/twisted/internet/defer.py", line 1416, in _inlineCallbacks
buildbot_1           | 	    result = result.throwExceptionIntoGenerator(g)
buildbot_1           | 	  File "/usr/lib/python3.8/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
buildbot_1           | 	    return g.throw(self.type, self.value, self.tb)
buildbot_1           | 	  File "/usr/lib/python3.8/site-packages/buildbot/reporters/base.py", line 183, in _got_event
buildbot_1           | 	    log.err(e, 'Got exception when handling reporter events')
buildbot_1           | 	--- <exception caught here> ---
buildbot_1           | 	  File "/usr/lib/python3.8/site-packages/buildbot/reporters/base.py", line 176, in _got_event
buildbot_1           | 	    report = yield g.generate(self.master, self, key, msg)
buildbot_1           | 	  File "/usr/lib/python3.8/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
buildbot_1           | 	    result = g.send(result)
buildbot_1           | 	  File "/usr/lib/python3.8/site-packages/buildbot/reporters/generators/build.py", line 119, in generate
buildbot_1           | 	    if not self.is_message_needed_by_props(build):
buildbot_1           | 	  File "/usr/lib/python3.8/site-packages/buildbot/reporters/generators/utils.py", line 104, in is_message_needed_by_props
buildbot_1           | 	    if self.tags is not None and not self._matches_any_tag(builder['tags']):
buildbot_1           | 	builtins.AttributeError: 'BuildStartEndStatusGenerator' object has no attribute '_matches_any_tag'

```

This output is from the official docker v2.10


Discussion:

Resolving patch:
diff --git a/master/buildbot/reporters/generators/build.py b/master/buildbot/reporters/generators/build.py
--- a/master/buildbot/reporters/generators/build.py
+++ b/master/buildbot/reporters/generators/build.py
@@ -122,3 +122,6 @@ def generate(self, master, reporter, key, build):
         report = yield self.build_message(formatter, master, reporter, build['builder']['name'],
                                           [build], build['results'])
         return report
+
+    def _matches_any_tag(self, tags):
+        return self.tags and any(tag for tag in self.tags if tag in tags)


Test patch:
diff --git a/master/buildbot/test/unit/reporters/test_generators_build.py b/master/buildbot/test/unit/reporters/test_generators_build.py
--- a/master/buildbot/test/unit/reporters/test_generators_build.py
+++ b/master/buildbot/test/unit/reporters/test_generators_build.py
@@ -516,6 +516,24 @@ def test_build_message_start_no_result(self):
             'logs': []
         })
 
+    @defer.inlineCallbacks
+    def test_is_message_needed_ignores_unspecified_tags(self):
+        build = yield self.insert_build_finished_get_props(SUCCESS)
+
+        # force tags
+        build['builder']['tags'] = ['tag']
+        g = BuildStartEndStatusGenerator(tags=['not_existing_tag'])
+        self.assertFalse(g.is_message_needed_by_props(build))
+
+    @defer.inlineCallbacks
+    def test_is_message_needed_tags(self):
+        build = yield self.insert_build_finished_get_props(SUCCESS)
+
+        # force tags
+        build['builder']['tags'] = ['tag']
+        g = BuildStartEndStatusGenerator(tags=['tag'])
+        self.assertTrue(g.is_message_needed_by_props(build))
+
     @defer.inlineCallbacks
     def test_build_message_add_logs(self):
         g = yield self.setup_generator(add_logs=True)