name: Build and Push Scratch Docker Image
on:
push:
tags:
- 'v*' workflow_dispatch: inputs:
debug_mode:
description: 'Enable debug mode (no push to registry)'
required: false
default: false
type: boolean
target_platforms:
description: 'Target platforms'
required: false
default: 'linux/amd64'
type: string
build_target:
description: 'Docker build target'
required: false
default: 'runtime'
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
REGISTRY: docker.io
IMAGE_NAME: ${{ github.event.repository.name }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up flags
id: flags
run: |
# 检测是否是 main 分支
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
echo "is_main=true" >> $GITHUB_OUTPUT
else
echo "is_main=false" >> $GITHUB_OUTPUT
fi
# 设置 debug_mode 标志,确保总是有值
DEBUG_MODE="${{ inputs.debug_mode }}"
if [ "$DEBUG_MODE" = "true" ]; then
echo "debug_mode=true" >> $GITHUB_OUTPUT
else
echo "debug_mode=false" >> $GITHUB_OUTPUT
fi
echo "is_main: ${{ steps.flags.outputs.is_main }}"
echo "debug_mode: ${{ steps.flags.outputs.debug_mode }}"
- name: Debug Information
run: |
echo "Debug Mode: ${{ inputs.debug_mode }}"
echo "Target Platforms: ${{ inputs.target_platforms }}"
echo "Build Target: ${{ inputs.build_target }}"
echo "Trigger Event: ${{ github.event_name }}"
echo "Ref: ${{ github.ref }}"
echo "SHA: ${{ github.sha }}"
echo "Is Main Branch: ${{ steps.flags.outputs.is_main }}"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub (skip in debug mode)
if: ${{ !inputs.debug_mode }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=tag
type=raw,value=scratch,enable=${{ steps.flags.outputs.is_main == 'true' }}
type=raw,value=latest,enable=${{ steps.flags.outputs.is_main == 'true' }}
type=raw,value=debug-${{ github.sha }},enable=${{ steps.flags.outputs.debug_mode == 'true' }}
- name: Build Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: ${{ inputs.target_platforms }}
push: ${{ !inputs.debug_mode }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
target: ${{ inputs.build_target }}
cache-from: type=gha
cache-to: type=gha,mode=max
outputs: ${{ inputs.debug_mode && 'type=docker,dest=/tmp/image.tar' || '' }}
- name: Save image locally (debug mode)
if: ${{ inputs.debug_mode }}
run: |
echo "🔧 Debug mode: Saving image to workspace..."
mkdir -p /tmp/debug-artifacts
cp /tmp/image.tar /tmp/debug-artifacts/${{ env.IMAGE_NAME }}-debug.tar
echo "Image saved to /tmp/debug-artifacts/"
- name: Upload debug artifacts
if: ${{ inputs.debug_mode }}
uses: actions/upload-artifact@v4
with:
name: docker-image-debug
path: /tmp/debug-artifacts/
retention-days: 1
- name: Image inspection (debug mode)
if: ${{ inputs.debug_mode }}
run: |
echo "🔍 Inspecting built image..."
docker load -i /tmp/image.tar
docker images
echo "=== Image details ==="
IMAGE_TAG="${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:debug-${{ github.sha }}"
if docker image inspect "$IMAGE_TAG" >/dev/null 2>&1; then
docker image inspect "$IMAGE_TAG" | jq '.[0] | {Size: .Size, Architecture: .Architecture, Os: .Os}'
else
echo "⚠️ Debug image not found for inspection, listing all images:"
docker images
fi
- name: Test image (debug mode)
if: ${{ inputs.debug_mode }}
run: |
echo "🧪 Testing built image..."
IMAGE_TAG="${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:debug-${{ github.sha }}"
if docker image inspect "$IMAGE_TAG" >/dev/null 2>&1; then
docker run --rm "$IMAGE_TAG" --version || echo "Version check failed, but image runs"
echo "✅ Image test completed"
else
echo "❌ Debug image not found for testing"
fi
- name: Success message (production mode)
if: ${{ !inputs.debug_mode }}
run: |
echo "✅ Successfully published images:"
echo "${{ steps.meta.outputs.tags }}"
- name: Debug mode completion message
if: ${{ inputs.debug_mode }}
run: |
echo "🔧 Debug mode completed successfully!"
echo "📦 Image built but NOT pushed to registry"
echo "💾 Artifacts saved for inspection"
echo "🔄 To publish, re-run without debug mode"