Add Prettier and ESLint tooling (Refs #77)
This commit is contained in:
+90
-29
@@ -1,19 +1,42 @@
|
||||
export interface ActivityEvent { id: number; created_at: string; message: string }
|
||||
export interface OperationStep { label: string; state: 'pending' | 'current' | 'done' | 'failed' }
|
||||
|
||||
interface BetaServer {
|
||||
stage: string; deployed_at: string | null; restarted_at: string | null;
|
||||
healthy_at: string | null; match_seen_at: string | null;
|
||||
export interface ActivityEvent {
|
||||
id: number;
|
||||
created_at: string;
|
||||
message: string;
|
||||
}
|
||||
export interface OperationStep {
|
||||
label: string;
|
||||
state: 'pending' | 'current' | 'done' | 'failed';
|
||||
}
|
||||
|
||||
export function betaFlow(beta: { state: string; wait_for_health: number; wait_for_match: number; testPlan?: boolean }, servers: BetaServer[]): OperationStep[] {
|
||||
interface BetaServer {
|
||||
stage: string;
|
||||
deployed_at: string | null;
|
||||
restarted_at: string | null;
|
||||
healthy_at: string | null;
|
||||
match_seen_at: string | null;
|
||||
}
|
||||
|
||||
export function betaFlow(
|
||||
beta: { state: string; wait_for_health: number; wait_for_match: number; testPlan?: boolean },
|
||||
servers: BetaServer[]
|
||||
): OperationStep[] {
|
||||
const stages = ['deploying', 'awaiting-empty', 'restarting'];
|
||||
const labels = ['Stage file changes', 'Wait for empty servers', 'Apply files and restart'];
|
||||
if (beta.wait_for_health) { stages.push('awaiting-health'); labels.push('Verify health'); }
|
||||
if (beta.wait_for_match) { stages.push('awaiting-match'); labels.push('Observe a completed match'); }
|
||||
if (beta.testPlan) { stages.push('observing'); labels.push('Evaluate test requirements'); }
|
||||
stages.push('ready'); labels.push('Review and promote');
|
||||
const positions = servers.map(s => {
|
||||
if (beta.wait_for_health) {
|
||||
stages.push('awaiting-health');
|
||||
labels.push('Verify health');
|
||||
}
|
||||
if (beta.wait_for_match) {
|
||||
stages.push('awaiting-match');
|
||||
labels.push('Observe a completed match');
|
||||
}
|
||||
if (beta.testPlan) {
|
||||
stages.push('observing');
|
||||
labels.push('Evaluate test requirements');
|
||||
}
|
||||
stages.push('ready');
|
||||
labels.push('Review and promote');
|
||||
const positions = servers.map((s) => {
|
||||
if (s.stage !== 'failed') return Math.max(0, stages.indexOf(s.stage));
|
||||
if (!s.deployed_at) return 0;
|
||||
if (!s.restarted_at) return 2;
|
||||
@@ -21,29 +44,67 @@ export function betaFlow(beta: { state: string; wait_for_health: number; wait_fo
|
||||
if (beta.wait_for_match && !s.match_seen_at) return stages.indexOf('awaiting-match');
|
||||
return stages.length - 1;
|
||||
});
|
||||
const current = beta.state === 'promoted' ? stages.length
|
||||
: beta.state === 'ready-promote' ? stages.length - 1
|
||||
: positions.length ? Math.min(...positions) : 0;
|
||||
return labels.map((label, i) => ({ label, state: i < current ? 'done' : i === current
|
||||
? beta.state === 'rolled-back' ? 'pending' : servers.some((s, j) => s.stage === 'failed' && positions[j] === i) ? 'failed' : 'current'
|
||||
: 'pending' }));
|
||||
const current =
|
||||
beta.state === 'promoted'
|
||||
? stages.length
|
||||
: beta.state === 'ready-promote'
|
||||
? stages.length - 1
|
||||
: positions.length
|
||||
? Math.min(...positions)
|
||||
: 0;
|
||||
return labels.map((label, i) => ({
|
||||
label,
|
||||
state:
|
||||
i < current
|
||||
? 'done'
|
||||
: i === current
|
||||
? beta.state === 'rolled-back'
|
||||
? 'pending'
|
||||
: servers.some((s, j) => s.stage === 'failed' && positions[j] === i)
|
||||
? 'failed'
|
||||
: 'current'
|
||||
: 'pending'
|
||||
}));
|
||||
}
|
||||
|
||||
export function campaignFlow(servers: { server?: string; restart_state: string; restarted_at: string | null; files_changed: number }[], finished: boolean,
|
||||
files: { server: string; snapshot_pending: number; apply_state: string }[] = []): OperationStep[] {
|
||||
const active = servers.filter(s => !['skipped', 'cancelled'].includes(s.restart_state));
|
||||
const positions = active.map(s => {
|
||||
export function campaignFlow(
|
||||
servers: {
|
||||
server?: string;
|
||||
restart_state: string;
|
||||
restarted_at: string | null;
|
||||
files_changed: number;
|
||||
}[],
|
||||
finished: boolean,
|
||||
files: { server: string; snapshot_pending: number; apply_state: string }[] = []
|
||||
): OperationStep[] {
|
||||
const active = servers.filter((s) => !['skipped', 'cancelled'].includes(s.restart_state));
|
||||
const positions = active.map((s) => {
|
||||
if (s.restart_state === 'done') return 5;
|
||||
if (s.restarted_at) return 4;
|
||||
const changes = files.filter(f => f.server === s.server && f.apply_state !== 'cancelled');
|
||||
if (changes.some(f => f.apply_state === 'applying')) return changes.some(f => f.snapshot_pending) ? 1 : 2;
|
||||
if (changes.length && changes.every(f => f.apply_state === 'applied')) return 3;
|
||||
const changes = files.filter((f) => f.server === s.server && f.apply_state !== 'cancelled');
|
||||
if (changes.some((f) => f.apply_state === 'applying'))
|
||||
return changes.some((f) => f.snapshot_pending) ? 1 : 2;
|
||||
if (changes.length && changes.every((f) => f.apply_state === 'applied')) return 3;
|
||||
return 0;
|
||||
});
|
||||
const current = positions.length ? Math.min(...positions) : finished ? 5 : 0;
|
||||
return ['Wait for empty servers and restart capacity', 'Capture rollback snapshots', 'Apply file changes', 'Restart servers', 'Verify health'].map((label, i) => ({
|
||||
label, state: i < current ? 'done' : i !== current ? 'pending'
|
||||
: active.some((s, j) => s.restart_state === 'failed' && positions[j] === i) ? 'failed'
|
||||
: active.some(s => ['manual', 'held'].includes(s.restart_state)) ? 'pending' : 'current'
|
||||
return [
|
||||
'Wait for empty servers and restart capacity',
|
||||
'Capture rollback snapshots',
|
||||
'Apply file changes',
|
||||
'Restart servers',
|
||||
'Verify health'
|
||||
].map((label, i) => ({
|
||||
label,
|
||||
state:
|
||||
i < current
|
||||
? 'done'
|
||||
: i !== current
|
||||
? 'pending'
|
||||
: active.some((s, j) => s.restart_state === 'failed' && positions[j] === i)
|
||||
? 'failed'
|
||||
: active.some((s) => ['manual', 'held'].includes(s.restart_state))
|
||||
? 'pending'
|
||||
: 'current'
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user