Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,89 @@ jobs:
echo " Numbered-variant class-name churn is expected; the semantic"
echo " alias tests and drift-version-pin test guard the real surface."
fi

storyboard:
name: AdCP storyboard runner — examples/seller_agent.py
runs-on: ubuntu-latest
# Non-blocking until seller-agent content gaps in #304 are resolved.
# Promote to required once overall_status: passing and controller_detected: true.
continue-on-error: true

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Set up Node 22
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Start seller agent
run: |
ADCP_PORT=3001 python examples/seller_agent.py &
AGENT_PID=$!
for i in $(seq 1 60); do
# Any HTTP response (including 405 on GET to a POST-only endpoint)
# means the server is up and accepting connections.
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 1 \
http://127.0.0.1:3001/mcp 2>/dev/null || echo "000")
if [ "$HTTP_CODE" != "000" ]; then
echo "Seller agent ready (HTTP ${HTTP_CODE}, pid ${AGENT_PID})"
break
fi
if ! kill -0 "$AGENT_PID" 2>/dev/null; then
echo "Seller agent process died during startup"
exit 1
fi
if [ "$i" -eq 60 ]; then
echo "Seller agent failed to start within 30s"
kill "$AGENT_PID" 2>/dev/null || true
exit 1
fi
sleep 0.5
done

- name: Run storyboard suite
timeout-minutes: 5
# @adcp/client@latest is intentionally unpinned — this is AdCP's own CI
# running AdCP's own canonical runner. Tracking latest surfaces protocol
# drift as soon as it ships, which is the point of this job.
run: |
npx -y -p @adcp/client@latest adcp storyboard run \
http://127.0.0.1:3001/mcp media_buy_seller \
--json --allow-http \
> storyboard-result.json

- name: Assert pass
run: |
python -c "
import json, sys, pathlib
p = pathlib.Path('storyboard-result.json')
if not p.exists() or p.stat().st_size == 0:
print('storyboard-result.json missing or empty — runner produced no output')
sys.exit(1)
with p.open() as f:
d = json.load(f)
if d.get('overall_status') != 'passing':
print(json.dumps(d, indent=2))
sys.exit(1)
if not d.get('controller_detected'):
print('controller_detected was false; check DemoStore overrides (see #304)')
sys.exit(1)
"

- if: always()
uses: actions/upload-artifact@v4
with:
name: storyboard-result-${{ github.run_attempt }}
path: storyboard-result.json
if-no-files-found: warn
Loading