name: Build and Push Docker Image
on:
push:
branches: [main]
paths:
- 'deployment/**'
- '.github/workflows/docker-build.yml'
workflow_dispatch:
env:
IMAGE_NAME: mcp-base-mcp
REGISTRY: us-central1-docker.pkg.dev
permissions:
contents: write
packages: write
attestations: write
id-token: write
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
attestations: write
id-token: write
steps:
- name: Checkout this repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Check if source code already imported
id: check-import
run: |
# Check if src/ or package.json exists (indicating source already imported)
if [ -f "package.json" ] || [ -f "pyproject.toml" ] || [ -f "Cargo.toml" ] || [ -f "go.mod" ] || [ -d "src" ]; then
echo "SOURCE_IMPORTED=true" >> $GITHUB_OUTPUT
echo "Source code already imported, skipping clone"
else
echo "SOURCE_IMPORTED=false" >> $GITHUB_OUTPUT
echo "Source code not yet imported, will clone from upstream"
fi
- name: Clone original source repository
if: steps.check-import.outputs.SOURCE_IMPORTED == 'false'
uses: actions/checkout@v4
with:
repository: base/base-mcp
ref: master
path: upstream-source
- name: Import source code to repository
if: steps.check-import.outputs.SOURCE_IMPORTED == 'false'
run: |
echo "=== Importing source code from base/base-mcp ==="
# Copy all source files (excluding .git and .github to avoid workflow permission issues)
cd upstream-source
find . -maxdepth 1 ! -name '.' ! -name '.git' ! -name '.github' -exec cp -r {} ../ \;
cd ..
# Remove the upstream-source directory
rm -rf upstream-source
# Configure git
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Commit the source code
git add -A
git commit -m "feat: Import source code from base/base-mcp@master" -m "Source: https://github.com/base/base-mcp | Branch: master | Imported: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
# Push the commit
git push origin main
echo "=== Source code imported successfully ==="
- name: Analyze source code structure
id: analyze
run: |
echo "=== Analyzing source code structure ==="
# Detect project type
if [ -f "package.json" ]; then
echo "PROJECT_TYPE=nodejs" >> $GITHUB_OUTPUT
echo "Detected: Node.js project"
# Check for TypeScript
if [ -f "tsconfig.json" ]; then
echo "HAS_TYPESCRIPT=true" >> $GITHUB_OUTPUT
echo " - TypeScript enabled"
fi
# Detect package manager
if [ -f "pnpm-lock.yaml" ]; then
echo "PKG_MANAGER=pnpm" >> $GITHUB_OUTPUT
echo " - Package manager: pnpm"
elif [ -f "yarn.lock" ]; then
echo "PKG_MANAGER=yarn" >> $GITHUB_OUTPUT
echo " - Package manager: yarn"
elif [ -f "bun.lockb" ]; then
echo "PKG_MANAGER=bun" >> $GITHUB_OUTPUT
echo " - Package manager: bun"
else
echo "PKG_MANAGER=npm" >> $GITHUB_OUTPUT
echo " - Package manager: npm"
fi
# Extract entry point from package.json
if command -v jq &> /dev/null; then
MAIN=$(jq -r '.main // "index.js"' package.json)
SCRIPTS_START=$(jq -r '.scripts.start // empty' package.json)
echo "ENTRY_POINT=$MAIN" >> $GITHUB_OUTPUT
echo " - Entry point: $MAIN"
if [ -n "$SCRIPTS_START" ]; then
echo " - Start script: $SCRIPTS_START"
fi
fi
elif [ -f "pyproject.toml" ] || [ -f "setup.py" ] || [ -f "requirements.txt" ]; then
echo "PROJECT_TYPE=python" >> $GITHUB_OUTPUT
echo "Detected: Python project"
# Check for common Python package managers
if [ -f "pyproject.toml" ]; then
if grep -q "tool.poetry" pyproject.toml 2>/dev/null; then
echo "PKG_MANAGER=poetry" >> $GITHUB_OUTPUT
echo " - Package manager: poetry"
elif grep -q "tool.uv" pyproject.toml 2>/dev/null; then
echo "PKG_MANAGER=uv" >> $GITHUB_OUTPUT
echo " - Package manager: uv"
else
echo "PKG_MANAGER=pip" >> $GITHUB_OUTPUT
echo " - Package manager: pip"
fi
else
echo "PKG_MANAGER=pip" >> $GITHUB_OUTPUT
echo " - Package manager: pip"
fi
# Find main Python file
if [ -f "main.py" ]; then
echo "ENTRY_POINT=main.py" >> $GITHUB_OUTPUT
elif [ -f "app.py" ]; then
echo "ENTRY_POINT=app.py" >> $GITHUB_OUTPUT
elif [ -f "server.py" ]; then
echo "ENTRY_POINT=server.py" >> $GITHUB_OUTPUT
fi
elif [ -f "Cargo.toml" ]; then
echo "PROJECT_TYPE=rust" >> $GITHUB_OUTPUT
echo "Detected: Rust project"
elif [ -f "go.mod" ]; then
echo "PROJECT_TYPE=go" >> $GITHUB_OUTPUT
echo "Detected: Go project"
else
echo "PROJECT_TYPE=unknown" >> $GITHUB_OUTPUT
echo "Warning: Could not detect project type"
fi
# Check if Dockerfile already exists
if [ -f "Dockerfile" ]; then
echo "HAS_DOCKERFILE=true" >> $GITHUB_OUTPUT
echo " - Has existing Dockerfile"
else
echo "HAS_DOCKERFILE=false" >> $GITHUB_OUTPUT
fi
# List key files for debugging
echo ""
echo "=== Key files found ==="
ls -la | head -20
- name: Copy deployment Dockerfile if needed
if: steps.analyze.outputs.HAS_DOCKERFILE != 'true'
run: |
if [ -f "deployment/Dockerfile" ] && [ ! -f "Dockerfile" ]; then
cp deployment/Dockerfile Dockerfile
echo "Copied deployment/Dockerfile to root"
fi
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_CREDENTIALS }}
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Configure Docker for Artifact Registry
run: gcloud auth configure-docker us-central1-docker.pkg.dev
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: us-central1-docker.pkg.dev/biomindtalks/docker-images/mcp-base-mcp
tags: |
type=ref,event=branch
type=sha,prefix=
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max