mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-19 07:54:38 +00:00
Merge remote-tracking branch 'origin/main' into feat/commit-attribution
# Conflicts: # packages/core/src/core/client.ts
This commit is contained in:
commit
acd06e3461
81 changed files with 10065 additions and 1420 deletions
|
|
@ -20,7 +20,9 @@ const __filename = fileURLToPath(import.meta.url);
|
|||
const __dirname = dirname(__filename);
|
||||
|
||||
const PACKAGE_NAME = 'qwen-code-sdk';
|
||||
const TAG_PREFIX = 'sdk-python-';
|
||||
const TAG_PREFIX = 'sdk-python-v';
|
||||
const NETWORK_COMMAND_TIMEOUT_MS = 30_000;
|
||||
const LOCAL_COMMAND_TIMEOUT_MS = 10_000;
|
||||
|
||||
function readPyprojectVersion() {
|
||||
const pyprojectPath = join(__dirname, '..', 'pyproject.toml');
|
||||
|
|
@ -117,7 +119,7 @@ function toBaseVersion(version) {
|
|||
async function getAllVersionsFromPyPI() {
|
||||
const response = await fetch(`https://pypi.org/pypi/${PACKAGE_NAME}/json`, {
|
||||
headers: { Accept: 'application/json' },
|
||||
signal: AbortSignal.timeout(30_000),
|
||||
signal: AbortSignal.timeout(NETWORK_COMMAND_TIMEOUT_MS),
|
||||
});
|
||||
|
||||
if (response.status === 404) {
|
||||
|
|
@ -241,28 +243,67 @@ function getUtcTimestamp() {
|
|||
}
|
||||
|
||||
function getGitShortHash() {
|
||||
return execSync('git rev-parse --short HEAD').toString().trim();
|
||||
try {
|
||||
return execSync('git rev-parse --short HEAD', {
|
||||
timeout: LOCAL_COMMAND_TIMEOUT_MS,
|
||||
})
|
||||
.toString()
|
||||
.trim();
|
||||
} catch (error) {
|
||||
if (isTimeoutError(error)) {
|
||||
throw new Error(
|
||||
`git rev-parse timed out after ${LOCAL_COMMAND_TIMEOUT_MS / 1000}s — local git may be unresponsive`,
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function getReleaseState({ packageVersion, releaseTag }, allVersions) {
|
||||
function isTimeoutError(error) {
|
||||
// Node.js execSync timeout: `code` is 'ETIMEDOUT' on POSIX; on some
|
||||
// versions/platforms `killed` is true with signal 'SIGTERM' or null.
|
||||
// Match the pattern used in packages/core/src/utils/pdf.ts.
|
||||
return (
|
||||
error.code === 'ETIMEDOUT' ||
|
||||
(error.killed === true &&
|
||||
(error.signal === 'SIGTERM' ||
|
||||
error.signal === undefined ||
|
||||
error.signal === null))
|
||||
);
|
||||
}
|
||||
|
||||
async function getReleaseState(
|
||||
{ packageVersion, releaseVersion },
|
||||
allVersions,
|
||||
) {
|
||||
const state = {
|
||||
packageVersionExistsOnPyPI: allVersions.includes(packageVersion),
|
||||
gitTagExists: false,
|
||||
githubReleaseExists: false,
|
||||
};
|
||||
const fullTag = `${TAG_PREFIX}${releaseTag}`;
|
||||
const fullTag = `${TAG_PREFIX}${releaseVersion}`;
|
||||
try {
|
||||
const tagOutput = execSync(`git tag -l '${fullTag}'`).toString().trim();
|
||||
const tagOutput = execSync(`git tag -l '${fullTag}'`, {
|
||||
timeout: LOCAL_COMMAND_TIMEOUT_MS,
|
||||
})
|
||||
.toString()
|
||||
.trim();
|
||||
if (tagOutput === fullTag) {
|
||||
state.gitTagExists = true;
|
||||
}
|
||||
} catch (error) {
|
||||
if (isTimeoutError(error)) {
|
||||
throw new Error(
|
||||
`git tag -l timed out after ${LOCAL_COMMAND_TIMEOUT_MS / 1000}s — local git may be unresponsive`,
|
||||
);
|
||||
}
|
||||
throw new Error(`Failed to check git tags for conflicts: ${error.message}`);
|
||||
}
|
||||
|
||||
try {
|
||||
const output = execSync(
|
||||
`gh release view "${fullTag}" --json tagName --jq .tagName`,
|
||||
{ timeout: NETWORK_COMMAND_TIMEOUT_MS },
|
||||
)
|
||||
.toString()
|
||||
.trim();
|
||||
|
|
@ -270,6 +311,13 @@ async function getReleaseState({ packageVersion, releaseTag }, allVersions) {
|
|||
state.githubReleaseExists = true;
|
||||
}
|
||||
} catch (error) {
|
||||
// Timeout check must precede isExpectedMissingGitHubRelease — a timed-out
|
||||
// process may emit partial stderr matching "release not found".
|
||||
if (isTimeoutError(error)) {
|
||||
throw new Error(
|
||||
`gh release view timed out after ${NETWORK_COMMAND_TIMEOUT_MS / 1000}s checking "${fullTag}" — GitHub API may be unavailable`,
|
||||
);
|
||||
}
|
||||
if (!isExpectedMissingGitHubRelease(error)) {
|
||||
throw new Error(
|
||||
`Failed to check GitHub releases for conflicts: ${error.message}`,
|
||||
|
|
@ -435,7 +483,7 @@ async function getVersion(options = {}) {
|
|||
const releaseState = await getReleaseState(
|
||||
{
|
||||
packageVersion: versionData.packageVersion,
|
||||
releaseTag: `v${versionData.releaseVersion}`,
|
||||
releaseVersion: versionData.releaseVersion,
|
||||
},
|
||||
allVersions,
|
||||
);
|
||||
|
|
@ -481,11 +529,11 @@ async function getVersion(options = {}) {
|
|||
|
||||
if (releaseState.githubReleaseExists) {
|
||||
console.error(
|
||||
`GitHub release ${TAG_PREFIX}v${versionData.releaseVersion} already exists.`,
|
||||
`GitHub release ${TAG_PREFIX}${versionData.releaseVersion} already exists.`,
|
||||
);
|
||||
} else if (releaseState.gitTagExists) {
|
||||
console.error(
|
||||
`::warning::Orphan git tag ${TAG_PREFIX}v${versionData.releaseVersion} exists without a PyPI version or GitHub release. Skipping to next version slot.`,
|
||||
`::warning::Orphan git tag ${TAG_PREFIX}${versionData.releaseVersion} exists without a PyPI version or GitHub release. Skipping to next version slot.`,
|
||||
);
|
||||
} else if (releaseState.packageVersionExistsOnPyPI) {
|
||||
console.error(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue