chore(repo): update testing and linting config #2321
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |