Commit Graph
9 Commits
Author SHA1 Message Date
Régis Hanol 318eb49a30 FIX: Skip GitHub linkback when topic is already linked (#37633)
The GitHub linkback feature posts comments on PRs/issues/commits when
they are mentioned in Discourse posts. However, it never checked whether
the GitHub PR/issue/commit already contained a link back to the same
Discourse topic (in its description or existing comments). This led to
redundant linkback comments when a PR already referenced the topic.

Before posting a linkback comment, we now fetch the PR/issue body and
existing comments (or commit comments) from the GitHub API and check
whether any of them already contain a URL pointing to the same Discourse
topic. URL matching uses Discourse.route_for — the same mechanism used
by the oneboxer, search, and TopicLink — to reliably recognize all topic
URL formats (/t/slug/id, /t/id, /t/id/post_number, etc.).

On any GitHub API error, the check fails open (still posts the linkback)
to preserve the pre-existing behavior — and because if the GET fails,
the subsequent POST will likely fail too.
2026-02-09 14:31:27 +01:00
ducksandzogstrip dd655f15d2 FEATURE: Add category ignore list for GitHub linkbacks (#35921)
Sometimes you have categories where posts mention GitHub URLs but you
don't actually want linkback comments posted to GitHub — think
AI-generated summaries or automated reports that reference commits but
would just create noise on the issue tracker.

This adds a `github_linkback_ignored_categories` site setting that lets
admins specify which categories should be skipped entirely when
processing linkbacks. Posts in those categories won't trigger any GitHub
comments, keeping things clean.

To make this work nicely, the setting uses the `category_list` type
which gives you a proper category picker in the admin UI rather than
having to type raw IDs. This required extending core's `_map`
metaprogramming helper (which previously only worked with `group_list`
settings) to also handle `category_list` — so now any `category_list`
setting automatically gets a `_map` variant that returns an array of
integers, just like group settings do.

Screenshot of new setting:
<img width="774" height="116" alt="discourse-github-ignore-cat"
src="https://github.com/user-attachments/assets/dd9a3c85-7f01-47c6-b1b7-fe6ef120ab8b"
/>

Ref: /t/141863

---------

Co-authored-by: zogstrip <regis@hanol.fr>
2025-12-27 00:42:20 +01:00
Régis Hanol 67985bff52 PERF: optimize GitHub PR onebox rebaking (#36739)
Previously, when rebaking posts containing GitHub PR oneboxes, we passed
`invalidate_oneboxes: true` to `rebake!` which would re-fetch the onebox
during cooking. This meant each post independently fetched the same PR
data from GitHub.

Now we:

1. Fetch and cache the onebox once upfront via `Oneboxer.preview`
2. Use the new `skip_publish_rebaked_changes` parameter to prevent
publishing intermediate states, without triggering onebox re-fetches
3. Filter posts by `cooked LIKE '%githubpullrequest%'` in SQL rather
than fetching all linked posts and filtering in Ruby

The new `skip_publish_rebaked_changes` parameter on `Post#rebake!`
allows callers to skip the `:rebaked` publish without triggering onebox
invalidation, which is useful when the caller has already refreshed the
cache separately.
2025-12-17 12:06:16 +01:00
Régis Hanol b45703646a FIX: Skip notifications when rebaking chat messages from GitHub webhooks (#36577)
When a GitHub PR webhook triggers a rebake of chat messages containing
PR oneboxes, mentioned users were being re-notified. This happened
because the Chat::ProcessMessage job always invokes the notifier, unlike
regular posts where alerting is handled separately.

Adds a `skip_notifications` parameter to Chat::Message#rebake! that
propagates to the ProcessMessage job, which then skips calling the
Chat::Notifier. The GitHub webhook job now passes this flag when
rebaking chat messages to prevent duplicate notifications.

Internal ref - t/169442
2025-12-10 01:08:36 +01:00
Régis Hanol 2ea603cd21 FIX: Skip rebaking posts with inline GitHub PR oneboxes (#36576)
Posts and chat messages with inline oneboxes to GitHub PRs were being
unnecessarily rebaked when the PR status changed. This happened because
the check `cooked.include?("onebox")` matched both full oneboxes
(`class="onebox githubpullrequest"`) and inline oneboxes
(`class="inline-onebox"`).

Changed the check to match "githubpullrequest" specifically, which only
appears in full PR oneboxes that actually display the status.

Internal ref - t/169442
2025-12-09 23:28:22 +01:00
Régis Hanol 05f83ee4d7 FIX: Rebake chat messages when GitHub PR status changes (#36561)
Fix GitHub PR onebox updates not working for chat messages.

When a GitHub webhook triggered the `RebakeGithubPrPosts` job, chat
messages containing PR links were not being rebaked. The issue was
twofold:

1. `defined?(Chat::MessageLink)` doesn't trigger Rails autoloading - it
only checks if a constant is already loaded, so it would return `nil`
before the class was ever accessed
2. Inside `module Jobs`, Ruby's constant resolution would look for
`Jobs::Chat::MessageLink` before the global `::Chat::MessageLink`

- Replace `defined?(Chat)` check with `SiteSetting.chat_enabled` which
is the idiomatic Discourse pattern for checking plugin availability
- Remove the redundant `defined?(Chat::MessageLink)` guard since the
site setting check already handles this
- Add `::` prefix to `Chat::MessageLink` and `Chat::Message` references
to ensure they resolve to the global namespace

Internal ref - t/169442
2025-12-09 15:20:54 +01:00
Régis Hanol f3680621bc FEATURE: GitHub PR live status icon (#36313)
I wanted a better way to show a live/up-to-date status of a PR than what
the https://github.com/discourse/github-status-theme provided.

First, I wanted it to work on any PR, including ones in private
repositories.

Second, I wanted to include the approved status, which requires a 2nd
call to GitHub's API.

Third, I wanted something that was less "intrusive" than the
"shield-like" status, so I opted out to use the icons & color that
GitHub uses (but maybe that's a bad idea).

After a first PoC that was a dump proxy to handle authentication for private repositories, the idea to use org webhooks was raised and turned out to be much lighter and easier than figuring out a proper caching strategy.

So this adds support for receiving `pull_request` and `pull_request_review` webhooks events to schedule a background job that will rebake posts and chat messages that have a link to the mentioned PR.

The GitHub PR onebox has been updated to query and parse the review state so we can have a better icon.

This also adds the `Chat::MessageLink` model (that is the #chat version of `TopicLink`) to help better keep track of links posted in chat.

**BEFORE**

<img width="1525" height="1356" alt="BEFORE"
src="https://github.com/user-attachments/assets/02f66137-9f4f-4a91-b321-73816161e204"
/>


**AFTER**

<img width="1525" height="1356" alt="AFTER"
src="https://github.com/user-attachments/assets/2164b7ef-8cd0-4cec-aea8-936a76a94fb2"
/>


Internal ref - t/17138
2025-12-04 21:42:44 +01:00
Jarek RadoszandLoïc Guitaut e372355fd0 DEV: Clean up scope resolution operators in plugins (#34979)
Co-authored-by: Loïc Guitaut <loic@discourse.org>
2025-09-30 14:36:34 +02:00
Jarek Radosz 97b1f04f8d DEV: Move discourse-github to core (#33749)
https://meta.discourse.org/t/373574

Internal `/t/-/156778`
2025-07-22 15:07:59 +02:00