harden UI builder artifact bootstrap with verified pinned metadata (#9189)

* feat: harden UI builder artifact bootstrap with verified pinned metadata

* fix: emit tab-indented artifact json to match prettier config

* refactor: rewrite artifact json with node instead of python

* refactor: simplify bootstrap to flat script, drop test scaffolding
This commit is contained in:
Ruben Fiszel
2026-05-16 07:40:29 +00:00
committed by GitHub
parent 4e25954722
commit 302ce58e98
3 changed files with 59 additions and 49 deletions
@@ -0,0 +1,5 @@
{
"baseUrl": "https://pub-06154ed168a24e73a86ab84db6bf15d8.r2.dev",
"version": "6715153",
"sha256": "1485930ea5f5309e4bdc09a55aae72eae8230eb74f0928715a0e6fe610703d9b"
}
+34 -39
View File
@@ -1,55 +1,50 @@
import path from 'path'
import fs from 'fs'
import { createHash } from 'node:crypto'
import fs from 'node:fs'
import path from 'node:path'
import artifact from './ui_builder_artifact.json' with { type: 'json' }
// Check if we're in node_modules (installed as dependency)
// Skip when installed as a dependency or outside the root project
if (process.cwd().includes('node_modules')) {
console.log('Skipping postinstall - running as dependency');
process.exit(0);
console.log('Skipping postinstall - running as dependency')
process.exit(0)
}
// Check if we're in the root project
if (process.env.INIT_CWD && process.env.INIT_CWD !== process.cwd()) {
console.log('Skipping postinstall - not root project');
process.exit(0);
console.log('Skipping postinstall - not root project')
process.exit(0)
}
// Your actual postinstall logic here
console.log('Running postinstall for root project');
console.log('Running postinstall for root project')
const tarUrl = `${artifact.baseUrl}/ui_builder-${artifact.version}.tar.gz`
const response = await fetch(tarUrl)
if (!response.ok) {
throw new Error(`Failed to download ${tarUrl}: ${response.status} ${response.statusText}`)
}
import { x } from 'tar'
const buffer = Buffer.from(await response.arrayBuffer())
const sha256 = createHash('sha256').update(buffer).digest('hex')
if (sha256 !== artifact.sha256) {
throw new Error(
`UI builder artifact checksum mismatch: expected ${artifact.sha256}, got ${sha256}`
)
}
const tarUrl = 'https://pub-06154ed168a24e73a86ab84db6bf15d8.r2.dev/ui_builder-6715153.tar.gz'
const outputTarPath = path.join(process.cwd(), 'ui_builder.tar.gz')
const extractTo = path.join(process.cwd(), 'static/ui_builder/')
import { fileURLToPath } from 'url'
import { dirname } from 'path'
await fs.promises.mkdir(extractTo, { recursive: true })
await fs.promises.writeFile(outputTarPath, buffer)
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
// Download the tar file
const response = await fetch(tarUrl)
const buffer = await response.arrayBuffer()
await fs.promises.writeFile(outputTarPath, Buffer.from(buffer))
// Create extract directory if it doesn't exist
const { x } = await import('tar')
try {
await fs.promises.mkdir(extractTo, { recursive: true })
} catch (err) {
if (err.code !== 'EEXIST') {
throw err
}
await x({
file: outputTarPath,
cwd: extractTo,
sync: false,
gzip: true,
preservePaths: false
})
} finally {
await fs.promises.rm(outputTarPath, { force: true })
}
await x({
file: outputTarPath,
cwd: extractTo,
sync: false,
gzip: true
})
await fs.promises.unlink(outputTarPath)
+20 -10
View File
@@ -1,20 +1,30 @@
#!/bin/bash
# Auto-detect operating system
if [[ "$OSTYPE" == "darwin"* ]]; then
IS_MAC=true
else
IS_MAC=false
fi
set -euo pipefail
cd ~/windmill-code-ui-builder
HASH=$(git rev-parse --short HEAD)
HASH=${HASH::-1}
ARTIFACT_URL="https://pub-06154ed168a24e73a86ab84db6bf15d8.r2.dev/ui_builder-${HASH}.tar.gz"
TMP_FILE=$(mktemp)
trap 'rm -f "$TMP_FILE"' EXIT
echo "Using UI Builder hash: ${HASH}"
curl -fsSL "$ARTIFACT_URL" -o "$TMP_FILE"
if [ "$IS_MAC" = true ]; then
sed -i '' "s/ui_builder-[^.]*\.tar\.gz/ui_builder-${HASH}.tar.gz/" ../windmill/frontend/scripts/untar_ui_builder.js
if command -v sha256sum >/dev/null 2>&1; then
SHA256=$(sha256sum "$TMP_FILE" | awk '{print $1}')
else
sed -i "s/ui_builder-[^.]*\.tar\.gz/ui_builder-${HASH}.tar.gz/" ../windmill/frontend/scripts/untar_ui_builder.js
SHA256=$(shasum -a 256 "$TMP_FILE" | awk '{print $1}')
fi
echo "Using UI Builder sha256: ${SHA256}"
node -e '
const fs = require("fs")
const [version, sha256] = process.argv.slice(1)
const artifactPath = "../windmill/frontend/scripts/ui_builder_artifact.json"
const artifact = JSON.parse(fs.readFileSync(artifactPath, "utf8"))
artifact.version = version
artifact.sha256 = sha256
fs.writeFileSync(artifactPath, JSON.stringify(artifact, null, "\t") + "\n")
' "$HASH" "$SHA256"