Files
ai/bin/deploy
2026-04-13 21:42:28 -04:00

220 lines
6.3 KiB
Bash
Executable File

#!/bin/bash
#REMOTE=northamerica-northeast2-docker.pkg.dev/dexorder-430504/dexorder
REMOTE=${REMOTE:-git.dxod.org/dexorder/dexorder}
if [ "$1" != "flink" ] && [ "$1" != "relay" ] && [ "$1" != "ingestor" ] && [ "$1" != "web" ] && [ "$1" != "gateway" ] && [ "$1" != "lifecycle-sidecar" ] && [ "$1" != "sandbox" ]; then
echo
echo usage: "$0 "'{flink|relay|ingestor|web|gateway|lifecycle-sidecar|sandbox} [''dev''] [config] [deployment] [kubernetes] [image_tag]'
echo
echo ' [''dev''] if the literal string ''dev'' is not the second argument, then the build refuses to run if source code is not checked in. Otherwise, the git revision numbers are used in the image tag.'
echo
echo ' [config] is used to find configuration files e.g. web/.env-{config} or backend/dexorder-{config}.toml. Defaults to project name.'
echo
echo ' [deployment] refers to the set of contracts bundled in the image, from contract/deployment/{deployment}. Defaults to config name.'
echo
echo ' [kubernetes] is used for the base image name and also to find the yaml file for deployment: deploy/k8s/{kubernetes}.yaml. Defaults to project name.'
echo
echo ' [image_tag] will be used for the container image name. The standard tag will always be generated as well.'
echo
exit 1
else
PROJECT=$1
shift
fi
if [ "$1" == "dev" ]; then
shift
DEV=1
fi
if [ "$1" == "prod" ]; then
shift
ENV=prod
KUBECTL="kubectl --context=prod"
else
ENV=dev
KUBECTL="kubectl"
fi
if [ "$PROJECT" == "dev" ]; then
DEV=1
# NO_CACHE=--no-cache
fi
if [ "$DEV" == "1" ]; then
TAG="dev`date -u +%Y%m%d%H%M%S`"
if [ "$1" != "" ]; then
CONFIG=$1
shift
else
CONFIG=dev
fi
else
if [ "$1" != "" ]; then
CONFIG=$1
shift
else
CONFIG=production
fi
DIRTY="$( cd $PROJECT && git status | grep "Changes " )"
if [ "$DIRTY" != "" ]; then
echo $PROJECT has uncommited changes.
echo
echo Use \`$0 $PROJECT dev\` to deploy a development-tagged version instead.
exit 1
fi
TAG="$( cd $PROJECT && git log --oneline | head -1 | cut -d ' ' -f 1 )"
fi
if [ "$1" != "" ]; then
DEPLOYMENT=$1
shift
else
DEPLOYMENT=$CONFIG
fi
if [ "$1" != "" ]; then
KUBERNETES=$1
shift
else
KUBERNETES=$PROJECT
fi
if [ "$1" != "" ]; then
IMG_TAG=$1
else
IMG_TAG=
fi
if [ $(basename "$0") == 'deploy' ]; then
DEPLOY=1
else
DEPLOY=0
fi
if [ "$DEPLOY" == "0" ]; then
ACTION=Building
#NO_CACHE=--no-cache
else
ACTION=Making
fi
echo $ACTION $PROJECT config=$CONFIG deployment=$DEPLOYMENT '=>' $TAG
# Copy protobuf definitions into project directory for Docker build (if not gateway or lifecycle-sidecar)
# Using rsync --checksum so unchanged files keep their timestamps (preserves docker layer cache)
if [ "$PROJECT" != "lifecycle-sidecar" ]; then
rsync -a --checksum --delete protobuf/ $PROJECT/protobuf/
fi
# For gateway: copy Python API files for research subagent
if [ "$PROJECT" == "gateway" ]; then
echo "Copying Python API files for research subagent..."
# Create api-source directory
mkdir -p gateway/src/harness/subagents/research/api-source
# Copy all Python API files (for easy future expansion)
cp sandbox/dexorder/api/*.py gateway/src/harness/subagents/research/api-source/
# Generate api-reference.md with verbatim Python source code
API_REF="gateway/src/harness/subagents/research/memory/api-reference.md"
cat > "$API_REF" << 'HEADER'
# Dexorder Research API Reference
This file contains the complete Python API source code with full docstrings.
These files are copied verbatim from `sandbox/dexorder/api/`.
The API provides access to market data and charting capabilities for research scripts.
---
## Overview
Research scripts access the API via:
```python
from dexorder.api import get_api
api = get_api()
```
The API instance provides:
- `api.data` - DataAPI for fetching OHLC market data
- `api.charting` - ChartingAPI for creating financial charts
---
## Complete API Source Code
The following sections contain the verbatim Python source files with complete
type hints, docstrings, and examples.
HEADER
# Append each Python file
for py_file in api.py data_api.py charting_api.py __init__.py; do
if [ -f "sandbox/dexorder/api/$py_file" ]; then
echo "" >> "$API_REF"
echo "### $py_file" >> "$API_REF"
echo '```python' >> "$API_REF"
cat "sandbox/dexorder/api/$py_file" >> "$API_REF"
echo '```' >> "$API_REF"
echo "" >> "$API_REF"
fi
done
cat >> "$API_REF" << 'FOOTER'
---
For practical usage patterns and complete working examples, see `usage-examples.md`.
FOOTER
echo "Generated api-reference.md with Python API source code"
fi
docker build $NO_CACHE -f $PROJECT/Dockerfile --build-arg="CONFIG=$CONFIG" --build-arg="DEPLOYMENT=$DEPLOYMENT" -t dexorder/ai-$PROJECT:latest $PROJECT || exit 1
# Cleanup is handled by trap
docker tag dexorder/ai-$PROJECT:latest dexorder/ai-$PROJECT:$TAG
docker tag dexorder/ai-$PROJECT:$TAG $REMOTE/ai-$PROJECT:$TAG
docker tag $REMOTE/ai-$PROJECT:$TAG $REMOTE/ai-$PROJECT:latest
if [ "$IMG_TAG" != "" ]; then
docker tag dexorder/ai-$PROJECT:$TAG $REMOTE/ai-$PROJECT:$IMG_TAG
TAG=$IMG_TAG
fi
echo "$(date)" built $REMOTE/ai-$PROJECT:$TAG
# Output just the tag for scripting purposes (to stderr so scripts can capture it)
echo "$TAG" >&2
if [ "$DEPLOY" == "1" ]; then
docker push $REMOTE/ai-$PROJECT:$TAG
docker push $REMOTE/ai-$PROJECT:latest
if [ "$ENV" == "prod" ]; then
case "$PROJECT" in
flink)
$KUBECTL set image deployment/flink-jobmanager flink-jobmanager=$REMOTE/ai-flink:$TAG
$KUBECTL set image deployment/flink-taskmanager flink-taskmanager=$REMOTE/ai-flink:$TAG
;;
web)
$KUBECTL set image deployment/ai-web ai-web=$REMOTE/ai-web:$TAG
;;
sandbox|lifecycle-sidecar)
echo "Image pushed. New sandboxes will use $REMOTE/ai-$PROJECT:$TAG"
;;
*)
$KUBECTL set image deployment/$PROJECT $PROJECT=$REMOTE/ai-$PROJECT:$TAG
;;
esac
echo "deployed $PROJECT $REMOTE/ai-$PROJECT:$TAG"
else
YAML=$(sed "s#image: dexorder/ai-$PROJECT*#image: $REMOTE/ai-$PROJECT:$TAG#" deploy/k8s/base/$KUBERNETES.yaml)
echo "$YAML" | kubectl apply -f - || { echo "$YAML"; echo "kubectl apply failed"; exit 1; }
echo deployed $KUBERNETES.yaml $REMOTE/ai-$PROJECT:$TAG
fi
fi