# Discourse GitHub

**URL:** https://meta.discourse.org/t/discourse-github/99895
**Category:** Plugin
**Tags:** official, github, included-in-core
**Created:** [October 18, 2018, 6:31pm UTC](https://meta.discourse.org/t/discourse-github/99895 "2018-10-18T18:31:26Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [October 18, 2018, 6:31pm UTC](https://meta.discourse.org/t/discourse-github/99895/1 "2018-10-18T18:31:26Z")

</div>

| | | |
| --- | --- | --- |
| :discourse2: | **Summary** | **Discourse GitHub** Allows staff to assign badges to users based on GitHub contributions. Also allows users to create Github Linkbacks, Permalinks, and display live PR status on oneboxes. |
| 📖 | **Install Guide** | **This plugin is bundled with Discourse core**. There is no need to install the plugin separately. |

> [@](#):
>
> :discourse2: As this is an #official plugin maintained by the Discourse team, #Support, #Contribute > Bug, #Contribute > UX, and #Contribute > Feature requests can be made in the respective categories here on Meta, and tagged with the appropriate plugin tag. Click on a link below to get one started. 👍
> 
> [❓&nbsp; **Support**](https://meta.discourse.org/new-topic?category_id=6&body=%3E%20Before%20asking,%20did%20you%20search%20first%3F%20Press%20%F0%9F%94%8D%20at%20the%20upper%20right%20to%20search.&tags=github "Ask for support on configuring and using Discourse GitHub") [🐛&nbsp; **Bug**](https://meta.discourse.org/new-topic?category_id=1&tags=github "A bug report means something is broken, preventing normal/typical use of the plugin") [👀&nbsp; **UX**](https://meta.discourse.org/new-topic?category_id=9&tags=github "Discussion about the user interface of Discourse GitHub, and how features are presented (including language and UI elements)") [💡&nbsp; **Feature**](https://meta.discourse.org/new-topic?category_id=2&tags=github "Discussion about how existing Discourse GitHub features can be improved or enhanced, and how proposed new features could work")

### Features

#### GitHub Badges

Assign badges to your users based on GitHub contributions.

##### How to use:

1. Enable `github badges enabled` in Settings → Plugins.
2. Generate a GitHub access token and paste it into the `github linkback access token` setting. See below for instructions.
3. Add one or more URLs of the GitHub repos to scan for contributions to the `github badges repos` site setting.

##### How badge counting works:

Badges count commits across all repositories, and when a user contributes to multiple repos, all their commits are added together into one total count.

_Committer Badges:_

| Badge | Commits Required |
| --- | --- |
| Bronze | 1 commit |
| Silver | 25 commits |
| Gold | 1000 commits |

_Badge Progression:_ As users accumulate more contributions across any of the tracked repositories, they automatically progress through badge tiers. For example, if a user commits to Repo A and then Repo B, both contributions count toward their total, allowing them to progress from Bronze to Silver to Gold.

* * *

#### GitHub Linkback

Create a link from a GitHub pull request or commit back to a Discourse post where it is mentioned.

 ![image](https://global.discourse-cdn.com/meta/original/3X/1/4/14fa55442fcee62f772b5b6e09437c9d2fe83f3d.png)

##### How to use:

1. Enable `github linkback enabled` in Settings → Plugins.
2. Generate a GitHub access token and paste it into the `github linkback access token` setting. See below for instructions.
3. Finally, add the projects you wish to post to in the `github linkback projects` site setting in the formats:
  - `username/repository` for specific repositories
  - `username/*` for all repositories of a certain user

* * *

#### GitHub Permalink

Replace GitHub non-permalinks with [permalinks](https://help.github.com/articles/getting-permanent-links-to-files/).

##### How to use:

1. Enable `github permalinks enabled` in Settings → Plugins.

* * *

#### PR Live Status

Display live status indicators on GitHub pull request oneboxes in posts and chat messages. The status updates automatically via webhooks when PRs change on GitHub.

##### Status Types

| Status | Color | Description |
| --- | --- | --- |
| Draft | Gray | PR is marked as draft |
| Open | Gray | PR is open and awaiting review |
| Approved | Green | PR has been approved by reviewers |
| Changes Requested | Orange | Reviewers have requested changes |
| Merged | Purple | PR has been merged |
| Closed | Red | PR was closed without merging |

##### How to use:

###### Step 1: Enable the Feature

Go to **Admin \> Settings \> Plugins** and set `github pr status enabled` to `true`.

###### Step 2: Configure GitHub Access Tokens

To fetch PR status (especially for private repositories), configure GitHub access tokens.

**Setting:** `github onebox access tokens`

**Format:**

```plaintext
organization_name|ghp_your_token_here
default|ghp_fallback_token_here

```

You can specify tokens per organization, plus a `default` token used as a fallback. Each line should contain `org_name|token` where the token is a GitHub Personal Access Token (classic) with `repo` scope.

**Example:**

```plaintext
discourse|ghp_xxxxxxxxxxxxxxxxxxxx
my-company|ghp_yyyyyyyyyyyyyyyyyyyy
default|ghp_zzzzzzzzzzzzzzzzzzzzzz

```

###### Step 3: Set Up GitHub Webhooks (for Real-Time Updates)

To get automatic status updates when PRs change, configure a webhook on GitHub.

**Generate a Webhook Secret:**

```bash
openssl rand -hex 32

```

Set the `github webhook secret` site setting to your generated secret.

**Create the Webhook on GitHub:**

You can create the webhook at the organization level (to cover all repos) or per-repository.

For an organization:

1. Go to your organization’s Settings
2. Navigate to **Webhooks** (under Code, planning, and automation)
3. Click **Add webhook**

For a repository:

1. Go to your repository’s Settings
2. Navigate to **Webhooks**
3. Click **Add webhook**

**Webhook Configuration:**

| Field | Value |
| --- | --- |
| Payload URL | `https://your-discourse-site.com/discourse-github/webhooks/github` |
| Content type | `application/json` |
| Secret | Your generated webhook secret |
| SSL verification | Enable (recommended) |
| Events | Select “Let me select individual events” |

**Select these events:**

- Pull requests
- Pull request reviews

Click **Add webhook** to save.

###### Step 4: Verify the Setup

1. Create a test post with a GitHub PR URL
2. Verify the onebox displays with a status icon
3. Change the PR status on GitHub (e.g., approve it, or close it)
4. Within a few seconds, refresh the Discourse page — the status should update

You can check the webhook delivery status in GitHub’s webhook settings to confirm events are being sent and received successfully.

##### Status Priority

When a PR has multiple states (e.g., approved but also has changes requested), the status is determined by this priority:

1. Merged (highest priority)
2. Closed
3. Draft
4. Changes Requested
5. Approved
6. Open (default)

##### Review Status Logic

The feature fetches review information from the GitHub API to determine approval status:

- Takes the latest review from each reviewer
- Ignores “commented” and “pending” review states
- Shows “changes requested” if any reviewer has requested changes
- Shows “approved” only if reviews exist and none request changes

##### Where It Works

- **Forum posts** — Any post containing a GitHub PR onebox
- **Chat messages** — PR oneboxes in chat also display live status

Note: Inline oneboxes (when a link appears inline in text rather than as a full preview) do not display status icons.

##### Migrating from GitHub Status Theme Component

This feature replaces the [GitHub Status Indicators](https://meta.discourse.org/t/github-status-indicators/130471) theme component. The two are not compatible and should not be used together.

If you’re currently using the theme component:

1. Disable and remove the `github-status-theme` theme component
2. Enable this built-in feature via the `github pr status enabled` setting

* * *

### Configuration

#### GitHub Access Token

In order for the linkback feature to work and the badges to be granted to your users, you need to provide a GitHub access token. You can generate your token here: [Sign in to GitHub · GitHub](https://github.com/settings/tokens/new).

The linkback feature requires the `public_repo` scope, and granting badges requires no scope (leave everything unchecked if you only want badges). Since the `public_repo` scope grants **write access** to repositories, we recommend you create a **throwaway GitHub account** that has access to no repositories and use it just to generate a token.

#### Token Scopes by Feature

| Feature | Required Scope |
| --- | --- |
| Badges | No scope required |
| Linkback | `public_repo` |
| PR Status (public repos) | No scope required |
| PR Status (private repos) | `repo` |

* * *

### Site Settings Reference

| Setting | Default | Description |
| --- | --- | --- |
| `enable discourse github plugin` | `false` | Master switch for the plugin |
| `github badges enabled` | `false` | Enable GitHub contribution badges |
| `github badges repos` | (empty) | Repository URLs to track for badges |
| `github linkback enabled` | `false` | Enable linkbacks from GitHub to Discourse |
| `github linkback access token` | (empty) | Access token for linkback feature |
| `github linkback projects` | (empty) | Projects to create linkbacks for |
| `github permalinks enabled` | `false` | Replace GitHub links with permalinks |
| `github pr status enabled` | `false` | Enable PR status icons on oneboxes |
| `github webhook secret` | (empty) | Secret for webhook signature verification |
| `github onebox access tokens` | (empty) | Access tokens for GitHub API (format: `org|token`) |

* * *

### Technical Details

#### PR Status API Usage

When a GitHub PR onebox is generated, Discourse makes up to two API calls:

1. **PR Data** : `GET /repos/{owner}/{repo}/pulls/{number}` — Fetches basic PR information including state, merged status, and draft status
2. **Reviews** : `GET /repos/{owner}/{repo}/pulls/{number}/reviews` — Fetches review data to determine approval status

These calls use your configured access token if available, allowing access to private repositories.

#### Webhook Security

Webhook requests are verified using HMAC-SHA256 signature validation. GitHub signs the webhook payload with your secret, and Discourse verifies this signature before processing. Invalid signatures are rejected with a 403 response.

#### Webhook Events That Trigger Updates

- PR state changes (opened, closed, reopened)
- PR merged
- Draft status changes (converted to draft, ready for review)
- Pull request reviews submitted
- Reviews edited or dismissed

#### Performance Considerations

- Rebaking is queued as a low-priority background job to avoid impacting site performance
- Only posts/messages with full GitHub PR oneboxes are rebaked (inline oneboxes are skipped)
- Chat message rebakes skip notifications to prevent duplicate alerts

* * *

### CHANGELOG

#### 2025-12-10

- FIX: Skip notifications when rebaking chat messages from GitHub webhooks

#### 2025-12-09

- FIX: Skip rebaking posts with inline GitHub PR oneboxes
- FIX: Avoid intermediate state when rebaking posts with oneboxes
- FIX: Rebake chat messages when GitHub PR status changes
- UX: Use min-height to prevent layout shift when the status icon changes
- UX: Reduce GitHub PR status icon size on mobile

#### 2025-12-08

- FEATURE: Add “changes requested” status to GitHub PR oneboxes

#### 2025-12-04

- FEATURE: GitHub PR live status icon

#### 2025-11-10

- FEATURE: Allow and denylist for linkbacks

#### 2025-11-08

- FEATURE: Add category ignore list for GitHub linkbacks

#### 2024-12-20

- DEV: Move discourse-github to core (no longer requires separate installation)

> Last edited by @zogstrip 2025-12-10T13:26:48Z
> 
> > **Check document**
> >
> > Perform check on document:

---

<div class="post-metadata">

### Author: ![ImmaZoni](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/immazoni/32/261840_2.png) [@ImmaZoni](https://meta.discourse.org/u/ImmaZoni)
#### Post date: [July 19, 2022, 1:10am UTC](https://meta.discourse.org/t/discourse-github/99895/71 "2022-07-19T01:10:43Z")

</div>

What is the process for multiple links? does it just add them to the same commit comment? or make a whole new comment every time?

---

<div class="post-metadata">

### Author: ![satonotdead](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/satonotdead/32/447830_2.png) [@satonotdead](https://meta.discourse.org/u/satonotdead)
#### Post date: [June 26, 2023, 5:35pm UTC](https://meta.discourse.org/t/discourse-github/99895/72 "2023-06-26T17:35:54Z")

</div>

I wonder if commits and PRs badges could be simplified because we are trying to keep away [The paradox of choice](https://thedecisionlab.com/reference-guide/economics/the-paradox-of-choice) 🙂

_Currently I just forked and deleted commit badges but of course, I loss myself from the commit badge (because I’m commiting directly) and fork is not equal to keeping always with the core._

---

<div class="post-metadata">

### Author: ![xomiamoore](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/xomiamoore/32/284056_2.png) [@xomiamoore](https://meta.discourse.org/u/xomiamoore)
#### Post date: [August 21, 2023, 10:05pm UTC](https://meta.discourse.org/t/discourse-github/99895/73 "2023-08-21T22:05:25Z")

</div>

> [@Discourse](#):
>
> - `username/repository` for specific repositories
> - `username/*` for all repositories of a certain user

The wildcard \* didn’t work for me for a GitHub organization, I ended up putting in every repo individually. Has anyone else had issues with this with an organization vs. a user?

---

<div class="post-metadata">

### Author: ![greyli](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/greyli/32/336213_2.png) [@greyli](https://meta.discourse.org/u/greyli)
#### Post date: [November 2, 2023, 12:48pm UTC](https://meta.discourse.org/t/discourse-github/99895/74 "2023-11-02T12:48:35Z")

</div>

How to set the linkback comment language?

---

<div class="post-metadata">

### Author: ![cultiv](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cultiv/32/483312_2.png) [@cultiv](https://meta.discourse.org/u/cultiv)
#### Post date: [February 1, 2025, 12:25pm UTC](https://meta.discourse.org/t/discourse-github/99895/75 "2025-02-01T12:25:30Z")

</div>

Thank you, I really like this plugin! I was confused about the badges system and was glad to find the explanation in a different topic: [Github Badges are not working. Its hard to see if I do something wrong or if the plugin is not working - #4 by simon](https://meta.discourse.org/t/github-badges-are-not-working-its-hard-to-see-if-i-do-something-wrong-or-if-the-plugin-is-not-working/148036/4)

However, that reply notes that

> The plugin creates 6 badges:

I don’t see any of these badges, not sure what happened? Is there a way to (re?)trigger the creation of these badges?

---

<div class="post-metadata">

### Author: ![cultiv](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cultiv/32/483312_2.png) [@cultiv](https://meta.discourse.org/u/cultiv)
#### Post date: [February 2, 2025, 8:23am UTC](https://meta.discourse.org/t/discourse-github/99895/76 "2025-02-02T08:23:56Z")

</div>

To answer my own question, after a few hours the scheduled task ran and that’s when the badges got created.

> [@cultiv](#):
>
> Is there a way to (re?)trigger the creation of these badges?

The manual way to do this would be to trigger the sidekiq job it seems.

---

<div class="post-metadata">

### Author: ![tomtjes](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tomtjes/32/131271_2.png) [@tomtjes](https://meta.discourse.org/u/tomtjes)
#### Post date: [May 15, 2025, 6:27am UTC](https://meta.discourse.org/t/discourse-github/99895/77 "2025-05-15T06:27:23Z")

</div>

Feature Request: exclude categories and/or tags from linkback

We have an `Announcements` category into which the RSS Plugin automatically pulls new GitHub releases. When the release notes link to issues, that link also appears in Discourse and a linkback is created, but one that is not helpful to anyone, creating clutter on Github.

I would like to be able to exclude certain posts, i.e. categories or tags or even just posts from the user that is configured in the RSS Plugin, from creating linkbacks.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [July 22, 2025, 1:13pm UTC](https://meta.discourse.org/t/discourse-github/99895/78 "2025-07-22T13:13:42Z")

</div>

🥳 This plugin is now bundled with Discourse core as part of [Bundling more popular plugins with Discourse core](https://meta.discourse.org/t/bundling-more-popular-plugins-with-discourse-core/373574). If you are self-hosting and use the plugin, you need to remove it from your `app.yml` before your next upgrade.
