ci: 무결성 검증 통합(권장 플로우)
- scripts/make-verify-json.js: 산출물 폴더 → extras/assets JSON 생성 - scripts/verify.js: JSON 입력으로 무결성 검증(종료코드 반영) - package.json: verify 스크립트 추가 - .gitea/workflows/ci.yml: ./artifacts/export 존재 시 검증 스텝 실행
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { generateVerifyInputs } from '@/lib/exporter/verify.serialize'
|
||||
|
||||
// helper to b64
|
||||
function toB64(u8: Uint8Array) {
|
||||
if (typeof Buffer !== 'undefined') return Buffer.from(u8).toString('base64')
|
||||
throw new Error('Buffer not available')
|
||||
}
|
||||
|
||||
describe('verify.serialize (from folder maps)', () => {
|
||||
it('collects assets.integrity.index.json into extras and assets/* into assets map', async () => {
|
||||
// virtual FS
|
||||
const files: Record<string, Uint8Array> = {
|
||||
'/artifacts/export/assets.integrity.index.json': new TextEncoder().encode(JSON.stringify({ entries: [], bundleHash: 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=' })),
|
||||
'/artifacts/export/index.html': new TextEncoder().encode('<!doctype html>'),
|
||||
'/artifacts/export/assets/img/a.png': new Uint8Array([1,2,3]),
|
||||
'/artifacts/export/assets/fonts/f.woff2': new Uint8Array([4,5,6,7]),
|
||||
}
|
||||
const listDir = async (dir: string): Promise<string[]> => {
|
||||
// return child paths (recursive listing simulated by filtering)
|
||||
return Object.keys(files).filter((p) => p.startsWith(dir)).map((p) => p)
|
||||
}
|
||||
const readFile = async (p: string) => {
|
||||
const v = files[p]
|
||||
if (!v) throw new Error('not found: ' + p)
|
||||
return v
|
||||
}
|
||||
const { extras, assets } = await generateVerifyInputs('/artifacts/export', listDir, readFile)
|
||||
// extras must have only the integrity index
|
||||
expect(Object.keys(extras)).toEqual(['assets.integrity.index.json'])
|
||||
expect(extras['assets.integrity.index.json']).toBe(toB64(files['/artifacts/export/assets.integrity.index.json']))
|
||||
// assets must include assets/* files only
|
||||
expect(Object.keys(assets).sort()).toEqual(['assets/fonts/f.woff2','assets/img/a.png'])
|
||||
expect(assets['assets/img/a.png']).toBe(toB64(files['/artifacts/export/assets/img/a.png']))
|
||||
})
|
||||
|
||||
it('ignores non-asset files and missing integrity index', async () => {
|
||||
const files: Record<string, Uint8Array> = {
|
||||
'/artifacts/export/index.html': new TextEncoder().encode('<!doctype html>'),
|
||||
'/artifacts/export/assets/img/a.png': new Uint8Array([9,9]),
|
||||
}
|
||||
const listDir = async (dir: string) => Object.keys(files).filter((p) => p.startsWith(dir))
|
||||
const readFile = async (p: string) => files[p]!
|
||||
const { extras, assets } = await generateVerifyInputs('/artifacts/export', listDir, readFile)
|
||||
expect(Object.keys(extras)).toEqual([])
|
||||
expect(Object.keys(assets)).toEqual(['assets/img/a.png'])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user