GitHub Actions concurrency for a Sume render job: the cancel trap
cancel-in-progress stops your workflow, not the Sume job it submitted. Group by branch, cancel via POST /v1/jobs/{id}/cancel in a final step, and cap the run.

Put the render job in a concurrency group keyed by branch, but know that cancel-in-progress: true only stops your workflow. The Sume job it already submitted keeps going unless a step calls POST /v1/jobs/{id}/cancel, and Sume accepts that cancel only before generation starts.
So the safe setup has three parts: a group, a deliberate choice about cancellation, and a step that records the job id so something can cancel it.
What GitHub's concurrency does
The concurrency docs (read 2026-10-10) say that only one run in a group runs at a time, and that while one is running only one other can be pending, so a newer pending run replaces the older pending one. cancel-in-progress: true instead cancels the running one. The workflow syntax reference (read 2026-10-10) adds a queue: max option, which lets up to 100 runs wait, and says that combining queue: max with cancel-in-progress is a validation error.
| Setting | Effect on the workflow | Effect on the Sume job |
|---|---|---|
| Default, no cancel | One run, one pending, older pending dropped | Each started run finishes its job |
| cancel-in-progress: true | Running workflow is stopped | Job keeps running unless you cancel it |
| queue: max | Up to 100 runs wait their turn | One render at a time, no duplicates |
A workflow that serializes renders
This file has a group per branch, no cancel-in-progress, a 30-minute workflow timeout, and a stable Idempotency-Key built from the run id. It submits and stores the job id as a step output. If you do enable cancellation, add a cleanup step that calls POST /v1/jobs/{id}/cancel with that output; check the step-condition rules in the workflow syntax reference for when such a step runs, and remember that Sume accepts the cancel only while generation has not started.
on: workflow_dispatch
concurrency:
group: sume-render-${{ github.ref }}
cancel-in-progress: false
jobs:
render:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
SUME_API_KEY: ${{ secrets.SUME_API_KEY }}
steps:
- id: submit
run: |
id=$(curl -sS https://api.sume.com/v1/image-1.0/generate \
-H "x-api-key: $SUME_API_KEY" \
-H "Idempotency-Key: ci-${{ github.run_id }}-1" \
-H "Content-Type: application/json" \
-d '{"prompt":"Matte bottle on marble","mode":"async"}' \
| jq -r '.data.job_id')
echo "job=$id" >> "$GITHUB_OUTPUT"
Choosing the group key
Group on what you want to serialize. github.ref serializes per branch, which is right for a preview render. A fixed string serializes the whole repository, which matches a small plan's concurrency limit but delays unrelated pull requests. Sume's own admission queue already absorbs bursts: a workspace at its concurrency limit can still accept jobs as queued while capacity remains, and fails with 429 queue_full only past it. That means the group key protects your budget and your queue, not Sume's servers.
Use the secret from repository secrets as shown, never echo it, and scope the key to what the job needs.
Sources
Related posts
More in Developers
- Go 1.27.2 and 1.26.9 patch net/http: update your Sume webhook receiver
Go 1.27.2 and 1.26.9 (2026-10-08) list security fixes in net/http and crypto/tls. A stdlib receiver for Sume webhooks that verifies the signature, in two files.
- Go errgroup SetLimit: submit Sume jobs within your concurrency budget
Cap in-flight Sume submissions in Go with errgroup.SetLimit, size the width from your concurrency limit, and keep one Idempotency-Key per item. 30 lines.
- Grok Image on Sume: one image per call, so fan out four in Python
x-ai/grok-image lists n as 1 to 1 in the Sume catalog. How to get four variants with four parallel calls, what it costs, and how to stay under queue limits.
- Grok Imagine ignores aspect_ratio on image-to-video; Sume rejects it
xAI says image-to-video output matches the input image and ignores aspect_ratio. Sume's Grok row goes further and rejects the field. Crop the still first.
Written by Sume