We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Only trigger experiments when a comment starts with `/gcbrun`
Currently, a `GCB` experiment will be triggered if our comment **_mentions_** `/gcbrun`.

This is problematic because experiments will be launched unintendedly (e.g., when we quote previous `/gcb` commands, or even when we mention `/gcb` in any form).

## Root cause
1. `GCB` trigger simply [checks for `/gcb` without any constraints](https://pantheon.corp.google.com/cloud-build/triggers/edit/fff67372-9e94-4eeb-ab8c-4566ca73badf?project=fuzzbench). 
2. Our `gcbrun_experiment.py` [iterates all previous comments](https://github.com/google/fuzzbench/blob/56caa83e81bc59a1389367c6bd29d46fd35d03e6/service/gcbrun_experiment.py#L57) to find the latest valid `/gcb` command, which might have already been run.

## Proofs
1. [This example](https://github.com/google/fuzzbench/pull/1893#issuecomment-1716770892) quotes an old command and modifies its experiment name. However, it triggers an experiment with the old name, indicating we launch the latest valid experiment command.
2. [This example](https://github.com/google/fuzzbench/pull/1893#issuecomment-1716780709) includes a random `/gcb` command in the middle of the sentence. It also triggers the same old experiment, confirming the same conclusion.

## Propose fix
Change https://github.com/google/fuzzbench/blob/56caa83e81bc59a1389367c6bd29d46fd35d03e6/service/gcbrun_experiment.py#L56-L57
to
```python
 if not body.startswith(RUN_EXPERIMENT_COMMAND_STR): 
     return None 
```

## Justification
1. Based on our setting on Google Cloud, all `/gcb` commands will immediately trigger an experiment, there is no need to search back in history for an old command.
2. If we need to run an old command, we can always add a new comment for it.

@jonathanmetzman: Did I miss anything?
If it looks good to you, I will implement the fix proposed above.
Only trigger experiments when a comment starts with `/gcbrun`
Currently, a `GCB` experiment will be triggered if our comment **_mentions_** `/gcbrun`.

This is problematic because experiments will be launched unintendedly (e.g., when we quote previous `/gcb` commands, or even when we mention `/gcb` in any form).

## Root cause
1. `GCB` trigger simply [checks for `/gcb` without any constraints](https://pantheon.corp.google.com/cloud-build/triggers/edit/fff67372-9e94-4eeb-ab8c-4566ca73badf?project=fuzzbench). 
2. Our `gcbrun_experiment.py` [iterates all previous comments](https://github.com/google/fuzzbench/blob/56caa83e81bc59a1389367c6bd29d46fd35d03e6/service/gcbrun_experiment.py#L57) to find the latest valid `/gcb` command, which might have already been run.

## Proofs
1. [This example](https://github.com/google/fuzzbench/pull/1893#issuecomment-1716770892) quotes an old command and modifies its experiment name. However, it triggers an experiment with the old name, indicating we launch the latest valid experiment command.
2. [This example](https://github.com/google/fuzzbench/pull/1893#issuecomment-1716780709) includes a random `/gcb` command in the middle of the sentence. It also triggers the same old experiment, confirming the same conclusion.

## Propose fix
Change https://github.com/google/fuzzbench/blob/56caa83e81bc59a1389367c6bd29d46fd35d03e6/service/gcbrun_experiment.py#L56-L57
to
```python
 if not body.startswith(RUN_EXPERIMENT_COMMAND_STR): 
     return None 
```

## Justification
1. Based on our setting on Google Cloud, all `/gcb` commands will immediately trigger an experiment, there is no need to search back in history for an old command.
2. If we need to run an old command, we can always add a new comment for it.

@jonathanmetzman: Did I miss anything?
If it looks good to you, I will implement the fix proposed above.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `service/gcbrun_experiment.py`
Content:
```
1 # Copyright 2023 Google LLC
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 #
15 ################################################################################
16 """Entrypoint for gcbrun into run_experiment. This script will get the command
17 from the last PR comment containing "/gcbrun" and pass it to run_experiment.py
18 which will run an experiment."""
19 
20 import logging
21 import os
22 import sys
23 
24 # pytype: disable=import-error
25 import github  # pylint: disable=import-error
26 
27 from experiment import run_experiment
28 
29 TRIGGER_COMMAND = '/gcbrun'
30 RUN_EXPERIMENT_COMMAND_STR = f'{TRIGGER_COMMAND} run_experiment.py '
31 SKIP_COMMAND_STR = f'{TRIGGER_COMMAND} skip'
32 
33 
34 def get_comments(pull_request_number):
35     """Returns comments on the GitHub Pull request referenced by
36   |pull_request_number|."""
37     github_obj = github.Github()
38     repo = github_obj.get_repo('google/fuzzbench')
39     pull = repo.get_pull(pull_request_number)
40     pull_comments = list(pull.get_comments())
41     issue = repo.get_issue(pull_request_number)
42     issue_comments = list(issue.get_comments())
43     # Github only returns comments if from the pull object when a pull request
44     # is open. If it is a draft, it will only return comments from the issue
45     # object.
46     return pull_comments + issue_comments
47 
48 
49 def get_latest_gcbrun_command(comments):
50     """Gets the last /gcbrun comment from comments."""
51     for comment in reversed(comments):
52         # This seems to get comments on code too.
53         body = comment.body
54         if body.startswith(SKIP_COMMAND_STR):
55             return None
56         if not body.startswith(RUN_EXPERIMENT_COMMAND_STR):
57             continue
58         if len(body) == len(RUN_EXPERIMENT_COMMAND_STR):
59             return None
60         command = body[len(RUN_EXPERIMENT_COMMAND_STR):].strip().split(' ')
61         # Items that only contain space are redundant and will confuse
62         # `run_experiment_main()` in `experiment/run_experiment.py`
63         return [word for word in command if word.strip()]
64     return None
65 
66 
67 def exec_command_from_github(pull_request_number):
68     """Executes the gcbrun command for run_experiment.py in the most recent
69   command on |pull_request_number|."""
70     comments = get_comments(pull_request_number)
71     print(comments)
72     command = get_latest_gcbrun_command(comments)
73     if command is None:
74         logging.info('Experiment not requested.')
75         return None
76     print(command)
77     logging.info('Command: %s.', command)
78     return run_experiment.run_experiment_main(command)
79 
80 
81 def main():
82     """Entrypoint for GitHub CI into run_experiment.py"""
83     logging.basicConfig(level=logging.INFO)
84     pull_request_number = int(os.environ['PULL_REQUEST_NUMBER'])
85     result = exec_command_from_github(pull_request_number)
86     print('result', result)
87     if not result:
88         return 0
89     return 1
90 
91 
92 if __name__ == '__main__':
93     sys.exit(main())
94
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/service/gcbrun_experiment.py b/service/gcbrun_experiment.py
--- a/service/gcbrun_experiment.py
+++ b/service/gcbrun_experiment.py
@@ -23,7 +23,6 @@
 
 # pytype: disable=import-error
 import github  # pylint: disable=import-error
-
 from experiment import run_experiment
 
 TRIGGER_COMMAND = '/gcbrun'
@@ -38,38 +37,41 @@
     repo = github_obj.get_repo('google/fuzzbench')
     pull = repo.get_pull(pull_request_number)
     pull_comments = list(pull.get_comments())
+    last_pull_comment = pull_comments[-1] if pull_comments else None
     issue = repo.get_issue(pull_request_number)
     issue_comments = list(issue.get_comments())
+    last_issue_comment = issue_comments[-1] if issue_comments else None
     # Github only returns comments if from the pull object when a pull request
     # is open. If it is a draft, it will only return comments from the issue
     # object.
-    return pull_comments + issue_comments
+    return last_pull_comment, last_issue_comment
 
 
-def get_latest_gcbrun_command(comments):
+def get_latest_gcbrun_command(comment):
     """Gets the last /gcbrun comment from comments."""
-    for comment in reversed(comments):
-        # This seems to get comments on code too.
-        body = comment.body
-        if body.startswith(SKIP_COMMAND_STR):
-            return None
-        if not body.startswith(RUN_EXPERIMENT_COMMAND_STR):
-            continue
-        if len(body) == len(RUN_EXPERIMENT_COMMAND_STR):
-            return None
-        command = body[len(RUN_EXPERIMENT_COMMAND_STR):].strip().split(' ')
-        # Items that only contain space are redundant and will confuse
-        # `run_experiment_main()` in `experiment/run_experiment.py`
-        return [word for word in command if word.strip()]
-    return None
+    # This seems to get comments on code too.
+    if comment is None:
+        return None
+    body = comment.body
+    if body.startswith(SKIP_COMMAND_STR):
+        return None
+    if not body.startswith(RUN_EXPERIMENT_COMMAND_STR):
+        return None
+    if len(body) == len(RUN_EXPERIMENT_COMMAND_STR):
+        return None
+    command = body[len(RUN_EXPERIMENT_COMMAND_STR):].strip().split(' ')
+    # Items that only contain space are redundant and will confuse
+    # `run_experiment_main()` in `experiment/run_experiment.py`
+    return [word for word in command if word.strip()]
 
 
 def exec_command_from_github(pull_request_number):
     """Executes the gcbrun command for run_experiment.py in the most recent
   command on |pull_request_number|."""
-    comments = get_comments(pull_request_number)
-    print(comments)
-    command = get_latest_gcbrun_command(comments)
+    pull_cmt, issue_cmt = get_comments(pull_request_number)
+    print(f'Pull comment: {pull_cmt}\nIssue comment: {issue_cmt}')
+    command = (get_latest_gcbrun_command(pull_cmt) or
+               get_latest_gcbrun_command(issue_cmt))
     if command is None:
         logging.info('Experiment not requested.')
         return None

{"golden_diff": "diff --git a/service/gcbrun_experiment.py b/service/gcbrun_experiment.py\n--- a/service/gcbrun_experiment.py\n+++ b/service/gcbrun_experiment.py\n@@ -23,7 +23,6 @@\n \n # pytype: disable=import-error\n import github  # pylint: disable=import-error\n-\n from experiment import run_experiment\n \n TRIGGER_COMMAND = '/gcbrun'\n@@ -38,38 +37,41 @@\n     repo = github_obj.get_repo('google/fuzzbench')\n     pull = repo.get_pull(pull_request_number)\n     pull_comments = list(pull.get_comments())\n+    last_pull_comment = pull_comments[-1] if pull_comments else None\n     issue = repo.get_issue(pull_request_number)\n     issue_comments = list(issue.get_comments())\n+    last_issue_comment = issue_comments[-1] if issue_comments else None\n     # Github only returns comments if from the pull object when a pull request\n     # is open. If it is a draft, it will only return comments from the issue\n     # object.\n-    return pull_comments + issue_comments\n+    return last_pull_comment, last_issue_comment\n \n \n-def get_latest_gcbrun_command(comments):\n+def get_latest_gcbrun_command(comment):\n     \"\"\"Gets the last /gcbrun comment from comments.\"\"\"\n-    for comment in reversed(comments):\n-        # This seems to get comments on code too.\n-        body = comment.body\n-        if body.startswith(SKIP_COMMAND_STR):\n-            return None\n-        if not body.startswith(RUN_EXPERIMENT_COMMAND_STR):\n-            continue\n-        if len(body) == len(RUN_EXPERIMENT_COMMAND_STR):\n-            return None\n-        command = body[len(RUN_EXPERIMENT_COMMAND_STR):].strip().split(' ')\n-        # Items that only contain space are redundant and will confuse\n-        # `run_experiment_main()` in `experiment/run_experiment.py`\n-        return [word for word in command if word.strip()]\n-    return None\n+    # This seems to get comments on code too.\n+    if comment is None:\n+        return None\n+    body = comment.body\n+    if body.startswith(SKIP_COMMAND_STR):\n+        return None\n+    if not body.startswith(RUN_EXPERIMENT_COMMAND_STR):\n+        return None\n+    if len(body) == len(RUN_EXPERIMENT_COMMAND_STR):\n+        return None\n+    command = body[len(RUN_EXPERIMENT_COMMAND_STR):].strip().split(' ')\n+    # Items that only contain space are redundant and will confuse\n+    # `run_experiment_main()` in `experiment/run_experiment.py`\n+    return [word for word in command if word.strip()]\n \n \n def exec_command_from_github(pull_request_number):\n     \"\"\"Executes the gcbrun command for run_experiment.py in the most recent\n   command on |pull_request_number|.\"\"\"\n-    comments = get_comments(pull_request_number)\n-    print(comments)\n-    command = get_latest_gcbrun_command(comments)\n+    pull_cmt, issue_cmt = get_comments(pull_request_number)\n+    print(f'Pull comment: {pull_cmt}\\nIssue comment: {issue_cmt}')\n+    command = (get_latest_gcbrun_command(pull_cmt) or\n+               get_latest_gcbrun_command(issue_cmt))\n     if command is None:\n         logging.info('Experiment not requested.')\n         return None\n", "issue": "Only trigger experiments when a comment starts with `/gcbrun`\nCurrently, a `GCB` experiment will be triggered if our comment **_mentions_** `/gcbrun`.\r\n\r\nThis is problematic because experiments will be launched unintendedly (e.g., when we quote previous `/gcb` commands, or even when we mention `/gcb` in any form).\r\n\r\n## Root cause\r\n1. `GCB` trigger simply [checks for `/gcb` without any constraints](https://pantheon.corp.google.com/cloud-build/triggers/edit/fff67372-9e94-4eeb-ab8c-4566ca73badf?project=fuzzbench). \r\n2. Our `gcbrun_experiment.py` [iterates all previous comments](https://github.com/google/fuzzbench/blob/56caa83e81bc59a1389367c6bd29d46fd35d03e6/service/gcbrun_experiment.py#L57) to find the latest valid `/gcb` command, which might have already been run.\r\n\r\n## Proofs\r\n1. [This example](https://github.com/google/fuzzbench/pull/1893#issuecomment-1716770892) quotes an old command and modifies its experiment name. However, it triggers an experiment with the old name, indicating we launch the latest valid experiment command.\r\n2. [This example](https://github.com/google/fuzzbench/pull/1893#issuecomment-1716780709) includes a random `/gcb` command in the middle of the sentence. It also triggers the same old experiment, confirming the same conclusion.\r\n\r\n## Propose fix\r\nChange https://github.com/google/fuzzbench/blob/56caa83e81bc59a1389367c6bd29d46fd35d03e6/service/gcbrun_experiment.py#L56-L57\r\nto\r\n```python\r\n if not body.startswith(RUN_EXPERIMENT_COMMAND_STR): \r\n     return None \r\n```\r\n\r\n## Justification\r\n1. Based on our setting on Google Cloud, all `/gcb` commands will immediately trigger an experiment, there is no need to search back in history for an old command.\r\n2. If we need to run an old command, we can always add a new comment for it.\r\n\r\n@jonathanmetzman: Did I miss anything?\r\nIf it looks good to you, I will implement the fix proposed above.\nOnly trigger experiments when a comment starts with `/gcbrun`\nCurrently, a `GCB` experiment will be triggered if our comment **_mentions_** `/gcbrun`.\r\n\r\nThis is problematic because experiments will be launched unintendedly (e.g., when we quote previous `/gcb` commands, or even when we mention `/gcb` in any form).\r\n\r\n## Root cause\r\n1. `GCB` trigger simply [checks for `/gcb` without any constraints](https://pantheon.corp.google.com/cloud-build/triggers/edit/fff67372-9e94-4eeb-ab8c-4566ca73badf?project=fuzzbench). \r\n2. Our `gcbrun_experiment.py` [iterates all previous comments](https://github.com/google/fuzzbench/blob/56caa83e81bc59a1389367c6bd29d46fd35d03e6/service/gcbrun_experiment.py#L57) to find the latest valid `/gcb` command, which might have already been run.\r\n\r\n## Proofs\r\n1. [This example](https://github.com/google/fuzzbench/pull/1893#issuecomment-1716770892) quotes an old command and modifies its experiment name. However, it triggers an experiment with the old name, indicating we launch the latest valid experiment command.\r\n2. [This example](https://github.com/google/fuzzbench/pull/1893#issuecomment-1716780709) includes a random `/gcb` command in the middle of the sentence. It also triggers the same old experiment, confirming the same conclusion.\r\n\r\n## Propose fix\r\nChange https://github.com/google/fuzzbench/blob/56caa83e81bc59a1389367c6bd29d46fd35d03e6/service/gcbrun_experiment.py#L56-L57\r\nto\r\n```python\r\n if not body.startswith(RUN_EXPERIMENT_COMMAND_STR): \r\n     return None \r\n```\r\n\r\n## Justification\r\n1. Based on our setting on Google Cloud, all `/gcb` commands will immediately trigger an experiment, there is no need to search back in history for an old command.\r\n2. If we need to run an old command, we can always add a new comment for it.\r\n\r\n@jonathanmetzman: Did I miss anything?\r\nIf it looks good to you, I will implement the fix proposed above.\n", "before_files": [{"content": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n################################################################################\n\"\"\"Entrypoint for gcbrun into run_experiment. This script will get the command\nfrom the last PR comment containing \"/gcbrun\" and pass it to run_experiment.py\nwhich will run an experiment.\"\"\"\n\nimport logging\nimport os\nimport sys\n\n# pytype: disable=import-error\nimport github  # pylint: disable=import-error\n\nfrom experiment import run_experiment\n\nTRIGGER_COMMAND = '/gcbrun'\nRUN_EXPERIMENT_COMMAND_STR = f'{TRIGGER_COMMAND} run_experiment.py '\nSKIP_COMMAND_STR = f'{TRIGGER_COMMAND} skip'\n\n\ndef get_comments(pull_request_number):\n    \"\"\"Returns comments on the GitHub Pull request referenced by\n  |pull_request_number|.\"\"\"\n    github_obj = github.Github()\n    repo = github_obj.get_repo('google/fuzzbench')\n    pull = repo.get_pull(pull_request_number)\n    pull_comments = list(pull.get_comments())\n    issue = repo.get_issue(pull_request_number)\n    issue_comments = list(issue.get_comments())\n    # Github only returns comments if from the pull object when a pull request\n    # is open. If it is a draft, it will only return comments from the issue\n    # object.\n    return pull_comments + issue_comments\n\n\ndef get_latest_gcbrun_command(comments):\n    \"\"\"Gets the last /gcbrun comment from comments.\"\"\"\n    for comment in reversed(comments):\n        # This seems to get comments on code too.\n        body = comment.body\n        if body.startswith(SKIP_COMMAND_STR):\n            return None\n        if not body.startswith(RUN_EXPERIMENT_COMMAND_STR):\n            continue\n        if len(body) == len(RUN_EXPERIMENT_COMMAND_STR):\n            return None\n        command = body[len(RUN_EXPERIMENT_COMMAND_STR):].strip().split(' ')\n        # Items that only contain space are redundant and will confuse\n        # `run_experiment_main()` in `experiment/run_experiment.py`\n        return [word for word in command if word.strip()]\n    return None\n\n\ndef exec_command_from_github(pull_request_number):\n    \"\"\"Executes the gcbrun command for run_experiment.py in the most recent\n  command on |pull_request_number|.\"\"\"\n    comments = get_comments(pull_request_number)\n    print(comments)\n    command = get_latest_gcbrun_command(comments)\n    if command is None:\n        logging.info('Experiment not requested.')\n        return None\n    print(command)\n    logging.info('Command: %s.', command)\n    return run_experiment.run_experiment_main(command)\n\n\ndef main():\n    \"\"\"Entrypoint for GitHub CI into run_experiment.py\"\"\"\n    logging.basicConfig(level=logging.INFO)\n    pull_request_number = int(os.environ['PULL_REQUEST_NUMBER'])\n    result = exec_command_from_github(pull_request_number)\n    print('result', result)\n    if not result:\n        return 0\n    return 1\n\n\nif __name__ == '__main__':\n    sys.exit(main())\n", "path": "service/gcbrun_experiment.py"}], "after_files": [{"content": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n################################################################################\n\"\"\"Entrypoint for gcbrun into run_experiment. This script will get the command\nfrom the last PR comment containing \"/gcbrun\" and pass it to run_experiment.py\nwhich will run an experiment.\"\"\"\n\nimport logging\nimport os\nimport sys\n\n# pytype: disable=import-error\nimport github  # pylint: disable=import-error\nfrom experiment import run_experiment\n\nTRIGGER_COMMAND = '/gcbrun'\nRUN_EXPERIMENT_COMMAND_STR = f'{TRIGGER_COMMAND} run_experiment.py '\nSKIP_COMMAND_STR = f'{TRIGGER_COMMAND} skip'\n\n\ndef get_comments(pull_request_number):\n    \"\"\"Returns comments on the GitHub Pull request referenced by\n  |pull_request_number|.\"\"\"\n    github_obj = github.Github()\n    repo = github_obj.get_repo('google/fuzzbench')\n    pull = repo.get_pull(pull_request_number)\n    pull_comments = list(pull.get_comments())\n    last_pull_comment = pull_comments[-1] if pull_comments else None\n    issue = repo.get_issue(pull_request_number)\n    issue_comments = list(issue.get_comments())\n    last_issue_comment = issue_comments[-1] if issue_comments else None\n    # Github only returns comments if from the pull object when a pull request\n    # is open. If it is a draft, it will only return comments from the issue\n    # object.\n    return last_pull_comment, last_issue_comment\n\n\ndef get_latest_gcbrun_command(comment):\n    \"\"\"Gets the last /gcbrun comment from comments.\"\"\"\n    # This seems to get comments on code too.\n    if comment is None:\n        return None\n    body = comment.body\n    if body.startswith(SKIP_COMMAND_STR):\n        return None\n    if not body.startswith(RUN_EXPERIMENT_COMMAND_STR):\n        return None\n    if len(body) == len(RUN_EXPERIMENT_COMMAND_STR):\n        return None\n    command = body[len(RUN_EXPERIMENT_COMMAND_STR):].strip().split(' ')\n    # Items that only contain space are redundant and will confuse\n    # `run_experiment_main()` in `experiment/run_experiment.py`\n    return [word for word in command if word.strip()]\n\n\ndef exec_command_from_github(pull_request_number):\n    \"\"\"Executes the gcbrun command for run_experiment.py in the most recent\n  command on |pull_request_number|.\"\"\"\n    pull_cmt, issue_cmt = get_comments(pull_request_number)\n    print(f'Pull comment: {pull_cmt}\\nIssue comment: {issue_cmt}')\n    command = (get_latest_gcbrun_command(pull_cmt) or\n               get_latest_gcbrun_command(issue_cmt))\n    if command is None:\n        logging.info('Experiment not requested.')\n        return None\n    print(command)\n    logging.info('Command: %s.', command)\n    return run_experiment.run_experiment_main(command)\n\n\ndef main():\n    \"\"\"Entrypoint for GitHub CI into run_experiment.py\"\"\"\n    logging.basicConfig(level=logging.INFO)\n    pull_request_number = int(os.environ['PULL_REQUEST_NUMBER'])\n    result = exec_command_from_github(pull_request_number)\n    print('result', result)\n    if not result:\n        return 0\n    return 1\n\n\nif __name__ == '__main__':\n    sys.exit(main())\n", "path": "service/gcbrun_experiment.py"}]}