Discord Notifications

Added: 2026-02-04 Status: Active in production PR: #497, #498


Overview

Discord notifications provide real-time visibility into repository activity. All PR updates, CI results, issues, and releases are posted to dedicated Discord channels with threaded conversations.

Key Components:

  1. repo-relay - Bot-based GitHub Action that bridges GitHub events to Discord
  2. SQLite state persistence - Tracks PR-to-message mappings for threaded updates
  3. Self-hosted runner requirement - State database must persist between runs

Architecture

GitHub Event ──▶ discord-notify.yml ──▶ repo-relay ──▶ Discord

Events:                        Channels:
• PR opened/updated/merged     • #archery-apprentice-github (PRs, Issues)
• CI pass/fail                 • Releases channel
• Issues opened/closed
• Releases published

Why Self-Hosted Runner?

repo-relay uses SQLite for state persistence (~/.repo-relay/state.db):

  • Tracks PR-to-Discord message mappings
  • Enables threaded updates (all PR activity goes to the same Discord thread)
  • On GitHub-hosted runners, state is lost between runs — threads would break

Workflow Configuration

File: .github/workflows/discord-notify.yml

Trigger Events

EventTypes
pull_requestopened, synchronize, closed, reopened, edited, ready_for_review, converted_to_draft
pull_request_reviewsubmitted
issue_commentcreated
issuesopened, closed
releasepublished
workflow_runcompleted (Android CI, iOS CI)

Required Secrets

SecretDescription
DISCORD_BOT_TOKENBot token from Discord Developer Portal
DISCORD_CHANNEL_PRSChannel ID for PR and CI notifications
DISCORD_CHANNEL_ISSUESChannel ID for issue notifications
DISCORD_CHANNEL_RELEASESChannel ID for release notifications

Bot Permissions Required

  • View Channel
  • Send Messages
  • Create Public Threads
  • Send Messages in Threads
  • Embed Links
  • Read Message History

Cascade Prevention

The workflow includes filters to prevent notification spam:

# Skip workflow_run events that aren't for a PR
(github.event_name != 'workflow_run' ||
  (github.event.workflow_run.pull_requests &&
   github.event.workflow_run.pull_requests[0]))
 
# Skip pull_request_review events from repo owner
# (avoids cascade when replying to Copilot review comments)
&& (github.event_name != 'pull_request_review' ||
    github.event.review.user.login != github.repository_owner)

Why the owner filter? When the /check-pr skill replies inline to Copilot review comments, GitHub fires pull_request_review events. Without the filter, each reply would trigger another Discord notification, creating a feedback loop.


Deployment Notifications (Legacy)

Play Store deployments use a separate webhook-based notification in deploy-to-play-store.yml:

  • Uses DISCORD_WEBHOOK_URL secret (not the bot)
  • Sends deployment success/failure messages
  • Includes version info and commit links

Troubleshooting

State Database Errors

Symptom: ERROR: no such column: <column_name>

Cause: repo-relay version was updated but the existing SQLite database on the self-hosted runner has the old schema.

Fix: Update to a repo-relay version that includes schema migrations. If the issue persists, delete the state directory and let it rebuild:

rm -rf ~/.repo-relay/blamechris-archery-apprentice

Note: Deleting the state directory means existing PR threads lose their mapping. New PR events will create new messages instead of threading onto existing ones.

Permission Errors

Symptom: ERROR: Could not resolve bot member in guild for channel

Cause: The Discord bot lacks permissions in one or more configured channels, or the channel ID is incorrect.

Fix:

  1. Verify channel IDs in repository secrets match actual Discord channel IDs
  2. Confirm the bot has been invited to the server
  3. Check bot role has the required permissions listed above


Tags: ci-cd discord notifications repo-relay Status: Active in production