fix(ci): point release-metadata checks at the relocated update and publish guards
Some checks are pending
ci / 정본·보안·린트·타입·테스트 (push) Waiting to run
ci / 워크스페이스 빌드 검증 (push) Blocked by required conditions
ci / 모바일 린트·타입·Jest (push) Waiting to run
ci / Supabase Edge Functions + Cloudflare Worker (push) Waiting to run
ci / .NET API 서버 테스트 (push) Waiting to run
deploy-site / deploy (push) Waiting to run
Some checks are pending
ci / 정본·보안·린트·타입·테스트 (push) Waiting to run
ci / 워크스페이스 빌드 검증 (push) Blocked by required conditions
ci / 모바일 린트·타입·Jest (push) Waiting to run
ci / Supabase Edge Functions + Cloudflare Worker (push) Waiting to run
ci / .NET API 서버 테스트 (push) Waiting to run
deploy-site / deploy (push) Waiting to run
CI run 121 failed at "버전·계약 정본 대조": earlier refactors moved update gating from UpdateService into update-policy.ts (evaluateUpdateOffer ties decideUpdate + isWithinRollout), the differential-download switch into update-adapters.ts, and the Forgejo re-release guard into lib/immutable-package-guard.mjs (sha256 comparison, abort on conflict). The checks still looked for the old markers in the old files. They now verify the same guarantees where the code lives, and the self-test's negative case targets assertNoImmutableConflicts. Also clears the lint gate: a control-character regex in Keycap (range now starts at U+0020) and unused helpers in two red-team tests.
This commit is contained in:
parent
171be8f4e8
commit
f505a03d34
4 changed files with 18 additions and 37 deletions
|
|
@ -28,7 +28,7 @@ interface KeycapProps {
|
|||
}
|
||||
|
||||
/** 모노 폰트는 라틴 키 이름에만 — 한글("마우스 왼쪽 버튼")은 모노에 글리프가 없어 자간이 벌어진다. */
|
||||
const NON_LATIN = /[^\u0000-\u024f]/
|
||||
const NON_LATIN = /[^ -\u024f]/
|
||||
|
||||
export function Keycap({ children, size = 'md', muted = false }: KeycapProps): React.ReactElement {
|
||||
const spec = SIZE_SPEC[size]
|
||||
|
|
|
|||
|
|
@ -17,19 +17,6 @@ vi.mock('../../../src/main/services/LoggerService', () => ({
|
|||
getLogger: () => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }),
|
||||
}))
|
||||
|
||||
interface Deferred<T> {
|
||||
promise: Promise<T>
|
||||
resolve: (value: T) => void
|
||||
}
|
||||
|
||||
function deferred<T>(): Deferred<T> {
|
||||
let resolve!: (value: T) => void
|
||||
const promise = new Promise<T>((res) => {
|
||||
resolve = res
|
||||
})
|
||||
return { promise, resolve }
|
||||
}
|
||||
|
||||
type SttResult = { text: string; segments: never[]; language: string; duration: number; processingTime: number }
|
||||
const result = (text: string): SttResult => ({ text, segments: [], language: 'ko', duration: 1, processingTime: 1 })
|
||||
|
||||
|
|
@ -126,7 +113,6 @@ vi.mock('../../../src/main/services/ScreenContextService', () => ({
|
|||
}))
|
||||
|
||||
type VoiceModeModule = typeof import('../../../src/main/services/VoiceModeService')
|
||||
let getVoiceModeService: VoiceModeModule['getVoiceModeService']
|
||||
let createWithStore: VoiceModeModule['createVoiceModeServiceForTests']
|
||||
|
||||
const SPEECH = Buffer.alloc(16000 * 2) // 1초
|
||||
|
|
@ -140,21 +126,6 @@ function advanceClock(ms: number): void {
|
|||
vi.spyOn(Date, 'now').mockReturnValue(base + ms)
|
||||
}
|
||||
|
||||
function key(
|
||||
actionId: 'dictation' | 'hands-free',
|
||||
type: 'pressed' | 'released',
|
||||
isDoublePress: boolean,
|
||||
): KeyBindingTriggerPayload {
|
||||
return {
|
||||
actionId,
|
||||
type,
|
||||
isDoublePress,
|
||||
holdMode: actionId === 'dictation',
|
||||
timestamp: Date.now(),
|
||||
durationMs: 0,
|
||||
} as unknown as KeyBindingTriggerPayload
|
||||
}
|
||||
|
||||
function screenContext(appName: string): { context: { appName: string; windowTitle: string; selectedText: null; capturedAt: number }; selectedTextAttempted: boolean } {
|
||||
return { context: { appName, windowTitle: 'w', selectedText: null, capturedAt: 0 }, selectedTextAttempted: false }
|
||||
}
|
||||
|
|
@ -196,7 +167,6 @@ beforeEach(async () => {
|
|||
screen.captureSelectedText.mockResolvedValue('선택 문장')
|
||||
const mod = await import('../../../src/main/services/VoiceModeService')
|
||||
mod.resetVoiceModeServiceForTests()
|
||||
getVoiceModeService = mod.getVoiceModeService
|
||||
createWithStore = mod.createVoiceModeServiceForTests
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,10 @@ describe('parseUpdatePolicy — 안전 필드 fail-closed', () => {
|
|||
})
|
||||
|
||||
it('필드가 아예 없으면 기존처럼 기본값을 쓴다', () => {
|
||||
const { killSwitch: _k, stagingPercentage: _s, ...rest } = BASE
|
||||
// 두 필드를 뺀 정책 — 나머지는 BASE 그대로
|
||||
const rest = Object.fromEntries(
|
||||
Object.entries(BASE).filter(([field]) => field !== 'killSwitch' && field !== 'stagingPercentage'),
|
||||
)
|
||||
const parsed = parseUpdatePolicy(rest)
|
||||
expect(parsed.killSwitch).toBe(DEFAULT_UPDATE_POLICY.killSwitch)
|
||||
expect(parsed.stagingPercentage).toBe(DEFAULT_UPDATE_POLICY.stagingPercentage)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue