name: Build and Push Docker Image description: > A reusable GitHub Action to build and push Docker images to a specified container registry. inputs: registry: description: 'Container registry host (e.g., ghcr.io, docker.io)' required: true username: description: 'Username for the container registry' required: true password: description: 'Password or token for the container registry' required: true image_name: description: 'Name of the Docker image (e.g., myuser/myimage)' required: true context_path: description: 'Path to the build context' required: false default: '.' dockerfile_path: description: 'Path to the Dockerfile' required: false default: './Dockerfile' platforms: description: 'Target platforms for the Docker image (e.g., linux/amd64,linux/arm64)' required: false default: 'linux/amd64' cache_ref: description: 'Reference for build cache' required: false default: '' github_token: description: 'GitHub token for metadata extraction' required: true runs: using: "composite" steps: - name: Checkout repository uses: actions/checkout@v5 - name: Define branch helpers id: branch run: | DEFAULT="${{ github.event.repository.default_branch }}" CURRENT="${{ github.ref_name }}" if [ "$DEFAULT" = "$CURRENT" ]; then echo "is_default_branch=true" >> $GITHUB_OUTPUT else echo "is_default_branch=false" >> $GITHUB_OUTPUT fi - name: Extract Docker metadata id: meta uses: docker/metadata-action@v5 with: github-token: ${{ inputs.github_token }} images: ${{ inputs.registry }}/${{ inputs.image_name }} tags: | type=ref,event=branch type=ref,event=tag type=sha type=raw,value=latest,enable=${{ steps.branch.outputs.is_default_branch }} - name: Set up QEMU # for multi-platform builds uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx # for advanced builds uses: docker/setup-buildx-action@v3 - name: Log in to registry uses: docker/login-action@v3 with: registry: ${{ inputs.registry }} username: ${{ inputs.username }} password: ${{ inputs.password }} - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: ${{ inputs.context_path }} file: ${{ inputs.dockerfile_path }} push: true platforms: ${{ inputs.platforms }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=registry,ref=${{ inputs.cache_ref }} cache-to: type=registry,ref=${{ inputs.cache_ref }},mode=max - name: Image details run: | echo "Image pushed: ${{ inputs.registry }}/${{ inputs.image_name }}" echo "Labels: ${{ steps.meta.outputs.labels }}" echo "Tags: ${{ steps.meta.outputs.tags }}" echo "Digest: ${{ steps.meta.outputs.digest }}"