rushabhcodes/fidget-counter
A tscircuit package created by rushabhcodes.
- Version
- 1.0.31
- License
- unset
- Stars
- 0
validation/check-cloud-build.mjs
import assert from "node:assert/strict"
import { createHash } from "node:crypto"
import { cpSync, mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"
import { tmpdir } from "node:os"
import { dirname, resolve } from "node:path"
import { fileURLToPath } from "node:url"
import { spawnSync } from "node:child_process"
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..")
const scratch = mkdtempSync(resolve(tmpdir(), "fidget-cloud-check-"))
const manifest = JSON.parse(readFileSync(resolve(root, "cloud-assets/manifest.json")))
const originalPackage = JSON.parse(readFileSync(resolve(root, "package.json")))
const hash = bytes => createHash("sha256").update(bytes).digest("hex")
const writePackage = value => writeFileSync(resolve(scratch, "package.json"), JSON.stringify(value, null, 2) + "\n")
const run = (cloud, expectedError) => {
const result = spawnSync(process.execPath, ["cloud-build.mjs"], {
cwd: scratch,
env: { ...process.env, TSCIRCUIT_INSIDE_BUILD_COMMAND: cloud ? "1" : "0" },
encoding: "utf8",
})
const output = result.stdout + result.stderr
if (expectedError) {
assert.notEqual(result.status, 0, "A stale preview was accepted")
assert(output.includes(expectedError), output)
} else {
assert.equal(result.status, 0, output)
for (const artifact of [...manifest.artifacts,...(manifest.variantArtifacts ?? [])])
assert.equal(hash(readFileSync(resolve(scratch, artifact.output))), artifact.sha256)
}
}
try {
const files = new Set([...Object.keys(manifest.inputs), ...manifest.artifacts.flatMap(a => a.sourceParts ?? [a.source]),
"cloud-assets/manifest.json", ...manifest.cadInputArchives.flatMap(a => a.sourceParts ?? [a.source]), "package.json", "bun.lock"])
for (const name of files) {
const target = resolve(scratch, name)
mkdirSync(dirname(target), { recursive: true })
cpSync(resolve(root, name), target)
}
run(false)
// TSCI receives the packed exports; its build must reconstruct exact bytes.
for (const name of manifest.cadInputArchives.flatMap(a => a.files)) rmSync(resolve(scratch, name))
run(false)
for (const name of manifest.cadInputArchives.flatMap(a => a.files))
assert.equal(hash(readFileSync(resolve(scratch, name))), manifest.inputs[name])
const cadPath = resolve(scratch, manifest.cadInputArchives.flatMap(a => a.files)[0])
const cadBytes = readFileSync(cadPath)
writeFileSync(cadPath, "changed CAD export")
run(false, `${manifest.cadInputArchives.flatMap(a => a.files)[0]} changed`)
writeFileSync(cadPath, cadBytes)
const chunkedCad = manifest.cadInputArchives.find(a => a.sourceParts?.length > 1)
assert(chunkedCad,"Exercise chunked CAD restoration")
const cadChunkPath=resolve(scratch,chunkedCad.sourceParts[0])
const cadChunkBytes=readFileSync(cadChunkPath)
writeFileSync(cadChunkPath,"corrupted CAD archive chunk")
run(false,"Invalid checked CAD input archive")
writeFileSync(cadChunkPath,cadChunkBytes)
const chunked = manifest.artifacts.find(a => a.sourceParts?.length > 1)
assert(chunked, "Exercise chunked preview restore")
const partPath = resolve(scratch, chunked.sourceParts[0])
const partBytes = readFileSync(partPath)
writeFileSync(partPath, "corrupted preview chunk")
run(false, "Invalid checked artifact")
writeFileSync(partPath, partBytes)
// Match the registry's compiler substitution and the subsequent CI install.
const cloudPackage = structuredClone(originalPackage)
cloudPackage.version = "1.0.99"
for (const field of ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"])
if (cloudPackage[field]) delete cloudPackage[field].tscircuit
cloudPackage.devDependencies.tscircuit = "file:/root/.bun/install/global/node_modules/tscircuit"
writePackage(cloudPackage)
writeFileSync(resolve(scratch, "bun.lock"), "Regenerated by the cloud dependency install\n")
assert.notEqual(hash(readFileSync(resolve(scratch, "package.json"))), hash(readFileSync(resolve(root, "package.json"))))
run(true)
// Older cloud workers remove the dependency without adding a file alias.
delete cloudPackage.devDependencies.tscircuit
writePackage(cloudPackage)
run(true)
writePackage(originalPackage)
run(false, "local bun.lock changed")
cloudPackage.dependencies["@tsci/tscircuit.standard-jst-programmer"] = "0.8.1"
writePackage(cloudPackage)
run(true, "component dependencies changed")
const changedCompiler = structuredClone(originalPackage)
changedCompiler.dependencies.tscircuit = "latest"
writePackage(changedCompiler)
run(true, "unexpected tscircuit compiler dependency")
writePackage(originalPackage)
const index = readFileSync(resolve(scratch, "index.circuit.tsx"))
writeFileSync(resolve(scratch, "index.circuit.tsx"), Buffer.concat([index, Buffer.from("\n// changed source\n")]))
run(true, "index.circuit.tsx changed")
writeFileSync(resolve(scratch, "index.circuit.tsx"), index)
const contract = readFileSync(resolve(scratch, "routing-contract.json"))
writeFileSync(resolve(scratch, "routing-contract.json"), "{}\n")
run(true, "routing-contract.json changed")
writeFileSync(resolve(scratch, "routing-contract.json"), contract)
writeFileSync(resolve(scratch, "cloud-assets/pcb.png.gz.b64"), Buffer.from("corrupted preview").toString("base64"))
const result = spawnSync(process.execPath, ["cloud-build.mjs"], {
cwd: scratch, env: { ...process.env, TSCIRCUIT_INSIDE_BUILD_COMMAND: "1" }, encoding: "utf8",
})
assert.notEqual(result.status, 0, "A corrupted preview was accepted")
console.log("Pass: local and both cloud bootstrap formats restore all six artifacts; changed dependencies, lockfile, source and corrupted assets are rejected")
} finally {
rmSync(scratch, { recursive: true, force: true })
}