chore: test deploy snapshot
This commit is contained in:
@@ -193,7 +193,8 @@ function normalizeTestServerDeploymentSnapshot(value: unknown): TestServerDeploy
|
|||||||
export async function readTestServerDeploymentState(): Promise<TestServerDeploymentSnapshot | null> {
|
export async function readTestServerDeploymentState(): Promise<TestServerDeploymentSnapshot | null> {
|
||||||
try {
|
try {
|
||||||
const raw = await readFile(getTestServerDeploymentStatePath(), 'utf8');
|
const raw = await readFile(getTestServerDeploymentStatePath(), 'utf8');
|
||||||
return normalizeTestServerDeploymentSnapshot(JSON.parse(raw));
|
const snapshot = normalizeTestServerDeploymentSnapshot(JSON.parse(raw));
|
||||||
|
return await resolveStaleRunningTestDeployment(snapshot);
|
||||||
} catch {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -209,6 +210,62 @@ async function clearTestServerDeploymentState() {
|
|||||||
await rm(getTestServerDeploymentStatePath(), { force: true }).catch(() => undefined);
|
await rm(getTestServerDeploymentStatePath(), { force: true }).catch(() => undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildStaleTestServerDeploymentFailure(snapshot: TestServerDeploymentSnapshot) {
|
||||||
|
const stalledAt = snapshot.updatedAt ?? snapshot.startedAt;
|
||||||
|
const stalledLabel = stalledAt ? `마지막 상태 갱신 ${stalledAt}` : '상태 갱신 시각 확인 불가';
|
||||||
|
return trimPreview(`TEST 배포 상태가 오래 갱신되지 않았고 잠금 파일도 없어 중단된 배포로 처리했습니다. ${stalledLabel}`, 500)
|
||||||
|
?? 'TEST 배포 상태가 오래 갱신되지 않아 중단된 배포로 처리했습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function finalizeStaleRunningTestDeployment(snapshot: TestServerDeploymentSnapshot) {
|
||||||
|
const failureMessage = buildStaleTestServerDeploymentFailure(snapshot);
|
||||||
|
const now = new Date().toISOString();
|
||||||
|
const activeStep = snapshot.steps.find((step) => step.status === 'running')?.key;
|
||||||
|
|
||||||
|
snapshot.status = 'failed';
|
||||||
|
snapshot.phase = 'failed';
|
||||||
|
snapshot.summary = buildTestServerDeploymentSummary('failed');
|
||||||
|
snapshot.completedAt = now;
|
||||||
|
snapshot.updatedAt = now;
|
||||||
|
snapshot.lastError = failureMessage;
|
||||||
|
|
||||||
|
if (activeStep) {
|
||||||
|
updateTestServerDeploymentStep(snapshot, activeStep, 'failed', failureMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeTestServerDeploymentState(snapshot);
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resolveStaleRunningTestDeployment(snapshot: TestServerDeploymentSnapshot) {
|
||||||
|
if (snapshot.status !== 'running') {
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
const freshnessSource = snapshot.updatedAt ?? snapshot.startedAt;
|
||||||
|
if (!freshnessSource) {
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
const staleForMs = Date.now() - Date.parse(freshnessSource);
|
||||||
|
if (!Number.isFinite(staleForMs) || staleForMs < TEST_SERVER_DEPLOYMENT_LOCK_STALE_MS) {
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lockPath = getTestServerDeploymentLockPath();
|
||||||
|
const lockStat = await stat(lockPath).catch(() => null);
|
||||||
|
|
||||||
|
if (lockStat?.isFile()) {
|
||||||
|
const lockFreshnessSource = normalizeDateTimeValue(lockStat.mtime.toISOString() ?? null);
|
||||||
|
if (lockFreshnessSource && Date.now() - Date.parse(lockFreshnessSource) < TEST_SERVER_DEPLOYMENT_LOCK_STALE_MS) {
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await rm(lockPath, { force: true }).catch(() => undefined);
|
||||||
|
return finalizeStaleRunningTestDeployment(snapshot);
|
||||||
|
}
|
||||||
|
|
||||||
async function acquireTestServerDeploymentLock() {
|
async function acquireTestServerDeploymentLock() {
|
||||||
const lockPath = getTestServerDeploymentLockPath();
|
const lockPath = getTestServerDeploymentLockPath();
|
||||||
await mkdir(path.dirname(lockPath), { recursive: true });
|
await mkdir(path.dirname(lockPath), { recursive: true });
|
||||||
|
|||||||
@@ -3552,6 +3552,17 @@ export function ChatSharePage() {
|
|||||||
const nextCustomContextContent = editingRoomCustomContextContent.trim();
|
const nextCustomContextContent = editingRoomCustomContextContent.trim();
|
||||||
const shouldPersistRoomDefaultContextIds = !areStringListsEqual(normalizedDefaultContextIds, inheritedDefaultContextIds);
|
const shouldPersistRoomDefaultContextIds = !areStringListsEqual(normalizedDefaultContextIds, inheritedDefaultContextIds);
|
||||||
const shouldPersistRoomCustomContext = Boolean(nextCustomContextTitle || nextCustomContextContent);
|
const shouldPersistRoomCustomContext = Boolean(nextCustomContextTitle || nextCustomContextContent);
|
||||||
|
const currentRoomDefaultContextIds = activeRoomContextSettings?.defaultContextIds ?? [];
|
||||||
|
const currentRoomCustomContextTitle = activeRoomContextSettings?.customContextTitle?.trim() ?? '';
|
||||||
|
const currentRoomCustomContextContent = activeRoomContextSettings?.customContextContent?.trim() ?? '';
|
||||||
|
const currentRoomCodexParticipants = activeRoomContextSettings?.codexParticipants ?? [];
|
||||||
|
const shouldSaveRoomContextSettings =
|
||||||
|
canManageSharedRoomSettings
|
||||||
|
&& (
|
||||||
|
!areStringListsEqual(normalizedDefaultContextIds, currentRoomDefaultContextIds)
|
||||||
|
|| nextCustomContextTitle !== currentRoomCustomContextTitle
|
||||||
|
|| nextCustomContextContent !== currentRoomCustomContextContent
|
||||||
|
);
|
||||||
const normalizedRoomTitle = editingRoomTitle.trim();
|
const normalizedRoomTitle = editingRoomTitle.trim();
|
||||||
const normalizedAccessPin = editingRoomAccessPin.trim();
|
const normalizedAccessPin = editingRoomAccessPin.trim();
|
||||||
const currentHasAccessPin = snapshot?.share.hasAccessPin === true;
|
const currentHasAccessPin = snapshot?.share.hasAccessPin === true;
|
||||||
@@ -3596,23 +3607,26 @@ export function ChatSharePage() {
|
|||||||
await ensureRoomNotificationRegistration();
|
await ensureRoomNotificationRegistration();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canManageSharedRoomSettings && nextChatType) {
|
if (shouldSaveRoomContextSettings) {
|
||||||
const nextRoomContexts =
|
const shouldKeepRoomContextRecord =
|
||||||
shouldPersistRoomDefaultContextIds || shouldPersistRoomCustomContext
|
shouldPersistRoomDefaultContextIds
|
||||||
? upsertChatRoomContextSettings(roomContexts, {
|
|| shouldPersistRoomCustomContext
|
||||||
sessionId: snapshot.conversation.sessionId,
|
|| currentRoomCodexParticipants.length > 0;
|
||||||
defaultContextIds: normalizedDefaultContextIds,
|
const nextRoomContexts = shouldKeepRoomContextRecord
|
||||||
customContextTitle: nextCustomContextTitle,
|
? upsertChatRoomContextSettings(roomContexts, {
|
||||||
customContextContent: nextCustomContextContent,
|
sessionId: snapshot.conversation.sessionId,
|
||||||
})
|
defaultContextIds: normalizedDefaultContextIds,
|
||||||
: roomContexts.filter((item) => item.sessionId !== snapshot.conversation.sessionId);
|
customContextTitle: nextCustomContextTitle,
|
||||||
|
customContextContent: nextCustomContextContent,
|
||||||
|
codexParticipants: currentRoomCodexParticipants,
|
||||||
|
})
|
||||||
|
: roomContexts.filter((item) => item.sessionId !== snapshot.conversation.sessionId);
|
||||||
|
|
||||||
await setChatContextSettingsStore({
|
await setChatContextSettingsStore({
|
||||||
defaultContexts,
|
defaultContexts,
|
||||||
chatTypeDefaults,
|
chatTypeDefaults,
|
||||||
roomContexts: nextRoomContexts,
|
roomContexts: nextRoomContexts,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const shouldSaveAccessPinSettings =
|
const shouldSaveAccessPinSettings =
|
||||||
@@ -3703,6 +3717,10 @@ export function ChatSharePage() {
|
|||||||
message,
|
message,
|
||||||
normalizedToken,
|
normalizedToken,
|
||||||
roomNotificationClientStatus.tone,
|
roomNotificationClientStatus.tone,
|
||||||
|
activeRoomContextSettings?.codexParticipants,
|
||||||
|
activeRoomContextSettings?.customContextContent,
|
||||||
|
activeRoomContextSettings?.customContextTitle,
|
||||||
|
activeRoomContextSettings?.defaultContextIds,
|
||||||
roomContexts,
|
roomContexts,
|
||||||
setChatContextSettingsStore,
|
setChatContextSettingsStore,
|
||||||
snapshot?.conversation.notifyOffline,
|
snapshot?.conversation.notifyOffline,
|
||||||
|
|||||||
Reference in New Issue
Block a user