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()

```

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(),

{"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"}]}