Build, Tag, and Push Docker Image #9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |