DEV Community

Pirate Prentice
Pirate Prentice

Posted on

n8n GitHub Node: Automate Issues, Pull Requests, and Releases in Your Workflows [Free Workflow JSON]

If your team lives in GitHub, you're already doing manual work that n8n can eliminate: pasting issue links into Slack, copying PR details into project trackers, sending release notes to customers, and keeping spreadsheets in sync with repo activity. The n8n GitHub node connects your repositories to every other tool in your stack—without webhooks you have to maintain, without Zapier's per-task pricing, and without writing GitHub API boilerplate.

This guide covers every GitHub node operation, the six most common gotchas, three production-ready workflow patterns, and a free downloadable JSON you can import directly into n8n.


What the n8n GitHub Node Can Do

The GitHub node in n8n wraps the GitHub REST API. Here's what you can read, create, and update:

Issues

  • Create Issue: open a new issue with title, body, labels, assignees, milestone
  • Edit Issue: update state (open/closed), labels, assignees, title, body
  • Get Issue / Get All Issues: fetch by number or list with filters (state, label, assignee, since)
  • Lock / Unlock Issue: restrict or restore comments
  • Create Comment: post a comment on an existing issue

Pull Requests

  • Create PR: open a pull request from branch to base
  • Get PR / Get All PRs: list open/closed/merged PRs with filters
  • Get PR Files: list changed files and their diffs
  • Get PR Reviews: fetch review status and comments
  • Update PR: change title, body, state, or base branch

Repositories

  • Get Repository: fetch repo metadata (stars, forks, topics, default branch)
  • List Repositories: list repos for a user or org
  • Get File: read file content from any branch/commit (base64 decoded)
  • Create / Edit File: commit a file change directly (useful for config updates, README patches)
  • Delete File: remove a file via commit

Releases

  • Create Release: publish a new release with tag, name, body, draft/prerelease flags
  • Get Release / Get All Releases: list releases with assets
  • Update Release: edit body, name, draft state
  • Delete Release

Triggers (GitHub Trigger node)

  • Fires on: push, pull_request, issues, issue_comment, release, create, delete, workflow_run, and more
  • Configure via n8n's built-in webhook URL—no manual GitHub webhook setup needed

Credentials Setup

  1. Generate a Personal Access Token (PAT) at GitHub → Settings → Developer settings → Personal access tokens (classic or fine-grained)
  2. Scopes needed: repo (full control of private repos) or public_repo for public-only access. For org repos, read:org may also be needed.
  3. In n8n: Credentials → New → GitHub → paste the PAT
  4. Fine-grained tokens (2024+): scope to specific repos and permissions for least-privilege access

Six Common Gotchas

1. Base64-encoded file content
The "Get File" operation returns content as base64. Add a Code node to decode: Buffer.from($input.item.json.content, 'base64').toString('utf-8'). Forgetting this gives you garbled output in downstream nodes.

2. Pagination on "Get All" operations
n8n's GitHub node handles pagination automatically when "Return All" is enabled—but large repos (1,000+ issues) can be slow and hit rate limits. Set filters (state, label, since date) to narrow the result set before enabling Return All.

3. Rate limits: 5,000 requests/hour per authenticated user
Authenticated requests get 5,000/hr; unauthenticated get 60/hr. Bulk operations over large repos can exhaust this. Add error handling and exponential backoff in a Code node, or schedule heavy pulls during off-hours.

4. GitHub Trigger requires a public webhook endpoint
The GitHub Trigger node needs a publicly reachable webhook URL. On a local n8n instance, you'll need an ngrok tunnel or cloud n8n. The trigger auto-registers the webhook in your repo settings.

5. SHA required for file updates
The "Edit File" operation requires the current file's SHA (returned by "Get File"). If you skip this step and pass a stale or missing SHA, the operation fails with a 409 conflict.

6. Organization repos vs. personal repos
Some operations require specifying the org name as the "Owner" (not your username). When accessing org repos, confirm the PAT has read:org scope and that the org allows PATs.


Three Production-Ready Workflow Patterns

Pattern 1: GitHub Issue → Slack + Linear Triage Bot

Problem: New issues pile up untracked. Team doesn't know which issues are high-priority until someone manually reviews them.

Workflow:

  1. GitHub Trigger: fires on issues event (action: opened)
  2. AI Node (OpenAI/Anthropic): classify the issue as bug/feature/question, assign severity 1-3 based on title + body
  3. IF node: if severity = 1 (critical bug)
    • Slack node: post to #incidents with issue link, title, and classification
    • Linear node (HTTP Request): create a Linear issue in the "Critical" team with GitHub link
  4. IF node else: post to #triage Slack channel for async review

Why it works: Zero manual triage. Critical bugs get immediate team visibility. Non-critical issues queue in Slack for async review. No context switching between GitHub and project tools.

Pattern 2: Release Notes Auto-Publisher

Problem: Every release requires someone to manually copy the GitHub release body into Slack, email subscribers, and update a changelog doc.

Workflow:

  1. GitHub Trigger: fires on release event (action: published)
  2. Filter node: skip prereleases (check $input.item.json.body.prerelease === true)
  3. Parallel branches:
    • Branch A: Slack node → post formatted release summary to #announcements
    • Branch B: Brevo/Resend node → send release email to opted-in changelog subscribers
    • Branch C: Google Sheets node → append version, date, and summary to a changelog Sheet
  4. GitHub node: Create Comment on all issues/PRs that reference this release milestone (via search)

Why it works: Releases trigger a full distribution chain with no manual steps. Every stakeholder is updated through their preferred channel within seconds of the tag being published.

Pattern 3: PR Quality Gate Notifier

Problem: PRs sit unreviewed for days. Large PRs (500+ lines) get rubber-stamped. No visibility into review queue health.

Workflow:

  1. Schedule Trigger: runs every day at 9 AM
  2. GitHub node: Get All PRs (state: open) for your repository
  3. Code node: calculate age in hours, count changed files from PR metadata
  4. Item Lists node: aggregate and sort by age descending
  5. IF node: filter PRs older than 48 hours OR with >10 files changed (high review burden)
  6. Slack node: post a daily digest to #engineering — "PRs needing attention" list with author, age, file count, link
  7. IF node (>7 days old): send a direct Slack DM to the PR author asking for a status update or close intent

Why it works: Surfaces stale reviews and oversized PRs before they become merge bottlenecks. The daily digest creates a lightweight standup artifact without any manual compilation.


Free Workflow JSON

Import this into n8n (Settings → Import Workflow) to get the PR Quality Gate Notifier pre-wired. Update the repository owner/name, Slack channel, and your alert thresholds.

{
  "name": "GitHub PR Quality Gate Notifier",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [{"field": "cronExpression", "expression": "0 9 * * 1-5"}]
        }
      },
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1,
      "position": [250, 300]
    },
    {
      "parameters": {
        "resource": "pullRequest",
        "operation": "getAll",
        "owner": "YOUR_ORG_OR_USER",
        "repository": "YOUR_REPO",
        "returnAll": true,
        "filters": {"state": "open"}
      },
      "name": "Get Open PRs",
      "type": "n8n-nodes-base.github",
      "typeVersion": 1,
      "position": [450, 300]
    },
    {
      "parameters": {
        "jsCode": "const now = Date.now();\nreturn $input.all().map(item => {\n  const pr = item.json;\n  const ageHours = (now - new Date(pr.created_at).getTime()) / 3600000;\n  return {\n    json: {\n      number: pr.number,\n      title: pr.title,\n      author: pr.user.login,\n      url: pr.html_url,\n      ageHours: Math.round(ageHours),\n      changedFiles: pr.changed_files || 0,\n      stale: ageHours > 48,\n      oversized: (pr.changed_files || 0) > 10\n    }\n  };\n});"
      },
      "name": "Enrich PRs",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [650, 300]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [{"value1": "={{$json.stale || $json.oversized}}", "value2": true}]
        }
      },
      "name": "Needs Attention?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [850, 300]
    },
    {
      "parameters": {
        "channel": "#engineering",
        "text": "=:github: *PR needs attention:* <{{$json.url}}|#{{$json.number}} {{$json.title}}>\nAuthor: @{{$json.author}} | Age: {{$json.ageHours}}h | Files: {{$json.changedFiles}}"
      },
      "name": "Slack Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2,
      "position": [1050, 300]
    }
  ],
  "connections": {
    "Schedule Trigger": {"main": [[{"node": "Get Open PRs", "type": "main", "index": 0}]]},
    "Get Open PRs": {"main": [[{"node": "Enrich PRs", "type": "main", "index": 0}]]},
    "Enrich PRs": {"main": [[{"node": "Needs Attention?", "type": "main", "index": 0}]]},
    "Needs Attention?": {"main": [[{"node": "Slack Alert", "type": "main", "index": 0}], []]}
  }
}
Enter fullscreen mode Exit fullscreen mode

GitHub Node vs. HTTP Request Node

GitHub node HTTP Request node
Auth setup PAT via n8n credential Manual header
Coverage Issues, PRs, releases, files Full GitHub API (GraphQL too)
Pagination Auto (Return All) Manual cursor handling
Ease of use High Lower

Use the GitHub node for the operations it covers. Drop to HTTP Request for GraphQL queries, Actions API, or endpoints not yet in the node.


Putting It All Together

The GitHub node turns your repository into a live data source for every other tool in your stack. Issues become Linear tickets. Releases become Slack announcements and changelog emails. PRs become engineering digest entries. None of this requires a custom integration service—just an n8n workflow and a PAT.


Want this built for your repo but don't have time to wire it up? The Done-For-You n8n Workflow Build service ($99) delivers a production-ready GitHub automation tailored to your team's workflow within 3 business days.

Or grab the n8n Workflow Automation Pack ($29) for 10+ pre-built workflow templates including GitHub integrations.

More n8n guides: pirateprentice on dev.to

Top comments (1)

Collapse
 
pirateprentice profile image
Pirate Prentice

Are you using the GitHub node to automate issue triage, release publishing, or PR quality gates? Drop your workflow pattern in the comments — always interested in what people are shipping.