Repository: python/bedevere
Pull request #598 (2023-10-17 19:42:00)

Return error status if bedevere is not used as an app.
Since bedevere now has to work as an app, return an error status if app installation is not found.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/python/bedevere/pull/598?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) Report
> Merging [#598](https://app.codecov.io/gh/python/bedevere/pull/598?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) (10f97af) into [main](https://app.codecov.io/gh/python/bedevere/commit/a3d2fc624ae8c3244faadf5a89d0423dd2c2157f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) (a3d2fc6) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://app.codecov.io/gh/python/bedevere/pull/598/graphs/tree.svg?width=650&height=150&src=pr&token=S7kyeapERi&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python)](https://app.codecov.io/gh/python/bedevere/pull/598?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python)

```diff
@@            Coverage Diff            @@
##              main      #598   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           18        18           
  Lines         2128      2129    +1     
  Branches       245       245           
=========================================
+ Hits          2128      2129    +1     
```

| [Flag](https://app.codecov.io/gh/python/bedevere/pull/598/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) | Coverage Δ | |
|---|---|---|
| [Python_3.10.13](https://app.codecov.io/gh/python/bedevere/pull/598/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) | `100.00% <100.00%> (ø)` | |
| [Python_3.11.5](https://app.codecov.io/gh/python/bedevere/pull/598/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) | `100.00% <100.00%> (ø)` | |
| [Python_3.12.0](https://app.codecov.io/gh/python/bedevere/pull/598/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) | `?` | |
| [Python_3.8.18](https://app.codecov.io/gh/python/bedevere/pull/598/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) | `100.00% <100.00%> (ø)` | |
| [Python_3.9.18](https://app.codecov.io/gh/python/bedevere/pull/598/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) | `100.00% <100.00%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Files](https://app.codecov.io/gh/python/bedevere/pull/598?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python) | Coverage Δ | |
|---|---|---|
| [bedevere/\_\_main\_\_.py](https://app.codecov.io/gh/python/bedevere/pull/598?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python#diff-YmVkZXZlcmUvX19tYWluX18ucHk=) | `100.00% <100.00%> (ø)` | |
| [tests/test\_\_\_main\_\_.py](https://app.codecov.io/gh/python/bedevere/pull/598?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python#diff-dGVzdHMvdGVzdF9fX21haW5fXy5weQ==) | `100.00% <100.00%> (ø)` | |
| [tests/test\_stage.py](https://app.codecov.io/gh/python/bedevere/pull/598?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=python#diff-dGVzdHMvdGVzdF9zdGFnZS5weQ==) | `100.00% <ø> (ø)` | |


Patch:
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 4b121bf..772a974 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -7,7 +7,10 @@ updates:
       interval: monthly
     assignees:
       - "ezio-melotti"
-    open-pull-requests-limit: 10
+    groups:
+      pip:
+        patterns:
+          - "*"
 
   # Maintain dependencies for GitHub Actions
   - package-ecosystem: "github-actions"
@@ -16,4 +19,7 @@ updates:
       interval: monthly
     assignees:
       - "ezio-melotti"
-    open-pull-requests-limit: 10
+    groups:
+      actions:
+        patterns:
+          - "*"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 20ee8de..70993e4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -36,6 +36,6 @@ jobs:
       - uses: codecov/codecov-action@v4
         if: always()
         with:
-          token: ${{ secrets.CODECOV_TOKEN }}
+          token: ${{ secrets.CODECOV_ORG_TOKEN }}
           file: ./coverage.xml
           flags: Python_${{ steps.python-install.outputs.python-version }}
diff --git a/bedevere/__main__.py b/bedevere/__main__.py
index a50855f..4bb678e 100644
--- a/bedevere/__main__.py
+++ b/bedevere/__main__.py
@@ -37,17 +37,17 @@ async def main(request):
 
         async with aiohttp.ClientSession() as session:
             gh = gh_aiohttp.GitHubAPI(session, "python/bedevere", cache=cache)
+            if not event.data.get("installation"):
+                return web.Response(text="Must be installed as an App.", status=400)
+            installation_id = event.data["installation"]["id"]
+            installation_access_token = await apps.get_installation_access_token(
+                gh,
+                installation_id=installation_id,
+                app_id=os.environ.get("GH_APP_ID"),
+                private_key=os.environ.get("GH_PRIVATE_KEY"),
+            )
+            gh.oauth_token = installation_access_token["token"]
 
-            if event.data.get("installation"):
-                # This path only works on GitHub App
-                installation_id = event.data["installation"]["id"]
-                installation_access_token = await apps.get_installation_access_token(
-                    gh,
-                    installation_id=installation_id,
-                    app_id=os.environ.get("GH_APP_ID"),
-                    private_key=os.environ.get("GH_PRIVATE_KEY"),
-                )
-                gh.oauth_token = installation_access_token["token"]
             # Give GitHub some time to reach internal consistency.
             await asyncio.sleep(1)
             await router.dispatch(event, gh, session=session)
@@ -63,7 +63,6 @@ async def main(request):
 
 @router.register("installation", action="created")
 async def repo_installation_added(event, gh, *args, **kwargs):
-    # installation_id = event.data["installation"]["id"]
     print(
         f"App installed by {event.data['installation']['account']['login']}, installation_id: {event.data['installation']['id']}"
     )
diff --git a/bedevere/news.py b/bedevere/news.py
index a67e5ba..6088af3 100644
--- a/bedevere/news.py
+++ b/bedevere/news.py
@@ -31,7 +31,7 @@ SKIP_LABEL_STATUS = create_status(
 
 HELP = f"""\
 Most changes to Python [require a NEWS entry]\
-(https://devguide.python.org/committing/#updating-news-and-what-s-new-in-python). \
+(https://devguide.python.org/core-developers/committing/#updating-news-and-what-s-new-in-python). \
 Add one using the [blurb_it]({BLURB_IT_URL}) web app or \
 the [blurb]({BLURB_PYPI_URL}) command-line tool.
 
diff --git a/dev-requirements.txt b/dev-requirements.txt
index d9d143a..f4b384e 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,6 +1,6 @@
 -r requirements.txt
 asynctest==0.13.0
-pytest==7.4.4
-pytest-asyncio==0.23.4
+pytest==8.1.1
+pytest-asyncio==0.23.6
 pytest-aiohttp==1.0.5
-pytest-cov==4.1.0
+pytest-cov==5.0.0
diff --git a/requirements.txt b/requirements.txt
index c0f8f63..8a87362 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,13 +1,13 @@
 aiohttp==3.9.3
 appdirs==1.4.4
 async-timeout==4.0.3
-cachetools==5.3.2
+cachetools==5.3.3
 chardet==5.2.0
 gidgethub==5.3.0
-multidict==6.0.4
-packaging==23.2
-pyparsing==3.1.1
+multidict==6.0.5
+packaging==24.0
+pyparsing==3.1.2
 six==1.16.0
 uritemplate==4.1.1
 yarl==1.9.4
-sentry-sdk==1.40.0
+sentry-sdk==1.44.0


Test patch:
diff --git a/tests/test___main__.py b/tests/test___main__.py
index 92962c9..397d133 100644
--- a/tests/test___main__.py
+++ b/tests/test___main__.py
@@ -23,7 +23,7 @@ async def test_ping(aiohttp_client):
     assert response.status == 200
 
 
-async def test_success(aiohttp_client):
+async def test_bad_request_if_no_installation(aiohttp_client):
     app = web.Application()
     app.router.add_post("/", main.main)
     client = await aiohttp_client(app)
@@ -32,7 +32,8 @@ async def test_success(aiohttp_client):
     # either.
     data = {"action": "created"}
     response = await client.post("/", headers=headers, json=data)
-    assert response.status == 200
+    assert response.status == 400
+    assert await response.text() == "Must be installed as an App."
 
 
 async def test_failure(aiohttp_client):
diff --git a/tests/test_stage.py b/tests/test_stage.py
index 5b635b1..4a1551e 100644
--- a/tests/test_stage.py
+++ b/tests/test_stage.py
@@ -1217,7 +1217,7 @@ async def test_new_commit_pushed_to_not_approved_pr(issue_url_key, repo_full_nam
 
 async def test_pushed_without_commits():
     # There is new commit on approved PR
-    sha = "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9"
+
     data = {"commits": []}
     event = sansio.Event(data, event="push", delivery_id="12345")
     gh = FakeGH()