ci(frontend-deploy): name what is being deployed - #8431
talissoncosta wants to merge 2 commits into
Conversation
The cards identified a deploy by short sha, which says nothing about what is in it. Adds the pull request title under the headline, linked to the pull request. No API call is needed. A squash merge puts the title and number in the first line of the commit message, as "title (#123)", and all of the last forty commits on main match that. A direct push or a merge commit will not, so the number is optional and the title falls back to the whole line unlinked. The title goes full width as a context line rather than into the field grid, which is two narrow columns and would wrap a real title badly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 3 Skipped Deployments
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8431 +/- ##
========================================
Coverage 98.81% 98.82%
========================================
Files 1621 1622 +1
Lines 66118 66727 +609
========================================
+ Hits 65334 65942 +608
- Misses 784 785 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
📝 WalkthroughWalkthroughThe notification action now accepts repository and commit-message inputs. It derives a pull-request title and URL from the first commit-message line. The Slack payload conditionally displays the escaped title as a link or plain text. Both production deployment notification jobs provide the new inputs. Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: 🟡 Moderate · up to Long commit subjects can suppress deployment notifications, and commit-title text can create unintended Slack links. Bound the title and disable automatic parsing before merging. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Docker builds report
|
✅ private-cloud · depot-ubuntu-latest-16 — run #20400 (attempt 1)Playwright Test Results (private-cloud - depot-ubuntu-latest-16)Details
🗂️ Previous results✅ private-cloud · depot-ubuntu-latest-arm-16 — run #20400 (attempt 1)Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)Details
✅ oss · depot-ubuntu-latest-arm-16 — run #20400 (attempt 1)Playwright Test Results (oss - depot-ubuntu-latest-arm-16)Details
✅ oss · depot-ubuntu-latest-16 — run #20400 (attempt 1)Playwright Test Results (oss - depot-ubuntu-latest-16)Details
✅ private-cloud · depot-ubuntu-latest-arm-16 — run #20355 (attempt 1)Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)Details
✅ private-cloud · depot-ubuntu-latest-16 — run #20355 (attempt 1)Playwright Test Results (private-cloud - depot-ubuntu-latest-16)Details
✅ oss · depot-ubuntu-latest-arm-16 — run #20355 (attempt 1)Playwright Test Results (oss - depot-ubuntu-latest-arm-16)Details
✅ oss · depot-ubuntu-latest-16 — run #20355 (attempt 1)Playwright Test Results (oss - depot-ubuntu-latest-16)Details
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Advanced
Run ID: 6ca7e52f-1f9f-4d93-9a26-c6f410cedb40
📒 Files selected for processing (3)
.github/actions/notify-slack-deploy/action.yml.github/actions/notify-slack-deploy/payload.jq.github/workflows/frontend-deploy-production.yml
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.
Visual Regression19 screenshots compared. See report for details. |
The title comes from the deployed commit subject, so it is the only free-form string in the card. A pull request titled "<!channel> ship it" would have pinged the whole channel on merge, and "<url|text>" would have rendered as a disguised link. Escapes the three characters Slack parses, ampersand first so the entities the other two produce are not re-encoded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Advanced
Run ID: 4fc8ad10-98e4-40e9-9c81-dbd55da672bf
📒 Files selected for processing (1)
.github/actions/notify-slack-deploy/payload.jq
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.
| [{ type: "context", elements: [{ type: "mrkdwn", text: ($title | mrkdwn) }] }] | ||
| else | ||
| [{ type: "context", elements: [{ type: "mrkdwn", text: "<\($pr_url)|\($title | mrkdwn)>" }] }] |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🤖 get_repo_knowledge executed:
get_repo_knowledge Flagsmith/flagsmith /tmp/coderabbit-repo-knowledge/flagsmith-flagsmith-a74d157a/conventions /tmp/coderabbit-repo-knowledge/flagsmith-flagsmith-a74d157a/learnings
Length of output: 6518
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- payload.jq ---'
cat -n .github/actions/notify-slack-deploy/payload.jq
printf '%s\n' '--- action references ---'
rg -n -C 4 'notify-slack-deploy|payload\.jq|repo_url|pr_number|title' .github/actions .github/workflowsRepository: Flagsmith/flagsmith
Length of output: 18587
🌐 Web query:
site:api.slack.com/reference/block-kit/composition-objects/text-object mrkdwn 3000 characters incoming webhook invalid_blocks
💡 Result:
Slack’s documentation confirms:
- A
mrkdwntext object must contain 1–3,000 characters. Exceeding that limit can cause an incoming webhook request to fail with aninvalid_blocks-style validation error. [1] - For a
sectionblock, thetextobject also has a 3,000-character maximum. [2] - Incoming webhooks accept Block Kit payloads and return HTTP 400 errors for malformed requests. [3]
Example fix:
const chunks = text.match(/[\s\S]{1,3000}/g) || [];
const payload = {
blocks: chunks.map(chunk => ({
type: "section",
text: {
type: "mrkdwn",
text: chunk
}
}))
};Also validate the serialized text content, escape &, <, and > where appropriate, and ensure each block is valid JSON. [4]
Sources
[1] (api.slack.com)
[2] (api.slack.com)
[3] (api.slack.com)
[4] (api.slack.com)
Citations:
- 1: https://api.slack.com/reference/block-kit/composition-objects?utm_source=openai
- 2: https://api.slack.com/reference/block-kit/blocks?utm_source=openai
- 3: https://api.slack.com/messaging/webhooks?utm_source=openai
- 4: https://api.slack.com/docs/message-attachments?utm_source=openai
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- action contract and webhook handling ---'
cat -n .github/actions/notify-slack-deploy/action.yml | sed -n '1,135p'
printf '%s\n' '--- commit-message constraints in the relevant workflows ---'
rg -n -C 5 'commit_message:|github\.event\.head_commit\.message|head_commit|commit message|subject' .github/workflows/frontend-deploy-production.yml .github/actions/notify-slack-deploy .github | head -220Repository: Flagsmith/flagsmith
Length of output: 16886
Bound the complete context text to Slack’s 3,000-character limit.
The context mrkdwn text includes the escaped $title and, when $pr_url is set, the link syntax. $title has no length limit, and escaping can increase its length. A long commit title can therefore make Slack reject the payload and remove the notification. Limit the complete rendered value to 3,000 characters without splitting an entity, while reserving space for the pull-request URL and link delimiters. The notification step already uses continue-on-error, so deployment continues but the notification is lost.
Source: MCP tools
🔒 Security & Privacy | 🛡️ Analyzed with Security Review | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
site:api.slack.com/reference/block-kit/composition-objects/text-object verbatim explicit mrkdwn links
💡 Result:
Slack Text objects support two formats:
type: "plain_text"— unformatted text; supports the optionalemojifield.type: "mrkdwn"— Slack’s Markdown-like syntax; supports bold, italics, strikethrough, line breaks, and links. [1][2]
For mrkdwn, links can be written as:
{
"type": "mrkdwn",
"text": "Visit <https://example.com|our website>."
}The optional verbatim field controls automatic parsing:
verbatim: false(default): Slack auto-links URLs, channel names, and certain mentions.verbatim: true: Slack preserves plain text as written, while still processing Markdown and explicit parsing strings. [1]
Example:
{
"type": "mrkdwn",
"verbatim": true,
"text": "Literal `#channel` and https://example.com"
}Here, the URL and channel reference are not automatically converted; use explicit syntax such as <https://example.com|Example> when you want a link. [1][2]
Sources
[1] Slack Text object reference (api.slack.com)
[2] Slack message formatting guide (api.slack.com)
Citations:
- 1: https://api.slack.com/reference/block-kit/composition-objects?utm_source=openai
- 2: https://api.slack.com/messaging/composing/formatting?utm_source=openai
Reachability: External
Exploitability: Moderate
CWE: CWE-116 — Improper Encoding or Escaping of Output
Disable automatic URL parsing for the title.
A commit title can contain a URL and reach this Slack notification. Set verbatim: true on both title mrkdwn objects. Slack will still process the explicit pull-request link.
Suggested fix
- [{ type: "context", elements: [{ type: "mrkdwn", text: ($title | mrkdwn) }] }]
+ [{ type: "context", elements: [{ type: "mrkdwn", verbatim: true, text: ($title | mrkdwn) }] }]
...
- [{ type: "context", elements: [{ type: "mrkdwn", text: "<\($pr_url)|\($title | mrkdwn)>" }] }]
+ [{ type: "context", elements: [{ type: "mrkdwn", verbatim: true, text: "<\($pr_url)|\($title | mrkdwn)>" }] }]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| [{ type: "context", elements: [{ type: "mrkdwn", text: ($title | mrkdwn) }] }] | |
| else | |
| [{ type: "context", elements: [{ type: "mrkdwn", text: "<\($pr_url)|\($title | mrkdwn)>" }] }] | |
| [{ type: "context", elements: [{ type: "mrkdwn", verbatim: true, text: ($title | mrkdwn) }] }] | |
| else | |
| [{ type: "context", elements: [{ type: "mrkdwn", verbatim: true, text: "<\($pr_url)|\($title | mrkdwn)>" }] }] |
Source: MCP tools
Thanks for submitting a PR! Please check the boxes below:
docs/if required so people know about the feature.Changes
The deploy cards identify a deploy by short sha, which tells you nothing about what is in it. This adds the pull request title under the headline, linked to the pull request.
No API call and no extra permission. A squash merge puts the title and number in the first line of the commit message as
title (#123), and all forty of the last forty commits onmainmatch that shape. A direct push or a merge commit will not, so the number is optional: the title then falls back to the whole first line, unlinked, rather than producing a broken link.The title goes full width as a
contextblock rather than into the field grid, which is two narrow columns and would wrap a real title badly.Deploying
Deployed
How did you test this code?
The parsing, against five commit message shapes:
refactor(styles): diff view and code theme on shared tokens (#8069)/pull/8069chore: a direct push with no pull request/pull/8420fix: mentions (#123) mid-sentence and ends plainlyThat last case is why the pattern is anchored to the end of the line.
The rendering, across all four states with and without a title, confirming the
contextblock appears only when there is one and the block order is otherwise unchanged:Both files parse as YAML. Not exercised end to end, since this workflow only runs on push to
main. The steps arecontinue-on-error: true, so nothing here can hold up or fail a deploy.