mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-09 15:59:30 +00:00
fix(ci): require billable Anthropic release key
This commit is contained in:
parent
65805e519d
commit
ed16f8fcf0
12 changed files with 61 additions and 84 deletions
|
|
@ -16,15 +16,10 @@ Use this with `$release-openclaw-maintainer` and `$openclaw-testing` when a rele
|
|||
- Watch one parent run plus compact child summaries. Avoid broad `gh run view` polling loops; REST quota is easy to burn.
|
||||
- Fetch logs only for failed or currently-blocking jobs. If quota is low, stop polling and wait for reset.
|
||||
- Treat live-provider flakes separately from code failures: prove key validity, provider HTTP status, retry evidence, and exact failing lane before editing code.
|
||||
- Anthropic release lanes support both API keys and OAuth. When API keys are
|
||||
exhausted but a maintainer-owned OAuth token passes a live Anthropic probe,
|
||||
set `ANTHROPIC_OAUTH_TOKEN` for provider/runtime lanes and
|
||||
refreshable `OPENCLAW_CLAUDE_CREDENTIALS_JSON` or
|
||||
`CLAUDE_CODE_OAUTH_TOKEN` for Claude CLI subscription lanes before rerunning
|
||||
the matrix. Revalidate short-lived OAuth immediately before dispatch. Never
|
||||
keep retrying a known exhausted API key. Live-cache validation must prefer
|
||||
the proven OAuth token instead of leaving an exhausted API key first in the
|
||||
runtime key pool.
|
||||
- A model-list response proves authentication, not billing or inference
|
||||
entitlement. Mandatory live providers must pass a real completion probe
|
||||
before release dispatch. Fix the credential first; do not add an alternate
|
||||
auth path merely to bypass a failed release credential.
|
||||
- Full Release Validation parent monitors fail fast: once a required child job
|
||||
fails, the parent cancels the remaining child matrix and prints the failed
|
||||
job summary. Inspect that first red job instead of waiting for unrelated
|
||||
|
|
@ -45,8 +40,8 @@ git rev-parse HEAD
|
|||
preflight. Inject those exact targeted keys first, then run the verifier; use
|
||||
ambient env only when it was already intentionally injected for this release.
|
||||
The script prints only provider status and HTTP class, never tokens.
|
||||
For Anthropic it prefers `ANTHROPIC_OAUTH_TOKEN` and validates it with bearer
|
||||
OAuth headers when present; otherwise it checks API-key-shaped credentials.
|
||||
The Anthropic check performs a tiny message completion so exhausted or
|
||||
non-billable credentials fail before the expensive release matrix.
|
||||
|
||||
## Dispatch
|
||||
|
||||
|
|
@ -124,11 +119,10 @@ Stop watchers before ending the turn or switching strategy.
|
|||
--jq '.jobs[] | select(.conclusion=="failure" or .conclusion=="timed_out" or .conclusion=="cancelled") | [.databaseId,.name,.conclusion,.url] | @tsv'
|
||||
```
|
||||
3. Fetch one failed job log. If rate-limited, note reset time and avoid more REST calls.
|
||||
4. For secret-looking failures, validate the provider endpoint from the same secret source before editing code.
|
||||
For Docker CLI-backend failures, also validate
|
||||
`OPENCLAW_CLAUDE_CREDENTIALS_JSON` or `CLAUDE_CODE_OAUTH_TOKEN` in a
|
||||
clean-home Claude CLI probe; that lane should use subscription mode when
|
||||
either credential exists.
|
||||
4. For secret-looking failures, validate a real completion from the same secret source before editing code. A successful model-list request is insufficient.
|
||||
Claude CLI subscription credentials are a separate native auth path; prove
|
||||
them in a clean-home CLI probe, never as a substitute for a required
|
||||
Anthropic API-key lane.
|
||||
5. For live-cache failures, inspect whether it is missing/invalid key, empty text, provider refusal, timeout, or baseline miss. Do not weaken release gates without clear provider evidence.
|
||||
6. Fix narrowly, run local/changed proof, commit, push, rerun the smallest matching group.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Release preflight helper that verifies required provider API keys can reach
|
||||
* their model-list endpoints without printing secret values.
|
||||
* Release preflight helper that verifies required provider API keys without
|
||||
* printing secret values. Anthropic must complete a prompt because model-list
|
||||
* access does not prove billing or inference entitlement.
|
||||
*/
|
||||
import process from "node:process";
|
||||
|
||||
const args = new Map();
|
||||
for (let index = 2; index < process.argv.length; index += 1) {
|
||||
const arg = process.argv[index];
|
||||
if (!arg.startsWith("--")) continue;
|
||||
if (!arg.startsWith("--")) {
|
||||
continue;
|
||||
}
|
||||
const [key, inlineValue] = arg.slice(2).split("=", 2);
|
||||
const value = inlineValue ?? process.argv[index + 1];
|
||||
if (inlineValue === undefined) index += 1;
|
||||
if (inlineValue === undefined) {
|
||||
index += 1;
|
||||
}
|
||||
args.set(key, value);
|
||||
}
|
||||
|
||||
|
|
@ -28,7 +33,9 @@ const timeoutMs = Number(args.get("timeout-ms") ?? 10_000);
|
|||
function envFirst(names) {
|
||||
for (const name of names) {
|
||||
const value = process.env[name]?.trim();
|
||||
if (value) return { name, value };
|
||||
if (value) {
|
||||
return { name, value };
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
|
@ -42,15 +49,21 @@ async function checkProvider(id, config) {
|
|||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
||||
try {
|
||||
const headers = config.headers(secret);
|
||||
const headers = config.headers(secret.value);
|
||||
const response = await fetch(config.url, {
|
||||
body: config.body,
|
||||
headers,
|
||||
method: config.method,
|
||||
signal: controller.signal,
|
||||
});
|
||||
const responseBody = config.validateResponse
|
||||
? await response.json().catch(() => undefined)
|
||||
: undefined;
|
||||
const ok = response.ok && (!config.validateResponse || config.validateResponse(responseBody));
|
||||
return {
|
||||
id,
|
||||
ok: response.ok,
|
||||
status: response.ok ? "ok" : `http_${response.status}`,
|
||||
ok,
|
||||
status: response.ok ? (ok ? "ok" : "invalid_response") : `http_${response.status}`,
|
||||
env: secret.name,
|
||||
};
|
||||
} catch (error) {
|
||||
|
|
@ -69,32 +82,35 @@ const providers = {
|
|||
openai: {
|
||||
env: ["OPENAI_API_KEY"],
|
||||
url: "https://api.openai.com/v1/models",
|
||||
headers: ({ value }) => ({ authorization: `Bearer ${value}` }),
|
||||
headers: (token) => ({ authorization: `Bearer ${token}` }),
|
||||
},
|
||||
anthropic: {
|
||||
env: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY", "ANTHROPIC_API_TOKEN"],
|
||||
url: "https://api.anthropic.com/v1/models",
|
||||
headers: ({ name, value }) =>
|
||||
name === "ANTHROPIC_OAUTH_TOKEN"
|
||||
? {
|
||||
"anthropic-beta": "oauth-2025-04-20",
|
||||
"anthropic-version": "2023-06-01",
|
||||
authorization: `Bearer ${value}`,
|
||||
}
|
||||
: {
|
||||
"anthropic-version": "2023-06-01",
|
||||
"x-api-key": value,
|
||||
},
|
||||
env: ["ANTHROPIC_API_KEY", "ANTHROPIC_API_TOKEN"],
|
||||
url: "https://api.anthropic.com/v1/messages",
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
max_tokens: 8,
|
||||
messages: [{ role: "user", content: "Reply with OK." }],
|
||||
model: "claude-haiku-4-5",
|
||||
}),
|
||||
headers: (token) => ({
|
||||
"anthropic-version": "2023-06-01",
|
||||
"content-type": "application/json",
|
||||
"x-api-key": token,
|
||||
}),
|
||||
validateResponse: (body) =>
|
||||
Array.isArray(body?.content) &&
|
||||
body.content.some((part) => typeof part?.text === "string" && part.text.trim()),
|
||||
},
|
||||
fireworks: {
|
||||
env: ["FIREWORKS_API_KEY"],
|
||||
url: "https://api.fireworks.ai/inference/v1/models",
|
||||
headers: ({ value }) => ({ authorization: `Bearer ${value}` }),
|
||||
headers: (token) => ({ authorization: `Bearer ${token}` }),
|
||||
},
|
||||
openrouter: {
|
||||
env: ["OPENROUTER_API_KEY"],
|
||||
url: "https://openrouter.ai/api/v1/models",
|
||||
headers: ({ value }) => ({ authorization: `Bearer ${value}` }),
|
||||
headers: (token) => ({ authorization: `Bearer ${token}` }),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -115,7 +131,9 @@ let failed = false;
|
|||
for (const result of results) {
|
||||
const requiredLabel = required.has(result.id) ? "required" : "optional";
|
||||
console.log(`${result.id}: ${result.status} env=${result.env} ${requiredLabel}`);
|
||||
if (required.has(result.id) && !result.ok) failed = true;
|
||||
if (required.has(result.id) && !result.ok) {
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
|
|
|
|||
|
|
@ -210,7 +210,6 @@ jobs:
|
|||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
DEEPINFRA_API_KEY: ${{ secrets.DEEPINFRA_API_KEY }}
|
||||
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_API_KEY }}
|
||||
|
|
|
|||
1
.github/workflows/ci-check-arm-testbox.yml
vendored
1
.github/workflows/ci-check-arm-testbox.yml
vendored
|
|
@ -128,7 +128,6 @@ jobs:
|
|||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
DEEPINFRA_API_KEY: ${{ secrets.DEEPINFRA_API_KEY }}
|
||||
FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}
|
||||
|
|
|
|||
1
.github/workflows/ci-check-testbox.yml
vendored
1
.github/workflows/ci-check-testbox.yml
vendored
|
|
@ -113,7 +113,6 @@ jobs:
|
|||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
DEEPINFRA_API_KEY: ${{ secrets.DEEPINFRA_API_KEY }}
|
||||
FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}
|
||||
|
|
|
|||
1
.github/workflows/crabbox-hydrate.yml
vendored
1
.github/workflows/crabbox-hydrate.yml
vendored
|
|
@ -663,7 +663,6 @@ jobs:
|
|||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
DEEPINFRA_API_KEY: ${{ secrets.DEEPINFRA_API_KEY }}
|
||||
FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}
|
||||
|
|
|
|||
|
|
@ -229,8 +229,6 @@ on:
|
|||
required: false
|
||||
ANTHROPIC_API_TOKEN:
|
||||
required: false
|
||||
ANTHROPIC_OAUTH_TOKEN:
|
||||
required: false
|
||||
FACTORY_API_KEY:
|
||||
required: false
|
||||
BYTEPLUS_API_KEY:
|
||||
|
|
@ -521,7 +519,6 @@ jobs:
|
|||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
OPENCLAW_LIVE_CACHE_TEST: "1"
|
||||
OPENCLAW_LIVE_TEST: "1"
|
||||
steps:
|
||||
|
|
@ -544,13 +541,10 @@ jobs:
|
|||
echo "Missing OPENAI_API_KEY secret for live-cache validation." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z "${ANTHROPIC_OAUTH_TOKEN:-}" && -z "${ANTHROPIC_API_KEY:-}" ]]; then
|
||||
echo "Missing ANTHROPIC_OAUTH_TOKEN or ANTHROPIC_API_KEY secret for live-cache validation." >&2
|
||||
if [[ -z "${ANTHROPIC_API_KEY:-}" ]]; then
|
||||
echo "Missing ANTHROPIC_API_KEY secret for live-cache validation." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "${ANTHROPIC_OAUTH_TOKEN:-}" ]]; then
|
||||
echo "ANTHROPIC_API_KEY=" >> "$GITHUB_ENV"
|
||||
fi
|
||||
|
||||
- name: Verify live prompt cache floors
|
||||
run: |
|
||||
|
|
@ -686,7 +680,6 @@ jobs:
|
|||
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
|
|
@ -951,7 +944,6 @@ jobs:
|
|||
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
|
|
@ -1663,7 +1655,6 @@ jobs:
|
|||
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
|
|
@ -1755,7 +1746,7 @@ jobs:
|
|||
}
|
||||
|
||||
case "${LIVE_MODEL_PROVIDERS}" in
|
||||
anthropic) require_any Anthropic ANTHROPIC_OAUTH_TOKEN ANTHROPIC_API_KEY ANTHROPIC_API_KEY_OLD ANTHROPIC_API_TOKEN ;;
|
||||
anthropic) require_any Anthropic ANTHROPIC_API_KEY ANTHROPIC_API_KEY_OLD ANTHROPIC_API_TOKEN ;;
|
||||
google) require_any Google GEMINI_API_KEY GOOGLE_API_KEY ;;
|
||||
minimax) require_any MiniMax MINIMAX_API_KEY ;;
|
||||
moonshot) require_any Moonshot MOONSHOT_API_KEY KIMI_API_KEY ;;
|
||||
|
|
@ -1787,7 +1778,6 @@ jobs:
|
|||
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
|
|
@ -1931,7 +1921,7 @@ jobs:
|
|||
IFS=',' read -r -a providers <<<"${OPENCLAW_LIVE_PROVIDERS}"
|
||||
for provider in "${providers[@]}"; do
|
||||
case "$provider" in
|
||||
anthropic) require_any Anthropic ANTHROPIC_OAUTH_TOKEN ANTHROPIC_API_KEY ANTHROPIC_API_KEY_OLD ANTHROPIC_API_TOKEN ;;
|
||||
anthropic) require_any Anthropic ANTHROPIC_API_KEY ANTHROPIC_API_KEY_OLD ANTHROPIC_API_TOKEN ;;
|
||||
google) require_any Google GEMINI_API_KEY GOOGLE_API_KEY ;;
|
||||
minimax) require_any MiniMax MINIMAX_API_KEY ;;
|
||||
moonshot) require_any Moonshot MOONSHOT_API_KEY KIMI_API_KEY ;;
|
||||
|
|
@ -2150,7 +2140,6 @@ jobs:
|
|||
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
|
|
@ -2371,7 +2360,6 @@ jobs:
|
|||
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
|
|
@ -2588,7 +2576,6 @@ jobs:
|
|||
OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
|
|
|
|||
|
|
@ -631,7 +631,6 @@ jobs:
|
|||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
|
|
@ -725,7 +724,6 @@ jobs:
|
|||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ jobs:
|
|||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
|
|
|
|||
3
.github/workflows/package-acceptance.yml
vendored
3
.github/workflows/package-acceptance.yml
vendored
|
|
@ -203,8 +203,6 @@ on:
|
|||
required: false
|
||||
ANTHROPIC_API_TOKEN:
|
||||
required: false
|
||||
ANTHROPIC_OAUTH_TOKEN:
|
||||
required: false
|
||||
FACTORY_API_KEY:
|
||||
required: false
|
||||
BYTEPLUS_API_KEY:
|
||||
|
|
@ -590,7 +588,6 @@ jobs:
|
|||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_API_KEY_OLD: ${{ secrets.ANTHROPIC_API_KEY_OLD }}
|
||||
ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}
|
||||
ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}
|
||||
FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}
|
||||
BYTEPLUS_API_KEY: ${{ secrets.BYTEPLUS_API_KEY }}
|
||||
CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY }}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ for env_key in \
|
|||
ANTHROPIC_API_KEY \
|
||||
ANTHROPIC_API_KEY_OLD \
|
||||
ANTHROPIC_API_TOKEN \
|
||||
ANTHROPIC_OAUTH_TOKEN \
|
||||
BYTEPLUS_API_KEY \
|
||||
CEREBRAS_API_KEY \
|
||||
DEEPINFRA_API_KEY \
|
||||
|
|
|
|||
|
|
@ -991,14 +991,11 @@ describe("package artifact reuse", () => {
|
|||
const providerVerifier = readFileSync(VERIFY_PROVIDER_SECRETS_SCRIPT, "utf8");
|
||||
|
||||
expect(hydrateScript).toContain(" FACTORY_API_KEY \\");
|
||||
expect(hydrateScript).toContain(" ANTHROPIC_OAUTH_TOKEN \\");
|
||||
expect(providerVerifier).toContain(
|
||||
'env: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY", "ANTHROPIC_API_TOKEN"]',
|
||||
);
|
||||
expect(providerVerifier).toContain('"anthropic-beta": "oauth-2025-04-20"');
|
||||
expect(providerVerifier).toContain("authorization: `Bearer ${value}`");
|
||||
expect(providerVerifier).toContain('url: "https://api.anthropic.com/v1/messages"');
|
||||
expect(providerVerifier).toContain('model: "claude-haiku-4-5"');
|
||||
expect(providerVerifier).toContain("validateResponse:");
|
||||
expect(providerVerifier).not.toContain("ANTHROPIC_OAUTH_TOKEN");
|
||||
expect(dockerPlanAction).toContain('if [[ "$credentials" == *",factory,"* ]]; then');
|
||||
expect(dockerPlanAction).not.toContain("require_any Anthropic ANTHROPIC_OAUTH_TOKEN");
|
||||
expectTextToIncludeAll(dockerPlanAction, [
|
||||
'if [[ "$credentials" == *",openai,"* ]]; then',
|
||||
"require_any OpenAI OPENAI_API_KEY",
|
||||
|
|
@ -1021,12 +1018,9 @@ describe("package artifact reuse", () => {
|
|||
testboxWorkflow,
|
||||
]) {
|
||||
expect(workflow).toContain("FACTORY_API_KEY: ${{ secrets.FACTORY_API_KEY }}");
|
||||
expect(workflow).toContain("ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}");
|
||||
}
|
||||
expect(reusableWorkflow).toContain("FACTORY_API_KEY:\n required: false");
|
||||
expect(reusableWorkflow).toContain("ANTHROPIC_OAUTH_TOKEN:\n required: false");
|
||||
expect(packageAcceptanceWorkflow).toContain("FACTORY_API_KEY:\n required: false");
|
||||
expect(packageAcceptanceWorkflow).toContain("ANTHROPIC_OAUTH_TOKEN:\n required: false");
|
||||
expectTextToIncludeAll(reusableWorkflow, [
|
||||
'if [[ "$credentials" == *",openai,"* ]]; then',
|
||||
"require_any OpenAI OPENAI_API_KEY",
|
||||
|
|
@ -1037,10 +1031,6 @@ describe("package artifact reuse", () => {
|
|||
'if [[ "$credentials" == *",opencode,"* ]]; then',
|
||||
"require_any OpenCode OPENCODE_API_KEY OPENCODE_ZEN_API_KEY",
|
||||
]);
|
||||
expect(reusableWorkflow).toContain(
|
||||
"anthropic) require_any Anthropic ANTHROPIC_OAUTH_TOKEN ANTHROPIC_API_KEY ANTHROPIC_API_KEY_OLD ANTHROPIC_API_TOKEN ;;",
|
||||
);
|
||||
expect(reusableWorkflow).toContain('echo "ANTHROPIC_API_KEY=" >> "$GITHUB_ENV"');
|
||||
expect(reusableWorkflow.match(/OPENCLAW_LIVE_CLI_BACKEND_AUTH=subscription/g)).toHaveLength(2);
|
||||
expect(
|
||||
reusableWorkflow.match(
|
||||
|
|
@ -1118,7 +1108,6 @@ describe("package artifact reuse", () => {
|
|||
);
|
||||
expect(workflow).toContain("ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}");
|
||||
expect(workflow).toContain("ANTHROPIC_API_TOKEN: ${{ secrets.ANTHROPIC_API_TOKEN }}");
|
||||
expect(workflow).toContain("ANTHROPIC_OAUTH_TOKEN: ${{ secrets.ANTHROPIC_OAUTH_TOKEN }}");
|
||||
expect(workflow).toContain(
|
||||
"OPENCLAW_QA_CONVEX_SITE_URL: ${{ secrets.OPENCLAW_QA_CONVEX_SITE_URL }}",
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue