diff --git a/src/server/config.ts b/src/server/config.ts index 6e4b0cc..11a9813 100644 --- a/src/server/config.ts +++ b/src/server/config.ts @@ -59,6 +59,7 @@ export function buildConfig(env: NodeJS.ProcessEnv) { return { authToken: env.AUTH_TOKEN || 'change-me-admin-token', proxyToken: env.PROXY_TOKEN || 'change-me-proxy-sk-token', + deployHelperToken: parseOptionalSecret(env.DEPLOY_HELPER_TOKEN || env.UPDATE_CENTER_HELPER_TOKEN), codexClientId: parseOptionalSecret(env.CODEX_CLIENT_ID) || DEFAULT_CODEX_CLIENT_ID, claudeClientId: parseOptionalSecret(env.CLAUDE_CLIENT_ID) || DEFAULT_CLAUDE_CLIENT_ID, claudeClientSecret: parseOptionalSecret(env.CLAUDE_CLIENT_SECRET), diff --git a/src/server/routes/api/updateCenter.test.ts b/src/server/routes/api/updateCenter.test.ts index b9ff351..ba20e0c 100644 --- a/src/server/routes/api/updateCenter.test.ts +++ b/src/server/routes/api/updateCenter.test.ts @@ -32,11 +32,13 @@ vi.mock('../../services/updateCenterHelperClient.js', () => ({ })); type DbModule = typeof import('../../db/index.js'); +type ConfigModule = typeof import('../../config.js'); describe('update center routes', () => { let app: FastifyInstance; let db: DbModule['db']; let schema: DbModule['schema']; + let appConfig: ConfigModule['config']; let dataDir = ''; let resetBackgroundTasks: (() => void) | null = null; let getBackgroundTask: ((taskId: string) => { status: string; logs?: Array<{ message: string }> } | null) | null = null; @@ -67,10 +69,12 @@ describe('update center routes', () => { process.env.DEPLOY_HELPER_TOKEN = 'helper-token'; await import('../../db/migrate.js'); + const configModule = await import('../../config.js'); const dbModule = await import('../../db/index.js'); const routesModule = await import('./updateCenter.js'); const backgroundTaskModule = await import('../../services/backgroundTaskService.js'); + appConfig = configModule.config; db = dbModule.db; schema = dbModule.schema; resetBackgroundTasks = backgroundTaskModule.__resetBackgroundTasksForTests; @@ -208,6 +212,54 @@ describe('update center routes', () => { }); }); + it('uses the shared config helper token when request-time env lookup is unavailable', async () => { + fetchLatestStableGitHubReleaseMock.mockResolvedValue({ + source: 'github-release', + rawVersion: 'v1.3.0', + normalizedVersion: '1.3.0', + url: 'https://github.com/cita-777/metapi/releases/tag/v1.3.0', + }); + getUpdateCenterHelperStatusMock.mockResolvedValue({ + ok: true, + releaseName: 'metapi', + namespace: 'ai', + revision: '12', + imageRepository: '1467078763/metapi', + imageTag: '1.2.3', + healthy: true, + }); + + await saveValidConfig(); + + const originalEnvToken = process.env.DEPLOY_HELPER_TOKEN; + delete process.env.DEPLOY_HELPER_TOKEN; + (appConfig as typeof appConfig & { deployHelperToken?: string }).deployHelperToken = 'helper-token'; + + try { + const statusResponse = await app.inject({ + method: 'GET', + url: '/api/update-center/status', + }); + + expect(statusResponse.statusCode).toBe(200); + expect(getUpdateCenterHelperStatusMock).toHaveBeenCalledWith( + expect.objectContaining({ + helperBaseUrl: 'http://metapi-deploy-helper.ai.svc.cluster.local:9850', + }), + 'helper-token', + ); + expect(statusResponse.json()).toMatchObject({ + helper: { + ok: true, + healthy: true, + }, + }); + } finally { + process.env.DEPLOY_HELPER_TOKEN = originalEnvToken; + delete (appConfig as typeof appConfig & { deployHelperToken?: string }).deployHelperToken; + } + }); + it('dedupes deploy requests while a task is already running', async () => { await saveValidConfig(); diff --git a/src/server/routes/api/updateCenter.ts b/src/server/routes/api/updateCenter.ts index 55230a2..8104e5e 100644 --- a/src/server/routes/api/updateCenter.ts +++ b/src/server/routes/api/updateCenter.ts @@ -1,4 +1,5 @@ import { FastifyInstance } from 'fastify'; +import { config as runtimeConfig } from '../../config.js'; import { appendBackgroundTaskLog, @@ -35,7 +36,12 @@ const UPDATE_CENTER_DEPLOY_TASK_TYPE = 'update-center.deploy'; const UPDATE_CENTER_DEPLOY_DEDUPE_KEY = 'update-center.deploy'; function getUpdateCenterHelperToken(): string { - return String(process.env.DEPLOY_HELPER_TOKEN || process.env.UPDATE_CENTER_HELPER_TOKEN || '').trim(); + return String( + runtimeConfig.deployHelperToken + || process.env.DEPLOY_HELPER_TOKEN + || process.env.UPDATE_CENTER_HELPER_TOKEN + || '', + ).trim(); } function assertDeployableConfig(config: UpdateCenterConfig) {