n8n GitHub PR Notifier

Overview

Type: AI Workflow
Node Types: webhook, noOp, executeCommand, stickyNote, github, splitInBatches, if, string, readWriteFile, main
Estimated Time: 6 min
Complexity: ⭐⭐⭐ Complex

🔔 n8n GitHub PR Notifier

This official n8n GitHub PR Notifier workflow automates Slack notifications whenever a new Pull Request (PR) or Issue is created in a GitHub repository.

✨ Features

  • Monitors GitHub PRs & Issues: Uses a webhook trigger to listen for GitHub events.
  • Sends Alerts to Slack: Automatically posts notifications to your team’s Slack channel.
  • Dynamic File Filtering: Fetches only valid .json files from repositories using conditions.
  • Workflow Import Support: Supports importing workflows directly from GitHub using n8n CLI.

🧩 Workflow Steps

  1. Webhook Node: Receives a GitHub webhook request (e.g., PR created).
  2. Create Folder: Ensures the workflows/ folder exists locally.
  3. GitHub List Files: Fetches root-level file listings from the target repository.
  4. Loop Over Files: Splits the GitHub file list into batches.
  5. If Node: Filters only `.json` type files.
  6. GitHub Download File: Downloads the matching JSON workflow file.
  7. Store Locally: Saves the file into the local workflows/ directory.
  8. Import + Clean: Executes the import via CLI and deletes local JSON files afterward.

✅ Use Case Examples

  • Notify your DevOps team on Slack when a developer opens a new pull request.
  • Monitor high-priority GitHub issues and bring them directly into your team communication workflow.
  • Automatically fetch JSON-based workflows from GitHub and import into your n8n instance.

⚠️ Things to Watch Out For

  • Make sure to configure your GitHub OAuth2 credentials correctly in the workflow.
  • Slack credentials and webhook configuration are required for the notifications to work.
  • This workflow assumes your GitHub webhook delivers a payload with owner and repository information.

🛠️ Commonly Used Nodes

  • Webhook
  • GitHub (List & Download File)
  • Slack (optional for notification)
  • If
  • Execute Command
  • Read/Write File

🚀 Bonus Tip

You can extend this n8n GitHub PR Notifier workflow to also post review reminders or summaries into Slack channels using an LLM summarizer like GPT-4, or log important PR metadata into a Notion database for weekly reporting.

Workflow Editor Screenshot

Workflow Screenshot

Workflow JSON Code

{
  "nodes": [
    {
      "id": "6dcae6fd-9631-4f73-985c-31c08cfba106",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -200,
        -45
      ],
      "webhookId": "182bd0f4-bab3-4d3f-8341-773c2af24107",
      "parameters": {
        "path": "import-workflows",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode",
        "authentication": "basicAuth"
      },
      "credentials": {
        "httpBasicAuth": {
          "id": "0sXvlBjKe1sDOYj0",
          "name": "Github action user"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "62de08a4-db11-4602-9e4b-756fdecd2809",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        900,
        -20
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "faff0550-2ddd-4903-a2c2-c6081cf3098e",
      "name": "create workflows sub folder if not exist",
      "type": "n8n-nodes-base.executeCommand",
      "position": [
        20,
        -45
      ],
      "parameters": {
        "command": "mkdir -p workflows"
      },
      "typeVersion": 1
    },
    {
      "id": "2b9a3378-f36a-4a25-bcc1-82fa403b85a7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -740,
        -300
      ],
      "parameters": {
        "color": 6,
        "width": 520,
        "height": 500,
        "content": "# Github import\nThis webhook is secured with a basic authentication credential. Make sure to edit it to values you own.\n\nThe webhook receives the github owner and repository from whitch it should import the workflows.\n\nIt will download all json files into a local directory and call the n8n cli to import them.\n\nThere is a companion developement template on github that complements this flow, including the Github Action that can call this workflow. You can get it from here: https://github.com/dynamicNerdsSolutions/n8n-git-flow-template\n\n## First step :\nCreate the credentials for the webhook authentication and github."
      },
      "typeVersion": 1
    },
    {
      "id": "9143f124-30b5-4a55-b3b7-03cd3c4fdfe8",
      "name": "List files from specified repo root",
      "type": "n8n-nodes-base.github",
      "position": [
        240,
        -45
      ],
      "webhookId": "b04d7d0c-b721-4d30-b4bd-29ed04f5ac9d",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Webhook').item.json.body.owner }}"
        },
        "resource": "file",
        "operation": "list",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Webhook').item.json.body.repository }}"
        }
      },
      "credentials": {
        "githubApi": {
          "id": "Nx9eJjTiUfwyntOr",
          "name": "GitHub account"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "f28d4f42-e7a0-4a25-8d1e-44de3a04f11a",
      "name": "Loop Over Files",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        460,
        -40
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "64d6aeac-bc11-4204-bea5-7f678fddf2b7",
      "name": "If it is a json file",
      "type": "n8n-nodes-base.if",
      "position": [
        680,
        -120
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8ad03c7c-1820-4f9e-998c-a209cc829ea3",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.type }}",
              "rightValue": "file"
            },
            {
              "id": "1a26b68e-91d6-468b-aed5-db0e4cee0f74",
              "operator": {
                "type": "string",
                "operation": "endsWith"
              },
              "leftValue": "={{ $json.name }}",
              "rightValue": ".json"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8c4f7bcc-0c3c-4333-a39e-51d29be43c87",
      "name": "Download file",
      "type": "n8n-nodes-base.github",
      "position": [
        900,
        -220
      ],
      "webhookId": "ec903eb1-d4be-4332-8e28-7f384479336a",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Webhook').item.json.body.owner }}"
        },
        "filePath": "={{ $json.path }}",
        "resource": "file",
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Webhook').item.json.body.repository }}"
        },
        "additionalParameters": {}
      },
      "credentials": {
        "githubApi": {
          "id": "Nx9eJjTiUfwyntOr",
          "name": "GitHub account"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "27ee1e73-66d5-4c86-a6ea-6be4786bc97e",
      "name": "Store file locally",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        1140,
        -60
      ],
      "parameters": {
        "options": {},
        "fileName": "=workflows/{{ $json.name }}",
        "operation": "write"
      },
      "typeVersion": 1
    },
    {
      "id": "3a2a58ae-2f8f-447a-8a95-073d1f5575d6",
      "name": "Call n8n import and cleanup folder",
      "type": "n8n-nodes-base.executeCommand",
      "position": [
        680,
        -320
      ],
      "parameters": {
        "command": "n8n import:workflow --separate --input=workflows && rm -f ./workflows/*.json"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "create workflows sub folder if not exist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download file": {
      "main": [
        [
          {
            "node": "Store file locally",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Files": {
      "main": [
        [
          {
            "node": "Call n8n import and cleanup folder",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If it is a json file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store file locally": {
      "main": [
        [
          {
            "node": "Loop Over Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If it is a json file": {
      "main": [
        [
          {
            "node": "Download file",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "No Operation, do nothing": {
      "main": [
        [
          {
            "node": "Loop Over Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List files from specified repo root": {
      "main": [
        [
          {
            "node": "Loop Over Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "create workflows sub folder if not exist": {
      "main": [
        [
          {
            "node": "List files from specified repo root",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}