Repository navigation
ci: workflow results → Discord #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| # Catch-all Discord reporter for EVERY workflow in this repo. | ||
| # | ||
| # Owner request 2026-08-20: all Actions (tests, e2e, canaries, deploys, | ||
| # terraform, agents) report to #ci_notifications. Triggered by workflow_run | ||
| # so individual workflows need NO edits; adding a NEW workflow = add its | ||
| # `name:` to the list below (workflow_run has no wildcard). | ||
| # | ||
| # Post rules: pull_request-event runs post only on FAILURE (green PRs stay | ||
| # quiet); push/schedule/dispatch runs post always; cancelled/superseded runs | ||
| # stay quiet. Per-job breakdown fetched via the API. Missing webhook secret → | ||
| # warning, never a red job. Runs from the DEFAULT branch. | ||
| name: Workflow results → Discord | ||
|
|
||
| on: | ||
| workflow_run: | ||
| types: [completed] | ||
| workflows: | ||
| - CI | ||
| - Release | ||
|
|
||
| jobs: | ||
| post: | ||
| name: Post to #ci_notifications | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| actions: read | ||
| contents: read | ||
| steps: | ||
| - name: Summarise the completed run and post | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| WEBHOOK: ${{ secrets.DISCORD_RELEASE_WEBHOOK }} | ||
| REPO: ${{ github.repository }} | ||
| RUN_ID: ${{ github.event.workflow_run.id }} | ||
| RUN_URL: ${{ github.event.workflow_run.html_url }} | ||
| WF_NAME: ${{ github.event.workflow_run.name }} | ||
| EVENT: ${{ github.event.workflow_run.event }} | ||
| BRANCH: ${{ github.event.workflow_run.head_branch }} | ||
| SHA: ${{ github.event.workflow_run.head_sha }} | ||
| CONCLUSION: ${{ github.event.workflow_run.conclusion }} | ||
| TITLE: ${{ github.event.workflow_run.display_title }} | ||
| run: | | ||
| set -uo pipefail | ||
| if [ "$CONCLUSION" = "cancelled" ] || [ "$CONCLUSION" = "skipped" ]; then | ||
| echo "Run $CONCLUSION — staying quiet." | ||
| exit 0 | ||
| fi | ||
| if { [ "$EVENT" = "pull_request" ] || [ "$EVENT" = "pull_request_target" ]; } && [ "$CONCLUSION" = "success" ]; then | ||
| echo "Green PR run — staying quiet." | ||
| exit 0 | ||
| fi | ||
| JOBS=$(gh api --paginate "repos/$REPO/actions/runs/$RUN_ID/jobs?per_page=100" \ | ||
| --jq '.jobs[] | [.name, (.conclusion // .status)] | @tsv') | ||
| LINES="" | ||
| while IFS=$'\t' read -r NAME RES; do | ||
| [ -z "$NAME" ] && continue | ||
| case "$RES" in | ||
| success) ICON="✅";; | ||
| skipped) ICON="⏭️";; | ||
| cancelled) ICON="⚪";; | ||
| failure) ICON="❌";; | ||
| *) ICON="❔";; | ||
| esac | ||
| LINES="$LINES"$'\n'"$ICON $NAME" | ||
| done <<< "$JOBS" | ||
| if [ "$CONCLUSION" = "success" ]; then HEAD="✅ **$WF_NAME passed**"; else HEAD="❌ **$WF_NAME $CONCLUSION**"; fi | ||
| case "$EVENT" in | ||
| schedule) CTX="nightly on $BRANCH";; | ||
| workflow_dispatch) CTX="manual on $BRANCH";; | ||
| pull_request*) CTX="PR — $TITLE";; | ||
| *) CTX="$EVENT on $BRANCH @ ${SHA:0:8}";; | ||
| esac | ||
| MSG=$(printf '%s · ide · %s%s\n%s' "$HEAD" "$CTX" "$LINES" "$RUN_URL") | ||
| echo "$MSG" | ||
| if [ -z "${WEBHOOK:-}" ]; then | ||
| echo "::warning::DISCORD_RELEASE_WEBHOOK not set — result not posted." | ||
| exit 0 | ||
| fi | ||
| jq -n --arg c "$MSG" '{content:$c, flags:4}' \ | ||
| | curl -sS -o /dev/null -w 'discord %{http_code}\n' -X POST -H 'Content-Type: application/json' -d @- "$WEBHOOK" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the webhook is expired, misconfigured, rate-limited, or rejects the payload, Discord can return an HTTP 4xx/5xx response while this Useful? React with 👍 / 👎. |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a failed run comes from a pull request,
MSGincludes the contributor-controlleddisplay_title; because this payload omitsallowed_mentions, a title containing@everyone,@here, or a Discord mention can trigger notifications in the channel. The existingflags:4only suppresses embeds, so setallowed_mentionsto an empty parse list before forwarding untrusted run metadata.Useful? React with 👍 / 👎.