Notify #gh-wallet-eng when a new issue is opened - #2951
Conversation
Posts to #gh-wallet-eng whenever an issue is opened. Fires on `opened` only, which the GitHub Slack app's `issues` subscription cannot express (it always covers opened + closed + reopened). Notifies for every new issue for now; the workflow comments document the `author_association` filter to add if the channel becomes too noisy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ka8rvrCJEKLroVskzayvo
A Slack-app incoming webhook is bound to the channel it was installed against and ignores the channel in the payload, so SLACK_CHANNEL alone cannot redirect release-workflow traffic to #gh-wallet-eng. Point this workflow at its own SLACK_WEBHOOK_GH_ISSUES secret, holding a webhook bound to #gh-wallet-eng, leaving SLACK_WEBHOOK untouched for the release workflows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ka8rvrCJEKLroVskzayvo
|
PR Preview build is ready: https://github.com/stellar/freighter/releases/tag/untagged-c974b109609ed4705559 (SDF collaborators only — install instructions in the release description) |
There was a problem hiding this comment.
Pull request overview
Adds Slack notifications to #gh-wallet-eng whenever an issue is opened.
Changes:
- Adds an issue-opened GitHub Actions workflow.
- Sends issue details through a dedicated Slack webhook.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| steps: | ||
| - name: Slack Notification | ||
| uses: rtCamp/action-slack-notify@07cbdbfd6c6190970778d8f98f11d073b2932aae #v2.3.3 | ||
| env: | ||
| MSG_MINIMAL: true | ||
| SLACK_CHANNEL: gh-wallet-eng | ||
| SLACK_COLOR: "#70E1C8" | ||
| SLACK_ICON: https://github.com/stellar/freighter/blob/master/docs/static/images/logo.png?size=48 | ||
| SLACK_MESSAGE: | ||
| "<${{ github.event.issue.html_url }}|#${{ github.event.issue.number | ||
| }}: ${{ github.event.issue.title }}> — opened by ${{ | ||
| github.event.issue.user.login }}" |
There was a problem hiding this comment.
Valid finding — fixed in ea37105.
The step no longer builds a mrkdwn string at all. The title now goes into a Block Kit plain_text object, which Slack does not parse as mrkdwn, so link and mention syntax renders literally rather than being interpreted. The payload is built with jq --arg and handed over via payload-file-path, so untrusted text is never interpolated into YAML or JSON syntax either.
The plain_text title is deliberately not entity-escaped, since plain_text is not mrkdwn and < would render as the literal characters. The escaping is applied to the top-level text fallback instead, which is used for push notifications and is parsed — & first, so the entities introduced aren't re-escaped.
Verified against a hostile title (pwn> <!channel> <https://evil.example|Reset your Freighter key> & "quotes"): output is valid JSON, the fallback is correctly escaped, and the plain_text block carries the title verbatim.
Generated by Claude Code
Addresses review feedback on the notification step. Issue titles are attacker-controlled, and the previous SLACK_MESSAGE put the title inside Slack's <url|label> syntax unescaped. A title could terminate the link and inject an arbitrary hyperlink into the channel. Switch to slackapi/slack-github-action and put the title in a Block Kit plain_text object, which Slack does not parse as mrkdwn, so link and mention syntax renders literally. The payload is built with `jq --arg` and passed as a file, so untrusted text is never interpolated into YAML or JSON syntax. The top-level fallback text, which IS parsed as mrkdwn, escapes &, < and > instead. This also closes a supply-chain gap: rtCamp's action is a composite that runs docker://ghcr.io/rtcamp/action-slack-notify at a mutable tag, so the SHA pin did not pin the executed code. slackapi's action is node24, so the SHA pin covers what actually runs. Drop the unused repository token permissions while here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ka8rvrCJEKLroVskzayvo
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ka8rvrCJEKLroVskzayvo
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ka8rvrCJEKLroVskzayvo
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ka8rvrCJEKLroVskzayvo
What
Adds
.github/workflows/notifySlackNewIssue.yml. Whenever an issue is opened in this repo, it posts a message to #gh-wallet-eng with the issue number, title, author, and a link.Triggers on
openedonly — not close, reopen, or edit — and notifies for every new issue regardless of who filed it. A companion workflow is added instellar/freighter-mobile(stellar/freighter-mobile#972).Why
New issues should surface in Slack without anyone having to watch GitHub notifications.
This is a workflow rather than the GitHub Slack app's
/github subscribe <repo> issuesbecause that feature notifies on opened, closed, and reopened events with no filtering by event type or author. Under it, triaging an issue re-notifies the channel.How it works
slackapi/slack-github-action, pinned by commit SHA. It is a Node action, so the pin covers the code that executes.jq --argand passed viapayload-file-path, so no value is interpolated into YAML or JSON syntax.plain_textobject. Slack does not parse that as mrkdwn, so link and mention syntax in a title renders literally rather than taking effect. The fallback text, which is mrkdwn-parsed, escapes&,<, and>.permissions: {}— the job does not use the repository token.Requirements
A
SLACK_WEBHOOK_GH_ISSUESsecret holding an incoming webhook bound to#gh-wallet-eng. This must exist before merge or the job fails. It is deliberately separate from theSLACK_WEBHOOKused by the release workflows, so a workflow driven by untrusted input does not share that webhook.Verification
The payload build and Slack delivery were exercised against the real secret on a branch build, using the same jq program and action pin as this workflow. The message posted to
#gh-wallet-engcorrectly, with markup in the title rendered as literal text rather than an active link.The
issues: [opened]trigger itself is not exercised until this reaches the default branch, since GitHub runs event-triggered workflows only from there.Limitations