Skip to content

chore(repo): update testing and linting config #2321

chore(repo): update testing and linting config

chore(repo): update testing and linting config #2321

name: Docker
on:
pull_request:
branches:
- main
- develop
push:
branches:
- main
- develop
release:
types: [published]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true
jobs:
meta:
name: Meta
runs-on: ubuntu-latest
outputs:
should-push: ${{ steps.should-push.outputs.should-push }}
release-tag: ${{ steps.should-push.outputs.release-tag }}
steps:
- name: Determine if we should push to GHCR
id: should-push
run: |
# Push to GHCR only when a release is published
if [[ "${{ github.event_name }}" == "release" ]]; then
echo "should-push=true" >> $GITHUB_OUTPUT
echo "release-tag=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
echo "Pushing to GHCR with release tag: ${{ github.event.release.tag_name }}"
else
echo "should-push=false" >> $GITHUB_OUTPUT
echo "release-tag=" >> $GITHUB_OUTPUT
echo "Building locally for testing (no GHCR push)"
fi
build-and-push:
name: Build (${{ matrix.images.name }})
needs: [meta]
runs-on: ubuntu-latest
permissions:
contents: read
actions: read
checks: write
packages: write
env:
# Use GitHub's Docker layer caching
DOCKER_BUILDKIT: 1
COMPOSE_DOCKER_CLI_BUILD: 1
strategy:
matrix:
images:
- name: web
context: .
dockerfile: ./apps/web/Dockerfile
path: apps/web
repo: ghcr.io/tambo-ai
image: tambo-web-server
description: Next.js web frontend for Tambo AI platform
- name: api
context: .
dockerfile: ./apps/api/Dockerfile
path: apps/api
repo: ghcr.io/tambo-ai
image: tambo-api-server
description: NestJS backend API for Tambo AI platform
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
id: setup-buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
if: needs.meta.outputs.should-push == 'true'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: tambo-bot
password: ${{ secrets.RELEASE_PACKAGES }}
- name: Extract metadata for web image
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ matrix.images.repo }}/${{ matrix.images.image }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,enable=true,priority=100,prefix=sha-,format=short
type=semver,pattern={{version}},value=${{ needs.meta.outputs.release-tag }}
labels: |
org.opencontainers.image.title=${{ matrix.images.title }}
org.opencontainers.image.description=${{ matrix.images.description }}
org.opencontainers.image.vendor=Tambo AI
org.opencontainers.image.licenses=MIT
org.opencontainers.image.source=https://github.com/tambo-ai/tambo/blob/${{ github.sha }}/${{ matrix.images.path }}
org.opencontainers.image.documentation=https://docs.tambo.co
- name: Build and push web image
uses: docker/build-push-action@v6
with:
builder: ${{ steps.setup-buildx.outputs.name }}
context: .
file: ./${{ matrix.images.path }}/Dockerfile
outputs: type=docker,dest=${{ runner.temp }}/docker-${{ matrix.images.name }}.tar
platforms: ${{ needs.meta.outputs.should-push == 'true' && 'linux/amd64,linux/arm64' || '' }}
tags: ${{ needs.meta.outputs.should-push == 'true' && steps.meta.outputs.tags || 'tambo-web:latest' }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: |
type=gha,scope=buildx-${{ matrix.images.name }}-${{ github.ref_name }}
type=gha,scope=buildx-${{ matrix.images.name }}-main
cache-to: |
type=gha,scope=buildx-${{ matrix.images.name }}-${{ github.ref_name }},mode=max
build-args: |
NODE_ENV=production
TURBO_TEAM=${{ vars.TURBO_TEAM }}
secrets: |
TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}
allow: network.host
network: host
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: docker-${{ matrix.images.name }}
path: ${{ runner.temp }}/docker-${{ matrix.images.name }}.tar
retention-days: 1
test:
needs: [meta, build-and-push]
name: Test
runs-on: ubuntu-latest
env:
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
permissions:
contents: read
actions: read
checks: write
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download artifact
uses: actions/download-artifact@v7
with:
path: ${{ runner.temp }}/
pattern: docker-*
- name: Load images
run: |
find ${{ runner.temp }} -type f -name "*.tar" -exec docker load --input "{}" \;
docker image ls -a
- name: Setup and start Docker stack
run: |
./scripts/cloud/tambo-setup.sh
./scripts/cloud/tambo-start.sh
timeout-minutes: 8
- name: Wait for services to be healthy
run: |
# Wait for PostgreSQL to be healthy (reduced wait time)
timeout 45 bash -c 'until docker inspect --format={{.State.Health.Status}} tambo_postgres 2>/dev/null | grep -q ^healthy$; do sleep 3; done'
# Wait for API to be ready (using the /health endpoint)
timeout 45 bash -c 'until curl -fso /dev/null http://localhost:3211/health 2>/dev/null; do sleep 3; done'
# Wait for Web to be ready
timeout 45 bash -c 'until curl -fso /dev/null http://localhost:3210/ 2>/dev/null; do sleep 3; done'
- name: Check service status
run: |
echo "=== Docker Compose Status ==="
docker compose --env-file docker.env ps
echo "=== Service Health Checks ==="
echo "PostgreSQL: $(docker compose --env-file docker.env ps postgres | grep -o 'healthy\|unhealthy\|starting' || echo 'unknown')"
echo "=== Service Endpoints ==="
echo "Testing API health endpoint..."
curl -fso /dev/null http://localhost:3211/health && echo -e "\nAPI health endpoint responding"
echo "Testing API root endpoint..."
curl -fso /dev/null http://localhost:3211/ && echo -e "\nAPI root endpoint responding"
echo "Testing Web endpoint..."
curl -fso /dev/null http://localhost:3210/ && echo -e "\nWeb endpoint responding"
- name: Initialize database
run: ./scripts/cloud/init-database.sh
timeout-minutes: 2
- name: Verify database initialization
run: |
# Check if database tables were created
echo "=== Database Tables ==="
docker compose --env-file docker.env exec -T postgres psql -U postgres -d tambo -c "\dt" || echo "Database tables not found"
# Check if migrations were applied
echo "=== Migration Status ==="
docker compose --env-file docker.env exec -T postgres psql -U postgres -d tambo -c "SELECT * FROM drizzle.__drizzle_migrations ORDER BY created_at DESC LIMIT 5;" || echo "Migration table not found"
- name: Stop Docker stack
if: always()
run: ./scripts/cloud/tambo-stop.sh
timeout-minutes: 2
- name: Debug Docker logs on failure
if: failure()
run: ./scripts/cloud/tambo-logs.sh