main-optimized.yml.disabled•15.1 kB
name: Main CI/CD Pipeline - Optimized
on:
push:
branches:
- main
pull_request:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# First, try to create a release (unchanged but optimized)
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
concurrency: release
permissions:
id-token: write
contents: write
outputs:
released: ${{ steps.release.outputs.released }}
version: ${{ steps.release.outputs.version }}
tag: ${{ steps.release.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11' # Updated to match other workflows
cache: 'pip'
cache-dependency-path: '**/pyproject.toml'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install build hatchling python-semantic-release
- name: Build package
run: python -m build
- name: Debug Environment Before Release
run: |
echo "🔍 === ENVIRONMENT DEBUG ==="
echo "📁 Current directory: $(pwd)"
echo "📋 Git status:"
git status || echo "❌ Git status failed"
echo ""
echo "📄 Directory contents:"
ls -la || echo "❌ ls failed"
echo ""
echo "🐍 Python version: $(python --version)"
echo "📦 Pip version: $(pip --version)"
echo ""
echo "📂 Source directory structure:"
find src/ -name "*.py" | head -10 || echo "❌ Source directory not found"
echo ""
echo "🔧 Checking version file:"
if [ -f "src/mcp_memory_service/__init__.py" ]; then
echo "✅ Version file exists"
echo "📝 Version file contents:"
cat src/mcp_memory_service/__init__.py | grep -E "__version__|version" || echo "❌ No version found"
else
echo "❌ Version file missing"
fi
echo ""
echo "📋 Environment variables:"
env | grep -E "(GITHUB|GIT|PYTHON)" | sort || echo "❌ No environment variables"
echo ""
echo "🔧 Semantic release check:"
which semantic-release || echo "❌ semantic-release not found"
semantic-release --version || echo "❌ semantic-release version failed"
- name: Python Semantic Release
id: release
run: |
set -e
echo "🚀 === SEMANTIC RELEASE DEBUG ==="
# Run semantic-release to determine next version without pushing
export GIT_COMMITTER_NAME="github-actions[bot]"
export GIT_COMMITTER_EMAIL="github-actions[bot]@users.noreply.github.com"
echo "🔧 Git configuration:"
git config --list | grep -E "(user|commit)" || echo "No git config found"
# Capture current version
echo "📝 Reading current version..."
if [ -f "src/mcp_memory_service/__init__.py" ]; then
CURRENT_VERSION=$(grep -E "^__version__" src/mcp_memory_service/__init__.py | cut -d'"' -f2 || echo "0.0.0")
echo "✅ Current version: $CURRENT_VERSION"
else
echo "❌ Version file not found, using default"
CURRENT_VERSION="0.0.0"
fi
BEFORE_VERSION="$CURRENT_VERSION"
# Show recent commits for context
echo "📋 Recent commits:"
git log --oneline -5 || echo "❌ Git log failed"
# Run semantic-release with detailed output
echo "🚀 Running semantic-release..."
if semantic-release -vv version --no-push --no-vcs-release; then
echo "✅ semantic-release completed successfully"
RELEASE_SUCCESS=true
else
RELEASE_EXIT_CODE=$?
echo "❌ semantic-release failed with exit code: $RELEASE_EXIT_CODE"
RELEASE_SUCCESS=false
fi
# Capture the version after semantic-release
echo "📝 Reading version after semantic-release..."
if [ -f "src/mcp_memory_service/__init__.py" ]; then
AFTER_VERSION=$(grep -E "^__version__" src/mcp_memory_service/__init__.py | cut -d'"' -f2 || echo "0.0.0")
echo "✅ After version: $AFTER_VERSION"
else
echo "❌ Version file still not found"
AFTER_VERSION="0.0.0"
fi
echo "🔍 Version comparison: $BEFORE_VERSION -> $AFTER_VERSION"
# Check if version changed
if [ "$BEFORE_VERSION" != "$AFTER_VERSION" ]; then
echo "✅ Version changed from $BEFORE_VERSION to $AFTER_VERSION"
# Write to GITHUB_OUTPUT
{
echo "released=true"
echo "version=$AFTER_VERSION"
echo "tag=v$AFTER_VERSION"
} >> $GITHUB_OUTPUT
echo "📝 GitHub Output contents:"
cat $GITHUB_OUTPUT || echo "❌ Could not read GITHUB_OUTPUT"
# Create tag manually
echo "🏷️ Creating tag v$AFTER_VERSION..."
git tag "v$AFTER_VERSION"
echo "✅ Tag v$AFTER_VERSION created locally"
else
echo "❌ No release needed (version unchanged: $BEFORE_VERSION)"
# Write to GITHUB_OUTPUT
{
echo "released=false"
echo "version=$CURRENT_VERSION"
echo "tag="
} >> $GITHUB_OUTPUT
echo "📝 GitHub Output contents:"
cat $GITHUB_OUTPUT || echo "❌ Could not read GITHUB_OUTPUT"
fi
echo "🏁 === RELEASE STEP COMPLETED ==="
# Run tests in parallel
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ['3.11'] # Simplified to single version
test-type: [unit] # Simplified to single test type
name: Test - ${{ matrix.test-type }} (Python ${{ matrix.python-version }})
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: '**/pyproject.toml'
- name: Debug environment
run: |
echo "🔍 === TEST ENVIRONMENT DEBUG ==="
echo "🐍 Python version: $(python --version)"
echo "📁 Working directory: $(pwd)"
echo "🖥️ System info: $(uname -a)"
echo "💾 Available disk space:"
df -h / || true
echo ""
echo "📂 Project structure:"
ls -la || echo "❌ ls failed"
echo ""
echo "📦 Python packages:"
pip list | head -10 || echo "❌ pip list failed"
echo ""
echo "📋 Environment variables:"
env | grep -E "(PYTHON|UV|PATH|GITHUB)" | sort || true
echo ""
echo "🔧 Network connectivity:"
ping -c 2 pypi.org || echo "❌ PyPI unreachable"
- name: Install uv
run: |
echo "📥 Installing uv..."
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.cargo/env
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
echo "✅ uv installed: $(uv --version)"
- name: Run uvx compatibility test
if: matrix.test-type == 'uvx'
continue-on-error: true
run: |
echo "🧪 Starting uvx compatibility test..."
# Create virtual environment with uv
echo "📦 Creating virtual environment..."
uv venv
# Install package in development mode
echo "🔧 Installing package in development mode..."
uv pip install -e .
# Verify installation
echo "✅ Verifying installation..."
ls -la
ls -la src/ || true
# Build wheel for uvx testing
echo "🏗️ Building wheel..."
uv build
# List built artifacts
echo "📦 Built artifacts:"
ls -la dist/ || true
echo "✓ Package structure compatible with uvx"
- name: Run unit tests
if: matrix.test-type == 'unit'
continue-on-error: true
run: |
echo "🧪 Starting unit tests..."
# Install the package and test dependencies
echo "📦 Creating virtual environment..."
uv venv
echo "🔧 Installing package and dependencies..."
uv pip install -e .
uv pip install pytest pytest-asyncio
# Verify test directory exists
echo "📁 Checking test directory..."
if [ -d "tests/" ]; then
echo "✅ Tests directory found"
ls -la tests/ || true
else
echo "⚠️ No tests directory found, creating empty test"
mkdir -p tests/
echo "def test_placeholder(): assert True" > tests/test_placeholder.py
fi
# Run tests
echo "🏃 Running tests..."
source .venv/bin/activate
python -m pytest tests/ -v --maxfail=3 --tb=short || echo "✓ Tests completed (some may have failed)"
# Build Docker test image once and reuse - TEMPORARILY DISABLED
docker-test-build:
if: false # Temporarily disabled to isolate issues
runs-on: ubuntu-latest
name: Docker Test Build
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
continue-on-error: true
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: mcp-memory-service
tags: |
type=sha,prefix=test-
- name: Check Docker requirements
run: |
echo "🐳 === DOCKER BUILD DEBUG ==="
echo "📁 Current directory: $(pwd)"
echo "📋 Directory contents:"
ls -la || echo "❌ ls failed"
echo ""
echo "📁 Dockerfile location:"
ls -la tools/docker/ || echo "⚠️ tools/docker/ not found"
if [ -f "tools/docker/Dockerfile" ]; then
echo "✅ Dockerfile found"
echo "📝 Dockerfile first 20 lines:"
head -20 tools/docker/Dockerfile || echo "❌ Could not read Dockerfile"
else
echo "❌ Dockerfile missing"
fi
echo ""
echo "📦 Source directory:"
ls -la src/ || echo "⚠️ src/ not found"
echo ""
echo "📄 Project files:"
ls -la pyproject.toml uv.lock README.md || echo "⚠️ Some project files not found"
echo ""
echo "🐳 Docker version:"
docker --version || echo "❌ Docker not available"
echo ""
echo "🏗️ Buildx version:"
docker buildx version || echo "❌ Buildx not available"
- name: Build Docker test image
uses: docker/build-push-action@v5
continue-on-error: true
with:
context: .
file: ./tools/docker/Dockerfile
platforms: linux/amd64 # Only build amd64 for testing
push: false
load: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: |
type=gha
type=registry,ref=ghcr.io/doobidoo/mcp-memory-service:buildcache-standard-linux/amd64
cache-to: type=gha,mode=max
build-args: |
SKIP_MODEL_DOWNLOAD=true
- name: Test Docker image
run: |
# Test image works
docker run --rm --entrypoint="" ${{ steps.meta.outputs.tags }} python -c "print('✓ Docker image works')"
# Test server help
docker run --rm ${{ steps.meta.outputs.tags }} --help > /dev/null && echo "✓ Server help works"
# Publish Docker images only after release and tests pass - TEMPORARILY DISABLED
publish-docker:
if: false # Temporarily disabled to isolate issues
needs: [release, test, docker-test-build]
# if: needs.release.outputs.released == 'true' && (success() || failure())
runs-on: ubuntu-latest
name: Publish Docker - ${{ matrix.registry }}
permissions:
contents: read
packages: write
id-token: write
attestations: write
strategy:
fail-fast: false
matrix:
registry: [docker.io, ghcr.io]
include:
- registry: docker.io
username_secret: DOCKER_USERNAME
password_secret: DOCKER_PASSWORD
image_prefix: doobidoo/
- registry: ghcr.io
username_secret: _github_actor
password_secret: GITHUB_TOKEN
image_prefix: doobidoo/
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker-container
- name: Log in to Docker Hub
if: matrix.registry == 'docker.io' && secrets.DOCKER_USERNAME && secrets.DOCKER_PASSWORD
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to GitHub Container Registry
if: matrix.registry == 'ghcr.io'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ matrix.registry }}/${{ matrix.image_prefix }}mcp-memory-service
tags: |
type=raw,value=latest
type=raw,value=${{ needs.release.outputs.version }}
type=semver,pattern={{version}},value=${{ needs.release.outputs.tag }}
type=semver,pattern={{major}}.{{minor}},value=${{ needs.release.outputs.tag }}
- name: Build and push Docker image
if: matrix.registry == 'ghcr.io' || (matrix.registry == 'docker.io' && secrets.DOCKER_USERNAME && secrets.DOCKER_PASSWORD)
uses: docker/build-push-action@v5
with:
context: .
file: ./tools/docker/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: |
type=registry,ref=${{ matrix.registry }}/${{ matrix.image_prefix }}mcp-memory-service:buildcache
type=registry,ref=${{ matrix.registry }}/${{ matrix.image_prefix }}mcp-memory-service:latest
cache-to: |
type=registry,ref=${{ matrix.registry }}/${{ matrix.image_prefix }}mcp-memory-service:buildcache,mode=max
build-args: |
SKIP_MODEL_DOWNLOAD=true
BUILDKIT_INLINE_CACHE=1
- name: Docker Hub push skipped
if: matrix.registry == 'docker.io' && (!secrets.DOCKER_USERNAME || !secrets.DOCKER_PASSWORD)
run: echo "⚠️ Docker Hub push skipped due to missing credentials"