Compose-ready workspace: packages/zappier (rate card, portal, Stripe), packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier (CLI app), vendor/zapier-platform, and research/zapier vendor corpus. Gate 0 structure checks pass. Product code and research are not yet wired.
281 lines
8.7 KiB
Bash
Executable file
281 lines
8.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# Exit on any command failure; in pipelines, fail if any command (not just the
|
|
# last) returns non-zero.
|
|
set -eo pipefail
|
|
|
|
#
|
|
# Build boilerplate - a zip file that is generated as if you `zapier-platform build` an empty CLI
|
|
# app. This zip file acts as a runtime for all the UI apps.
|
|
#
|
|
# Usage:
|
|
#
|
|
# $ ./scripts/build.sh [CORE_VERSION] [LEGACY_SCRIPTING_RUNNER_VERSION]
|
|
#
|
|
# This scripts accepts two optional arguments - core and legacy-scripting-runner
|
|
# versions. If the version is specified, that packgage will be downloaded from npm
|
|
# instead of built from local.
|
|
#
|
|
# For example, this builds core and legacy-scripting-runner from local code:
|
|
#
|
|
# $ ./scripts/build.sh
|
|
#
|
|
# Download both core and legacy-scripting-runner from npm:
|
|
#
|
|
# $ ./scripts/build.sh 9.7.1 3.8.5
|
|
#
|
|
# Build core from local and download legacy-scripting-runner from npm:
|
|
#
|
|
# $ ./scripts/build.sh '' 3.8.5
|
|
#
|
|
# Download core from npm and build legacy-scripting-runner from local:
|
|
#
|
|
# $ ./scripts/build.sh 9.7.1
|
|
#
|
|
|
|
update_deps() {
|
|
package_json=$1
|
|
core_version=$2
|
|
lsr_version=$3
|
|
|
|
cmd_for_core="s|\"zapier-platform-core\": \"[^\"]*\""
|
|
cmd_for_core+="|\"zapier-platform-core\": \"$core_version\"|g"
|
|
|
|
cmd_for_lsr="s|\"zapier-platform-legacy-scripting-runner\": \"[^\"]*\""
|
|
cmd_for_lsr+="|\"zapier-platform-legacy-scripting-runner\": \"$lsr_version\"|g"
|
|
|
|
sed -i.bak "$cmd_for_core" "$package_json"
|
|
sed -i.bak "$cmd_for_lsr" "$package_json"
|
|
|
|
rm -f "$package_json.bak"
|
|
}
|
|
|
|
inspect_build() {
|
|
local zip_file=$1
|
|
local expected_core=$2
|
|
local expected_schema=$3
|
|
local expected_lsr=$4
|
|
|
|
temp_dir="`dirname $zip_file`/_temp"
|
|
unzip -q $zip_file -d $temp_dir
|
|
|
|
# Build a JSON object of expected versions and compare against actual
|
|
actual=$(find $temp_dir/node_modules -maxdepth 2 -name package.json -path "*/zapier-platform-*/*" | xargs cat | jq -s '
|
|
map({(.name): .version}) | add')
|
|
echo "$actual" | jq .
|
|
|
|
rm -rf $temp_dir
|
|
|
|
expected=$(jq -n \
|
|
--arg core "$expected_core" \
|
|
--arg schema "$expected_schema" \
|
|
--arg lsr "$expected_lsr" \
|
|
'{"zapier-platform-core": $core, "zapier-platform-schema": $schema, "zapier-platform-legacy-scripting-runner": $lsr}')
|
|
|
|
if echo "$actual" | jq -e --argjson expected "$expected" '. == $expected' > /dev/null 2>&1; then
|
|
echo "All dependency versions match ✅"
|
|
else
|
|
echo "ERROR: dependency version mismatch ❌"
|
|
echo "Expected: $expected"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_size() {
|
|
local min_mb=3
|
|
local max_mb=10
|
|
local min_bytes=$((min_mb * 1024 * 1024))
|
|
local max_bytes=$((max_mb * 1024 * 1024))
|
|
local file_size=$(stat -f%z "$1" 2>/dev/null || stat -c%s "$1")
|
|
local size_mb=$(echo "scale=2; $file_size / 1024 / 1024" | bc)
|
|
if [[ $file_size -lt $min_bytes || $file_size -gt $max_bytes ]]; then
|
|
echo "ERROR: zip file size ${size_mb} MB is outside expected range (${min_mb}-${max_mb} MB) ❌"
|
|
return 1
|
|
else
|
|
echo "Zip file size ${size_mb} MB is within expected range (${min_mb}-${max_mb} MB) ✅"
|
|
fi
|
|
}
|
|
|
|
test_build() {
|
|
temp_dir="`dirname $1`/_temp"
|
|
unzip -q $1 -d $temp_dir
|
|
|
|
pushd $temp_dir > /dev/null
|
|
local rc=0
|
|
node zapierwrapper.js || rc=$?
|
|
popd > /dev/null
|
|
rm -rf $temp_dir
|
|
|
|
if [[ $rc -eq 0 ]]; then
|
|
echo "Entry point can be loaded successfully ✅"
|
|
else
|
|
echo "Entry point failed to load ❌"
|
|
fi
|
|
return $rc
|
|
}
|
|
|
|
# Get the absolute path of the directory holding this script file
|
|
SCRIPT_DIR=$(dirname $0)
|
|
pushd $SCRIPT_DIR > /dev/null
|
|
SCRIPT_DIR=$(pwd)
|
|
popd > /dev/null
|
|
|
|
REPO_DIR=$(dirname $(dirname $SCRIPT_DIR))
|
|
CORE_DIR="$REPO_DIR/packages/core"
|
|
SCHEMA_DIR="$REPO_DIR/packages/schema"
|
|
LSR_DIR="$REPO_DIR/packages/legacy-scripting-runner"
|
|
BOILERPLATE_DIR="$REPO_DIR/boilerplate"
|
|
|
|
BUILD_DIR="$BOILERPLATE_DIR/build"
|
|
|
|
# Restore modified files on exit (success or failure)
|
|
cleanup() {
|
|
local exit_code=$?
|
|
# Restore pnpm-workspace.yaml if a backup exists
|
|
if [ -f "$BOILERPLATE_DIR/pnpm-workspace.yaml.bak" ]; then
|
|
mv "$BOILERPLATE_DIR/pnpm-workspace.yaml.bak" "$BOILERPLATE_DIR/pnpm-workspace.yaml"
|
|
fi
|
|
# Restore package.json placeholders
|
|
update_deps "$BOILERPLATE_DIR/package.json" PLACEHOLDER PLACEHOLDER
|
|
exit $exit_code
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# Prevent leftover old builds from being included in new build
|
|
if [ -d $BUILD_DIR ]; then
|
|
echo "Removing existing boilerplate/build directory..."
|
|
rm -r "$BUILD_DIR"
|
|
fi
|
|
|
|
# Prevent stale dependencies from being included in new build
|
|
if [ -d "$BOILERPLATE_DIR/node_modules" ]; then
|
|
echo "Removing existing boilerplate/node_modules directory..."
|
|
rm -r "$BOILERPLATE_DIR/node_modules"
|
|
fi
|
|
|
|
mkdir -p $BUILD_DIR
|
|
|
|
# Copy files
|
|
cp "$CORE_DIR/include/zapierwrapper.js" "$BOILERPLATE_DIR/"
|
|
|
|
# Get core version
|
|
if [ "$1" == "" ]; then
|
|
pushd $CORE_DIR > /dev/null
|
|
CORE_VERSION="$(node -p "require('./package.json').version")"
|
|
popd > /dev/null
|
|
else
|
|
CORE_VERSION=$1
|
|
fi
|
|
|
|
# core, schema, and cli are always published together, so they should use the same
|
|
# version
|
|
SCHEMA_VERSION=$CORE_VERSION
|
|
|
|
# Get legacy-scripting-runner version
|
|
if [ "$2" == "" ]; then
|
|
pushd $LSR_DIR > /dev/null
|
|
LSR_VERSION="$(node -p "require('./package.json').version")"
|
|
popd > /dev/null
|
|
else
|
|
LSR_VERSION=$2
|
|
fi
|
|
|
|
TARGET_FILE="$BUILD_DIR/$CORE_VERSION.zip"
|
|
rm -f $TARGET_FILE
|
|
|
|
# Build core and legacy-scripting-runner locally. Needs to generate a unique filename
|
|
# with a timestamp to avoid the package manager using any cache.
|
|
TIMESTAMP=`date +"%s"`
|
|
CORE_PACK_FILENAME="core-$TIMESTAMP.tgz"
|
|
SCHEMA_PACK_FILENAME="schema-$TIMESTAMP.tgz"
|
|
LSR_PACK_FILENAME="lsr-$TIMESTAMP.tgz"
|
|
|
|
echo "Building..."
|
|
|
|
# Patch boilerplate's package.json with appropriate dependency versions
|
|
if [ "$1" == "" ]; then
|
|
echo "> core from local, version $CORE_VERSION"
|
|
|
|
pushd $CORE_DIR > /dev/null
|
|
pnpm pack --out "$BOILERPLATE_DIR/$CORE_PACK_FILENAME"
|
|
popd > /dev/null
|
|
|
|
# Also pack schema so core's transitive dependency resolves locally
|
|
# instead of from npm (which may not have the current version yet)
|
|
echo "> schema from local"
|
|
pushd $SCHEMA_DIR > /dev/null
|
|
pnpm pack --out "$BOILERPLATE_DIR/$SCHEMA_PACK_FILENAME"
|
|
popd > /dev/null
|
|
|
|
if [ "$2" == "" ]; then
|
|
echo "> legacy-scripting-runner from local, version $LSR_VERSION"
|
|
|
|
pushd $LSR_DIR > /dev/null
|
|
pnpm pack --out "$BOILERPLATE_DIR/$LSR_PACK_FILENAME"
|
|
popd > /dev/null
|
|
|
|
# Replace core and legacy-scripting-runner versions in package.json
|
|
update_deps "$BOILERPLATE_DIR/package.json" "./$CORE_PACK_FILENAME" "./$LSR_PACK_FILENAME"
|
|
else
|
|
echo "> legacy-scripting-runner from npm, version $LSR_VERSION"
|
|
|
|
# Replace core and legacy-scripting-runner versions in package.json
|
|
update_deps "$BOILERPLATE_DIR/package.json" "./$CORE_PACK_FILENAME" $LSR_VERSION
|
|
fi
|
|
else
|
|
echo "> core from from npm, version $CORE_VERSION"
|
|
|
|
if [ "$2" == "" ]; then
|
|
echo "> legacy-scripting-runner from local, version $LSR_VERSION"
|
|
|
|
pushd $LSR_DIR > /dev/null
|
|
pnpm pack --out "$BOILERPLATE_DIR/$LSR_PACK_FILENAME"
|
|
popd > /dev/null
|
|
|
|
# Replace core and legacy-scripting-runner versions in package.json
|
|
update_deps "$BOILERPLATE_DIR/package.json" $CORE_VERSION "./$LSR_PACK_FILENAME"
|
|
else
|
|
echo "> legacy-scripting-runner from npm, version: $LSR_VERSION"
|
|
|
|
# Replace core and legacy-scripting-runner versions in package.json
|
|
update_deps "$BOILERPLATE_DIR/package.json" $CORE_VERSION $LSR_VERSION
|
|
fi
|
|
fi
|
|
|
|
# Install boilerplate deps
|
|
pushd $BOILERPLATE_DIR > /dev/null
|
|
echo "{\"version\": \"1.0.0\", \"platformVersion\": \"$CORE_VERSION\"}" > definition.json
|
|
|
|
# When building core from local, replace the placeholder in pnpm-workspace.yaml
|
|
# with an override so schema resolves from the local tarball
|
|
if [ "$1" == "" ]; then
|
|
sed -i.bak "s|# OVERRIDES_PLACEHOLDER|overrides:\n zapier-platform-schema: \"./$SCHEMA_PACK_FILENAME\"|" pnpm-workspace.yaml
|
|
fi
|
|
|
|
pnpm install --no-lockfile
|
|
|
|
popd > /dev/null
|
|
|
|
# Monkey patch boilerplate package.json so zapier-platform-core and
|
|
# zapier-platform-legacy-scripting-runner have version numbers specified instead
|
|
# of local file path
|
|
update_deps "$BOILERPLATE_DIR/package.json" $CORE_VERSION $LSR_VERSION
|
|
|
|
pushd $BOILERPLATE_DIR > /dev/null
|
|
|
|
# Build the zip!
|
|
# the node-X segment in the next line should match the latest major version
|
|
zip -9 -R $TARGET_FILE '*.js' '*.cjs' '*.json'
|
|
|
|
# Remove generated files
|
|
rm -f zapierwrapper.js definition.json core-*.tgz schema-*.tgz lsr-*.tgz
|
|
rm -rf node_modules
|
|
|
|
popd > /dev/null
|
|
|
|
echo -e "\nDone! Here's your output zip file (size should be 4-6 MB normally):"
|
|
ls -hl $TARGET_FILE
|
|
|
|
check_size $TARGET_FILE
|
|
inspect_build $TARGET_FILE $CORE_VERSION $SCHEMA_VERSION $LSR_VERSION
|
|
test_build $TARGET_FILE
|