Skip to content

Notify #gh-wallet-eng when a new issue is opened - #972

Merged
JakeUrban merged 7 commits into
mainfrom
claude/slack-external-issue-notifications-d3wuc6
Aug 12, 2026
Merged

Notify #gh-wallet-eng when a new issue is opened#972
JakeUrban merged 7 commits into
mainfrom
claude/slack-external-issue-notifications-d3wuc6

Conversation

@JakeUrban

@JakeUrban JakeUrban commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

What

Adds .github/workflows/notify-slack-new-issue.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 opened only — not close, reopen, or edit — and notifies for every new issue regardless of who filed it. A companion workflow is added in stellar/freighter (stellar/freighter#2951).

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 because 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

  • Posts via slackapi/slack-github-action, pinned by commit SHA. It is a Node action, so the pin covers the code that executes.
  • The payload is built with jq --arg and passed via payload-file-path, so no value is interpolated into YAML or JSON syntax.
  • The issue title is untrusted input, so it goes into a Block Kit plain_text object. 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_ISSUES secret on this repo, holding an incoming webhook bound to #gh-wallet-eng. This must exist before merge or the job fails. It is deliberately separate from stellar/freighter's SLACK_WEBHOOK, 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-eng correctly, 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

  • Every new issue notifies, including issues opened by the team.

Checklist

PR structure

  • This PR does not mix refactoring changes with feature changes (break it down into smaller PRs if not).
  • This PR has reasonably narrow scope (break it down into smaller PRs if not).
  • This PR includes relevant before and after screenshots/videos highlighting these changes. — N/A, CI-only change with no UI surface.
  • I took the time to review my own PR.

Testing

  • These changes have been tested and confirmed to work as intended on Android. — N/A, CI-only change; does not touch app code.
  • These changes have been tested and confirmed to work as intended on iOS. — N/A, as above.
  • These changes have been tested and confirmed to work as intended on small iOS screens. — N/A, as above.
  • These changes have been tested and confirmed to work as intended on small Android screens. — N/A, as above.
  • I have tried to break these changes while extensively testing them. — Payload build and Slack delivery verified against the real webhook, including a title containing Slack link markup.
  • This PR adds tests for the new functionality or fixes. — N/A, no test harness for workflow files in this repo.

Release

  • This is not a breaking change.
  • This PR updates existing JSDocs when applicable. — N/A, no source changes.
  • This PR adds JSDocs to new functionalities. — N/A, no source changes.
  • I've checked with the product team if we should add metrics to these changes. — N/A, internal tooling.
  • I've shared relevant before and after screenshots/videos highlighting these changes with the design team and they've approved the changes. — N/A, no design surface.

claude added 2 commits August 10, 2026 22:13
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.

This repo had no Slack workflows previously, so the SLACK_WEBHOOK secret
needs to resolve here — see the note in the workflow header.

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 traffic to #gh-wallet-eng.

Point this workflow at its own SLACK_WEBHOOK_GH_ISSUES secret, holding a
webhook bound to #gh-wallet-eng. This repo has no other Slack workflows,
so this is the only Slack secret it needs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ka8rvrCJEKLroVskzayvo
Copilot AI balanced review requested due to automatic review settings August 10, 2026 22:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds issue-opened notifications for the #gh-wallet-eng Slack channel.

Changes:

  • Adds an issues: opened workflow.
  • Formats issue details for Slack.
  • Uses a repository webhook secret.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +51 to +54
SLACK_MESSAGE:
"<${{ github.event.issue.html_url }}|#${{ github.event.issue.number
}}: ${{ github.event.issue.title }}> — opened by ${{
github.event.issue.user.login }}"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid finding — fixed in e417c70.

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.

I kept the title rather than omitting it — it's the most useful part of the notification, and plain_text makes it safe to include structurally rather than by remembering to escape.

The plain_text title is deliberately not entity-escaped, since plain_text is not mrkdwn and &lt; 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

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not applicable — the premise doesn't hold for this workspace, and the setting is gone regardless.

SLACK_USERNAME/SLACK_ICON demonstrably do take effect on the webhook these workflows use. A current release notification in #release posts as Freighter Administrative Assistant (B09QQ8J4CKU) with the configured identity, from the same rtCamp + SLACK_USERNAME setup this PR was copied from:

Freighter v5.44.0 has been submitted to app stores for review!

So the general rule about app-model incoming webhooks ignoring payload identity overrides isn't what's happening here. Worth noting it's also the same comment that introduced the app-model premise two threads earlier, without checking it.

That said, e417c70 replaces the rtCamp action with slackapi/slack-github-action, so SLACK_USERNAME/SLACK_ICON no longer exist in this file. Message identity now comes from the Slack app the webhook belongs to, which is the behaviour you described — so this resolves either way.


Generated by Claude Code

runs-on: ubuntu-latest
steps:
- name: Slack Notification
uses: rtCamp/action-slack-notify@07cbdbfd6c6190970778d8f98f11d073b2932aae #v2.3.3

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed and fixed in e417c70.

I checked action.yml at the pinned SHA. The framing is slightly off — it's using: composite, not a Docker action — but the substance is right: it shells out to docker://ghcr.io/rtcamp/action-slack-notify:v2.3.3, a mutable tag, so the SHA pin did not pin the code that actually executes.

Replaced with slackapi/slack-github-action, pinned to dcb1066f776dd043e64d0e8ba94ca15cc7e1875d (v4.0.0). That action is runs: using: node24 — a plain JavaScript action with no container indirection — so the SHA pin covers the executed code. It's also first-party Slack rather than a third party.

Worth recording for anyone reading this later: the same gap exists in the five rtCamp Slack steps in stellar/freighter. Those are triggered by our own release process rather than by untrusted input, so they're lower priority, but migrating them is a reasonable follow-up.


Generated by Claude Code

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

iOS Simulator preview build is ready: https://github.com/stellar/freighter-mobile/releases/tag/untagged-18a738158491912057aa (SDF collaborators only — install instructions in the release description)

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 avoids introducing a supply-chain gap to this repo: rtCamp's
action is a composite that runs docker://ghcr.io/rtcamp/action-slack-notify
at a mutable tag, so a SHA pin would not have pinned 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
@JakeUrban JakeUrban self-assigned this Aug 11, 2026
claude added 2 commits August 11, 2026 23:16
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ka8rvrCJEKLroVskzayvo
@JakeUrban
JakeUrban merged commit 9e521c9 into main Aug 12, 2026
26 of 35 checks passed
@JakeUrban
JakeUrban deleted the claude/slack-external-issue-notifications-d3wuc6 branch August 12, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants