build(cli): post release notes and binary status to Slack - #1428
build(cli): post release notes and binary status to Slack#1428Chase J (chajac) wants to merge 4 commits into
Conversation
WalkthroughThe change adds Slack mrkdwn conversion, release-note grouping, release payload validation, binary status formatting, and a Bun CLI. The release workflow posts a publish announcement, exports its Slack timestamp, and updates the message after binary builds with uploaded or missing asset status. Tests cover formatting, validation, payload construction, truncation, and binary reporting. Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant ReleaseWorkflow
participant slackReleaseMessage
participant Slack
participant BinaryBuilds
ReleaseWorkflow->>slackReleaseMessage: generate publish payload
slackReleaseMessage->>Slack: post release announcement
Slack-->>ReleaseWorkflow: return message timestamp
BinaryBuilds-->>ReleaseWorkflow: provide release assets
ReleaseWorkflow->>slackReleaseMessage: generate binary status payload
slackReleaseMessage->>Slack: update release announcement
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Around line 80-84: Add explicit curl timeouts to both Slack API calls,
`chat.postMessage` and `chat.update`, by applying `--connect-timeout` and/or
`--max-time` in their shared request options. Keep the existing request
payloads, headers, and response validation unchanged while ensuring unresponsive
Slack requests terminate promptly.
- Around line 121-134: Add continue-on-error: true to the “Update release
message with binary status” workflow step, matching the existing Slack publish
notification step so failures from chat.update or jq do not fail the release
workflow.
In `@scripts/slackMrkdwn.ts`:
- Around line 32-50: Extract the existing Slack mrkdwn escaping logic from
toMrkdwn into a reusable escapeMrkdwn helper, then apply it to each group title
in splitReleaseNotes before returning the mapped groups. Preserve the current
fixed groupTitles mappings and continue using toMrkdwn for group.text.
In `@scripts/slackReleaseBlocks.ts`:
- Around line 5-12: Add an automated validation for the expectedBinaries list
that compares its asset/label entries against the release matrix defined in
.github/workflows/release-binaries.yml, and fail clearly when targets are added,
removed, or changed so binariesLine cannot silently become stale.
In `@scripts/slackReleaseMessage.ts`:
- Around line 13-29: Add a colocated Bun test file for the CLI validation
surrounding parseArgs and the phase/channel/ts checks. Exercise missing --phase,
missing --channel, and binaries without --ts by spawning the script with
Bun.spawn or testing an extracted exported validator, and assert each case exits
unsuccessfully with the expected stderr usage/error message.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0f4d8d5a-1c09-4b42-8fa7-23b83696c9dd
📒 Files selected for processing (6)
.github/workflows/release.ymlscripts/slackMrkdwn.test.tsscripts/slackMrkdwn.tsscripts/slackReleaseBlocks.test.tsscripts/slackReleaseBlocks.tsscripts/slackReleaseMessage.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/slackMrkdwn.ts`:
- Line 51: Update the title mapping logic in scripts/slackMrkdwn.ts to use
groupTitles only when it owns the requested heading key, preventing inherited
keys such as toString or __proto__ from reaching escapeMrkdwn as non-string
values. Preserve undefined for unmapped headings, and add a regression test
covering a prototype-like heading.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: b9c2dc59-f542-4248-811f-b62f1f491a72
📒 Files selected for processing (5)
.github/workflows/release.ymlscripts/slackMrkdwn.test.tsscripts/slackMrkdwn.tsscripts/slackReleaseBlocks.test.tsscripts/slackReleaseBlocks.ts
Note
PR body AI drafted & edited as needed
Overview of Changes
Releases currently announce themselves nowhere, the changesets action publishes to npm and creates the GitHub Release, but anyone following deployments has to poll the repo. The binaries matrix also runs with
fail-fast: false, so a partially failed binary set is invisible unless someone opens the workflow run.This adds a two-phase Slack notification driven entirely from
release.yml, no hosted service, no incoming webhook.scripts/slackReleaseMessage.ts: CLI entry — takesgh release view --json body,url,tagName[,assets]on stdin plus--phase publish|binaries --channel [--ts], prints achat.postMessage/chat.updatepayload. Dependency free by design so the notify jobs skipbun install.scripts/slackMrkdwn.ts: converts changeset markdown to Slack mrkdwn (bold/link/bullet translation, escaping) and splits notes into per-group blocks (✨ Minor changes/🩹 Patch changes). Strips changesets' commit-hash bullet prefixes — noise in Slack; the GitHub-release link covers provenance.scripts/slackReleaseBlocks.ts: validates the release JSON and assembles the Block Kit layout, including the binaries line —⏳ Binaries building…at publish, per-target ✅/❌ on update. Sections are clamped under Slack's 3000-char limit.release.yml: aNotify Slack of releasestep (gated onpublished == 'true',continue-on-errorso a Slack outage can never fail a release) exports the messagets; anotify-binariesjob (needs: [release, binaries],if: always()to report partial failures) updates the message in place. Binary status comes from diffing the release's uploaded assets against the five expected targets — matrix jobs share one output namespace, so assets are the reliable per-leg ground truth, and they also catch upload failures.Testing
bun run test bun run typecheck bun run lint bun run format:check bun run knipslackMrkdwn.test.ts/slackReleaseBlocks.test.ts: mrkdwn conversion (escaping, hash stripping, dedent-vs-sub-bullet indent), change-group splitting, payload shape for both phases, ✅/❌ rendering against partial asset lists, 3000-char truncation,tsomitted from the publish payload.v1.4.0release with the live bot token and channel: message posted with release notes and ⏳ line, then updated in place to five ✅s viachat.update. Both API calls returnedok: true.Checklist