Skip to content

Build, Tag, and Push Docker Image #9

Build, Tag, and Push Docker Image

Build, Tag, and Push Docker Image #9

Workflow file for this run

name: Build, Tag, and Push Docker Image
on:
workflow_dispatch:
inputs:
tag_version:
description: 'Docker image tag version (e.g., 3.3.11)'
required: true
branch:
description: 'Branch to build from (default: staging)'
required: false
default: 'staging'
env:
DOCKER_IMAGE_NAME: elevate-user
DOCKER_REGISTRY: docker.io
DOCKER_NAMESPACE: shikshalokamqa
permissions:
contents: write
jobs:
docker-image-build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code from target branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch || 'staging' }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Get Docker tag version
id: get-version
shell: bash
run: |
VERSION="${{ github.event.inputs.tag_version }}"
# Strip leading "v" if present
VERSION="${VERSION#v}"
# Enforce x.y.z or x.y.z-rc.1 format
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$ ]]; then
echo "Error: tag_version must look like 3.4.0 or 3.4.0-rc.1 (no other suffixes allowed)"
exit 1
fi
printf 'version=%s\n' "$VERSION" >> "$GITHUB_OUTPUT"
- name: Check if Git tag already exists
run: |
VERSION="${{ steps.get-version.outputs.version }}"
git fetch --tags
if git rev-parse "$VERSION" >/dev/null 2>&1; then
echo "Error: Git tag $VERSION already exists"
exit 1
fi
- name: Check if version exists on Docker Hub
run: |
VERSION="${{ steps.get-version.outputs.version }}"
LOGIN_RESPONSE=$(curl -s -w "\n%{http_code}" \
-u "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" \
"https://hub.docker.com/v2/users/login")
LOGIN_HTTP=$(echo "$LOGIN_RESPONSE" | tail -n1)
LOGIN_BODY=$(echo "$LOGIN_RESPONSE" | head -n-1)
if [ "$LOGIN_HTTP" -ne 200 ]; then
echo "Error: Docker Hub login failed with HTTP $LOGIN_HTTP"
exit 1
fi
TOKEN=$(echo "$LOGIN_BODY" | jq -r .token)
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
echo "Error: Docker Hub login succeeded but returned no token"
exit 1
fi
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $TOKEN" \
"https://hub.docker.com/v2/namespaces/${{ env.DOCKER_NAMESPACE }}/repositories/${{ env.DOCKER_IMAGE_NAME }}/tags/$VERSION")
if [ "$RESPONSE" -eq 200 ]; then
echo "Error: Tag $VERSION already exists on Docker Hub"
exit 1
elif [ "$RESPONSE" -eq 404 ]; then
echo "Tag $VERSION not found on Docker Hub — safe to push"
else
echo "Error: Unexpected HTTP $RESPONSE from Docker Hub tag check; aborting to fail safe"
exit 1
fi
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_NAMESPACE }}/${{ env.DOCKER_IMAGE_NAME }}
tags: |
type=raw,value=${{ steps.get-version.outputs.version }}
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Create and push Git tag
run: |
VERSION="${{ steps.get-version.outputs.version }}"
git config user.name "github-actions"
git config user.email "[email protected]"
git tag -a "$VERSION" -m "Release $VERSION"
git push origin "$VERSION"
- name: Job summary
run: |
echo "### Docker Image Published 🚀" >> $GITHUB_STEP_SUMMARY
echo "**Tag:** ${{ steps.get-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**Digest:** ${{ steps.build.outputs.digest }}" >> $GITHUB_STEP_SUMMARY