Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .github/workflows/discord-discussions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
# automatically once this merges to the default branch.
command -v discord_applied_tags >/dev/null 2>&1 || discord_applied_tags() { printf '[]'; }
command -v extract_discord_thread >/dev/null 2>&1 || extract_discord_thread() { :; }
command -v discord_archive_thread >/dev/null 2>&1 || discord_archive_thread() { :; }
command -v discord_sync_thread >/dev/null 2>&1 || discord_sync_thread() { :; }

NUMBER="${{ github.event.discussion.number }}"
OWNER="${REPO%/*}"
Expand Down Expand Up @@ -335,13 +335,17 @@ jobs:
fi
fi

# ── Mirror closed/open state onto the forum thread (archive) ─────
# No-op unless DISCORD_GITHUB_BOT_TOKEN is set.
# ── Sync forum thread: archive flag + live tags in ONE PATCH ─────
# No-op unless DISCORD_GITHUB_BOT_TOKEN is set. archived + applied_tags
# are set together so re-tagging also works on reopen and on threads
# Discord auto-archived by inactivity (an applied_tags edit on an
# already-archived thread is rejected with 400). Tags cover state,
# answer status, category, and labels.
FINAL_THREAD_ID="${DISCORD_THREAD_ID:-}"
[ -z "$FINAL_THREAD_ID" ] && FINAL_THREAD_ID="${WINNER_THREAD_ID:-}"
[ -z "$FINAL_THREAD_ID" ] && FINAL_THREAD_ID="${NEW_THREAD_ID:-}"
if [ "$IS_CLOSED" = "true" ]; then
discord_archive_thread "$FINAL_THREAD_ID" true
discord_sync_thread "$FINAL_THREAD_ID" true "$APPLIED_TAGS"
else
discord_archive_thread "$FINAL_THREAD_ID" false
discord_sync_thread "$FINAL_THREAD_ID" false "$APPLIED_TAGS"
fi
15 changes: 9 additions & 6 deletions .github/workflows/discord-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
# automatically once this merges to the default branch.
command -v discord_applied_tags >/dev/null 2>&1 || discord_applied_tags() { printf '[]'; }
command -v extract_discord_thread >/dev/null 2>&1 || extract_discord_thread() { :; }
command -v discord_archive_thread >/dev/null 2>&1 || discord_archive_thread() { :; }
command -v discord_sync_thread >/dev/null 2>&1 || discord_sync_thread() { :; }

NUMBER="${{ github.event.issue.number }}"

Expand Down Expand Up @@ -229,14 +229,17 @@ jobs:
fi
fi

# ── Mirror closed/open state onto the forum thread (archive) ─────
# No-op unless DISCORD_GITHUB_BOT_TOKEN is set. Prefer the stored thread id,
# then the race winner's, then a freshly created one.
# ── Sync forum thread: archive flag + live tags in ONE PATCH ─────
# No-op unless DISCORD_GITHUB_BOT_TOKEN is set. Prefer the stored thread
# id, then the race winner's, then a freshly created one. archived +
# applied_tags are set together so re-tagging also works on reopen and
# on threads Discord auto-archived by inactivity (an applied_tags edit
# on an already-archived thread is rejected with 400).
FINAL_THREAD_ID="${DISCORD_THREAD_ID:-}"
[ -z "$FINAL_THREAD_ID" ] && FINAL_THREAD_ID="${WINNER_THREAD_ID:-}"
[ -z "$FINAL_THREAD_ID" ] && FINAL_THREAD_ID="${NEW_THREAD_ID:-}"
if [ "$STATE" = "open" ]; then
discord_archive_thread "$FINAL_THREAD_ID" false
discord_sync_thread "$FINAL_THREAD_ID" false "$APPLIED_TAGS"
else
discord_archive_thread "$FINAL_THREAD_ID" true
discord_sync_thread "$FINAL_THREAD_ID" true "$APPLIED_TAGS"
fi
15 changes: 9 additions & 6 deletions .github/workflows/discord-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
# automatically once this merges to the default branch.
command -v discord_applied_tags >/dev/null 2>&1 || discord_applied_tags() { printf '[]'; }
command -v extract_discord_thread >/dev/null 2>&1 || extract_discord_thread() { :; }
command -v discord_archive_thread >/dev/null 2>&1 || discord_archive_thread() { :; }
command -v discord_sync_thread >/dev/null 2>&1 || discord_sync_thread() { :; }

# ── Resolve PR number ────────────────────────────────────────────
if [ "$EVENT_NAME" = "pull_request" ] || [ "$EVENT_NAME" = "pull_request_target" ] || [ "$EVENT_NAME" = "pull_request_review" ]; then
Expand Down Expand Up @@ -331,14 +331,17 @@ jobs:
fi
fi

# ── Mirror closed/merged state onto the forum thread (archive) ───
# No-op unless DISCORD_GITHUB_BOT_TOKEN is set. Closed AND merged PRs both
# have PR_STATE=closed, so both archive; reopened PRs unarchive.
# ── Sync forum thread: archive flag + live tags in ONE PATCH ─────
# No-op unless DISCORD_GITHUB_BOT_TOKEN is set. Closed AND merged PRs
# both have PR_STATE=closed, so both archive; reopened PRs unarchive.
# archived + applied_tags are set together so re-tagging also works on
# reopen and on threads Discord auto-archived by inactivity (an
# applied_tags edit on an already-archived thread is rejected with 400).
FINAL_THREAD_ID="${DISCORD_THREAD_ID:-}"
[ -z "$FINAL_THREAD_ID" ] && FINAL_THREAD_ID="${WINNER_THREAD_ID:-}"
[ -z "$FINAL_THREAD_ID" ] && FINAL_THREAD_ID="${NEW_THREAD_ID:-}"
if [ "$PR_STATE" = "open" ]; then
discord_archive_thread "$FINAL_THREAD_ID" false
discord_sync_thread "$FINAL_THREAD_ID" false "$APPLIED_TAGS"
else
discord_archive_thread "$FINAL_THREAD_ID" true
discord_sync_thread "$FINAL_THREAD_ID" true "$APPLIED_TAGS"
fi
46 changes: 33 additions & 13 deletions .github/workflows/scripts/discord-helper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -150,21 +150,41 @@ discord_applied_tags() {
| .[0:5]'
}

# ── Forum thread archiving ───────────────────────────────────────────────
# discord_archive_thread <thread_id> <true|false> — archive/unarchive a forum
# thread so its Discord state mirrors the GitHub issue/PR/discussion (closed →
# archived, reopened → unarchived). Forum threads can only be (un)archived with
# a BOT token that has Manage Threads — webhooks cannot do it — so this is a
# no-op (returns 0) unless DISCORD_GITHUB_BOT_TOKEN is set and a thread id is known.
# Best-effort: archiving is cosmetic (the embed already reflects state), so a
# transient failure must never abort the calling workflow.
discord_archive_thread() {
local thread_id="$1" archived="$2"
# ── Forum thread sync (archive state + tags in one PATCH) ────────────────
# discord_sync_thread <thread_id> <archived:true|false> <applied_tags_json>
# — mirror the GitHub state onto the forum thread: set the archived flag AND
# re-apply applied_tags so tags track state/labels (open→closed→merged, label
# adds). Both are set in a SINGLE PATCH on purpose: Discord rejects an
# applied_tags edit on an already-archived thread (400), so setting tags and
# then (un)archiving in separate calls fails on reopen or on threads Discord
# auto-archived by inactivity. Combining them works from any state.
#
# Forum threads can only be edited with a BOT token that has Manage Threads/
# Posts — webhooks cannot — so this is a no-op unless DISCORD_GITHUB_BOT_TOKEN
# and a thread id are set. If <applied_tags_json> is empty ("" or "[]") only the
# archived flag is sent (an empty list means the channel has no tag config, so
# never clobber it to untagged). Best-effort: a transient failure never aborts
# the calling workflow (the embed already reflects state).
discord_sync_thread() {
local thread_id="$1" archived="$2" tags="$3" body
[ -z "${DISCORD_GITHUB_BOT_TOKEN:-}" ] && return 0
[ -z "$thread_id" ] && return 0
curl -sS -o /dev/null --connect-timeout 10 --max-time 30 -X PATCH \
if [ -z "$tags" ] || [ "$tags" = "[]" ]; then
body="{\"archived\": ${archived}}"
else
body="{\"archived\": ${archived}, \"applied_tags\": ${tags}}"
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
local status
status=$(curl -sS -o /dev/null -w '%{http_code}' --connect-timeout 10 --max-time 30 -X PATCH \
Comment thread
asclearuc marked this conversation as resolved.
Outdated
-H "Authorization: Bot ${DISCORD_GITHUB_BOT_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"archived\": ${archived}}" \
"https://discord.com/api/v10/channels/${thread_id}" || true
-d "$body" \
"https://discord.com/api/v10/channels/${thread_id}") || status=""
# Best-effort: never fail the job, but surface non-2xx (e.g. missing Manage
# Threads → 403, bad payload → 400) so it's diagnosable in the run log.
case "$status" in
2??) : ;;
*) echo "::warning::Discord thread sync returned '${status:-no response}' for thread ${thread_id} (archive/tags not applied)" >&2 ;;
esac
return 0
}
Loading