prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Sentry should include deployment SHA
  Sentry has options for specifying the SHA of the current code, so you can see when an error was introduced. We currently don't take advantage of this.
  
  ### Describe the problem that you'd like solved
  <!-- A clear and concise description of what you want to happen. -->
  
  ### Proposal & Constraints
  <!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->
  
  <!-- Which suggestions or requirements should be considered for how feature needs to appear or be implemented? -->
  
  ### Additional context
  <!-- Add any other context or screenshots about the feature request here. -->
  
  ### Stakeholders
  @cdrini 
  
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `openlibrary/plugins/openlibrary/sentry.py`
  Content:
  ```
  1 import logging
  2 
  3 import sentry_sdk
  4 
  5 import infogami
  6 from infogami.utils import delegate
  7 
  8 logger = logging.getLogger("openlibrary.sentry")
  9 
  10 
  11 def is_enabled():
  12     return hasattr(infogami.config, 'sentry') and infogami.config.sentry.enabled
  13 
  14 
  15 def setup():
  16     logger.info("Setting up sentry (enabled={})".format(is_enabled()))
  17 
  18     if not is_enabled():
  19         return
  20 
  21     sentry_sdk.init(dsn=infogami.config.sentry.dsn,
  22                     environment=infogami.config.sentry.environment)
  23     delegate.add_exception_hook(lambda: sentry_sdk.capture_exception())
  24
  ```
  
  Path: `openlibrary/plugins/openlibrary/status.py`
  Content:
  ```
  1 import web
  2 
  3 import datetime
  4 import socket
  5 import subprocess
  6 import sys
  7 
  8 from infogami import config
  9 from infogami.utils import delegate
  10 from infogami.utils.view import render_template, public
  11 from openlibrary.core import stats
  12 
  13 status_info = {}
  14 feature_flags = {}
  15 
  16 class status(delegate.page):
  17     def GET(self):
  18         template = render_template("status", status_info, feature_flags)
  19         template.v2 = True
  20         return template
  21 
  22 @public
  23 def get_git_revision_short_hash():
  24     return (status_info.get('Software version')
  25             if status_info and isinstance(status_info, dict) 
  26             else None)
  27 
  28 def get_software_version():
  29     return subprocess.Popen("git rev-parse --short HEAD --".split(), stdout = subprocess.PIPE, stderr = subprocess.STDOUT).stdout.read().strip()
  30 
  31 def get_features_enabled():
  32     return config.features
  33 
  34 def setup():
  35     "Basic startup status for the server"
  36     global status_info, feature_flags
  37     version = get_software_version()
  38     if bytes != str:  # Python 3
  39         version = version.decode("utf-8")
  40     host = socket.gethostname()
  41     status_info = {
  42         "Software version": version,
  43         "Python version": sys.version.split()[0],
  44         "Host": host,
  45         "Start time": datetime.datetime.utcnow(),
  46     }
  47     feature_flags = get_features_enabled()
  48 
  49     # Host is e.g. ol-web4.blah.archive.org ; we just want the first subdomain
  50     first_subdomain = host.split('.')[0] or 'unknown'
  51     stats.increment('ol.servers.%s.started' % first_subdomain)
  52
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/openlibrary/plugins/openlibrary/sentry.py b/openlibrary/plugins/openlibrary/sentry.py
  --- a/openlibrary/plugins/openlibrary/sentry.py
  +++ b/openlibrary/plugins/openlibrary/sentry.py
  @@ -5,6 +5,8 @@
   import infogami
   from infogami.utils import delegate
   
  +from openlibrary.plugins.openlibrary.status import get_software_version
  +
   logger = logging.getLogger("openlibrary.sentry")
   
   
  @@ -19,5 +21,6 @@
           return
   
       sentry_sdk.init(dsn=infogami.config.sentry.dsn,
  -                    environment=infogami.config.sentry.environment)
  +                    environment=infogami.config.sentry.environment,
  +                    release=get_software_version())
       delegate.add_exception_hook(lambda: sentry_sdk.capture_exception())
  diff --git a/openlibrary/plugins/openlibrary/status.py b/openlibrary/plugins/openlibrary/status.py
  --- a/openlibrary/plugins/openlibrary/status.py
  +++ b/openlibrary/plugins/openlibrary/status.py
  @@ -2,8 +2,8 @@
   
   import datetime
   import socket
  -import subprocess
   import sys
  +from subprocess import PIPE, Popen, STDOUT
   
   from infogami import config
   from infogami.utils import delegate
  @@ -25,8 +25,10 @@
               if status_info and isinstance(status_info, dict) 
               else None)
   
  -def get_software_version():
  -    return subprocess.Popen("git rev-parse --short HEAD --".split(), stdout = subprocess.PIPE, stderr = subprocess.STDOUT).stdout.read().strip()
  +
  +def get_software_version():  # -> str:
  +    cmd = "git rev-parse --short HEAD --".split()
  +    return str(Popen(cmd, stdout=PIPE, stderr=STDOUT).stdout.read().decode().strip())
   
   def get_features_enabled():
       return config.features
  @@ -34,12 +36,9 @@
   def setup():
       "Basic startup status for the server"
       global status_info, feature_flags
  -    version = get_software_version()
  -    if bytes != str:  # Python 3
  -        version = version.decode("utf-8")
       host = socket.gethostname()
       status_info = {
  -        "Software version": version,
  +        "Software version": get_software_version(),
           "Python version": sys.version.split()[0],
           "Host": host,
           "Start time": datetime.datetime.utcnow(),
  
verification_info: {"golden_diff": "diff --git a/openlibrary/plugins/openlibrary/sentry.py b/openlibrary/plugins/openlibrary/sentry.py\n--- a/openlibrary/plugins/openlibrary/sentry.py\n+++ b/openlibrary/plugins/openlibrary/sentry.py\n@@ -5,6 +5,8 @@\n import infogami\n from infogami.utils import delegate\n \n+from openlibrary.plugins.openlibrary.status import get_software_version\n+\n logger = logging.getLogger(\"openlibrary.sentry\")\n \n \n@@ -19,5 +21,6 @@\n         return\n \n     sentry_sdk.init(dsn=infogami.config.sentry.dsn,\n-                    environment=infogami.config.sentry.environment)\n+                    environment=infogami.config.sentry.environment,\n+                    release=get_software_version())\n     delegate.add_exception_hook(lambda: sentry_sdk.capture_exception())\ndiff --git a/openlibrary/plugins/openlibrary/status.py b/openlibrary/plugins/openlibrary/status.py\n--- a/openlibrary/plugins/openlibrary/status.py\n+++ b/openlibrary/plugins/openlibrary/status.py\n@@ -2,8 +2,8 @@\n \n import datetime\n import socket\n-import subprocess\n import sys\n+from subprocess import PIPE, Popen, STDOUT\n \n from infogami import config\n from infogami.utils import delegate\n@@ -25,8 +25,10 @@\n             if status_info and isinstance(status_info, dict) \n             else None)\n \n-def get_software_version():\n-    return subprocess.Popen(\"git rev-parse --short HEAD --\".split(), stdout = subprocess.PIPE, stderr = subprocess.STDOUT).stdout.read().strip()\n+\n+def get_software_version():  # -> str:\n+    cmd = \"git rev-parse --short HEAD --\".split()\n+    return str(Popen(cmd, stdout=PIPE, stderr=STDOUT).stdout.read().decode().strip())\n \n def get_features_enabled():\n     return config.features\n@@ -34,12 +36,9 @@\n def setup():\n     \"Basic startup status for the server\"\n     global status_info, feature_flags\n-    version = get_software_version()\n-    if bytes != str:  # Python 3\n-        version = version.decode(\"utf-8\")\n     host = socket.gethostname()\n     status_info = {\n-        \"Software version\": version,\n+        \"Software version\": get_software_version(),\n         \"Python version\": sys.version.split()[0],\n         \"Host\": host,\n         \"Start time\": datetime.datetime.utcnow(),\n", "issue": "Sentry should include deployment SHA\nSentry has options for specifying the SHA of the current code, so you can see when an error was introduced. We currently don't take advantage of this.\r\n\r\n### Describe the problem that you'd like solved\r\n<!-- A clear and concise description of what you want to happen. -->\r\n\r\n### Proposal & Constraints\r\n<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->\r\n\r\n<!-- Which suggestions or requirements should be considered for how feature needs to appear or be implemented? -->\r\n\r\n### Additional context\r\n<!-- Add any other context or screenshots about the feature request here. -->\r\n\r\n### Stakeholders\r\n@cdrini \r\n\r\n\r\n\n", "before_files": [{"content": "import logging\n\nimport sentry_sdk\n\nimport infogami\nfrom infogami.utils import delegate\n\nlogger = logging.getLogger(\"openlibrary.sentry\")\n\n\ndef is_enabled():\n    return hasattr(infogami.config, 'sentry') and infogami.config.sentry.enabled\n\n\ndef setup():\n    logger.info(\"Setting up sentry (enabled={})\".format(is_enabled()))\n\n    if not is_enabled():\n        return\n\n    sentry_sdk.init(dsn=infogami.config.sentry.dsn,\n                    environment=infogami.config.sentry.environment)\n    delegate.add_exception_hook(lambda: sentry_sdk.capture_exception())\n", "path": "openlibrary/plugins/openlibrary/sentry.py"}, {"content": "import web\n\nimport datetime\nimport socket\nimport subprocess\nimport sys\n\nfrom infogami import config\nfrom infogami.utils import delegate\nfrom infogami.utils.view import render_template, public\nfrom openlibrary.core import stats\n\nstatus_info = {}\nfeature_flags = {}\n\nclass status(delegate.page):\n    def GET(self):\n        template = render_template(\"status\", status_info, feature_flags)\n        template.v2 = True\n        return template\n\n@public\ndef get_git_revision_short_hash():\n    return (status_info.get('Software version')\n            if status_info and isinstance(status_info, dict) \n            else None)\n\ndef get_software_version():\n    return subprocess.Popen(\"git rev-parse --short HEAD --\".split(), stdout = subprocess.PIPE, stderr = subprocess.STDOUT).stdout.read().strip()\n\ndef get_features_enabled():\n    return config.features\n\ndef setup():\n    \"Basic startup status for the server\"\n    global status_info, feature_flags\n    version = get_software_version()\n    if bytes != str:  # Python 3\n        version = version.decode(\"utf-8\")\n    host = socket.gethostname()\n    status_info = {\n        \"Software version\": version,\n        \"Python version\": sys.version.split()[0],\n        \"Host\": host,\n        \"Start time\": datetime.datetime.utcnow(),\n    }\n    feature_flags = get_features_enabled()\n\n    # Host is e.g. ol-web4.blah.archive.org ; we just want the first subdomain\n    first_subdomain = host.split('.')[0] or 'unknown'\n    stats.increment('ol.servers.%s.started' % first_subdomain)\n", "path": "openlibrary/plugins/openlibrary/status.py"}], "after_files": [{"content": "import logging\n\nimport sentry_sdk\n\nimport infogami\nfrom infogami.utils import delegate\n\nfrom openlibrary.plugins.openlibrary.status import get_software_version\n\nlogger = logging.getLogger(\"openlibrary.sentry\")\n\n\ndef is_enabled():\n    return hasattr(infogami.config, 'sentry') and infogami.config.sentry.enabled\n\n\ndef setup():\n    logger.info(\"Setting up sentry (enabled={})\".format(is_enabled()))\n\n    if not is_enabled():\n        return\n\n    sentry_sdk.init(dsn=infogami.config.sentry.dsn,\n                    environment=infogami.config.sentry.environment,\n                    release=get_software_version())\n    delegate.add_exception_hook(lambda: sentry_sdk.capture_exception())\n", "path": "openlibrary/plugins/openlibrary/sentry.py"}, {"content": "import web\n\nimport datetime\nimport socket\nimport sys\nfrom subprocess import PIPE, Popen, STDOUT\n\nfrom infogami import config\nfrom infogami.utils import delegate\nfrom infogami.utils.view import render_template, public\nfrom openlibrary.core import stats\n\nstatus_info = {}\nfeature_flags = {}\n\nclass status(delegate.page):\n    def GET(self):\n        template = render_template(\"status\", status_info, feature_flags)\n        template.v2 = True\n        return template\n\n@public\ndef get_git_revision_short_hash():\n    return (status_info.get('Software version')\n            if status_info and isinstance(status_info, dict) \n            else None)\n\n\ndef get_software_version():  # -> str:\n    cmd = \"git rev-parse --short HEAD --\".split()\n    return str(Popen(cmd, stdout=PIPE, stderr=STDOUT).stdout.read().decode().strip())\n\ndef get_features_enabled():\n    return config.features\n\ndef setup():\n    \"Basic startup status for the server\"\n    global status_info, feature_flags\n    host = socket.gethostname()\n    status_info = {\n        \"Software version\": get_software_version(),\n        \"Python version\": sys.version.split()[0],\n        \"Host\": host,\n        \"Start time\": datetime.datetime.utcnow(),\n    }\n    feature_flags = get_features_enabled()\n\n    # Host is e.g. ol-web4.blah.archive.org ; we just want the first subdomain\n    first_subdomain = host.split('.')[0] or 'unknown'\n    stats.increment('ol.servers.%s.started' % first_subdomain)\n", "path": "openlibrary/plugins/openlibrary/status.py"}]}