Automate with the API and CI
Keep recipes in your repository, next to the tests that use them, and let CI generate fresh data before the suite runs.
1. Create a key for the job
In Account → API keys, create a key for this pipeline only:
- Scopes:
generateandjobs:read— nothing else. - Valid for: as short as your rotation allows; at most 90 days.
- Credit limit: what the pipeline may spend in total. A runaway loop stops there instead of draining your balance.
Store it as a CI secret, for example GB_KEY. The key is shown once; if it leaks, revoke it and create another.
2. A reusable script
#!/usr/bin/env sh
# Usage: generate.sh recipe.yaml output-file
set -eu
API=https://api.ghostbakery.com
AUTH="Authorization: Bearer $GB_KEY"
job=$(curl -fsS "$API/api/v1/generate" -H "$AUTH" \
-H "Content-Type: application/x-yaml" --data-binary @"$1" | jq -r .job_id)
for _ in $(seq 120); do
status=$(curl -fsS "$API/api/v1/jobs/$job" -H "$AUTH" | jq -r .status)
case "$status" in
completed) curl -fsS "$API/api/v1/jobs/$job/download" -H "$AUTH" -o "$2"; exit 0 ;;
failed|expired) curl -fsS "$API/api/v1/jobs/$job" -H "$AUTH" | jq -r .error >&2; exit 1 ;;
esac
sleep 1
done
echo "timed out waiting for job $job" >&2; exit 1curl -f turns HTTP errors into a failed step. A recipe that does not validate returns 422 with every problem listed, so CI fails before spending anything.
3. Wire it into CI
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Generate fixtures
env:
GB_KEY: ${{ secrets.GB_KEY }}
run: sh scripts/generate.sh testdata/customers.yaml testdata/customers.csv
- name: Test
run: make testGood practice
- Assert invariants, not values. Every run draws new values. Check formats, uniqueness and relationships, not specific names.
- Generate once per pipeline. Hosted generation belongs in setup or integration stages; unit tests can read the file it produced.
- Download promptly. Results expire a while after the job completes.
- Check the cost as you grow.
POST /api/v1/estimatereturns the exact cost; put it in a pre-merge check when recipes change often. - Failures cost nothing. A job that fails is refunded, and the error is in the job status.
See the API reference for every endpoint and scope.