Skip to content

v0 for new daily event proopser #67

v0 for new daily event proopser

v0 for new daily event proopser #67

name: Build Docker Images
on:
push:
branches:
- main
# pull_request:
# branches:
# - main
env:
AWS_REGION: eu-central-1 # Change this to your AWS region
ECR_REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.eu-central-1.amazonaws.com # Change region if needed
jobs:
detect-changes:
name: Detect Changed Areas
runs-on: ubuntu-latest
outputs:
orchestrator: ${{ steps.filter.outputs.orchestrator }}
robot_gateway: ${{ steps.filter.outputs.robot_gateway }}
frontend: ${{ steps.filter.outputs.frontend }}
mobile: ${{ steps.filter.outputs.mobile }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Filter changed paths
id: filter
uses: dorny/paths-filter@v3
with:
filters: |
orchestrator:
- 'backend/orchestrator/**'
- 'backend/db/**'
- '.github/workflows/build-docker-images.yml'
robot_gateway:
- 'backend/robot-gateway/**'
- '.github/workflows/build-docker-images.yml'
frontend:
- 'frontend/**'
- '.github/workflows/build-docker-images.yml'
mobile:
- 'mobile/**'
- '.github/workflows/build-docker-images.yml'
test-orchestrator:
name: Test Orchestrator
needs: detect-changes
if: needs.detect-changes.outputs.orchestrator == 'true'
runs-on: ubuntu-latest
env:
# Required by backend imports (llm_helpers/auth) during test collection.
LLM_BASE_URL: http://localhost:11434/v1
LLM_CHAT_MODEL_FAST: ci-test-fast-model
LLM_CHAT_MODEL_SMART: ci-test-smart-model
GOOGLE_CLIENT_ID: ci-test-client-id.apps.googleusercontent.com
defaults:
run:
working-directory: backend/orchestrator
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
cache-dependency-path: backend/orchestrator/requirements*.txt
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run tests
run: |
python -m pytest tests/ -v --tb=short
- name: Run linter
run: |
ruff check .
test-robot-gateway:
name: Test Robot Gateway
needs: detect-changes
if: needs.detect-changes.outputs.robot_gateway == 'true'
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend/robot-gateway
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
cache-dependency-path: backend/robot-gateway/requirements*.txt
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run tests
run: |
python -m pytest tests/ -v --tb=short
- name: Run linter
run: |
ruff check .
build-orchestrator:
name: Build Orchestrator Image
needs:
- detect-changes
- test-orchestrator
if: needs.detect-changes.outputs.orchestrator == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for OIDC authentication (if using)
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.ECR_REGISTRY }}/appcalipse/digital-brain-orchestrator
tags: |
type=raw,value=latest,enable={{is_default_branch}}
- name: Prepare version metadata
run: |
VERSION="${{ steps.meta.outputs.version }}"
if [ -z "$VERSION" ]; then
VERSION="${GITHUB_SHA}"
fi
BUILD_TIME="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
echo "SERVICE_VERSION=${VERSION}" >> "${GITHUB_ENV}"
echo "SERVICE_GIT_SHA=${GITHUB_SHA}" >> "${GITHUB_ENV}"
echo "SERVICE_BUILD_TIME=${BUILD_TIME}" >> "${GITHUB_ENV}"
echo "SERVICE_DEPLOYMENT=${GITHUB_REF_NAME}" >> "${GITHUB_ENV}"
echo "SERVICE_IMAGE=${{ env.ECR_REGISTRY }}/appcalipse/digital-brain-orchestrator:${VERSION}" >> "${GITHUB_ENV}"
- name: Generate service manifest
run: |
python scripts/generate_service_manifest.py \
--output backend/orchestrator/config/service_manifest.json \
--deployment "${GITHUB_REF_NAME}"
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./backend/orchestrator
file: ./backend/orchestrator/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Delete untagged ECR images
if: ${{ github.event_name != 'pull_request' }}
run: |
NEXT_TOKEN=""
while :; do
if [ -n "${NEXT_TOKEN}" ]; then
RESP=$(aws ecr list-images \
--repository-name appcalipse/digital-brain-orchestrator \
--filter tagStatus=UNTAGGED \
--max-results 100 \
--next-token "${NEXT_TOKEN}")
else
RESP=$(aws ecr list-images \
--repository-name appcalipse/digital-brain-orchestrator \
--filter tagStatus=UNTAGGED \
--max-results 100)
fi
IMAGE_IDS=$(python -c 'import json,sys;print(json.dumps(json.load(sys.stdin).get("imageIds", [])))' <<< "${RESP}")
if [ "${IMAGE_IDS}" != "[]" ]; then
TMP_FILE="$(mktemp)"
echo "${IMAGE_IDS}" > "${TMP_FILE}"
aws ecr batch-delete-image \
--repository-name appcalipse/digital-brain-orchestrator \
--image-ids "file://${TMP_FILE}"
rm -f "${TMP_FILE}"
fi
NEXT_TOKEN=$(python -c 'import json,sys;print(json.load(sys.stdin).get("nextToken",""))' <<< "${RESP}")
if [ -z "${NEXT_TOKEN}" ]; then
break
fi
done
build-robot-gateway:
name: Build Robot Gateway Image
needs:
- detect-changes
- test-robot-gateway
if: needs.detect-changes.outputs.robot_gateway == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.ECR_REGISTRY }}/appcalipse/digital-brain-robot-gateway
tags: |
type=raw,value=latest,enable={{is_default_branch}}
- name: Prepare version metadata
run: |
VERSION="${{ steps.meta.outputs.version }}"
if [ -z "$VERSION" ]; then
VERSION="${GITHUB_SHA}"
fi
BUILD_TIME="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
echo "SERVICE_VERSION=${VERSION}" >> "${GITHUB_ENV}"
echo "SERVICE_GIT_SHA=${GITHUB_SHA}" >> "${GITHUB_ENV}"
echo "SERVICE_BUILD_TIME=${BUILD_TIME}" >> "${GITHUB_ENV}"
echo "SERVICE_DEPLOYMENT=${GITHUB_REF_NAME}" >> "${GITHUB_ENV}"
echo "SERVICE_IMAGE=${{ env.ECR_REGISTRY }}/appcalipse/digital-brain-robot-gateway:${VERSION}" >> "${GITHUB_ENV}"
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./backend/robot-gateway
file: ./backend/robot-gateway/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Delete untagged ECR images
if: ${{ github.event_name != 'pull_request' }}
run: |
NEXT_TOKEN=""
while :; do
if [ -n "${NEXT_TOKEN}" ]; then
RESP=$(aws ecr list-images \
--repository-name appcalipse/digital-brain-robot-gateway \
--filter tagStatus=UNTAGGED \
--max-results 100 \
--next-token "${NEXT_TOKEN}")
else
RESP=$(aws ecr list-images \
--repository-name appcalipse/digital-brain-robot-gateway \
--filter tagStatus=UNTAGGED \
--max-results 100)
fi
IMAGE_IDS=$(python -c 'import json,sys;print(json.dumps(json.load(sys.stdin).get("imageIds", [])))' <<< "${RESP}")
if [ "${IMAGE_IDS}" != "[]" ]; then
TMP_FILE="$(mktemp)"
echo "${IMAGE_IDS}" > "${TMP_FILE}"
aws ecr batch-delete-image \
--repository-name appcalipse/digital-brain-robot-gateway \
--image-ids "file://${TMP_FILE}"
rm -f "${TMP_FILE}"
fi
NEXT_TOKEN=$(python -c 'import json,sys;print(json.load(sys.stdin).get("nextToken",""))' <<< "${RESP}")
if [ -z "${NEXT_TOKEN}" ]; then
break
fi
done
lint-frontend:
name: Lint Frontend
needs: detect-changes
if: needs.detect-changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend/web
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: frontend/web/package-lock.json
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npx eslint .
lint-mobile:
name: Lint Mobile
needs: detect-changes
if: needs.detect-changes.outputs.mobile == 'true'
runs-on: ubuntu-latest
defaults:
run:
working-directory: mobile
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: mobile/package-lock.json
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
build-frontend:
name: Build Frontend Image
needs:
- detect-changes
- lint-frontend
if: needs.detect-changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for OIDC authentication (if using)
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.ECR_REGISTRY }}/appcalipse/digital-brain-frontend
tags: |
type=raw,value=latest,enable={{is_default_branch}}
- name: Prepare version metadata
run: |
VERSION="${{ steps.meta.outputs.version }}"
if [ -z "$VERSION" ]; then
VERSION="${GITHUB_SHA}"
fi
BUILD_TIME="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
echo "SERVICE_VERSION=${VERSION}" >> "${GITHUB_ENV}"
echo "SERVICE_GIT_SHA=${GITHUB_SHA}" >> "${GITHUB_ENV}"
echo "SERVICE_BUILD_TIME=${BUILD_TIME}" >> "${GITHUB_ENV}"
echo "SERVICE_DEPLOYMENT=${GITHUB_REF_NAME}" >> "${GITHUB_ENV}"
echo "SERVICE_IMAGE=${{ env.ECR_REGISTRY }}/appcalipse/digital-brain-frontend:${VERSION}" >> "${GITHUB_ENV}"
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./frontend/web
file: ./frontend/web/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
NEXT_PUBLIC_APP_VERSION=${{ env.SERVICE_VERSION }}
NEXT_PUBLIC_APP_BUILD_TIME=${{ env.SERVICE_BUILD_TIME }}
NEXT_PUBLIC_APP_GIT_SHA=${{ env.SERVICE_GIT_SHA }}
NEXT_PUBLIC_APP_DEPLOYMENT=${{ env.SERVICE_DEPLOYMENT }}
- name: Delete untagged ECR images
if: ${{ github.event_name != 'pull_request' }}
run: |
NEXT_TOKEN=""
while :; do
if [ -n "${NEXT_TOKEN}" ]; then
RESP=$(aws ecr list-images \
--repository-name appcalipse/digital-brain-frontend \
--filter tagStatus=UNTAGGED \
--max-results 100 \
--next-token "${NEXT_TOKEN}")
else
RESP=$(aws ecr list-images \
--repository-name appcalipse/digital-brain-frontend \
--filter tagStatus=UNTAGGED \
--max-results 100)
fi
IMAGE_IDS=$(python -c 'import json,sys;print(json.dumps(json.load(sys.stdin).get("imageIds", [])))' <<< "${RESP}")
if [ "${IMAGE_IDS}" != "[]" ]; then
TMP_FILE="$(mktemp)"
echo "${IMAGE_IDS}" > "${TMP_FILE}"
aws ecr batch-delete-image \
--repository-name appcalipse/digital-brain-frontend \
--image-ids "file://${TMP_FILE}"
rm -f "${TMP_FILE}"
fi
NEXT_TOKEN=$(python -c 'import json,sys;print(json.load(sys.stdin).get("nextToken",""))' <<< "${RESP}")
if [ -z "${NEXT_TOKEN}" ]; then
break
fi
done
ci-status:
name: CI Status
needs:
- detect-changes
- test-orchestrator
- build-orchestrator
- test-robot-gateway
- build-robot-gateway
- lint-frontend
- build-frontend
- lint-mobile
if: always()
runs-on: ubuntu-latest
steps:
- name: Validate required jobs
run: |
set -euo pipefail
ORCHESTRATOR_CHANGED='${{ needs.detect-changes.outputs.orchestrator }}'
ROBOT_GATEWAY_CHANGED='${{ needs.detect-changes.outputs.robot_gateway }}'
FRONTEND_CHANGED='${{ needs.detect-changes.outputs.frontend }}'
MOBILE_CHANGED='${{ needs.detect-changes.outputs.mobile }}'
TEST_ORCH_RESULT='${{ needs.test-orchestrator.result }}'
BUILD_ORCH_RESULT='${{ needs.build-orchestrator.result }}'
TEST_GW_RESULT='${{ needs.test-robot-gateway.result }}'
BUILD_GW_RESULT='${{ needs.build-robot-gateway.result }}'
LINT_FRONTEND_RESULT='${{ needs.lint-frontend.result }}'
BUILD_FRONTEND_RESULT='${{ needs.build-frontend.result }}'
LINT_MOBILE_RESULT='${{ needs.lint-mobile.result }}'
echo "orchestrator changed: ${ORCHESTRATOR_CHANGED}"
echo "robot-gateway changed: ${ROBOT_GATEWAY_CHANGED}"
echo "frontend changed: ${FRONTEND_CHANGED}"
echo "mobile changed: ${MOBILE_CHANGED}"
echo "test-orchestrator: ${TEST_ORCH_RESULT}"
echo "build-orchestrator: ${BUILD_ORCH_RESULT}"
echo "test-robot-gateway: ${TEST_GW_RESULT}"
echo "build-robot-gateway: ${BUILD_GW_RESULT}"
echo "lint-frontend: ${LINT_FRONTEND_RESULT}"
echo "build-frontend: ${BUILD_FRONTEND_RESULT}"
echo "lint-mobile: ${LINT_MOBILE_RESULT}"
if [ "${ORCHESTRATOR_CHANGED}" = "true" ]; then
if [ "${TEST_ORCH_RESULT}" != "success" ]; then
echo "Orchestrator tests did not succeed."
exit 1
fi
if [ "${BUILD_ORCH_RESULT}" != "success" ]; then
echo "Orchestrator image build did not succeed."
exit 1
fi
fi
if [ "${ROBOT_GATEWAY_CHANGED}" = "true" ]; then
if [ "${TEST_GW_RESULT}" != "success" ]; then
echo "Robot gateway tests did not succeed."
exit 1
fi
if [ "${BUILD_GW_RESULT}" != "success" ]; then
echo "Robot gateway image build did not succeed."
exit 1
fi
fi
if [ "${FRONTEND_CHANGED}" = "true" ]; then
if [ "${LINT_FRONTEND_RESULT}" != "success" ]; then
echo "Frontend lint did not succeed."
exit 1
fi
if [ "${BUILD_FRONTEND_RESULT}" != "success" ]; then
echo "Frontend image build did not succeed."
exit 1
fi
fi
if [ "${MOBILE_CHANGED}" = "true" ]; then
if [ "${LINT_MOBILE_RESULT}" != "success" ]; then
echo "Mobile lint did not succeed."
exit 1
fi
fi
echo "CI status check passed."