GITHUB_STEP_SUMMARY for Sume jobs: an audit table in the run page

Write the Sume job id, status and artifact URL to GITHUB_STEP_SUMMARY: 1 MiB per step, 20 step summaries shown per job. Public URLs only, no prompts or keys.

4 min readSume
All posts

A step can append Markdown to $GITHUB_STEP_SUMMARY, and GitHub shows it on the workflow run page. For a Sume job, write one table row with the job id, final status and artifact URL. GitHub allows 1 MiB per step and shows at most 20 step summaries per job, so a table of ids and links is tiny compared with the limit.

What GitHub documents

From GitHub's workflow commands reference:

GITHUB_STEP_SUMMARY facts (GitHub Docs, read 2026-10-05)
TopicGitHub says
Size1 MiB per step
ShownA maximum of 20 step summaries per job
FormatGitHub flavored Markdown: headings, lists, tables
WritingAppend with >> in Bash
SecretsSecrets are masked

A step that submits, waits and summarizes

The step below starts a Music Router job, polls until the job envelope says terminal, reads the audio artifact from the result, and appends the table. The Music Router charges a fixed $0.125 per generation. request_id in the submit response is the job id. The Idempotency-Key uses run_id, which does not change on a re-run, so a re-run reuses the same job instead of paying twice.

- name: Generate a bed and summarize
  env:
    SUME_API_KEY: ${{ secrets.SUME_API_KEY }}
  run: |
    H="Authorization: Bearer $SUME_API_KEY"
    job=$(curl -fsS -X POST https://api.sume.com/v1/music-router/generate \
      -H "$H" -H "Content-Type: application/json" \
      -H "Idempotency-Key: gh-${{ github.run_id }}-bed" \
      -d '{"prompt":"Warm lo-fi bed, 84 BPM, C minor. A 30-second track. Instrumental, no vocals."}' \
      | jq -r .request_id)
    until [ "$(curl -fsS https://api.sume.com/v1/jobs/$job/status -H "$H" | jq -r .terminal)" = true ]; do
      sleep 10
    done
    url=$(curl -fsS https://api.sume.com/v1/jobs/$job/result -H "$H" \
      | jq -r '[.result.artifacts[]? | select(.type=="audio")][0].url // "none"')
    {
      echo "### Sume music job"
      echo "| job | audio |"
      echo "|---|---|"
      echo "| $job | $url |"
    } >> "$GITHUB_STEP_SUMMARY"

What belongs in the summary

Summaries are readable by anyone who can read the run. Write the job id, the status, the model that ran (job.request.routed_model on a router job) and the artifact URL. Leave out prompts that you consider private. GitHub masks secrets that it knows about, but it cannot know that a brief for an unreleased campaign is sensitive.

The job id is the useful part. GitHub keeps run logs for a limited time, and the id lets you read the job later from the Sume API or dashboard, long after the run page is gone.

Limits

Twenty summaries per job is a cap on steps, not on rows: put all jobs of a matrix leg in one step. A job that fails still needs a summary line, so write the table in a final step with if: always() that reads a small file the earlier steps appended. A loop that polls for ever burns runner minutes: add a step timeout and, if the job is still not terminal, record its id and exit. Never submit the paid request again just because the wait ended.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume