Skip to content

Commit 88be832

Browse files
emranemranclaude
andcommitted
feat: skill asks for fal app+env, deploys, then runs Playwright
"test cloud" should actually test the user's current working tree, not whatever code happens to be deployed. Previously the skill documented running Playwright directly against scope-livepeer-emran, which could silently false-pass against a stale deploy. Three changes make this work: - Parametrize `deploy-staging.sh` on SCOPE_FAL_APP_NAME + SCOPE_FAL_ENV (+ optional SCOPE_FAL_AUTH), defaulted from .env.local. Also make it track its own HERE path so it works when called from any cwd. - Document both vars in .env.example, grouped into client-side and deploy-side sections. SCOPE_CLOUD_APP_ID stays — but we now note that the skill derives it from the app+env the user confirms at test time (fal's URL convention: main has no suffix, other envs get --<env>). - Rewrite the SKILL's "Running the Playwright test" section with an explicit flow: ask for app+env → sanity-check secrets → free port 8000 → deploy → start scope with derived URL → run Playwright. This is what agents should follow when a user says "test cloud". Also add `deploy-staging.sh` to the repo (it was previously an untracked per-user file); needed so any contributor following the skill can actually run the deploy step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: emranemran <emran.mah@gmail.com>
1 parent 48909aa commit 88be832

3 files changed

Lines changed: 138 additions & 9 deletions

File tree

.agents/skills/testing-livepeer-fal-deploy/SKILL.md

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,71 @@ Do **not** use this skill for local-only livepeer testing — that's
7878

7979
## Running the Playwright test (primary)
8080

81+
When the user says "test cloud" (or any trigger in the description),
82+
**always deploy their current working tree before running Playwright**.
83+
Otherwise the test runs against whatever stale code was last deployed
84+
and can false-positive on their change.
85+
86+
### Step 0 — Ask the user where to deploy
87+
88+
Before anything else, confirm the deploy target. Use AskUserQuestion
89+
(or plain text prompts) and persist answers for the session:
90+
91+
1. **Fal app name** — required. If `SCOPE_FAL_APP_NAME` is set in
92+
`.env.local`, show that value and ask the user to confirm or
93+
override. Otherwise ask outright (e.g. `scope-livepeer-<name>`).
94+
2. **Fal env** — defaults to `main`. If `SCOPE_FAL_ENV` is set in
95+
`.env.local`, show and offer to override. Non-default envs (e.g.
96+
`preview`) change the URL suffix in `SCOPE_CLOUD_APP_ID` — see
97+
below.
98+
99+
Once confirmed, export both for the current shell, and derive /
100+
overwrite `SCOPE_CLOUD_APP_ID`:
101+
102+
| Env | `SCOPE_CLOUD_APP_ID` |
103+
|---|---|
104+
| `main` | `daydream/<app>/ws` (no suffix) |
105+
| anything else | `daydream/<app>--<env>/ws` (with suffix) |
106+
107+
This is a fal convention — the default `main` env is exposed without
108+
a suffix; all other envs include `--<env>` in the URL. Getting this
109+
wrong produces `did not receive ready message from websocket`.
110+
111+
### Step 1 — Sanity-check `.env.local`
112+
113+
- `SCOPE_CLOUD_API_KEY` must be set (otherwise:
114+
`discover_orchestrators requires discovery_url or signer_url`)
115+
- `SCOPE_USER_ID` must be set (otherwise the runner's
116+
`validate_user_access` rejects with `ACCESS_DENIED`)
117+
118+
If either is missing, stop and ask the user before deploying.
119+
120+
### Step 2 — Kill any scope already on :8000
121+
122+
If another scope process is bound to the port, stop it (or ask the
123+
user) before continuing. The run-app.sh the script starts must be the
124+
one under test.
125+
126+
### Step 3 — Deploy
127+
128+
```bash
129+
SCOPE_FAL_APP_NAME=<app> SCOPE_FAL_ENV=<env> ./deploy-staging.sh
130+
```
131+
132+
Abort with a clear error if this fails — don't run Playwright against
133+
stale deployed code. Common failure: the `{git-short-sha}-cloud`
134+
Docker base image isn't built yet (CI for the current commit is still
135+
running). If that's the case, either wait for CI or have the user
136+
confirm they want to deploy against an older base image.
137+
138+
### Step 4 — Start scope and run Playwright
139+
81140
```bash
82141
# Terminal 1 — scope (port 8000)
83-
./run-app.sh
142+
SCOPE_CLOUD_APP_ID=<derived-url> ./run-app.sh
84143

85144
# Terminal 2 — test
86-
cd e2e
87-
npx playwright test
145+
cd e2e && npx playwright test
88146
```
89147

90148
Expected on success (≤5 min cold, ~20 s warm):

.env.example

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# Copy this file to `.env.local` (gitignored) and fill in real values.
2-
# Used by run-app.sh and test-cloud-connect.sh.
2+
# Used by run-app.sh, deploy-staging.sh, and test-cloud-connect.sh.
33

4-
# Required — fal app ID for your livepeer deployment.
4+
# --- Client-side (the local scope process) ---
5+
6+
# Required — fal app URL for your livepeer deployment.
57
# Format: daydream/<app-name>/ws (no --main suffix for the default env;
6-
# for non-default envs the URL includes the env, e.g. --preview/ws)
8+
# for non-default envs the URL includes the env, e.g. --preview/ws).
9+
# This MUST match SCOPE_FAL_APP_NAME + SCOPE_FAL_ENV below — the skill
10+
# derives it for you when it asks which app + env to test against.
711
export SCOPE_CLOUD_APP_ID=daydream/<your-app>/ws
812

913
# Required — daydream cloud API key (used to auth with signer.daydream.live).
@@ -14,7 +18,23 @@ export SCOPE_CLOUD_API_KEY=sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1418
# ~/.daydream-scope/logs/scope-logs-*.log after a UI-driven connect.
1519
export SCOPE_USER_ID=user_xxxxxxxxxxxxxxxxxxxxxxxxx
1620

17-
# Optional — enable DEBUG logs from livepeer_gateway so per-orchestrator
18-
# rejection reasons appear in scope.log (e.g. "ACCESS_DENIED",
19-
# "did not receive ready message from websocket").
21+
# --- Deploy-side (what deploy-staging.sh pushes to) ---
22+
23+
# Optional default app name for deploy-staging.sh. If unset, the skill
24+
# asks the user. Example: scope-livepeer-<your-name>
25+
export SCOPE_FAL_APP_NAME=scope-livepeer-<your-name>
26+
27+
# Optional default env for deploy-staging.sh. Defaults to "main". For
28+
# non-default envs remember that the URL in SCOPE_CLOUD_APP_ID includes
29+
# a --<env> suffix (e.g. "daydream/scope-livepeer-foo--preview/ws").
30+
# export SCOPE_FAL_ENV=main
31+
32+
# Optional — auth mode for the fal deploy. Defaults to "public".
33+
# export SCOPE_FAL_AUTH=public
34+
35+
# --- Optional ---
36+
37+
# Enable DEBUG logs from livepeer_gateway so per-orchestrator rejection
38+
# reasons appear in scope.log (e.g. "ACCESS_DENIED", "did not receive
39+
# ready message from websocket").
2040
# export LIVEPEER_DEBUG=1

deploy-staging.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
# Deploy the Livepeer fal wrapper to a fal.ai app.
3+
#
4+
# Reads from env (typically sourced from .env.local):
5+
# SCOPE_FAL_APP_NAME required, e.g. "scope-livepeer-emran"
6+
# SCOPE_FAL_ENV optional, defaults to "main"
7+
# SCOPE_FAL_AUTH optional, defaults to "public"
8+
#
9+
# Exits non-zero on any failure so callers can fail fast.
10+
11+
set -euo pipefail
12+
13+
HERE="$(cd "$(dirname "$0")" && pwd)"
14+
15+
if [ -f "$HERE/.env.local" ]; then
16+
# shellcheck disable=SC1091
17+
source "$HERE/.env.local"
18+
fi
19+
20+
: "${SCOPE_FAL_APP_NAME:?Set SCOPE_FAL_APP_NAME in .env.local (see .env.example). Example: scope-livepeer-<your-name>}"
21+
SCOPE_FAL_ENV="${SCOPE_FAL_ENV:-main}"
22+
SCOPE_FAL_AUTH="${SCOPE_FAL_AUTH:-public}"
23+
24+
VENV_DIR="$HERE/.venv-fal"
25+
26+
# Ensure a Python 3.12 venv for fal (matches the scope image).
27+
if [ ! -d "$VENV_DIR" ]; then
28+
echo "Creating Python 3.12 venv at $VENV_DIR..."
29+
uv venv --python 3.12 "$VENV_DIR"
30+
fi
31+
32+
if ! "$VENV_DIR/bin/python" -c "import fal" &>/dev/null; then
33+
echo "Installing fal..."
34+
uv pip install --python "$VENV_DIR/bin/python" fal
35+
fi
36+
37+
if ! "$VENV_DIR/bin/fal" auth whoami &>/dev/null; then
38+
echo "Not logged in to fal. Running 'fal auth login' (interactive)..."
39+
"$VENV_DIR/bin/fal" auth login
40+
fi
41+
42+
echo "Deploying src/scope/cloud/livepeer_fal_app.py"
43+
echo " → app: $SCOPE_FAL_APP_NAME"
44+
echo " → env: $SCOPE_FAL_ENV"
45+
echo " → auth: $SCOPE_FAL_AUTH"
46+
47+
"$VENV_DIR/bin/fal" deploy \
48+
"$HERE/src/scope/cloud/livepeer_fal_app.py" \
49+
--app "$SCOPE_FAL_APP_NAME" \
50+
--auth "$SCOPE_FAL_AUTH" \
51+
--env "$SCOPE_FAL_ENV"

0 commit comments

Comments
 (0)