Slack shows a download card, not the report

You drag coverage/index.html into the channel. Slack posts a file card with a paperclip and a Download button. Nobody clicks it.

Why Slack refuses

Rendering uploaded HTML in-client means executing uploaded JavaScript inside a Slack origin, with a logged-in session attached to it. That is a stored-XSS surface aimed at everyone in the workspace, and no messaging product ships it. GitHub declines for the same reason, and so does every mail client.

So .html is an opaque file. For small ones you get the snippet view — escaped source, truncated. It is a way to read markup, not a way to read a report.

Why the download path is worse than it looks

The colleague who does click Download gets a file in ~/Downloads and opens it from file://, which is where the second wave of problems starts:

  • Relative asset references 404, so the report loses its styling — the five causes.
  • Reports that load results over XHR render blank outright: Allure, Playwright, several coverage UIs.
  • A single index.html pulled out of its directory was never going to work at all.

So the file that "was shared" often cannot be read by the person it was shared with, and neither of you finds out.

What actually gets read

Post a link. A published report unfurls in the channel with its title and description, opens in one click, and renders identically on a phone and a desktop.

The part that matters after the click: the discussion goes in the report. Someone selects the failing test, or the table cell with the suspicious number, and comments there. That thread stays anchored to that content across revisions — where a channel thread scrolls out of reach by Thursday and nobody can reconstruct which chart "this looks wrong" was about. See comment on HTML and share an HTML report in Slack.

Automating it

From CI, publish at the end of the job and post the URL:

- name: Publish and announce
  if: always()
  run: |
    curl -sS -X PATCH \
      "https://commareports.com/api/v1/reports/$COMMA_REPORT_ID" \
      -H "Authorization: Bearer $COMMA_API_TOKEN" \
      -H "Content-Type: application/json" \
      --data @<(jq -Rs '{html: .}' htmlcov/index.html)
    curl -sS -X POST "$SLACK_WEBHOOK_URL" \
      -H "Content-Type: application/json" \
      --data "{\"text\":\"Coverage for \`$GITHUB_SHA\`: https://commareports.com/p/$COMMA_REPORT_ID\"}"

Because the report id is stable, a pinned message keeps working — each run appends a revision at the same URL rather than creating a new link to re-pin. Setup in publish from CI.

Agents can do the same thing over MCP: an agent that just finished an analysis publishes it and hands back a link, rather than pasting three thousand tokens of markup into the channel — where should my agent post.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a report and post the link →

Related