Files
imagefind/scripts/build-fnos.sh
T

106 lines
4.3 KiB
Bash
Executable File

#!/bin/sh
set -eu
PROJECT_ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
BASE_VERSION=$(sed -n 's/^version[[:space:]]*=[[:space:]]*//p' "$PROJECT_ROOT/fnos/manifest" | head -n 1 | tr -d '\r')
PACKAGE_VERSION="${PACKAGE_VERSION:-$BASE_VERSION}"
case "$PACKAGE_VERSION" in
''|*[!0-9.]*|.*|*..*|*.) printf 'invalid fnOS package version: %s\n' "$PACKAGE_VERSION" >&2; exit 1 ;;
esac
[ "$(printf '%s' "$PACKAGE_VERSION" | awk -F. '{ print NF }')" -eq 3 ] || {
printf 'fnOS package version must contain exactly three numeric components: %s\n' "$PACKAGE_VERSION" >&2
exit 1
}
BUILD_ROOT="$PROJECT_ROOT/.build-fnos"
STAGE="$BUILD_ROOT/imagefind"
PACKED_ROOT="$BUILD_ROOT/packed"
FNPACK_TMP_ROOT="$BUILD_ROOT/fnpack-tmp"
WHEEL_BUILD_ROOT="$BUILD_ROOT/application-wheel"
OUTPUT="${1:-$PROJECT_ROOT/dist/imagefind-${PACKAGE_VERSION}-x86_64.fpk}"
WHEEL_CACHE="${IMAGEFIND_WHEEL_CACHE:-$PROJECT_ROOT/.fnos-wheel-cache/python312}"
if [ -n "${FNPACK:-}" ]; then
FNPACK_BIN="$FNPACK"
elif [ -x "$PROJECT_ROOT/.tools/fnpack" ]; then
FNPACK_BIN="$PROJECT_ROOT/.tools/fnpack"
else
FNPACK_BIN=fnpack
fi
if [ -n "${PYTHON:-}" ]; then
PYTHON_BIN="$PYTHON"
elif [ -x "$PROJECT_ROOT/.release-venv/bin/python" ]; then
PYTHON_BIN="$PROJECT_ROOT/.release-venv/bin/python"
elif [ -x "$PROJECT_ROOT/.venv/bin/python" ]; then
PYTHON_BIN="$PROJECT_ROOT/.venv/bin/python"
else
PYTHON_BIN=python3
fi
require_file() {
if [ ! -e "$1" ]; then
printf 'missing required release artifact: %s\n' "$1" >&2
exit 1
fi
}
FNPACK_BIN=$(command -v "$FNPACK_BIN") || {
printf 'fnpack is required; install it from the fnOS developer portal.\n' >&2
exit 1
}
PYTHON_BIN=$(command -v "$PYTHON_BIN") || {
printf 'Python with hatchling is required to assemble the release.\n' >&2
exit 1
}
APP_VERSION=$("$PYTHON_BIN" -c 'import pathlib,sys,tomllib; print(tomllib.loads(pathlib.Path(sys.argv[1]).read_text())["project"]["version"])' "$PROJECT_ROOT/pyproject.toml")
command -v npm >/dev/null 2>&1 || { printf 'npm is required.\n' >&2; exit 1; }
"$PYTHON_BIN" -c 'import hatchling' >/dev/null 2>&1 || {
printf 'hatchling is required in the release Python environment.\n' >&2
exit 1
}
for artifact in libOpenCL.so.1; do
require_file "$PROJECT_ROOT/vendor/$artifact"
done
require_file "$PROJECT_ROOT/requirements/runtime-core.txt"
require_file "$PROJECT_ROOT/requirements/runtime-ai/constraints-cp312.txt"
[ -d "$WHEEL_CACHE" ] || { printf 'missing Python 3.12 core wheelhouse: %s\n' "$WHEEL_CACHE" >&2; exit 1; }
rm -rf "$BUILD_ROOT"
mkdir -p "$STAGE/app/bin" "$STAGE/app/frontend" "$STAGE/app/runtime/ai" \
"$STAGE/app/runtime/wheels" "$PACKED_ROOT" "$FNPACK_TMP_ROOT" \
"$WHEEL_BUILD_ROOT" "$(dirname "$OUTPUT")"
npm run build --prefix "$PROJECT_ROOT/frontend"
"$PYTHON_BIN" -m hatchling build -t wheel -d "$WHEEL_BUILD_ROOT"
cp -R "$PROJECT_ROOT/fnos/." "$STAGE/"
sed -i -E "s/^version[[:space:]]*=.*/version=${PACKAGE_VERSION}/" "$STAGE/manifest"
cp -R "$PROJECT_ROOT/frontend/dist/." "$STAGE/app/frontend/"
cp -p "$PROJECT_ROOT/vendor/libOpenCL.so.1" "$STAGE/app/bin/libOpenCL.so.1"
cp -p "$PROJECT_ROOT/requirements/runtime-core.txt" "$STAGE/app/runtime/runtime-core.txt"
cp -p "$PROJECT_ROOT/requirements/runtime-ai/"*.txt "$STAGE/app/runtime/ai/"
cp -p "$WHEEL_CACHE/"*.whl "$STAGE/app/runtime/wheels/"
cp -p "$WHEEL_BUILD_ROOT/"imagefind-*.whl "$STAGE/app/runtime/"
STAGED_APP_WHEEL=""
for candidate in "$STAGE/app/runtime/"imagefind-*.whl; do
if [ -f "$candidate" ]; then
STAGED_APP_WHEEL="$candidate"
break
fi
done
[ -n "$STAGED_APP_WHEEL" ] || { printf 'built application wheel is missing\n' >&2; exit 1; }
PACKAGE_ID=$("$PYTHON_BIN" -c \
'import hashlib,sys; h=hashlib.sha256(); [h.update(open(path,"rb").read()) for path in sys.argv[1:]]; print(h.hexdigest())' \
"$STAGED_APP_WHEEL" "$STAGE/app/runtime/runtime-core.txt")
printf '%s\n%s\n%s\n' "$PACKAGE_VERSION" "$APP_VERSION" "$PACKAGE_ID" >"$STAGE/app/runtime/VERSION"
"$PYTHON_BIN" "$PROJECT_ROOT/scripts/make_icons.py" "$STAGE"
chmod 0755 "$STAGE/cmd/"*
(
cd "$PACKED_ROOT"
TMPDIR="$FNPACK_TMP_ROOT" "$FNPACK_BIN" build --directory "$STAGE"
)
mv "$PACKED_ROOT/imagefind.fpk" "$OUTPUT"
(
cd "$(dirname "$OUTPUT")"
sha256sum "$(basename "$OUTPUT")" >"$(basename "$OUTPUT").sha256"
)
printf 'created %s\n' "$OUTPUT"