guardian / prout

Looks after your pull requests, tells you when they're live
https://www.theguardian.com/info/developer-blog/2015/feb/03/prout-is-your-pull-request-out
Apache License 2.0
146 stars 15 forks source link

Handle organisation level ping webhooks #122

Open mbarton opened 3 months ago

mbarton commented 3 months ago

When set up at the organisation level the initial "ping" webhook GitHub sends to test the connection is missing the "repository" key. We crashed on that before meaning the webhook was never enabled:

java.lang.NullPointerException: null
        at scala.collection.StringOps$.split$extension(StringOps.scala:836)
        at com.madgag.scalagithub.ResponseMeta$.requestScopesFrom(GitHub.scala:90)
        at com.madgag.scalagithub.ResponseMeta$.from(GitHub.scala:100)
        at com.madgag.scalagithub.GitHub$.logAndGetMeta(GitHub.scala:126)
        at com.madgag.scalagithub.GitHub.$anonfun$executeAndWrap$1(GitHub.scala:392)                                                                                                                                       at com.madgag.okhttpscala.package$RickOkHttpClient$$anon$1.$anonfun$onResponse$1(package.scala:45)
        at scala.util.Try$.apply(Try.scala:217)
        at com.madgag.okhttpscala.package$RickOkHttpClient$$anon$1.onResponse(package.scala:45)
        at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)

To test:

Add this test JSON payload to a file (copied from the GitHub webhooks debugging UI)

{
  "zen": "Mind your words, they are important.",
  "hook_id": 491530939,
  "hook": {
    "type": "Organization",
    "id": 491530939,
    "name": "web",
    "active": true,
    "events": [
      "pull_request",
      "push"
    ],
    "config": {
      "content_type": "json",
      "insecure_ssl": "0",
      "url": "https://prout.grayrock-a815685f.uksouth.azurecontainerapps.io/api/hooks/github"
    },
    "updated_at": "2024-07-22T10:40:22Z",
    "created_at": "2024-07-22T10:40:22Z",
    "url": "https://api.github.com/orgs/rcpch/hooks/491530939",
    "ping_url": "https://api.github.com/orgs/rcpch/hooks/491530939/pings",
    "deliveries_url": "https://api.github.com/orgs/rcpch/hooks/491530939/deliveries"
  },
  "organization": {
    "login": "rcpch",
    "id": 20457825,
    "node_id": "MDEyOk9yZ2FuaXphdGlvbjIwNDU3ODI1",
    "url": "https://api.github.com/orgs/rcpch",
    "repos_url": "https://api.github.com/orgs/rcpch/repos",
    "events_url": "https://api.github.com/orgs/rcpch/events",
    "hooks_url": "https://api.github.com/orgs/rcpch/hooks",
    "issues_url": "https://api.github.com/orgs/rcpch/issues",
    "members_url": "https://api.github.com/orgs/rcpch/members{/member}",
    "public_members_url": "https://api.github.com/orgs/rcpch/public_members{/member}",
    "avatar_url": "https://avatars.githubusercontent.com/u/20457825?v=4",
    "description": "Best Practice As Code, from the RCPCH"
  },
  "sender": {
    "login": "mbarton",
    "id": 395805,
    "node_id": "MDQ6VXNlcjM5NTgwNQ==",
    "avatar_url": "https://avatars.githubusercontent.com/u/395805?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/mbarton",
    "html_url": "https://github.com/mbarton",
    "followers_url": "https://api.github.com/users/mbarton/followers",
    "following_url": "https://api.github.com/users/mbarton/following{/other_user}",
    "gists_url": "https://api.github.com/users/mbarton/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/mbarton/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/mbarton/subscriptions",
    "organizations_url": "https://api.github.com/users/mbarton/orgs",
    "repos_url": "https://api.github.com/users/mbarton/repos",
    "events_url": "https://api.github.com/users/mbarton/events{/privacy}",
    "received_events_url": "https://api.github.com/users/mbarton/received_events",
    "type": "User",
    "site_admin": false
  }
}

Send a request

curl -X POST \
  -H 'X-GitHub-Event: ping' \
  -H 'X-GitHub-Delivery: mtest' \
  -H 'Content-Type: application/json' \
  -d @/tmp/github_org_hook_payload.json \
  -v \
  http://localhost:9000/api/hooks/github
rtyley commented 4 weeks ago

Hi @mbarton ! Sorry I missed the notification for this PR, I'll try to take a look at it today!

mbarton commented 4 weeks ago

No worries @rtyley there's another one here in the lib :) https://github.com/rtyley/play-git-hub/pull/10. We've been successfully using Prout @rcpch on our clinical audit platforms (example https://github.com/rcpch/rcpch-audit-engine/pull/1070). It's already caught a couple of crashing deploys!