fix: Refactoring release TFO-Python-MCP #4
Workflow file for this run
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
| # ============================================================================= | |
| # TelemetryFlow Python MCP Server - Docker Image Builder Workflow | |
| # ============================================================================= | |
| # | |
| # TelemetryFlow Python MCP Server - Community Enterprise Observability Platform (CEOP) | |
| # Copyright (c) 2024-2026 DevOpsCorner Indonesia. All rights reserved. | |
| # | |
| # This workflow builds and publishes Docker images for TelemetryFlow Python MCP: | |
| # - Multi-platform support: linux/amd64, linux/arm64 | |
| # - Semantic versioning tags | |
| # - Docker Hub | |
| # | |
| # Triggers: | |
| # - Push tags matching v*.*.* | |
| # - Push to main/master branch (latest tag) | |
| # - Manual workflow dispatch | |
| # | |
| # ============================================================================= | |
| name: Docker Build - TFO Python MCP | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - master | |
| tags: | |
| - 'v*.*.*' | |
| paths: | |
| - 'Dockerfile*' | |
| - 'src/**' | |
| - 'pyproject.toml' | |
| - '.github/workflows/docker.yml' | |
| pull_request: | |
| branches: | |
| - main | |
| - master | |
| paths: | |
| - 'Dockerfile*' | |
| - 'src/**' | |
| - 'pyproject.toml' | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version tag (e.g., 1.0.0)' | |
| required: false | |
| default: '' | |
| push: | |
| description: 'Push images to registry' | |
| required: false | |
| type: boolean | |
| default: true | |
| platforms: | |
| description: 'Target platforms' | |
| required: false | |
| default: 'linux/amd64,linux/arm64' | |
| env: | |
| REGISTRY_DOCKER: docker.io | |
| IMAGE_NAME: telemetryflow/telemetryflow-python-mcp | |
| PRODUCT_NAME: TelemetryFlow Python MCP Server | |
| PYTHON_VERSION: '3.12' | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| security-events: write | |
| jobs: | |
| # =========================================================================== | |
| # Prepare Build Context | |
| # =========================================================================== | |
| prepare: | |
| name: Prepare Build | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.meta.outputs.version }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| commit: ${{ steps.info.outputs.commit }} | |
| branch: ${{ steps.info.outputs.branch }} | |
| build_time: ${{ steps.info.outputs.build_time }} | |
| python_version: ${{ steps.info.outputs.python_version }} | |
| push: ${{ steps.check.outputs.push }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get build info | |
| id: info | |
| run: | | |
| echo "commit=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | |
| echo "branch=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_OUTPUT | |
| echo "build_time=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT | |
| echo "python_version=${{ env.PYTHON_VERSION }}" >> $GITHUB_OUTPUT | |
| - name: Check if should push | |
| id: check | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| echo "push=false" >> $GITHUB_OUTPUT | |
| elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "push=${{ github.event.inputs.push }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "push=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: | | |
| ${{ env.REGISTRY_DOCKER }}/${{ env.IMAGE_NAME }} | |
| flavor: | | |
| latest=false | |
| tags: | | |
| # Semantic versioning from tags | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| # Manual version input | |
| type=raw,value=${{ github.event.inputs.version }},enable=${{ github.event.inputs.version != '' }} | |
| # Branch name for non-tag pushes | |
| type=ref,event=branch | |
| # PR number | |
| type=ref,event=pr | |
| # Latest for default branch | |
| type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') || github.ref == format('refs/heads/{0}', 'master') }} | |
| # Git SHA | |
| type=sha,prefix=sha-,format=short | |
| labels: | | |
| org.opencontainers.image.title=${{ env.PRODUCT_NAME }} | |
| org.opencontainers.image.description=MCP Server for TelemetryFlow with Claude API integration | |
| org.opencontainers.image.vendor=TelemetryFlow | |
| io.telemetryflow.product=${{ env.PRODUCT_NAME }} | |
| io.telemetryflow.component=mcp-server | |
| io.telemetryflow.platform=CEOP | |
| # =========================================================================== | |
| # Build and Push Docker Image | |
| # =========================================================================== | |
| build: | |
| name: Build & Push | |
| runs-on: ubuntu-latest | |
| needs: prepare | |
| steps: | |
| - name: Free up disk space | |
| run: | | |
| echo "=== Disk space before cleanup ===" | |
| df -h | |
| # Remove unnecessary tools and SDKs | |
| sudo rm -rf /usr/share/dotnet | |
| sudo rm -rf /usr/local/lib/android | |
| sudo rm -rf /opt/ghc | |
| sudo rm -rf /opt/hostedtoolcache/CodeQL | |
| sudo rm -rf /usr/local/share/boost | |
| sudo rm -rf /usr/share/swift | |
| sudo rm -rf "$AGENT_TOOLSDIRECTORY" | |
| # Clean apt cache | |
| sudo apt-get clean | |
| # Remove Docker images we don't need | |
| docker system prune -af --volumes || true | |
| echo "=== Disk space after cleanup ===" | |
| df -h | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Create Dockerfile | |
| run: | | |
| cat > Dockerfile << 'EOF' | |
| # ============================================================================= | |
| # TelemetryFlow Python MCP Server - Multi-stage Dockerfile | |
| # ============================================================================= | |
| FROM python:3.12-slim AS builder | |
| ARG VERSION=dev | |
| ARG GIT_COMMIT=unknown | |
| ARG BUILD_TIME=unknown | |
| WORKDIR /build | |
| # Install build dependencies | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| git \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Copy package files | |
| COPY pyproject.toml README.md ./ | |
| COPY src/ ./src/ | |
| # Build wheel | |
| RUN pip install --no-cache-dir build && \ | |
| python -m build --wheel | |
| # ============================================================================= | |
| # Final image | |
| # ============================================================================= | |
| FROM python:3.12-slim | |
| ARG VERSION=dev | |
| # Install the built wheel | |
| COPY --from=builder /build/dist/*.whl /tmp/ | |
| RUN pip install --no-cache-dir /tmp/*.whl && \ | |
| rm /tmp/*.whl | |
| # Labels | |
| LABEL org.opencontainers.image.title="TelemetryFlow Python MCP Server" | |
| LABEL org.opencontainers.image.description="MCP Server with DDD/CQRS architecture" | |
| LABEL org.opencontainers.image.vendor="TelemetryFlow" | |
| LABEL org.opencontainers.image.licenses="Apache-2.0" | |
| LABEL org.opencontainers.image.version="${VERSION}" | |
| WORKDIR /app | |
| ENTRYPOINT ["tfo-mcp"] | |
| CMD ["serve"] | |
| EOF | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to Docker Hub | |
| if: needs.prepare.outputs.push == 'true' && vars.DOCKERHUB_USERNAME != '' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY_DOCKER }} | |
| username: ${{ vars.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Determine version | |
| id: version | |
| run: | | |
| if [ "${{ github.event.inputs.version }}" != "" ]; then | |
| VERSION="${{ github.event.inputs.version }}" | |
| elif [[ "${{ github.ref }}" == refs/tags/v* ]]; then | |
| VERSION="${GITHUB_REF#refs/tags/v}" | |
| else | |
| VERSION="${{ needs.prepare.outputs.commit }}" | |
| fi | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| - name: Build and push | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| platforms: ${{ github.event.inputs.platforms || 'linux/amd64,linux/arm64' }} | |
| push: ${{ needs.prepare.outputs.push == 'true' }} | |
| tags: ${{ needs.prepare.outputs.tags }} | |
| labels: ${{ needs.prepare.outputs.labels }} | |
| build-args: | | |
| VERSION=${{ steps.version.outputs.version }} | |
| GIT_COMMIT=${{ needs.prepare.outputs.commit }} | |
| BUILD_TIME=${{ needs.prepare.outputs.build_time }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| provenance: true | |
| sbom: true | |
| - name: Generate SBOM | |
| if: needs.prepare.outputs.push == 'true' | |
| uses: anchore/sbom-action@v0 | |
| with: | |
| image: ${{ env.REGISTRY_DOCKER }}/${{ env.IMAGE_NAME }}:sha-${{ needs.prepare.outputs.commit }} | |
| format: spdx-json | |
| output-file: sbom-${{ steps.version.outputs.version }}.spdx.json | |
| upload-release-assets: false | |
| continue-on-error: true | |
| - name: Upload SBOM | |
| if: needs.prepare.outputs.push == 'true' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sbom-${{ needs.prepare.outputs.commit }} | |
| path: sbom-*.spdx.json | |
| retention-days: 90 | |
| continue-on-error: true | |
| # =========================================================================== | |
| # Security Scan | |
| # =========================================================================== | |
| scan: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| needs: [prepare, build] | |
| if: needs.prepare.outputs.push == 'true' && vars.DOCKERHUB_USERNAME != '' | |
| steps: | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY_DOCKER }} | |
| username: ${{ vars.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| image-ref: ${{ env.REGISTRY_DOCKER }}/${{ env.IMAGE_NAME }}:sha-${{ needs.prepare.outputs.commit }} | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| severity: 'CRITICAL,HIGH' | |
| continue-on-error: true | |
| - name: Upload Trivy scan results | |
| uses: github/codeql-action/upload-sarif@v4 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| continue-on-error: true | |
| # =========================================================================== | |
| # Summary | |
| # =========================================================================== | |
| summary: | |
| name: Build Summary | |
| runs-on: ubuntu-latest | |
| needs: [prepare, build] | |
| if: always() | |
| steps: | |
| - name: Summary | |
| run: | | |
| echo "## Docker Build Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Item | Value |" >> $GITHUB_STEP_SUMMARY | |
| echo "|------|-------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Product** | ${{ env.PRODUCT_NAME }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Python Version** | ${{ needs.prepare.outputs.python_version }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Commit** | ${{ needs.prepare.outputs.commit }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Branch** | ${{ needs.prepare.outputs.branch }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Build Time** | ${{ needs.prepare.outputs.build_time }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Push** | ${{ needs.prepare.outputs.push }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Tags" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "${{ needs.prepare.outputs.tags }}" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Pull Commands" >> $GITHUB_STEP_SUMMARY | |
| echo '```bash' >> $GITHUB_STEP_SUMMARY | |
| echo "docker pull ${{ env.IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Usage" >> $GITHUB_STEP_SUMMARY | |
| echo '```bash' >> $GITHUB_STEP_SUMMARY | |
| echo "# Start MCP server" >> $GITHUB_STEP_SUMMARY | |
| echo "docker run --rm -it \\" >> $GITHUB_STEP_SUMMARY | |
| echo " -e ANTHROPIC_API_KEY=\$ANTHROPIC_API_KEY \\" >> $GITHUB_STEP_SUMMARY | |
| echo " ${{ env.IMAGE_NAME }}:latest serve" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "# Show help" >> $GITHUB_STEP_SUMMARY | |
| echo "docker run --rm ${{ env.IMAGE_NAME }}:latest --help" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY |