mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:50:44 +00:00
659 lines
24 KiB
YAML
659 lines
24 KiB
YAML
name: OpenClaw Live And E2E Checks (Reusable)
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
ref:
|
|
description: Ref, tag, or SHA to validate
|
|
required: true
|
|
default: main
|
|
type: string
|
|
include_repo_e2e:
|
|
description: Whether to run pnpm test:e2e plus repo-specific extra E2E lanes
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
include_release_path_suites:
|
|
description: Whether to run the Docker release-path suites
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
include_openwebui:
|
|
description: Whether to run the Open WebUI Docker smoke
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
include_live_suites:
|
|
description: Whether to run live-provider coverage
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
workflow_call:
|
|
inputs:
|
|
ref:
|
|
description: Ref, tag, or SHA to validate
|
|
required: true
|
|
type: string
|
|
include_repo_e2e:
|
|
description: Whether to run pnpm test:e2e
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
include_release_path_suites:
|
|
description: Whether to run the Docker release-path suites
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
include_openwebui:
|
|
description: Whether to run the Open WebUI Docker smoke
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
include_live_suites:
|
|
description: Whether to run live-provider coverage
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
secrets:
|
|
OPENAI_API_KEY:
|
|
required: false
|
|
OPENAI_BASE_URL:
|
|
required: false
|
|
ANTHROPIC_API_KEY:
|
|
required: false
|
|
ANTHROPIC_API_KEY_OLD:
|
|
required: false
|
|
ANTHROPIC_API_TOKEN:
|
|
required: false
|
|
BYTEPLUS_API_KEY:
|
|
required: false
|
|
CEREBRAS_API_KEY:
|
|
required: false
|
|
DASHSCOPE_API_KEY:
|
|
required: false
|
|
GROQ_API_KEY:
|
|
required: false
|
|
KIMI_API_KEY:
|
|
required: false
|
|
MODELSTUDIO_API_KEY:
|
|
required: false
|
|
MOONSHOT_API_KEY:
|
|
required: false
|
|
MISTRAL_API_KEY:
|
|
required: false
|
|
MINIMAX_API_KEY:
|
|
required: false
|
|
OPENCODE_API_KEY:
|
|
required: false
|
|
OPENCODE_ZEN_API_KEY:
|
|
required: false
|
|
OPENCLAW_LIVE_BROWSER_CDP_URL:
|
|
required: false
|
|
OPENCLAW_LIVE_SETUP_TOKEN:
|
|
required: false
|
|
OPENCLAW_LIVE_SETUP_TOKEN_MODEL:
|
|
required: false
|
|
OPENCLAW_LIVE_SETUP_TOKEN_PROFILE:
|
|
required: false
|
|
OPENCLAW_LIVE_SETUP_TOKEN_VALUE:
|
|
required: false
|
|
GEMINI_API_KEY:
|
|
required: false
|
|
GOOGLE_API_KEY:
|
|
required: false
|
|
OPENROUTER_API_KEY:
|
|
required: false
|
|
QWEN_API_KEY:
|
|
required: false
|
|
FAL_KEY:
|
|
required: false
|
|
RUNWAY_API_KEY:
|
|
required: false
|
|
DEEPGRAM_API_KEY:
|
|
required: false
|
|
TOGETHER_API_KEY:
|
|
required: false
|
|
VYDRA_API_KEY:
|
|
required: false
|
|
XAI_API_KEY:
|
|
required: false
|
|
ZAI_API_KEY:
|
|
required: false
|
|
Z_AI_API_KEY:
|
|
required: false
|
|
BYTEPLUS_ACCESS_KEY_ID:
|
|
required: false
|
|
BYTEPLUS_SECRET_ACCESS_KEY:
|
|
required: false
|
|
CLAUDE_CODE_OAUTH_TOKEN:
|
|
required: false
|
|
OPENCLAW_CODEX_AUTH_JSON:
|
|
required: false
|
|
OPENCLAW_CODEX_CONFIG_TOML:
|
|
required: false
|
|
OPENCLAW_CLAUDE_JSON:
|
|
required: false
|
|
OPENCLAW_CLAUDE_CREDENTIALS_JSON:
|
|
required: false
|
|
OPENCLAW_CLAUDE_SETTINGS_JSON:
|
|
required: false
|
|
OPENCLAW_CLAUDE_SETTINGS_LOCAL_JSON:
|
|
required: false
|
|
OPENCLAW_GEMINI_SETTINGS_JSON:
|
|
required: false
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: read
|
|
|
|
env:
|
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
|
NODE_VERSION: "24.x"
|
|
PNPM_VERSION: "10.32.1"
|
|
|
|
jobs:
|
|
validate_selected_ref:
|
|
runs-on: blacksmith-8vcpu-ubuntu-2404
|
|
outputs:
|
|
selected_sha: ${{ steps.validate.outputs.selected_sha }}
|
|
trusted_reason: ${{ steps.validate.outputs.trusted_reason }}
|
|
steps:
|
|
- name: Checkout selected ref
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ inputs.ref }}
|
|
fetch-depth: 0
|
|
|
|
- name: Validate selected ref
|
|
id: validate
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
INPUT_REF: ${{ inputs.ref }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
selected_sha="$(git rev-parse HEAD)"
|
|
trusted_reason=""
|
|
|
|
git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main
|
|
|
|
if git merge-base --is-ancestor "$selected_sha" refs/remotes/origin/main; then
|
|
trusted_reason="main-ancestor"
|
|
elif git tag --points-at "$selected_sha" | grep -Eq '^v'; then
|
|
trusted_reason="release-tag"
|
|
else
|
|
pr_head_count="$(
|
|
gh api \
|
|
-H "Accept: application/vnd.github+json" \
|
|
"repos/${GITHUB_REPOSITORY}/commits/${selected_sha}/pulls" \
|
|
--jq '[.[] | select(.state == "open" and .head.repo.full_name == "'"${GITHUB_REPOSITORY}"'" and .head.sha == "'"${selected_sha}"'")] | length'
|
|
)"
|
|
if [[ "$pr_head_count" != "0" ]]; then
|
|
trusted_reason="open-pr-head"
|
|
fi
|
|
fi
|
|
|
|
if [[ -z "$trusted_reason" ]]; then
|
|
echo "Ref '${INPUT_REF}' resolved to $selected_sha, which is not trusted for secret-bearing live/E2E checks." >&2
|
|
echo "Allowed refs must be on main, point to a release tag, or match an open PR head in ${GITHUB_REPOSITORY}." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "selected_sha=$selected_sha" >> "$GITHUB_OUTPUT"
|
|
echo "trusted_reason=$trusted_reason" >> "$GITHUB_OUTPUT"
|
|
{
|
|
echo "Validated ref: \`${INPUT_REF}\`"
|
|
echo "Resolved SHA: \`$selected_sha\`"
|
|
echo "Trust reason: \`$trusted_reason\`"
|
|
} >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
validate_release_live_cache:
|
|
needs: validate_selected_ref
|
|
if: inputs.include_live_suites
|
|
runs-on: blacksmith-32vcpu-ubuntu-2404
|
|
timeout-minutes: 60
|
|
env:
|
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
OPENCLAW_LIVE_CACHE_TEST: "1"
|
|
OPENCLAW_LIVE_TEST: "1"
|
|
steps:
|
|
- name: Checkout selected ref
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node environment
|
|
uses: ./.github/actions/setup-node-env
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
pnpm-version: ${{ env.PNPM_VERSION }}
|
|
install-bun: "true"
|
|
|
|
- name: Validate live cache credentials
|
|
run: |
|
|
set -euo pipefail
|
|
if [[ -z "${OPENAI_API_KEY:-}" ]]; then
|
|
echo "Missing OPENAI_API_KEY secret for live-cache validation." >&2
|
|
exit 1
|
|
fi
|
|
if [[ -z "${ANTHROPIC_API_KEY:-}" ]]; then
|
|
echo "Missing ANTHROPIC_API_KEY secret for live-cache validation." >&2
|
|
exit 1
|
|
fi
|
|
|
|
- name: Verify live prompt cache floors
|
|
run: pnpm test:live:cache
|
|
|
|
validate_repo_e2e:
|
|
needs: validate_selected_ref
|
|
if: inputs.include_repo_e2e
|
|
runs-on: blacksmith-32vcpu-ubuntu-2404
|
|
timeout-minutes: 90
|
|
env:
|
|
OPENCLAW_VITEST_MAX_WORKERS: "2"
|
|
steps:
|
|
- name: Checkout selected ref
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node environment
|
|
uses: ./.github/actions/setup-node-env
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
pnpm-version: ${{ env.PNPM_VERSION }}
|
|
install-bun: "true"
|
|
|
|
- name: Build dist for repo E2E
|
|
run: pnpm build
|
|
|
|
- name: Run repo E2E suite
|
|
run: pnpm test:e2e
|
|
|
|
validate_special_e2e:
|
|
needs: validate_selected_ref
|
|
if: inputs.include_repo_e2e || inputs.include_live_suites
|
|
runs-on: blacksmith-32vcpu-ubuntu-2404
|
|
timeout-minutes: ${{ matrix.timeout_minutes }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- suite_id: openshell-e2e
|
|
label: OpenShell repo E2E
|
|
command: pnpm test:e2e:openshell
|
|
timeout_minutes: 120
|
|
requires_repo_e2e: true
|
|
requires_live_suites: false
|
|
- suite_id: openai-ws-stream-live-e2e
|
|
label: OpenAI WebSocket live E2E
|
|
command: pnpm test:e2e -- src/agents/openai-ws-stream.e2e.test.ts
|
|
timeout_minutes: 90
|
|
requires_repo_e2e: false
|
|
requires_live_suites: true
|
|
env:
|
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
OPENCLAW_E2E_WORKERS: "1"
|
|
OPENCLAW_VITEST_MAX_WORKERS: "1"
|
|
steps:
|
|
- name: Checkout selected ref
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node environment
|
|
uses: ./.github/actions/setup-node-env
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
pnpm-version: ${{ env.PNPM_VERSION }}
|
|
install-bun: "true"
|
|
|
|
- name: Build dist for special E2E
|
|
if: |
|
|
(inputs.include_repo_e2e && matrix.requires_repo_e2e) ||
|
|
(inputs.include_live_suites && matrix.requires_live_suites)
|
|
run: pnpm build
|
|
|
|
- name: Configure suite-specific env
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
case "${{ matrix.suite_id }}" in
|
|
openai-ws-stream-live-e2e)
|
|
echo "OPENAI_LIVE_TEST=1" >> "$GITHUB_ENV"
|
|
echo "OPENCLAW_LIVE_TEST=1" >> "$GITHUB_ENV"
|
|
;;
|
|
esac
|
|
|
|
- name: Validate suite credentials
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
case "${{ matrix.suite_id }}" in
|
|
openai-ws-stream-live-e2e)
|
|
[[ -n "${OPENAI_API_KEY:-}" ]] || {
|
|
echo "OPENAI_API_KEY is required for the OpenAI WebSocket live E2E suite." >&2
|
|
exit 1
|
|
}
|
|
;;
|
|
esac
|
|
|
|
- name: Run ${{ matrix.label }}
|
|
if: |
|
|
(inputs.include_repo_e2e && matrix.requires_repo_e2e) ||
|
|
(inputs.include_live_suites && matrix.requires_live_suites)
|
|
run: ${{ matrix.command }}
|
|
|
|
validate_docker_e2e:
|
|
needs: validate_selected_ref
|
|
if: inputs.include_release_path_suites || inputs.include_openwebui
|
|
runs-on: blacksmith-32vcpu-ubuntu-2404
|
|
timeout-minutes: ${{ matrix.timeout_minutes }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- suite_id: docker-onboard
|
|
label: Onboarding Docker E2E
|
|
command: pnpm test:docker:onboard
|
|
timeout_minutes: 60
|
|
release_path: true
|
|
openwebui_only: false
|
|
- suite_id: docker-gateway-network
|
|
label: Gateway Network Docker E2E
|
|
command: pnpm test:docker:gateway-network
|
|
timeout_minutes: 60
|
|
release_path: true
|
|
openwebui_only: false
|
|
- suite_id: docker-mcp-channels
|
|
label: MCP Channels Docker E2E
|
|
command: pnpm test:docker:mcp-channels
|
|
timeout_minutes: 60
|
|
release_path: true
|
|
openwebui_only: false
|
|
- suite_id: docker-plugins
|
|
label: Plugins Docker E2E
|
|
command: pnpm test:docker:plugins
|
|
timeout_minutes: 75
|
|
release_path: true
|
|
openwebui_only: false
|
|
- suite_id: docker-doctor-switch
|
|
label: Doctor Install Switch Docker E2E
|
|
command: pnpm test:docker:doctor-switch
|
|
timeout_minutes: 60
|
|
release_path: true
|
|
openwebui_only: false
|
|
- suite_id: docker-qr
|
|
label: QR Import Docker E2E
|
|
command: pnpm test:docker:qr
|
|
timeout_minutes: 60
|
|
release_path: true
|
|
openwebui_only: false
|
|
- suite_id: docker-install-e2e
|
|
label: Installer Docker E2E
|
|
command: pnpm test:install:e2e
|
|
timeout_minutes: 120
|
|
release_path: true
|
|
openwebui_only: false
|
|
- suite_id: docker-openwebui
|
|
label: Open WebUI Docker E2E
|
|
command: pnpm test:docker:openwebui
|
|
timeout_minutes: 75
|
|
release_path: false
|
|
openwebui_only: true
|
|
env:
|
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
|
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
|
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
|
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
|
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
|
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
|
|
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
|
|
KIMI_API_KEY: ${{ secrets.KIMI_API_KEY }}
|
|
MODELSTUDIO_API_KEY: ${{ secrets.MODELSTUDIO_API_KEY }}
|
|
MOONSHOT_API_KEY: ${{ secrets.MOONSHOT_API_KEY }}
|
|
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
|
|
MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
|
|
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
|
OPENCODE_ZEN_API_KEY: ${{ secrets.OPENCODE_ZEN_API_KEY }}
|
|
OPENCLAW_LIVE_BROWSER_CDP_URL: ${{ secrets.OPENCLAW_LIVE_BROWSER_CDP_URL }}
|
|
OPENCLAW_LIVE_SETUP_TOKEN: ${{ secrets.OPENCLAW_LIVE_SETUP_TOKEN }}
|
|
OPENCLAW_LIVE_SETUP_TOKEN_MODEL: ${{ secrets.OPENCLAW_LIVE_SETUP_TOKEN_MODEL }}
|
|
OPENCLAW_LIVE_SETUP_TOKEN_PROFILE: ${{ secrets.OPENCLAW_LIVE_SETUP_TOKEN_PROFILE }}
|
|
OPENCLAW_LIVE_SETUP_TOKEN_VALUE: ${{ secrets.OPENCLAW_LIVE_SETUP_TOKEN_VALUE }}
|
|
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
|
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
|
|
QWEN_API_KEY: ${{ secrets.QWEN_API_KEY }}
|
|
FAL_KEY: ${{ secrets.FAL_KEY }}
|
|
RUNWAY_API_KEY: ${{ secrets.RUNWAY_API_KEY }}
|
|
DEEPGRAM_API_KEY: ${{ secrets.DEEPGRAM_API_KEY }}
|
|
TOGETHER_API_KEY: ${{ secrets.TOGETHER_API_KEY }}
|
|
VYDRA_API_KEY: ${{ secrets.VYDRA_API_KEY }}
|
|
XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
|
|
ZAI_API_KEY: ${{ secrets.ZAI_API_KEY }}
|
|
Z_AI_API_KEY: ${{ secrets.Z_AI_API_KEY }}
|
|
BYTEPLUS_ACCESS_KEY_ID: ${{ secrets.BYTEPLUS_ACCESS_KEY_ID }}
|
|
BYTEPLUS_SECRET_ACCESS_KEY: ${{ secrets.BYTEPLUS_SECRET_ACCESS_KEY }}
|
|
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
OPENCLAW_CODEX_AUTH_JSON: ${{ secrets.OPENCLAW_CODEX_AUTH_JSON }}
|
|
OPENCLAW_CODEX_CONFIG_TOML: ${{ secrets.OPENCLAW_CODEX_CONFIG_TOML }}
|
|
OPENCLAW_CLAUDE_JSON: ${{ secrets.OPENCLAW_CLAUDE_JSON }}
|
|
OPENCLAW_CLAUDE_CREDENTIALS_JSON: ${{ secrets.OPENCLAW_CLAUDE_CREDENTIALS_JSON }}
|
|
OPENCLAW_CLAUDE_SETTINGS_JSON: ${{ secrets.OPENCLAW_CLAUDE_SETTINGS_JSON }}
|
|
OPENCLAW_CLAUDE_SETTINGS_LOCAL_JSON: ${{ secrets.OPENCLAW_CLAUDE_SETTINGS_LOCAL_JSON }}
|
|
OPENCLAW_GEMINI_SETTINGS_JSON: ${{ secrets.OPENCLAW_GEMINI_SETTINGS_JSON }}
|
|
steps:
|
|
- name: Checkout selected ref
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node environment
|
|
uses: ./.github/actions/setup-node-env
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
pnpm-version: ${{ env.PNPM_VERSION }}
|
|
install-bun: "true"
|
|
|
|
- name: Hydrate live auth/profile inputs
|
|
run: bash scripts/ci-hydrate-live-auth.sh
|
|
|
|
- name: Configure suite-specific env
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
case "${{ matrix.suite_id }}" in
|
|
docker-install-e2e)
|
|
echo "OPENCLAW_E2E_MODELS=both" >> "$GITHUB_ENV"
|
|
;;
|
|
esac
|
|
|
|
- name: Validate suite credentials
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
case "${{ matrix.suite_id }}" in
|
|
docker-install-e2e)
|
|
[[ -n "${OPENAI_API_KEY:-}" ]] || {
|
|
echo "OPENAI_API_KEY is required for installer Docker E2E." >&2
|
|
exit 1
|
|
}
|
|
if [[ -z "${ANTHROPIC_API_TOKEN:-}" && -z "${ANTHROPIC_API_KEY:-}" ]]; then
|
|
echo "ANTHROPIC_API_TOKEN or ANTHROPIC_API_KEY is required for installer Docker E2E." >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
docker-openwebui)
|
|
[[ -n "${OPENAI_API_KEY:-}" ]] || {
|
|
echo "OPENAI_API_KEY is required for the Open WebUI Docker smoke." >&2
|
|
exit 1
|
|
}
|
|
;;
|
|
esac
|
|
|
|
- name: Run ${{ matrix.label }}
|
|
if: |
|
|
(inputs.include_release_path_suites && matrix.release_path) ||
|
|
(inputs.include_openwebui && matrix.openwebui_only)
|
|
run: ${{ matrix.command }}
|
|
|
|
validate_live_provider_suites:
|
|
needs: validate_selected_ref
|
|
if: inputs.include_live_suites
|
|
runs-on: blacksmith-32vcpu-ubuntu-2404
|
|
timeout-minutes: ${{ matrix.timeout_minutes }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- suite_id: live-all
|
|
label: pnpm test:live
|
|
command: pnpm test:live
|
|
timeout_minutes: 180
|
|
profile_env_only: false
|
|
- suite_id: live-models-docker
|
|
label: Docker live models
|
|
command: pnpm test:docker:live-models
|
|
timeout_minutes: 120
|
|
profile_env_only: false
|
|
- suite_id: live-gateway-docker
|
|
label: Docker live gateway
|
|
command: pnpm test:docker:live-gateway
|
|
timeout_minutes: 120
|
|
profile_env_only: false
|
|
- suite_id: live-cli-backend-docker
|
|
label: Docker live CLI backend
|
|
command: pnpm test:docker:live-cli-backend
|
|
timeout_minutes: 120
|
|
profile_env_only: false
|
|
- suite_id: live-acp-bind-docker
|
|
label: Docker live ACP bind
|
|
command: pnpm test:docker:live-acp-bind
|
|
timeout_minutes: 120
|
|
profile_env_only: false
|
|
- suite_id: live-codex-harness-docker
|
|
label: Docker live Codex harness
|
|
command: pnpm test:docker:live-codex-harness
|
|
timeout_minutes: 120
|
|
profile_env_only: false
|
|
env:
|
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
|
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
|
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
|
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
|
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
|
DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
|
|
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
|
|
KIMI_API_KEY: ${{ secrets.KIMI_API_KEY }}
|
|
MODELSTUDIO_API_KEY: ${{ secrets.MODELSTUDIO_API_KEY }}
|
|
MOONSHOT_API_KEY: ${{ secrets.MOONSHOT_API_KEY }}
|
|
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
|
|
MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
|
|
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
|
OPENCODE_ZEN_API_KEY: ${{ secrets.OPENCODE_ZEN_API_KEY }}
|
|
OPENCLAW_LIVE_BROWSER_CDP_URL: ${{ secrets.OPENCLAW_LIVE_BROWSER_CDP_URL }}
|
|
OPENCLAW_LIVE_SETUP_TOKEN: ${{ secrets.OPENCLAW_LIVE_SETUP_TOKEN }}
|
|
OPENCLAW_LIVE_SETUP_TOKEN_MODEL: ${{ secrets.OPENCLAW_LIVE_SETUP_TOKEN_MODEL }}
|
|
OPENCLAW_LIVE_SETUP_TOKEN_PROFILE: ${{ secrets.OPENCLAW_LIVE_SETUP_TOKEN_PROFILE }}
|
|
OPENCLAW_LIVE_SETUP_TOKEN_VALUE: ${{ secrets.OPENCLAW_LIVE_SETUP_TOKEN_VALUE }}
|
|
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
|
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
|
|
QWEN_API_KEY: ${{ secrets.QWEN_API_KEY }}
|
|
FAL_KEY: ${{ secrets.FAL_KEY }}
|
|
RUNWAY_API_KEY: ${{ secrets.RUNWAY_API_KEY }}
|
|
DEEPGRAM_API_KEY: ${{ secrets.DEEPGRAM_API_KEY }}
|
|
TOGETHER_API_KEY: ${{ secrets.TOGETHER_API_KEY }}
|
|
VYDRA_API_KEY: ${{ secrets.VYDRA_API_KEY }}
|
|
XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
|
|
ZAI_API_KEY: ${{ secrets.ZAI_API_KEY }}
|
|
Z_AI_API_KEY: ${{ secrets.Z_AI_API_KEY }}
|
|
BYTEPLUS_ACCESS_KEY_ID: ${{ secrets.BYTEPLUS_ACCESS_KEY_ID }}
|
|
BYTEPLUS_SECRET_ACCESS_KEY: ${{ secrets.BYTEPLUS_SECRET_ACCESS_KEY }}
|
|
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
OPENCLAW_CODEX_AUTH_JSON: ${{ secrets.OPENCLAW_CODEX_AUTH_JSON }}
|
|
OPENCLAW_CODEX_CONFIG_TOML: ${{ secrets.OPENCLAW_CODEX_CONFIG_TOML }}
|
|
OPENCLAW_CLAUDE_JSON: ${{ secrets.OPENCLAW_CLAUDE_JSON }}
|
|
OPENCLAW_CLAUDE_CREDENTIALS_JSON: ${{ secrets.OPENCLAW_CLAUDE_CREDENTIALS_JSON }}
|
|
OPENCLAW_CLAUDE_SETTINGS_JSON: ${{ secrets.OPENCLAW_CLAUDE_SETTINGS_JSON }}
|
|
OPENCLAW_CLAUDE_SETTINGS_LOCAL_JSON: ${{ secrets.OPENCLAW_CLAUDE_SETTINGS_LOCAL_JSON }}
|
|
OPENCLAW_GEMINI_SETTINGS_JSON: ${{ secrets.OPENCLAW_GEMINI_SETTINGS_JSON }}
|
|
OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS: ""
|
|
OPENCLAW_LIVE_VYDRA_VIDEO: "1"
|
|
OPENCLAW_VITEST_MAX_WORKERS: "2"
|
|
steps:
|
|
- name: Checkout selected ref
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ needs.validate_selected_ref.outputs.selected_sha }}
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node environment
|
|
uses: ./.github/actions/setup-node-env
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
pnpm-version: ${{ env.PNPM_VERSION }}
|
|
install-bun: "true"
|
|
|
|
- name: Hydrate live auth/profile inputs
|
|
run: bash scripts/ci-hydrate-live-auth.sh
|
|
|
|
- name: Configure suite-specific env
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
if [[ "${{ matrix.profile_env_only }}" == "true" ]]; then
|
|
echo "OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1" >> "$GITHUB_ENV"
|
|
fi
|
|
case "${{ matrix.suite_id }}" in
|
|
live-cli-backend-docker)
|
|
echo "OPENCLAW_LIVE_CLI_BACKEND_MODEL=codex-cli/gpt-5.4" >> "$GITHUB_ENV"
|
|
# The CLI backend Docker lane should exercise the same staged
|
|
# Codex auth path Peter uses locally so MCP cron creation and
|
|
# multimodal probes stay covered in CI. Replace the staged
|
|
# config.toml with a minimal CI-safe config so the repo stays
|
|
# trusted for MCP/tool use without inheriting maintainer-local
|
|
# provider/profile overrides that do not exist inside CI.
|
|
# Codex's workspace-write sandbox relies on user namespaces that
|
|
# this Docker lane does not provide, so run Codex unsandboxed
|
|
# inside the already-isolated container to keep MCP cron/tool
|
|
# execution representative instead of failing on nested sandbox
|
|
# setup.
|
|
echo 'OPENCLAW_LIVE_CLI_BACKEND_CLEAR_ENV=["OPENAI_API_KEY","OPENAI_BASE_URL"]' >> "$GITHUB_ENV"
|
|
echo 'OPENCLAW_LIVE_CLI_BACKEND_ARGS=["exec","--json","--color","never","--sandbox","danger-full-access","--skip-git-repo-check"]' >> "$GITHUB_ENV"
|
|
echo 'OPENCLAW_LIVE_CLI_BACKEND_RESUME_ARGS=["exec","resume","{sessionId}","-c","sandbox_mode=\"danger-full-access\"","--skip-git-repo-check"]' >> "$GITHUB_ENV"
|
|
echo "OPENCLAW_LIVE_CLI_BACKEND_DEBUG=1" >> "$GITHUB_ENV"
|
|
echo "OPENCLAW_CLI_BACKEND_LOG_OUTPUT=1" >> "$GITHUB_ENV"
|
|
echo "OPENCLAW_LIVE_CLI_BACKEND_USE_CI_SAFE_CODEX_CONFIG=1" >> "$GITHUB_ENV"
|
|
;;
|
|
live-codex-harness-docker)
|
|
# Keep CI on the API-key path for now. The staged Codex auth secret
|
|
# is currently stale, but the wrapper still supports codex-auth for
|
|
# local maintainer reruns without changing Peter's flow.
|
|
echo "OPENCLAW_LIVE_CODEX_HARNESS_AUTH=api-key" >> "$GITHUB_ENV"
|
|
;;
|
|
live-acp-bind-docker)
|
|
if [[ -n "${GEMINI_API_KEY:-}" || -n "${GOOGLE_API_KEY:-}" ]]; then
|
|
echo "OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini" >> "$GITHUB_ENV"
|
|
else
|
|
# The hydrated Gemini settings file only selects Gemini CLI auth
|
|
# mode. CI still needs a usable Gemini or Google API key before
|
|
# ACP bind can initialize a Gemini session.
|
|
echo "OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex" >> "$GITHUB_ENV"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
- name: Run ${{ matrix.label }}
|
|
run: ${{ matrix.command }}
|