Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Merge branch 'main' of https://github.com/neverinfamous/postgres-mcp #79

Merge branch 'main' of https://github.com/neverinfamous/postgres-mcp

Merge branch 'main' of https://github.com/neverinfamous/postgres-mcp #79

# act -W ../.github/workflows/docker-build-dockerhub.yml -s DOCKERHUB_USERNAME -s DOCKERHUB_TOKEN -s GITHUB_TOKEN="$(gh auth token)"
---
name: Build and Push Docker Image to DockerHub
on:
push:
branches: [ main ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
workflow_dispatch:
inputs:
version:
description: "Version to release (without v prefix)"
required: true
default: ""
# Security: Explicit permissions following principle of least privilege
permissions:
contents: read
packages: write
security-events: write # For security scanning
pull-requests: write # For PR comments
attestations: write # For generating attestations
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.set-version.outputs.VERSION }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Extract version from pyproject.toml
id: set-version
run: |
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_type }}" == "tag" ]]; then
# Extract version from git tag (remove 'v' prefix)
VERSION="${GITHUB_REF#refs/tags/v}"
elif [[ -n "${{ github.event.inputs.version }}" ]]; then
# Use workflow_dispatch input
VERSION="${{ github.event.inputs.version }}"
else
# Extract from pyproject.toml for regular pushes
VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
fi
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"
build-and-push:
needs: prepare
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
with:
install: true
version: latest
driver-opts: image=moby/buildkit:latest
- name: Inspect builder
run: |
echo "Available platforms: $(docker buildx inspect --bootstrap | grep 'Platforms:')"
docker buildx ls
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: arm64,amd64
image: tonistiigi/binfmt:latest
- name: Prepare Docker tags
id: docker_meta
uses: docker/metadata-action@v5
with:
images: writenotenow/postgres-mcp-enhanced
flavor: |
latest=false
tags: |
# Create latest tag for main branch pushes only
type=raw,value=latest,enable={{is_default_branch}}
# Create version tags (v1.1.0)
type=raw,value=v${{ needs.prepare.outputs.version }},enable={{is_default_branch}}
# Create short SHA tags for traceability (e.g., sha-8f8183d)
type=sha,prefix=sha-,format=short,enable={{is_default_branch}}
- name: Check directory structure
run: |
echo "check pwd: $(pwd)"
echo "check ls: $(ls -lta)"
# Login to Docker Hub for Scout scanning (needs auth for full vulnerability data)
- name: Login to DockerHub for Scout
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# Build locally first for security scanning (AMD64 only)
- name: Build Docker image for scanning
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
platforms: linux/amd64
push: false
load: true
tags: local-scan:latest
cache-from: type=gha
# Security scanning with Docker Scout CLI - BLOCKS build on critical/high CVEs
- name: Docker Scout security scan (blocking)
timeout-minutes: 10
continue-on-error: false
run: |
# Install Docker Scout CLI
curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --
# Verify image exists
docker images local-scan:latest
# Run security scan - block vulnerabilities above medium level (critical, high)
echo "🔍 Running Docker Scout security scan for local-scan:latest"
# Run scan and capture output
set +e # Don't exit on error, we'll handle it
docker scout cves local-scan:latest 2>&1 | tee scout_output.txt
SCOUT_EXIT=$?
set -e
echo ""
echo "📊 Scout scan completed with exit code: $SCOUT_EXIT"
# Check if critical or high vulnerabilities are present in the output
if grep -E "(CRITICAL|HIGH)" scout_output.txt 2>/dev/null | grep -v "0C" | grep -v "0H" | grep -v "0 " > /dev/null 2>&1; then
echo "❌ Critical or high severity vulnerabilities detected"
echo "🚨 Build blocked due to unacceptable security risk"
exit 1
else
echo "✅ Security scan passed - no critical/high severity vulnerabilities"
echo "ℹ️ Low/medium severity vulnerabilities are acceptable"
fi
# Only push if security scan passes
# Note: Already logged in from Scout scan step
- name: Build and push
if: success()
id: build-push
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
# Use GitHub Actions cache instead of registry cache to avoid buildcache tag
cache-from: type=gha
cache-to: type=gha,mode=max
# Security: Enable build attestations for supply chain security
provenance: mode=max
sbom: true
# Retry mechanism for transient Docker Hub API failures
- name: Retry Docker push on failure
if: failure() && steps.build-push.outcome == 'failure'
run: |
echo "⚠️ Initial push failed - retrying in 30 seconds..."
sleep 30
echo "🔄 Retry attempt starting..."
# Post-push Docker Scout analysis for reporting (non-blocking)
- name: Docker Scout Analysis (reporting only)
uses: docker/scout-action@v1
if: github.event_name == 'push' && success()
continue-on-error: true
with:
command: cves,recommendations
image: writenotenow/postgres-mcp-enhanced:v${{ needs.prepare.outputs.version }}
only-severities: critical,high
exit-code: false
write-comment: true
- name: Docker Scout Compare (reporting only)
uses: docker/scout-action@v1
if: github.event_name == 'push' && success()
continue-on-error: true
with:
command: compare
image: writenotenow/postgres-mcp-enhanced:v${{ needs.prepare.outputs.version }}
to: writenotenow/postgres-mcp-enhanced:latest
exit-code: false
- name: Update Docker Hub Description
if: github.event_name == 'push'
uses: peter-evans/dockerhub-description@v5
continue-on-error: true
timeout-minutes: 5
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: writenotenow/postgres-mcp-enhanced
readme-filepath: ./DOCKER_README.md
short-description: "Enterprise PostgreSQL MCP Server - 63 specialized tools with comprehensive security and AI-native operations"