106 lines
4.4 KiB
Bash
Executable File
106 lines
4.4 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,zipfile; h=hashlib.sha256(); z=zipfile.ZipFile(sys.argv[1]); [(h.update(n.encode()),h.update(z.read(n))) for n in sorted(z.namelist())]; h.update(open(sys.argv[2],"rb").read()); 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"
|