mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-01-09 02:19:12 +00:00
Compare commits
1 Commits
chore/rele
...
fix/missin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15912892f2 |
127
.github/workflows/release-sdk.yml
vendored
127
.github/workflows/release-sdk.yml
vendored
@@ -34,8 +34,7 @@ on:
|
|||||||
default: false
|
default: false
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
# Serialize all release workflows (CLI + SDK) to avoid racing on `main` pushes.
|
group: '${{ github.workflow }}'
|
||||||
group: 'release-main'
|
|
||||||
cancel-in-progress: false
|
cancel-in-progress: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -51,6 +50,7 @@ jobs:
|
|||||||
packages: 'write'
|
packages: 'write'
|
||||||
id-token: 'write'
|
id-token: 'write'
|
||||||
issues: 'write'
|
issues: 'write'
|
||||||
|
pull-requests: 'write'
|
||||||
outputs:
|
outputs:
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
||||||
|
|
||||||
@@ -128,13 +128,12 @@ jobs:
|
|||||||
IS_PREVIEW: '${{ steps.vars.outputs.is_preview }}'
|
IS_PREVIEW: '${{ steps.vars.outputs.is_preview }}'
|
||||||
MANUAL_VERSION: '${{ inputs.version }}'
|
MANUAL_VERSION: '${{ inputs.version }}'
|
||||||
|
|
||||||
- name: 'Set SDK package version'
|
- name: 'Set SDK package version (local only)'
|
||||||
env:
|
env:
|
||||||
RELEASE_VERSION: '${{ steps.version.outputs.RELEASE_VERSION }}'
|
RELEASE_VERSION: '${{ steps.version.outputs.RELEASE_VERSION }}'
|
||||||
run: |-
|
run: |-
|
||||||
# Ensure the package version matches the computed release version.
|
# Ensure the package version matches the computed release version.
|
||||||
# This is required for nightly/preview because npm does not allow re-publishing the same version.
|
# This is required for nightly/preview because npm does not allow re-publishing the same version.
|
||||||
# Using --no-git-tag-version because we create tags via GitHub Release, not npm.
|
|
||||||
npm version -w @qwen-code/sdk "${RELEASE_VERSION}" --no-git-tag-version --allow-same-version
|
npm version -w @qwen-code/sdk "${RELEASE_VERSION}" --no-git-tag-version --allow-same-version
|
||||||
|
|
||||||
- name: 'Build CLI Bundle'
|
- name: 'Build CLI Bundle'
|
||||||
@@ -169,40 +168,37 @@ jobs:
|
|||||||
git config user.name "github-actions[bot]"
|
git config user.name "github-actions[bot]"
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
- name: 'Create and switch to a release branch (stable only)'
|
- name: 'Build SDK'
|
||||||
|
working-directory: 'packages/sdk-typescript'
|
||||||
|
run: |-
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
- name: 'Publish @qwen-code/sdk'
|
||||||
|
working-directory: 'packages/sdk-typescript'
|
||||||
|
run: |-
|
||||||
|
npm publish --access public --tag=${{ steps.version.outputs.NPM_TAG }} ${{ steps.vars.outputs.is_dry_run == 'true' && '--dry-run' || '' }}
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'
|
||||||
|
|
||||||
|
- name: 'Create and switch to a release branch'
|
||||||
if: |-
|
if: |-
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' && steps.vars.outputs.is_nightly == 'false' && steps.vars.outputs.is_preview == 'false' }}
|
${{ steps.vars.outputs.is_dry_run == 'false' && steps.vars.outputs.is_nightly == 'false' && steps.vars.outputs.is_preview == 'false' }}
|
||||||
id: 'release_branch'
|
id: 'release_branch'
|
||||||
env:
|
env:
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
||||||
run: |-
|
run: |-
|
||||||
set -euo pipefail
|
|
||||||
BRANCH_NAME="release/sdk-typescript/${RELEASE_TAG}"
|
BRANCH_NAME="release/sdk-typescript/${RELEASE_TAG}"
|
||||||
|
git switch -c "${BRANCH_NAME}"
|
||||||
# Make reruns idempotent: reuse an existing remote branch if it already exists.
|
|
||||||
if git show-ref --verify --quiet "refs/heads/${BRANCH_NAME}"; then
|
|
||||||
git switch "${BRANCH_NAME}"
|
|
||||||
elif git ls-remote --exit-code --heads origin "${BRANCH_NAME}" >/dev/null 2>&1; then
|
|
||||||
git fetch origin "${BRANCH_NAME}:${BRANCH_NAME}"
|
|
||||||
git switch "${BRANCH_NAME}"
|
|
||||||
else
|
|
||||||
git switch -c "${BRANCH_NAME}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
|
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
- name: 'Build SDK'
|
- name: 'Commit and Push package version (stable only)'
|
||||||
working-directory: 'packages/sdk-typescript'
|
|
||||||
run: |-
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
- name: 'Commit and Push package version to release branch (stable only)'
|
|
||||||
if: |-
|
if: |-
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' && steps.vars.outputs.is_nightly == 'false' && steps.vars.outputs.is_preview == 'false' }}
|
${{ steps.vars.outputs.is_dry_run == 'false' && steps.vars.outputs.is_nightly == 'false' && steps.vars.outputs.is_preview == 'false' }}
|
||||||
env:
|
env:
|
||||||
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
BRANCH_NAME: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
||||||
run: |-
|
run: |-
|
||||||
|
# Only persist version bumps after a successful publish.
|
||||||
git add packages/sdk-typescript/package.json package-lock.json
|
git add packages/sdk-typescript/package.json package-lock.json
|
||||||
if git diff --staged --quiet; then
|
if git diff --staged --quiet; then
|
||||||
echo "No version changes to commit"
|
echo "No version changes to commit"
|
||||||
@@ -212,47 +208,9 @@ jobs:
|
|||||||
echo "Pushing release branch to remote..."
|
echo "Pushing release branch to remote..."
|
||||||
git push --set-upstream origin "${BRANCH_NAME}" --follow-tags
|
git push --set-upstream origin "${BRANCH_NAME}" --follow-tags
|
||||||
|
|
||||||
- name: 'Check if @qwen-code/sdk version is already published (rerun safety)'
|
|
||||||
id: 'npm_check'
|
|
||||||
env:
|
|
||||||
RELEASE_VERSION: '${{ steps.version.outputs.RELEASE_VERSION }}'
|
|
||||||
run: |-
|
|
||||||
set -euo pipefail
|
|
||||||
if npm view "@qwen-code/sdk@${RELEASE_VERSION}" version >/dev/null 2>&1; then
|
|
||||||
echo "already_published=true" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "@qwen-code/sdk@${RELEASE_VERSION} already exists on npm."
|
|
||||||
else
|
|
||||||
echo "already_published=false" >> "${GITHUB_OUTPUT}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: 'Publish @qwen-code/sdk'
|
|
||||||
working-directory: 'packages/sdk-typescript'
|
|
||||||
if: |-
|
|
||||||
${{ steps.vars.outputs.is_dry_run == 'true' || steps.npm_check.outputs.already_published != 'true' }}
|
|
||||||
run: |-
|
|
||||||
npm publish --access public --tag=${{ steps.version.outputs.NPM_TAG }} ${{ steps.vars.outputs.is_dry_run == 'true' && '--dry-run' || '' }}
|
|
||||||
env:
|
|
||||||
NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'
|
|
||||||
|
|
||||||
- name: 'Check if GitHub Release already exists (rerun safety)'
|
|
||||||
if: |-
|
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' }}
|
|
||||||
id: 'gh_release_check'
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
|
||||||
run: |-
|
|
||||||
set -euo pipefail
|
|
||||||
if gh release view "sdk-typescript-${RELEASE_TAG}" >/dev/null 2>&1; then
|
|
||||||
echo "already_exists=true" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "GitHub Release sdk-typescript-${RELEASE_TAG} already exists."
|
|
||||||
else
|
|
||||||
echo "already_exists=false" >> "${GITHUB_OUTPUT}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: 'Create GitHub Release and Tag'
|
- name: 'Create GitHub Release and Tag'
|
||||||
if: |-
|
if: |-
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' && steps.gh_release_check.outputs.already_exists != 'true' }}
|
${{ steps.vars.outputs.is_dry_run == 'false' }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
RELEASE_BRANCH: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
RELEASE_BRANCH: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
||||||
@@ -278,27 +236,48 @@ jobs:
|
|||||||
--generate-notes \
|
--generate-notes \
|
||||||
${PRERELEASE_FLAG}
|
${PRERELEASE_FLAG}
|
||||||
|
|
||||||
- name: 'Create release PR for SDK version bump'
|
- name: 'Create PR to merge release branch into main'
|
||||||
if: |-
|
if: |-
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' && steps.vars.outputs.is_nightly == 'false' && steps.vars.outputs.is_preview == 'false' }}
|
${{ steps.vars.outputs.is_dry_run == 'false' && steps.vars.outputs.is_nightly == 'false' && steps.vars.outputs.is_preview == 'false' }}
|
||||||
|
id: 'pr'
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: '${{ secrets.CI_BOT_PAT }}'
|
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
|
||||||
RELEASE_BRANCH: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
RELEASE_BRANCH: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
||||||
|
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
||||||
run: |-
|
run: |-
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
pr_exists=$(gh pr list --head "${RELEASE_BRANCH}" --state open --json number --jq 'length')
|
pr_url="$(gh pr list --head "${RELEASE_BRANCH}" --base main --json url --jq '.[0].url')"
|
||||||
if [[ "${pr_exists}" != "0" ]]; then
|
if [[ -z "${pr_url}" ]]; then
|
||||||
echo "Open PR already exists for ${RELEASE_BRANCH}; skipping creation."
|
pr_url="$(gh pr create \
|
||||||
exit 0
|
--base main \
|
||||||
|
--head "${RELEASE_BRANCH}" \
|
||||||
|
--title "chore(release): sdk-typescript ${RELEASE_TAG}" \
|
||||||
|
--body "Automated release PR for sdk-typescript ${RELEASE_TAG}.")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
gh pr create \
|
echo "PR_URL=${pr_url}" >> "${GITHUB_OUTPUT}"
|
||||||
--base main \
|
|
||||||
--head "${RELEASE_BRANCH}" \
|
- name: 'Wait for CI checks to complete'
|
||||||
--title "chore(release): sdk-typescript ${RELEASE_TAG}" \
|
if: |-
|
||||||
--body "Automated SDK version bump for ${RELEASE_TAG}."
|
${{ steps.vars.outputs.is_dry_run == 'false' && steps.vars.outputs.is_nightly == 'false' && steps.vars.outputs.is_preview == 'false' }}
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
PR_URL: '${{ steps.pr.outputs.PR_URL }}'
|
||||||
|
run: |-
|
||||||
|
set -euo pipefail
|
||||||
|
echo "Waiting for CI checks to complete..."
|
||||||
|
gh pr checks "${PR_URL}" --watch --interval 30
|
||||||
|
|
||||||
|
- name: 'Enable auto-merge for release PR'
|
||||||
|
if: |-
|
||||||
|
${{ steps.vars.outputs.is_dry_run == 'false' && steps.vars.outputs.is_nightly == 'false' && steps.vars.outputs.is_preview == 'false' }}
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
PR_URL: '${{ steps.pr.outputs.PR_URL }}'
|
||||||
|
run: |-
|
||||||
|
set -euo pipefail
|
||||||
|
gh pr merge "${PR_URL}" --merge --auto
|
||||||
|
|
||||||
- name: 'Create Issue on Failure'
|
- name: 'Create Issue on Failure'
|
||||||
if: |-
|
if: |-
|
||||||
|
|||||||
75
.github/workflows/release.yml
vendored
75
.github/workflows/release.yml
vendored
@@ -38,11 +38,6 @@ on:
|
|||||||
type: 'boolean'
|
type: 'boolean'
|
||||||
default: false
|
default: false
|
||||||
|
|
||||||
concurrency:
|
|
||||||
# Serialize all release workflows (CLI + SDK) to avoid racing on `main` pushes.
|
|
||||||
group: 'release-main'
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: 'ubuntu-latest'
|
runs-on: 'ubuntu-latest'
|
||||||
@@ -155,19 +150,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
||||||
run: |-
|
run: |-
|
||||||
set -euo pipefail
|
|
||||||
BRANCH_NAME="release/${RELEASE_TAG}"
|
BRANCH_NAME="release/${RELEASE_TAG}"
|
||||||
|
git switch -c "${BRANCH_NAME}"
|
||||||
# Make reruns idempotent: reuse an existing remote branch if it already exists.
|
|
||||||
if git show-ref --verify --quiet "refs/heads/${BRANCH_NAME}"; then
|
|
||||||
git switch "${BRANCH_NAME}"
|
|
||||||
elif git ls-remote --exit-code --heads origin "${BRANCH_NAME}" >/dev/null 2>&1; then
|
|
||||||
git fetch origin "${BRANCH_NAME}:${BRANCH_NAME}"
|
|
||||||
git switch "${BRANCH_NAME}"
|
|
||||||
else
|
|
||||||
git switch -c "${BRANCH_NAME}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
|
echo "BRANCH_NAME=${BRANCH_NAME}" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
- name: 'Update package versions'
|
- name: 'Update package versions'
|
||||||
@@ -207,47 +191,16 @@ jobs:
|
|||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
scope: '@qwen-code'
|
scope: '@qwen-code'
|
||||||
|
|
||||||
- name: 'Check if @qwen-code/qwen-code version is already published (rerun safety)'
|
|
||||||
id: 'npm_check'
|
|
||||||
env:
|
|
||||||
RELEASE_VERSION: '${{ steps.version.outputs.RELEASE_VERSION }}'
|
|
||||||
run: |-
|
|
||||||
set -euo pipefail
|
|
||||||
if npm view "@qwen-code/qwen-code@${RELEASE_VERSION}" version >/dev/null 2>&1; then
|
|
||||||
echo "already_published=true" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "@qwen-code/qwen-code@${RELEASE_VERSION} already exists on npm."
|
|
||||||
else
|
|
||||||
echo "already_published=false" >> "${GITHUB_OUTPUT}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: 'Publish @qwen-code/qwen-code'
|
- name: 'Publish @qwen-code/qwen-code'
|
||||||
working-directory: 'dist'
|
working-directory: 'dist'
|
||||||
if: |-
|
|
||||||
${{ steps.vars.outputs.is_dry_run == 'true' || steps.npm_check.outputs.already_published != 'true' }}
|
|
||||||
run: |-
|
run: |-
|
||||||
npm publish --access public --tag=${{ steps.version.outputs.NPM_TAG }} ${{ steps.vars.outputs.is_dry_run == 'true' && '--dry-run' || '' }}
|
npm publish --access public --tag=${{ steps.version.outputs.NPM_TAG }} ${{ steps.vars.outputs.is_dry_run == 'true' && '--dry-run' || '' }}
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'
|
NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'
|
||||||
|
|
||||||
- name: 'Check if GitHub Release already exists (rerun safety)'
|
|
||||||
if: |-
|
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' }}
|
|
||||||
id: 'gh_release_check'
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
|
||||||
run: |-
|
|
||||||
set -euo pipefail
|
|
||||||
if gh release view "${RELEASE_TAG}" >/dev/null 2>&1; then
|
|
||||||
echo "already_exists=true" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "GitHub Release ${RELEASE_TAG} already exists."
|
|
||||||
else
|
|
||||||
echo "already_exists=false" >> "${GITHUB_OUTPUT}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: 'Create GitHub Release and Tag'
|
- name: 'Create GitHub Release and Tag'
|
||||||
if: |-
|
if: |-
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' && steps.gh_release_check.outputs.already_exists != 'true' }}
|
${{ steps.vars.outputs.is_dry_run == 'false' }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
RELEASE_BRANCH: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
RELEASE_BRANCH: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
||||||
@@ -261,34 +214,12 @@ jobs:
|
|||||||
--notes-start-tag "$PREVIOUS_RELEASE_TAG" \
|
--notes-start-tag "$PREVIOUS_RELEASE_TAG" \
|
||||||
--generate-notes
|
--generate-notes
|
||||||
|
|
||||||
- name: 'Create release PR for version bump'
|
|
||||||
if: |-
|
|
||||||
${{ steps.vars.outputs.is_dry_run == 'false' && steps.vars.outputs.is_nightly == 'false' && steps.vars.outputs.is_preview == 'false' }}
|
|
||||||
env:
|
|
||||||
GH_TOKEN: '${{ secrets.CI_BOT_PAT }}'
|
|
||||||
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }}'
|
|
||||||
RELEASE_BRANCH: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
|
|
||||||
run: |-
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
pr_exists=$(gh pr list --head "${RELEASE_BRANCH}" --state open --json number --jq 'length')
|
|
||||||
if [[ "${pr_exists}" != "0" ]]; then
|
|
||||||
echo "Open PR already exists for ${RELEASE_BRANCH}; skipping creation."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
gh pr create \
|
|
||||||
--base main \
|
|
||||||
--head "${RELEASE_BRANCH}" \
|
|
||||||
--title "chore(release): ${RELEASE_TAG}" \
|
|
||||||
--body "Automated version bump for ${RELEASE_TAG}."
|
|
||||||
|
|
||||||
- name: 'Create Issue on Failure'
|
- name: 'Create Issue on Failure'
|
||||||
if: |-
|
if: |-
|
||||||
${{ failure() }}
|
${{ failure() }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
RELEASE_TAG: "${{ steps.version.outputs.RELEASE_TAG || 'N/A' }}"
|
RELEASE_TAG: '${{ steps.version.outputs.RELEASE_TAG }} || "N/A"'
|
||||||
DETAILS_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
|
DETAILS_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
|
||||||
run: |-
|
run: |-
|
||||||
gh issue create \
|
gh issue create \
|
||||||
|
|||||||
@@ -771,6 +771,52 @@ describe('runNonInteractive', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle API errors in text mode and exit with error code', async () => {
|
||||||
|
(mockConfig.getOutputFormat as Mock).mockReturnValue(OutputFormat.TEXT);
|
||||||
|
setupMetricsMock();
|
||||||
|
|
||||||
|
// Simulate an API error event (like 401 unauthorized)
|
||||||
|
const apiErrorEvent: ServerGeminiStreamEvent = {
|
||||||
|
type: GeminiEventType.Error,
|
||||||
|
value: {
|
||||||
|
error: {
|
||||||
|
message: '401 Incorrect API key provided',
|
||||||
|
status: 401,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
mockGeminiClient.sendMessageStream.mockReturnValue(
|
||||||
|
createStreamFromEvents([apiErrorEvent]),
|
||||||
|
);
|
||||||
|
|
||||||
|
let thrownError: Error | null = null;
|
||||||
|
try {
|
||||||
|
await runNonInteractive(
|
||||||
|
mockConfig,
|
||||||
|
mockSettings,
|
||||||
|
'Test input',
|
||||||
|
'prompt-id-api-error',
|
||||||
|
);
|
||||||
|
// Should not reach here
|
||||||
|
expect.fail('Expected error to be thrown');
|
||||||
|
} catch (error) {
|
||||||
|
thrownError = error as Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should throw with the API error message
|
||||||
|
expect(thrownError).toBeTruthy();
|
||||||
|
expect(thrownError?.message).toContain('401');
|
||||||
|
expect(thrownError?.message).toContain('Incorrect API key provided');
|
||||||
|
|
||||||
|
// Verify error was written to stderr
|
||||||
|
expect(processStderrSpy).toHaveBeenCalled();
|
||||||
|
const stderrCalls = processStderrSpy.mock.calls;
|
||||||
|
const errorOutput = stderrCalls.map((call) => call[0]).join('');
|
||||||
|
expect(errorOutput).toContain('401');
|
||||||
|
expect(errorOutput).toContain('Incorrect API key provided');
|
||||||
|
});
|
||||||
|
|
||||||
it('should handle FatalInputError with custom exit code in JSON format', async () => {
|
it('should handle FatalInputError with custom exit code in JSON format', async () => {
|
||||||
(mockConfig.getOutputFormat as Mock).mockReturnValue(OutputFormat.JSON);
|
(mockConfig.getOutputFormat as Mock).mockReturnValue(OutputFormat.JSON);
|
||||||
setupMetricsMock();
|
setupMetricsMock();
|
||||||
|
|||||||
@@ -308,6 +308,8 @@ export async function runNonInteractive(
|
|||||||
config.getContentGeneratorConfig()?.authType,
|
config.getContentGeneratorConfig()?.authType,
|
||||||
);
|
);
|
||||||
process.stderr.write(`${errorText}\n`);
|
process.stderr.write(`${errorText}\n`);
|
||||||
|
// Throw error to exit with non-zero code
|
||||||
|
throw new Error(errorText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@qwen-code/sdk",
|
"name": "@qwen-code/sdk",
|
||||||
"version": "0.1.1",
|
"version": "0.1.0",
|
||||||
"description": "TypeScript SDK for programmatic access to qwen-code CLI",
|
"description": "TypeScript SDK for programmatic access to qwen-code CLI",
|
||||||
"main": "./dist/index.cjs",
|
"main": "./dist/index.cjs",
|
||||||
"module": "./dist/index.mjs",
|
"module": "./dist/index.mjs",
|
||||||
|
|||||||
Reference in New Issue
Block a user