mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-18 08:01:26 +00:00
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:
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"baseUrl": "https://pub-06154ed168a24e73a86ab84db6bf15d8.r2.dev",
|
||||
"version": "6715153",
|
||||
"sha256": "1485930ea5f5309e4bdc09a55aae72eae8230eb74f0928715a0e6fe610703d9b"
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user