mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-07 17:09:13 -10:00
fix(action): accept OrcaRouter keys and recommend the free route [skip ci]
The explicit provider allowlist omitted OrcaRouter. Pass only ORCAROUTER_API_KEY to its existing Engine route and keep no-key failure closed. The setup example uses our existing public referral and orcarouter/free, with required authentication and rate/runner limits disclosed. No provider or credential fallback. Validation:8 existing Action cases pass, expanded existing assertions cover missing Orca key, exact route, selected-secret isolation and receipt redaction. Actual unauthenticated POST orcarouter/free returned401 Invalid API key on2026-10-26; no authenticated provider completion. Whitespace pass. No workflow enabled or deployed.
This commit is contained in:
1 parent
81558024ca
commit
6f92f0d5e2
3 files changed
+27
-7
No files matched your search
+16
-6
@@ -19,15 +19,25 @@ pins. Adding these source files does not enable a workflow.
|
||||
|
||||
## Setup with your own provider key
|
||||
|
||||
Pick `deepseek`, `anthropic`, `openrouter`, `zai`, or `modelstudio-token-plan`,
|
||||
Pick `orcarouter`, `deepseek`, `anthropic`, `openrouter`, `zai`, or `modelstudio-token-plan`,
|
||||
an exact model ID, and a released CLI tag. Store the matching provider key as
|
||||
an Actions secret. Pass only that provider's key to the analysis job. The
|
||||
Action never chooses a different credential after an authentication or payment
|
||||
failure. The example uses DeepSeek; replace its provider and secret together
|
||||
when choosing another route.
|
||||
failure. The example uses the recommended OrcaRouter connection; replace its
|
||||
provider and secret together when choosing another route.
|
||||
|
||||
Create or connect your own [OrcaRouter account](https://www.orcarouter.ai/ref/ref_df843907ad10d887b867),
|
||||
then store its API key as `ORCAROUTER_API_KEY`. Codewhale earns a referral fee
|
||||
from OrcaRouter. `orcarouter/free` is an available starting model when listed
|
||||
for your workspace; it still requires an API key. A direct no-key request on
|
||||
2026-10-26 returned HTTP 401. OrcaRouter's [free-route documentation](https://www.orcarouter.ai/models/orcarouter/free)
|
||||
describes zero-priced usage with request-rate limits. A limit or authentication
|
||||
failure does not authorize a paid fallback. GitHub runner compute has its own
|
||||
cost and limits.
|
||||
|
||||
Set `CODEWHALE_REVIEW_VERSION` to an exact `vX.Y.Z` release and
|
||||
`CODEWHALE_REVIEW_MODEL` to the chosen provider's exact model ID. Replace both
|
||||
`CODEWHALE_REVIEW_MODEL` to the chosen provider's exact model ID (for example
|
||||
`orcarouter/free`). Replace both
|
||||
`REPLACE_WITH_REVIEWED_COMMIT_SHA` placeholders with the same reviewed Action
|
||||
commit containing the publisher. Pin third-party actions to reviewed commits
|
||||
under your repository's Actions policy.
|
||||
@@ -64,12 +74,12 @@ jobs:
|
||||
id: review
|
||||
with:
|
||||
version: ${{ vars.CODEWHALE_REVIEW_VERSION }}
|
||||
provider: deepseek
|
||||
provider: orcarouter
|
||||
model: ${{ vars.CODEWHALE_REVIEW_MODEL }}
|
||||
pr-number: ${{ inputs.pr-number }}
|
||||
post: 'false'
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ (github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository) && secrets.DEEPSEEK_API_KEY || '' }}
|
||||
ORCAROUTER_API_KEY: ${{ (github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository) && secrets.ORCAROUTER_API_KEY || '' }}
|
||||
- uses: actions/upload-artifact@v7
|
||||
if: steps.review.outputs.findings != ''
|
||||
with:
|
||||
|
||||
@@ -15,7 +15,7 @@ const REPO = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
||||
const MODEL = /^[A-Za-z0-9][A-Za-z0-9_./:@+-]{0,199}$/;
|
||||
const KEYS = {
|
||||
deepseek: 'DEEPSEEK_API_KEY', anthropic: 'ANTHROPIC_API_KEY',
|
||||
openrouter: 'OPENROUTER_API_KEY', zai: 'ZAI_API_KEY',
|
||||
openrouter: 'OPENROUTER_API_KEY', orcarouter: 'ORCAROUTER_API_KEY', zai: 'ZAI_API_KEY',
|
||||
'modelstudio-token-plan': 'MODELSTUDIO_API_KEY',
|
||||
};
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ test('stale events and a head changed during fetch stop before inference', t =>
|
||||
test('bad config cannot fall back to a stale vendor key or contact another GitHub host', t => {
|
||||
for (const env of [
|
||||
{ CODEWHALE_API_KEY: '', DEEPSEEK_API_KEY: 'stale' }, { CW_PROVIDER: 'deepseek', DEEPSEEK_API_KEY: 'stale' },
|
||||
{ CODEWHALE_API_KEY: '', CW_PROVIDER: 'orcarouter', CW_MODEL: 'orcarouter/free', DEEPSEEK_API_KEY: 'stale' },
|
||||
{ CW_MODEL: 'guessed-model' }, { CW_MODEL: 'provider/model\n::error::injection' },
|
||||
{ CW_VERSION: 'latest' }, { CW_MAX_PASSES: '65' }, { CW_MAX_CHARS: '8388609' },
|
||||
{ CW_MAX_OUTPUT_TOKENS: '1000' }, { CW_TIMEOUT_SECONDS: '0' }, { CW_POST: 'maybe' },
|
||||
@@ -109,6 +110,15 @@ test('bad config cannot fall back to a stale vendor key or contact another GitHu
|
||||
assert.equal(result.calls.length, 0);
|
||||
}
|
||||
assert.equal(settings({ ...defaults, CODEWHALE_API_KEY: '', CW_PROVIDER: 'deepseek', CW_MODEL: 'exact-model', DEEPSEEK_API_KEY: 'vendor' }).provider, 'deepseek');
|
||||
const orca = fixture(t, { env: { CODEWHALE_API_KEY: '', CW_PROVIDER: 'orcarouter', CW_MODEL: 'orcarouter/free',
|
||||
ORCAROUTER_API_KEY: 'orca-fixture-secret', DEEPSEEK_API_KEY: 'stale' } });
|
||||
assert.equal(orca.exitCode, 0);
|
||||
const review = orca.calls.find(call => call.args.includes('review'));
|
||||
assert.equal(review.opts.env.ORCAROUTER_API_KEY, 'orca-fixture-secret');
|
||||
assert.equal(review.opts.env.DEEPSEEK_API_KEY, undefined);
|
||||
assert.equal(review.opts.env.CODEWHALE_API_KEY, undefined);
|
||||
assert.equal(review.args[review.args.indexOf('--model') + 1], 'orcarouter/free');
|
||||
assert.doesNotMatch(JSON.stringify(orca.saved) + orca.summary, /orca-fixture-secret/);
|
||||
assert.throws(() => target({ ...defaults, GITHUB_REPOSITORY: '../x' }, event));
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user