bug_filer: Don't close bug on no recent builds

If there are no recent builds don't close any bugs. Previously bugs
would be closed if there were no recent failures, regardless of whether
there were any recent passes.

Bug: b/377570481
Change-Id: Ibdea582bd96a085ad067c839c754583d76a97c49
Reviewed-on: https://pigweed-review.googlesource.com/c/infra/recipes/+/248084
Pigweed-Auto-Submit: Rob Mohr <mohrr@google.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Reviewed-by: Danielle Kay <danikay@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
diff --git a/recipes/bug_filer.py b/recipes/bug_filer.py
index d636bb6..7d7ce7c 100644
--- a/recipes/bug_filer.py
+++ b/recipes/bug_filer.py
@@ -161,15 +161,19 @@
                         else:
                             api.step.empty('no recent failures')
 
-                        if not recently_failed:
-                            if props.dry_run:
-                                api.step.empty('mark fixed')
+                            if status.builds:
+                                if props.dry_run:
+                                    api.step.empty('mark fixed')
+                                else:
+                                    api.issuetracker.mark_issue_as_fixed(
+                                        'mark fixed',
+                                        builder_state[key]['bug_id'],
+                                    )
                             else:
-                                api.issuetracker.mark_issue_as_fixed(
-                                    'mark fixed', builder_state[key]['bug_id']
-                                )
-                            builder_state[key]['foo'] = 'bar'
+                                api.step.empty('no recent builds')
+
                             del builder_state[key]
+
                         continue
 
                     api.step.empty('no open bug')
@@ -358,6 +362,12 @@
             f'{bucket}.{builder}.no recent failures',
         )
 
+    def no_recent_builds(bucket, builder):
+        return api.post_process(
+            post_process.MustRun,
+            f'{bucket}.{builder}.no recent builds',
+        )
+
     def was_passing(bucket, builder):
         return api.post_process(
             post_process.MustRun,
@@ -400,6 +410,12 @@
             f'{bucket}.{builder}.mark fixed',
         )
 
+    def not_marked_fixed(bucket, builder):
+        return api.post_process(
+            post_process.DoesNotRun,
+            f'{bucket}.{builder}.mark fixed',
+        )
+
     def obsolete(bucket, builder):
         return api.post_process(
             post_process.MustRun,
@@ -541,11 +557,27 @@
         open_bug_exists('abc.ci', 'foo'),
         build_status('abc.ci', 'foo', ['failure'] * 20),
         recently_failed('abc.ci', 'foo'),
+        not_marked_fixed('abc.ci', 'foo'),
         output_state_contains('abc.ci', 'foo'),
         drop_expectations_must_be_last(),
     )
 
     yield test(
+        'bug-no-builds',
+        api.builder_state(
+            {'abc.ci/foo': {'timestamp': _START - _DAY, 'bug_id': 123}},
+        ),
+        abc_bb_config,
+        open_bug_exists('abc.ci', 'foo'),
+        build_status('abc.ci', 'foo', []),
+        no_recent_failures('abc.ci', 'foo'),
+        no_recent_builds('abc.ci', 'foo'),
+        not_marked_fixed('abc.ci', 'foo'),
+        output_state_lacks('abc.ci', 'foo'),
+        drop_expectations_must_be_last(),
+    )
+
+    yield test(
         'bug-passing',
         api.builder_state(
             {'abc.ci/foo': {'timestamp': _START - _DAY, 'bug_id': 123}},
@@ -583,6 +615,7 @@
         open_bug_exists('abc.ci', 'foo'),
         build_status('abc.ci', 'foo', ['failure'] * 20),
         recently_failed('abc.ci', 'foo'),
+        not_marked_fixed('abc.ci', 'foo'),
         obsolete('abc.ci', 'foo'),
         output_state_lacks('abc.ci', 'foo'),
         drop_expectations_must_be_last(),