Implement AUTH_PROVIDER environment variable filtering for OAuth prov… #5
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: Build and Publish Container Images | ||
|
Check failure on line 1 in .github/workflows/publish-containers.yml
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| - master | ||
| tags: | ||
| - 'v*' | ||
| pull_request: | ||
| branches: | ||
| - main | ||
| - master | ||
| workflow_dispatch: | ||
| inputs: | ||
| version: | ||
| description: 'Version tag (e.g., v1.0.0)' | ||
| required: false | ||
| default: 'latest' | ||
| push_to_registry: | ||
| description: 'Push to registries (yes/no)' | ||
| required: true | ||
| default: 'yes' | ||
| env: | ||
| REGISTRY_DOCKERHUB: docker.io | ||
| REGISTRY_GHCR: ghcr.io | ||
| DOCKERHUB_ORG: mcpgateway | ||
| PLATFORMS: linux/amd64,linux/arm64 | ||
| jobs: | ||
| build-and-publish: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
| id-token: write | ||
| strategy: | ||
| matrix: | ||
| component: | ||
| - name: registry | ||
| context: . | ||
| dockerfile: ./docker/Dockerfile.registry | ||
| - name: auth-server | ||
| context: . | ||
| dockerfile: ./docker/Dockerfile.auth | ||
| - name: currenttime-server | ||
| context: . | ||
| dockerfile: ./docker/Dockerfile.mcp-server | ||
| build_args: SERVER_PATH=servers/currenttime | ||
| - name: realserverfaketools | ||
| context: . | ||
| dockerfile: ./docker/Dockerfile.mcp-server | ||
| build_args: SERVER_PATH=servers/realserverfaketools | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Set up QEMU | ||
| uses: docker/setup-qemu-action@v3 | ||
| with: | ||
| platforms: all | ||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
| with: | ||
| driver-opts: network=host | ||
| - name: Log in to Docker Hub | ||
| if: | | ||
| github.event_name != 'pull_request' && | ||
| (github.event_name != 'workflow_dispatch' || github.event.inputs.push_to_registry == 'yes') && | ||
| secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' | ||
| continue-on-error: true | ||
| id: dockerhub_login | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ${{ env.REGISTRY_DOCKERHUB }} | ||
| username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
| password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
| - name: Log in to GitHub Container Registry | ||
| if: | | ||
| github.event_name != 'pull_request' && | ||
| (github.event_name != 'workflow_dispatch' || github.event.inputs.push_to_registry == 'yes') | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ${{ env.REGISTRY_GHCR }} | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Extract metadata | ||
| id: meta | ||
| uses: docker/metadata-action@v5 | ||
| with: | ||
| images: | | ||
| ${{ steps.dockerhub_login.outcome == 'success' && (env.DOCKERHUB_ORG && format('{0}/{1}/{2}', env.REGISTRY_DOCKERHUB, env.DOCKERHUB_ORG, matrix.component.name) || format('{0}/{1}/{2}', env.REGISTRY_DOCKERHUB, secrets.DOCKERHUB_USERNAME, matrix.component.name)) || '' }} | ||
| ${{ env.REGISTRY_GHCR }}/${{ env.GITHUB_ORG && env.GITHUB_ORG || github.repository_owner }}/mcp-${{ matrix.component.name }} | ||
| tags: | | ||
| type=ref,event=branch | ||
| type=ref,event=pr | ||
| type=semver,pattern={{version}} | ||
| type=semver,pattern={{major}}.{{minor}} | ||
| type=semver,pattern={{major}} | ||
| type=raw,value=latest,enable={{is_default_branch}} | ||
| type=raw,value=${{ github.event.inputs.version }},enable=${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }} | ||
| type=sha,prefix=sha-,format=short | ||
| flavor: | | ||
| latest=auto | ||
| - name: Check if Dockerfile exists | ||
| id: dockerfile_check | ||
| run: | | ||
| if [ -f "${{ matrix.component.dockerfile }}" ]; then | ||
| echo "exists=true" >> $GITHUB_OUTPUT | ||
| echo "✅ Dockerfile found: ${{ matrix.component.dockerfile }}" | ||
| else | ||
| echo "exists=false" >> $GITHUB_OUTPUT | ||
| echo "⚠️ Dockerfile not found: ${{ matrix.component.dockerfile }}" | ||
| fi | ||
| - name: Build and push Docker image | ||
| if: steps.dockerfile_check.outputs.exists == 'true' | ||
| uses: docker/build-push-action@v5 | ||
| with: | ||
| context: ${{ matrix.component.context }} | ||
| file: ${{ matrix.component.dockerfile }} | ||
| platforms: ${{ env.PLATFORMS }} | ||
| push: ${{ github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || github.event.inputs.push_to_registry == 'yes') }} | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| labels: ${{ steps.meta.outputs.labels }} | ||
| cache-from: type=gha,scope=${{ matrix.component.name }} | ||
| cache-to: type=gha,mode=max,scope=${{ matrix.component.name }} | ||
| build-args: | | ||
| BUILD_DATE=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} | ||
| VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} | ||
| REVISION=${{ github.sha }} | ||
| ${{ matrix.component.build_args && matrix.component.build_args || '' }} | ||
| - name: Image digest | ||
| if: steps.dockerfile_check.outputs.exists == 'true' | ||
| run: | | ||
| echo "### 📦 ${{ matrix.component.name }} Image Published" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Component**: ${{ matrix.component.name }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Tags**: " >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | ||
| echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | ||
| create-manifest: | ||
| needs: build-and-publish | ||
| runs-on: ubuntu-latest | ||
| if: | | ||
| github.event_name != 'pull_request' && | ||
| (github.event_name != 'workflow_dispatch' || github.event.inputs.push_to_registry == 'yes') | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
| - name: Create docker-compose.prebuilt.yml | ||
| run: | | ||
| cat > docker-compose.prebuilt.yml << 'EOF' | ||
| version: '3.8' | ||
| services: | ||
| registry: | ||
| image: ${{ env.DOCKERHUB_ORG }}/registry:${{ github.event.inputs.version || 'latest' }} | ||
| ports: | ||
| - "7860:7860" | ||
| environment: | ||
| - ADMIN_USER=${ADMIN_USER} | ||
| - ADMIN_PASSWORD=${ADMIN_PASSWORD} | ||
| - AUTH_SERVER_URL=${AUTH_SERVER_URL} | ||
| - DOMAIN_NAME=${DOMAIN_NAME} | ||
| - AUTH_PROVIDER=${AUTH_PROVIDER} | ||
| depends_on: | ||
| - auth-server | ||
| networks: | ||
| - mcp-network | ||
| volumes: | ||
| - ./registry_data:/app/data | ||
| auth-server: | ||
| image: ${{ env.DOCKERHUB_ORG }}/auth-server:${{ github.event.inputs.version || 'latest' }} | ||
| ports: | ||
| - "8888:8888" | ||
| environment: | ||
| - AUTH_PROVIDER=${AUTH_PROVIDER} | ||
| - KEYCLOAK_URL=${KEYCLOAK_URL} | ||
| - KEYCLOAK_REALM=${KEYCLOAK_REALM} | ||
| - KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID} | ||
| - KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET} | ||
| - COGNITO_USER_POOL_ID=${COGNITO_USER_POOL_ID} | ||
| - COGNITO_CLIENT_ID=${COGNITO_CLIENT_ID} | ||
| - COGNITO_CLIENT_SECRET=${COGNITO_CLIENT_SECRET} | ||
| - COGNITO_REGION=${COGNITO_REGION} | ||
| networks: | ||
| - mcp-network | ||
| currenttime-server: | ||
| image: ${{ env.DOCKERHUB_ORG }}/currenttime-server:${{ github.event.inputs.version || 'latest' }} | ||
| ports: | ||
| - "8000:8000" | ||
| networks: | ||
| - mcp-network | ||
| realserverfaketools: | ||
| image: ${{ env.DOCKERHUB_ORG }}/realserverfaketools:${{ github.event.inputs.version || 'latest' }} | ||
| ports: | ||
| - "8001:8001" | ||
| networks: | ||
| - mcp-network | ||
| # External services (not built, using existing images) | ||
| keycloak: | ||
| image: quay.io/keycloak/keycloak:latest | ||
| environment: | ||
| - KEYCLOAK_ADMIN=${KEYCLOAK_ADMIN:-admin} | ||
| - KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD:-admin} | ||
| command: | ||
| - start-dev | ||
| ports: | ||
| - "8080:8080" | ||
| networks: | ||
| - mcp-network | ||
| volumes: | ||
| - keycloak_data:/opt/keycloak/data | ||
| postgres: | ||
| image: postgres:15 | ||
| environment: | ||
| - POSTGRES_DB=keycloak | ||
| - POSTGRES_USER=keycloak | ||
| - POSTGRES_PASSWORD=keycloak | ||
| volumes: | ||
| - postgres_data:/var/lib/postgresql/data | ||
| networks: | ||
| - mcp-network | ||
| networks: | ||
| mcp-network: | ||
| driver: bridge | ||
| volumes: | ||
| postgres_data: | ||
| keycloak_data: | ||
| registry_data: | ||
| EOF | ||
| echo "✅ Created docker-compose.prebuilt.yml" | ||
| - name: Create release artifacts | ||
| if: startsWith(github.ref, 'refs/tags/v') | ||
| run: | | ||
| mkdir -p release | ||
| cp docker-compose.prebuilt.yml release/ | ||
| cp .env.example release/.env.example | ||
| cp scripts/publish_containers.sh release/ | ||
| tar -czf mcp-gateway-registry-${{ github.ref_name }}.tar.gz release/ | ||
| - name: Upload release artifacts | ||
| if: startsWith(github.ref, 'refs/tags/v') | ||
| uses: actions/upload-artifact@v3 | ||
| with: | ||
| name: release-artifacts | ||
| path: mcp-gateway-registry-*.tar.gz | ||
| - name: Create summary | ||
| run: | | ||
| echo "## 🚀 Container Images Published Successfully!" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| # Only show Docker Hub section if credentials were provided and login succeeded | ||
| if [ "${{ steps.dockerhub_login.outcome }}" = "success" ]; then | ||
| echo "### Docker Hub Images:" >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY | ||
| # Use organization if set, otherwise use username | ||
| if [ -n "${{ env.DOCKERHUB_ORG }}" ]; then | ||
| DOCKER_PREFIX="${{ env.DOCKERHUB_ORG }}" | ||
| else | ||
| DOCKER_PREFIX="${{ secrets.DOCKERHUB_USERNAME }}" | ||
| fi | ||
| echo "docker pull $DOCKER_PREFIX/registry:${{ github.event.inputs.version || 'latest' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "docker pull $DOCKER_PREFIX/auth-server:${{ github.event.inputs.version || 'latest' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "docker pull $DOCKER_PREFIX/currenttime-server:${{ github.event.inputs.version || 'latest' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "docker pull $DOCKER_PREFIX/realserverfaketools:${{ github.event.inputs.version || 'latest' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| fi | ||
| echo "### GitHub Container Registry Images:" >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY | ||
| # Use organization if set, otherwise use repository owner (username) | ||
| if [ -n "${{ env.GITHUB_ORG }}" ]; then | ||
| GITHUB_PREFIX="${{ env.GITHUB_ORG }}" | ||
| else | ||
| GITHUB_PREFIX="${{ github.repository_owner }}" | ||
| fi | ||
| echo "docker pull ghcr.io/$GITHUB_PREFIX/mcp-registry:${{ github.event.inputs.version || 'latest' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "docker pull ghcr.io/$GITHUB_PREFIX/mcp-auth-server:${{ github.event.inputs.version || 'latest' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "docker pull ghcr.io/$GITHUB_PREFIX/mcp-currenttime-server:${{ github.event.inputs.version || 'latest' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "docker pull ghcr.io/$GITHUB_PREFIX/mcp-realserverfaketools:${{ github.event.inputs.version || 'latest' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | ||
| # Add note about missing Docker Hub credentials if they weren't provided | ||
| if [ "${{ steps.dockerhub_login.outcome }}" != "success" ]; then | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "### ℹ️ Docker Hub Publishing" >> $GITHUB_STEP_SUMMARY | ||
| echo "Docker Hub credentials were not configured, so images were only published to GitHub Container Registry." >> $GITHUB_STEP_SUMMARY | ||
| echo "To publish to Docker Hub, add \`DOCKERHUB_USERNAME\` and \`DOCKERHUB_TOKEN\` repository secrets." >> $GITHUB_STEP_SUMMARY | ||
| fi | ||