name: Multi-Registry Docker Build and Push on: workflow_dispatch: inputs: repo_url: description: 'Repository URL to clone' required: true type: string default: 'https://git.lolcat.ca/lolcat/4get' image_name: description: 'Docker image name (without registry prefix)' required: true type: string default: 'user/image' tags: description: 'Comma-separated list of tags' required: true type: string default: 'latest' dockerfile_path: description: 'Path to Dockerfile (relative to repo root, e.g., "Dockerfile" or "docker/Dockerfile")' required: false type: string default: 'auto' push_to_dockerhub: description: 'Push to Docker Hub' required: true type: boolean default: true push_to_ghcr: description: 'Push to GitHub Container Registry' required: true type: boolean default: true push_to_quay: description: 'Push to Quay.io' required: true type: boolean default: true jobs: build-and-push: runs-on: ubuntu-latest steps: - name: Checkout workflow repository uses: actions/checkout@v4 - name: Clone target repository run: | git clone ${{ inputs.repo_url }} ./target-repo cd ./target-repo echo "REPO_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV echo "REPO_SHORT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - name: Detect Dockerfile location id: dockerfile run: | cd ./target-repo DOCKERFILE_PATH="${{ inputs.dockerfile_path }}" if [[ "$DOCKERFILE_PATH" == "auto" ]]; then # Auto-detect Dockerfile location if [[ -f "Dockerfile" ]]; then DOCKERFILE_PATH="Dockerfile" echo "Found Dockerfile in root directory" elif [[ -f "docker/Dockerfile" ]]; then DOCKERFILE_PATH="docker/Dockerfile" echo "Found Dockerfile in docker/ directory" else echo "Error: No Dockerfile found in root or docker/ directory" exit 1 fi else # Verify the specified Dockerfile exists if [[ ! -f "$DOCKERFILE_PATH" ]]; then echo "Error: Specified Dockerfile not found at: $DOCKERFILE_PATH" exit 1 fi echo "Using specified Dockerfile: $DOCKERFILE_PATH" fi echo "path=$DOCKERFILE_PATH" >> $GITHUB_OUTPUT echo "DOCKERFILE_PATH=$DOCKERFILE_PATH" >> $GITHUB_ENV - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub if: inputs.push_to_dockerhub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Log in to GitHub Container Registry if: inputs.push_to_ghcr uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GHCR_TOKEN }} - name: Log in to Quay.io if: inputs.push_to_quay uses: docker/login-action@v3 with: registry: quay.io username: ${{ secrets.QUAY_USERNAME }} password: ${{ secrets.QUAY_PASSWORD }} - name: Generate metadata id: meta run: | # Parse comma-separated tags IFS=',' read -ra TAG_ARRAY <<< "${{ inputs.tags }}" # Clean up image name (remove any leading/trailing slashes or spaces) IMAGE_NAME=$(echo "${{ inputs.image_name }}" | sed 's|^/||' | sed 's|/$||' | xargs) # Initialize tag list ALL_TAGS="" # Generate tags for each registry for tag in "${TAG_ARRAY[@]}"; do # Trim whitespace tag=$(echo "$tag" | xargs) # Skip empty tags if [[ -z "$tag" ]]; then continue fi # Docker Hub tags if [[ "${{ inputs.push_to_dockerhub }}" == "true" ]]; then if [[ -n "$ALL_TAGS" ]]; then ALL_TAGS="$ALL_TAGS," fi ALL_TAGS="$ALL_TAGS$IMAGE_NAME:$tag" fi # GHCR tags if [[ "${{ inputs.push_to_ghcr }}" == "true" ]]; then if [[ -n "$ALL_TAGS" ]]; then ALL_TAGS="$ALL_TAGS," fi ALL_TAGS="${ALL_TAGS}ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME:$tag" fi # Quay tags if [[ "${{ inputs.push_to_quay }}" == "true" ]]; then if [[ -n "$ALL_TAGS" ]]; then ALL_TAGS="$ALL_TAGS," fi ALL_TAGS="${ALL_TAGS}quay.io/$IMAGE_NAME:$tag" fi done echo "tags=$ALL_TAGS" >> $GITHUB_OUTPUT echo "Generated tags: $ALL_TAGS" - name: Build and push Docker images uses: docker/build-push-action@v5 with: context: ./target-repo file: ./target-repo/${{ steps.dockerfile.outputs.path }} platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: | org.opencontainers.image.title=${{ inputs.image_name }} org.opencontainers.image.description=Built from ${{ inputs.repo_url }} org.opencontainers.image.url=${{ inputs.repo_url }} org.opencontainers.image.source=${{ inputs.repo_url }} org.opencontainers.image.revision=${{ env.REPO_COMMIT }} org.opencontainers.image.created=${{ github.event.head_commit.timestamp }} cache-from: type=gha cache-to: type=gha,mode=max - name: Summary run: | echo "## Build Summary" >> $GITHUB_STEP_SUMMARY echo "**Repository:** ${{ inputs.repo_url }}" >> $GITHUB_STEP_SUMMARY echo "**Commit:** ${{ env.REPO_SHORT_COMMIT }}" >> $GITHUB_STEP_SUMMARY echo "**Dockerfile:** ${{ steps.dockerfile.outputs.path }}" >> $GITHUB_STEP_SUMMARY echo "**Image Name:** ${{ inputs.image_name }}" >> $GITHUB_STEP_SUMMARY echo "**Tags:** ${{ inputs.tags }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Registries:" >> $GITHUB_STEP_SUMMARY if [[ "${{ inputs.push_to_dockerhub }}" == "true" ]]; then echo "- ✅ Docker Hub" >> $GITHUB_STEP_SUMMARY else echo "- ❌ Docker Hub" >> $GITHUB_STEP_SUMMARY fi if [[ "${{ inputs.push_to_ghcr }}" == "true" ]]; then echo "- ✅ GitHub Container Registry" >> $GITHUB_STEP_SUMMARY else echo "- ❌ GitHub Container Registry" >> $GITHUB_STEP_SUMMARY fi if [[ "${{ inputs.push_to_quay }}" == "true" ]]; then echo "- ✅ Quay.io" >> $GITHUB_STEP_SUMMARY else echo "- ❌ Quay.io" >> $GITHUB_STEP_SUMMARY fi echo "" >> $GITHUB_STEP_SUMMARY echo "### Built Tags:" >> $GITHUB_STEP_SUMMARY echo "${{ steps.meta.outputs.tags }}" | tr ',' '\n' | sed 's/^/- /' >> $GITHUB_STEP_SUMMARY