Search code examples
githubgithub-apiprobotgithub-app

Significance of the generic pull_request event and other more specific pull_request events like pull_request.opened


I am developing a GitHub App using nodejs and probot framework. I can see the Application class (https://probot.github.io/api/latest/classes/application.html) of the probot framework contains events like :

> event: "pull_request" | "pull_request.assigned" |
> "pull_request.closed" | "pull_request.edited" | "pull_request.labeled"
> | "pull_request.opened" | "pull_request.reopened" |
> "pull_request.review_request_removed" |
> "pull_request.review_requested" | "pull_request.unassigned" |
> "pull_request.unlabeled" | "pull_request.synchronize

I have noticed that when the "Create pull request" button is clicked, then the pull_request as well as pull_request.opened events are fired.

In order to understand this behavior of firing multiple seemingly similar events upon the click of the same button, I tried to reopen a closed request and print out the Context object for both pull_request event as well as pull_request.reopened event.

I did a diff comparison of both the contexts and found that the contexts returned by both the events are identical except that the context of pull_request event contained below additional properties :

merged: false,
        mergeable: null,
        rebaseable: null,
        mergeable_state: 'unknown',
        merged_by: null,
        comments: 6,
        review_comments: 0,
        maintainer_can_modify: false,
        commits: 1,
        additions: 1,
        deletions: 0,
        changed_files: 1 },
     repository:
      { id: 123456789,
        node_id: '',
        name: '',
        full_name: '',
        private: true,
        owner: [Object],
        html_url: 'some-url-here'
        .
        .
        ///////////////////--------many more urls-------//////////////////////
        created_at: '2020-04-0',
        updated_at: '2020-04-0',

We know that the general format of the context object returned is as follows :

Context {
  name: 'pull_request',
  id: '187128937812-8219-89891892133-16752-1234576765545',
  payload:
   { action: 'reopened',
     number: 1,
     pull_request:
      { url:
        .
        .
        .and so on.......

This above information is present in both the contexts. We can see that this also tells us about the specific action that was performed and this is denoted by the context.payload.action. So, if someone's requirement is to get hold of the pull_request.opened he/she could do it by just by using pull_request event as follows :

app.on('pull_request', async context => {
    console.log('---------------------- on pull_request event')
    console.log('Context returned :----', context)
  })

And doesn't need to care about the other more specific events(here pull_request.opened) i.e. apart from what is achieved from the above code, below code would provide no real additional help :

app.on('pull_request.opened', async context => {
    console.log('---------------------- on pull_request.opened')
    console.log('Context returned :----', context)
  })

So here is the question that's troubling me : What is the purpose of the pull_request event , if its other specific forms (like pull_request.reopened) carry no different information(more precisely, if their contexts contain no different infos) ?

I am quite sure that there does lie some wisdom behind it. I'm not able to find anything on the internet, nothing in the docs that could explain this.

Please help me understand the hidden wisdom.

EDIT 1 : START

Forgot to mention one observation and that is : Reopening the pull request also triggers issue_comment.created event. So, So three events are triggered by one action(clicking Create Pull Request).

EDIT 2 : START


Solution

  • What is the purpose of the pull_request event , if its other specific forms (like pull_request.reopened) carry no different information(more precisely, if their contexts contain no different infos) ?

    This is just a feature of Probot to simplify processing webhook events from GitHub. I'll try and explain why it's helpful.

    If you were to consume webhook events without Probot, you would have to parse every pull_request event, check the action field for a case, and decide whether to handle it.

    There are several events that have a top-level action field in the payload, incuding:

    Rather than make application developers perform this parsing and inspection of the JSON themselves they decided to simplify the callbacks so you can subscribe to webhooks using the specific [event].[action] pattern, and the framework takes care of invoking your callback when the matching event and action is received.

    So you have two options for handling pull_request events:

    • if you don't know which events you need, or need to dynamically process events, subscribing to pull_request is how you would receive all pull request events
    • if you know which events you should handle, and can ignore the rest, subscribe to explicit pull_request.[event] should simplify your application code

    You could also subscribe to *, which represents all events the probot app receives, rather than explicitly listing all supported events in your app.