From 236d1122ecc2decaec30203871d16f2414f06604 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 11 May 2026 15:49:10 +0530 Subject: [PATCH 01/10] workflow file added --- .github/workflows/docker-image.yml | 160 +++++++++++++++++++++++------ 1 file changed, 130 insertions(+), 30 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 1f18816fa..45b9c4650 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -1,63 +1,150 @@ -name: Build and Push Docker Image +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 + description: 'Docker image tag version (e.g., 3.3.11) — leave blank to auto-increment' + required: false + default: '' + version_bump: + description: 'Part to increment when tag_version is blank' + required: false + type: choice + options: + - patch + - minor + - major + default: patch + branch: + description: 'Branch to build from (default: staging)' + required: false + default: 'staging' + push_image: + description: 'Build and push Docker image (leave unchecked to only create the Git tag)' + required: false + type: boolean + default: false env: - DOCKER_IMAGE_NAME: elevate-mentoring # Configure your image name here + DOCKER_IMAGE_NAME: elevate-mentoring DOCKER_REGISTRY: docker.io DOCKER_NAMESPACE: shikshalokamqa +permissions: + contents: write + jobs: docker-image-build-and-push: - if: github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: - - name: Checkout code + - name: Checkout code from target branch uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.branch || 'staging' }} + fetch-depth: 0 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - name: Resolve tag version + id: get-version + shell: bash + run: | + INPUT="${{ github.event.inputs.tag_version }}" + BUMP="${{ github.event.inputs.version_bump }}" + + if [ -n "$INPUT" ]; then + # Manual version provided — strip leading "v" and validate + VERSION="${INPUT#v}" + if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Error: tag_version must be in x.y.z format (e.g. 3.4.0)" + exit 1 + fi + else + # Auto-increment from latest tag + LATEST=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1) + + if [ -z "$LATEST" ]; then + echo "No existing tags found — starting from scratch" + case "$BUMP" in + major) VERSION="1.0.0" ;; + minor) VERSION="0.1.0" ;; + *) VERSION="0.0.1" ;; + esac + else + echo "Latest tag: $LATEST" + MAJOR=$(echo "$LATEST" | cut -d. -f1) + MINOR=$(echo "$LATEST" | cut -d. -f2) + PATCH=$(echo "$LATEST" | cut -d. -f3) + case "$BUMP" in + major) VERSION="$((MAJOR + 1)).0.0" ;; + minor) VERSION="${MAJOR}.$((MINOR + 1)).0" ;; + *) VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" ;; + esac + fi + echo "Auto-incremented version ($BUMP): $VERSION" + fi + + printf 'version=%s\n' "$VERSION" >> "$GITHUB_OUTPUT" + + - name: Check if Git tag already exists + run: | + VERSION="${{ steps.get-version.outputs.version }}" + if git rev-parse "$VERSION" >/dev/null 2>&1; then + echo "Error: Git tag $VERSION already exists" + exit 1 + fi - name: Login to Docker Hub + if: ${{ github.event.inputs.push_image == 'true' }} uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Get Docker tag version (fail if not provided) - id: get-version + - name: Check if version exists on Docker Hub + if: ${{ github.event.inputs.push_image == 'true' }} run: | - # Use workflow_dispatch input if provided - if [ ! -z "${{ github.event.inputs.tag_version }}" ]; then - VERSION="${{ github.event.inputs.tag_version }}" - # Or use TAG_VERSION env if set (for push/PR) - elif [ ! -z "${TAG_VERSION}" ]; then - VERSION="${TAG_VERSION}" - else - echo "Error: Docker image version must be provided as workflow_dispatch input or TAG_VERSION env." + VERSION="${{ steps.get-version.outputs.version }}" + + LOGIN_RESPONSE=$(curl -s -w "\n%{http_code}" \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{"username": "${{ secrets.DOCKERHUB_USERNAME }}", "password": "${{ 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 - echo "version=$VERSION" >> $GITHUB_OUTPUT - - name: Check if version exists on Docker Hub - id: check-version - run: | - VERSION=${{ steps.get-version.outputs.version }} - RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" "https://hub.docker.com/v2/namespaces/${{ env.DOCKER_NAMESPACE }}/repositories/${{ env.DOCKER_IMAGE_NAME }}/tags/$VERSION") + 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 "Tag $VERSION does not exist, proceeding with build" + echo "Error: Unexpected HTTP $RESPONSE from Docker Hub tag check; aborting to fail safe" + exit 1 fi + - name: Set up Docker Buildx + if: ${{ github.event.inputs.push_image == 'true' }} + uses: docker/setup-buildx-action@v3 + - name: Extract metadata + if: ${{ github.event.inputs.push_image == 'true' }} id: meta uses: docker/metadata-action@v5 with: @@ -66,6 +153,7 @@ jobs: type=raw,value=${{ steps.get-version.outputs.version }} - name: Build and push Docker image + if: ${{ github.event.inputs.push_image == 'true' }} id: build uses: docker/build-push-action@v5 with: @@ -78,10 +166,22 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max - - name: Image digest - run: echo "Image pushed with digest ${{ steps.build.outputs.digest }}" + - name: Create and push Git tag + run: | + VERSION="${{ steps.get-version.outputs.version }}" + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git tag -a "$VERSION" -m "Release $VERSION" + git push origin "$VERSION" - - name: Print pushed tags + - name: Job summary run: | - echo "Pushed tags:" - echo "${{ steps.meta.outputs.tags }}" | tr ',' '\n' \ No newline at end of file + echo "### Git Tag Created 🏷️" >> $GITHUB_STEP_SUMMARY + echo "**Tag:** ${{ steps.get-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "**Branch:** ${{ github.event.inputs.branch || 'staging' }}" >> $GITHUB_STEP_SUMMARY + if [ "${{ github.event.inputs.push_image }}" == "true" ]; then + echo "**Docker Image:** ${{ env.DOCKER_NAMESPACE }}/${{ env.DOCKER_IMAGE_NAME }}:${{ steps.get-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "**Digest:** ${{ steps.build.outputs.digest }}" >> $GITHUB_STEP_SUMMARY + else + echo "_Docker image was not pushed. Re-run with **push_image** checked to build and push._" >> $GITHUB_STEP_SUMMARY + fi From acbefd8b76b6a6a9f5f65c5a346526f67e993a9f Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 11 May 2026 16:00:43 +0530 Subject: [PATCH 02/10] github actions updated --- .github/workflows/docker-image.yml | 53 +++++++++-- .github/workflows/prod-release.yml | 138 +++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/prod-release.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 45b9c4650..f106aa7a8 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: tag_version: - description: 'Docker image tag version (e.g., 3.3.11) — leave blank to auto-increment' + description: 'Docker image tag version (e.g., 3.4.0) — leave blank to auto-increment' required: false default: '' version_bump: @@ -16,6 +16,11 @@ on: - minor - major default: patch + is_rc: + description: 'Tag this as a Release Candidate (e.g. 3.4.1-rc.1)' + required: false + type: boolean + default: false branch: description: 'Branch to build from (default: staging)' required: false @@ -51,27 +56,59 @@ jobs: run: | INPUT="${{ github.event.inputs.tag_version }}" BUMP="${{ github.event.inputs.version_bump }}" + IS_RC="${{ github.event.inputs.is_rc }}" if [ -n "$INPUT" ]; then - # Manual version provided — strip leading "v" and validate + # Manual version — strip leading "v" and validate VERSION="${INPUT#v}" - if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Error: tag_version must be in x.y.z format (e.g. 3.4.0)" + if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$ ]]; then + echo "Error: tag_version must be x.y.z or x.y.z-rc.N (e.g. 3.4.0 or 3.4.0-rc.1)" exit 1 fi + elif [ "$IS_RC" == "true" ]; then + # Auto-increment RC + # If an RC tag already exists, increment its RC number + LATEST_RC=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$' | head -1) + + if [ -n "$LATEST_RC" ]; then + echo "Latest RC tag: $LATEST_RC" + BASE=$(echo "$LATEST_RC" | sed 's/-rc\.[0-9]*$//') + RC_NUM=$(echo "$LATEST_RC" | grep -oE '[0-9]+$') + VERSION="${BASE}-rc.$((RC_NUM + 1))" + else + # No existing RC — compute next release version from latest release tag and add -rc.1 + LATEST=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1) + if [ -z "$LATEST" ]; then + case "$BUMP" in + major) BASE="1.0.0" ;; + minor) BASE="0.1.0" ;; + *) BASE="0.0.1" ;; + esac + else + echo "Latest release tag: $LATEST" + MAJOR=$(echo "$LATEST" | cut -d. -f1) + MINOR=$(echo "$LATEST" | cut -d. -f2) + PATCH=$(echo "$LATEST" | cut -d. -f3) + case "$BUMP" in + major) BASE="$((MAJOR + 1)).0.0" ;; + minor) BASE="${MAJOR}.$((MINOR + 1)).0" ;; + *) BASE="${MAJOR}.${MINOR}.$((PATCH + 1))" ;; + esac + fi + VERSION="${BASE}-rc.1" + fi + echo "Auto-incremented RC version: $VERSION" else - # Auto-increment from latest tag + # Auto-increment regular release LATEST=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1) - if [ -z "$LATEST" ]; then - echo "No existing tags found — starting from scratch" case "$BUMP" in major) VERSION="1.0.0" ;; minor) VERSION="0.1.0" ;; *) VERSION="0.0.1" ;; esac else - echo "Latest tag: $LATEST" + echo "Latest release tag: $LATEST" MAJOR=$(echo "$LATEST" | cut -d. -f1) MINOR=$(echo "$LATEST" | cut -d. -f2) PATCH=$(echo "$LATEST" | cut -d. -f3) diff --git a/.github/workflows/prod-release.yml b/.github/workflows/prod-release.yml new file mode 100644 index 000000000..1fae802d2 --- /dev/null +++ b/.github/workflows/prod-release.yml @@ -0,0 +1,138 @@ +name: Promote RC to Production Release + +on: + workflow_dispatch: + inputs: + rc_tag: + description: 'RC tag to promote (e.g. 3.4.0-rc.2)' + required: true + +env: + DOCKER_IMAGE_NAME: elevate-mentoring + DOCKER_REGISTRY: docker.io + DOCKER_NAMESPACE: shikshalokamqa + +permissions: + contents: write + +jobs: + promote: + runs-on: ubuntu-latest + + steps: + - name: Validate RC tag format + id: validate + shell: bash + run: | + RC_TAG="${{ github.event.inputs.rc_tag }}" + RC_TAG="${RC_TAG#v}" + if ! [[ "$RC_TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then + echo "Error: rc_tag must be in x.y.z-rc.N format (e.g. 3.4.0-rc.2)" + exit 1 + fi + # Derive the production version by stripping the -rc.N suffix + PROD_VERSION=$(echo "$RC_TAG" | sed 's/-rc\.[0-9]*$//') + printf 'rc_tag=%s\n' "$RC_TAG" >> "$GITHUB_OUTPUT" + printf 'prod_version=%s\n' "$PROD_VERSION" >> "$GITHUB_OUTPUT" + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check RC tag exists in repository + run: | + RC_TAG="${{ steps.validate.outputs.rc_tag }}" + if ! git rev-parse "$RC_TAG" >/dev/null 2>&1; then + echo "Error: Git tag $RC_TAG does not exist in this repository" + exit 1 + fi + + - name: Check production tag does not already exist + run: | + PROD_VERSION="${{ steps.validate.outputs.prod_version }}" + if git rev-parse "$PROD_VERSION" >/dev/null 2>&1; then + echo "Error: Production tag $PROD_VERSION already exists" + exit 1 + fi + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Check RC image exists on Docker Hub + run: | + RC_TAG="${{ steps.validate.outputs.rc_tag }}" + + LOGIN_RESPONSE=$(curl -s -w "\n%{http_code}" \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{"username": "${{ secrets.DOCKERHUB_USERNAME }}", "password": "${{ 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 + + # Confirm RC image exists + RC_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/$RC_TAG") + if [ "$RC_RESPONSE" -ne 200 ]; then + echo "Error: RC image $RC_TAG not found on Docker Hub (HTTP $RC_RESPONSE)" + exit 1 + fi + echo "RC image $RC_TAG confirmed on Docker Hub" + + # Confirm production tag does not already exist + PROD_VERSION="${{ steps.validate.outputs.prod_version }}" + PROD_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/$PROD_VERSION") + if [ "$PROD_RESPONSE" -eq 200 ]; then + echo "Error: Production tag $PROD_VERSION already exists on Docker Hub" + exit 1 + fi + echo "Production tag $PROD_VERSION not found on Docker Hub — safe to promote" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Retag RC image as production release + id: retag + uses: docker/build-push-action@v5 + with: + push: true + tags: ${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_NAMESPACE }}/${{ env.DOCKER_IMAGE_NAME }}:${{ steps.validate.outputs.prod_version }} + platforms: linux/amd64,linux/arm64 + provenance: false + cache-from: type=registry,ref=${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_NAMESPACE }}/${{ env.DOCKER_IMAGE_NAME }}:${{ steps.validate.outputs.rc_tag }} + + - name: Create and push production Git tag + run: | + PROD_VERSION="${{ steps.validate.outputs.prod_version }}" + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git tag -a "$PROD_VERSION" -m "Release $PROD_VERSION" + git push origin "$PROD_VERSION" + + - name: Job summary + run: | + echo "### Production Release Published 🚀" >> $GITHUB_STEP_SUMMARY + echo "| | |" >> $GITHUB_STEP_SUMMARY + echo "|---|---|" >> $GITHUB_STEP_SUMMARY + echo "| **RC Tag** | ${{ steps.validate.outputs.rc_tag }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Production Tag** | ${{ steps.validate.outputs.prod_version }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Docker Image** | ${{ env.DOCKER_NAMESPACE }}/${{ env.DOCKER_IMAGE_NAME }}:${{ steps.validate.outputs.prod_version }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Digest** | ${{ steps.retag.outputs.digest }} |" >> $GITHUB_STEP_SUMMARY From f48cf80a821f2ce51f7bcac4ddfac207f7bd9c46 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 11 May 2026 16:05:24 +0530 Subject: [PATCH 03/10] github actions updated --- .github/workflows/docker-image.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index f106aa7a8..824e5b0e5 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -68,7 +68,7 @@ jobs: elif [ "$IS_RC" == "true" ]; then # Auto-increment RC # If an RC tag already exists, increment its RC number - LATEST_RC=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$' | head -1) + LATEST_RC=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$' | head -1 || true) if [ -n "$LATEST_RC" ]; then echo "Latest RC tag: $LATEST_RC" @@ -77,7 +77,7 @@ jobs: VERSION="${BASE}-rc.$((RC_NUM + 1))" else # No existing RC — compute next release version from latest release tag and add -rc.1 - LATEST=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1) + LATEST=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || true) if [ -z "$LATEST" ]; then case "$BUMP" in major) BASE="1.0.0" ;; @@ -100,7 +100,7 @@ jobs: echo "Auto-incremented RC version: $VERSION" else # Auto-increment regular release - LATEST=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1) + LATEST=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || true) if [ -z "$LATEST" ]; then case "$BUMP" in major) VERSION="1.0.0" ;; From 62d6c794155eb13a9532b38f965a711ed35d40bb Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 11 May 2026 16:11:51 +0530 Subject: [PATCH 04/10] github actions updated --- .github/workflows/docker-image.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 824e5b0e5..d4be74e60 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -65,6 +65,10 @@ jobs: echo "Error: tag_version must be x.y.z or x.y.z-rc.N (e.g. 3.4.0 or 3.4.0-rc.1)" exit 1 fi + # If is_rc is checked and no RC suffix was typed, append -rc.1 + if [ "$IS_RC" == "true" ] && [[ ! "$VERSION" =~ -rc\.[0-9]+$ ]]; then + VERSION="${VERSION}-rc.1" + fi elif [ "$IS_RC" == "true" ]; then # Auto-increment RC # If an RC tag already exists, increment its RC number From bd55b0b89d70d91bcc0c7a580e4af44d607f9077 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 11 May 2026 16:15:38 +0530 Subject: [PATCH 05/10] github actions updated --- .github/workflows/docker-image.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index d4be74e60..d9c8909c8 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -65,9 +65,15 @@ jobs: echo "Error: tag_version must be x.y.z or x.y.z-rc.N (e.g. 3.4.0 or 3.4.0-rc.1)" exit 1 fi - # If is_rc is checked and no RC suffix was typed, append -rc.1 + # If is_rc is checked and no RC suffix was typed, find the next RC number for this base version if [ "$IS_RC" == "true" ] && [[ ! "$VERSION" =~ -rc\.[0-9]+$ ]]; then - VERSION="${VERSION}-rc.1" + LATEST_RC_FOR_BASE=$(git tag --sort=-v:refname | grep -E "^${VERSION}-rc\.[0-9]+$" | head -1 || true) + if [ -n "$LATEST_RC_FOR_BASE" ]; then + RC_NUM=$(echo "$LATEST_RC_FOR_BASE" | grep -oE '[0-9]+$') + VERSION="${VERSION}-rc.$((RC_NUM + 1))" + else + VERSION="${VERSION}-rc.1" + fi fi elif [ "$IS_RC" == "true" ]; then # Auto-increment RC From 6848b89bbc7308ff27ed23e308290003b7186a5e Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 11 May 2026 16:25:23 +0530 Subject: [PATCH 06/10] github actions updated --- .github/workflows/docker-image.yml | 2 +- .github/workflows/prod-release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index d9c8909c8..9a65bc78f 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -34,7 +34,7 @@ on: env: DOCKER_IMAGE_NAME: elevate-mentoring DOCKER_REGISTRY: docker.io - DOCKER_NAMESPACE: shikshalokamqa + DOCKER_NAMESPACE: borkarsaish65 permissions: contents: write diff --git a/.github/workflows/prod-release.yml b/.github/workflows/prod-release.yml index 1fae802d2..4f0e7cdc7 100644 --- a/.github/workflows/prod-release.yml +++ b/.github/workflows/prod-release.yml @@ -10,7 +10,7 @@ on: env: DOCKER_IMAGE_NAME: elevate-mentoring DOCKER_REGISTRY: docker.io - DOCKER_NAMESPACE: shikshalokamqa + DOCKER_NAMESPACE: borkarsaish65 permissions: contents: write From 1597da38dce2e80767a4678a7f1bc25823789403 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 11 May 2026 16:59:10 +0530 Subject: [PATCH 07/10] github actions updated --- .github/workflows/docker-image.yml | 2 +- .github/workflows/prod-release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 9a65bc78f..d9c8909c8 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -34,7 +34,7 @@ on: env: DOCKER_IMAGE_NAME: elevate-mentoring DOCKER_REGISTRY: docker.io - DOCKER_NAMESPACE: borkarsaish65 + DOCKER_NAMESPACE: shikshalokamqa permissions: contents: write diff --git a/.github/workflows/prod-release.yml b/.github/workflows/prod-release.yml index 4f0e7cdc7..1fae802d2 100644 --- a/.github/workflows/prod-release.yml +++ b/.github/workflows/prod-release.yml @@ -10,7 +10,7 @@ on: env: DOCKER_IMAGE_NAME: elevate-mentoring DOCKER_REGISTRY: docker.io - DOCKER_NAMESPACE: borkarsaish65 + DOCKER_NAMESPACE: shikshalokamqa permissions: contents: write From c7deb5442e788ed3654ee799c919179ce391d4ba Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 11 May 2026 17:06:34 +0530 Subject: [PATCH 08/10] github actions updated --- .github/workflows/docker-image.yml | 15 +++++++++++---- .github/workflows/prod-release.yml | 13 ++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index d9c8909c8..17ed07727 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -39,6 +39,10 @@ env: permissions: contents: write +concurrency: + group: docker-release + cancel-in-progress: false + jobs: docker-image-build-and-push: runs-on: ubuntu-latest @@ -77,7 +81,6 @@ jobs: fi elif [ "$IS_RC" == "true" ]; then # Auto-increment RC - # If an RC tag already exists, increment its RC number LATEST_RC=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$' | head -1 || true) if [ -n "$LATEST_RC" ]; then @@ -153,7 +156,7 @@ jobs: run: | VERSION="${{ steps.get-version.outputs.version }}" - LOGIN_RESPONSE=$(curl -s -w "\n%{http_code}" \ + LOGIN_RESPONSE=$(curl -s --connect-timeout 10 --max-time 30 -w "\n%{http_code}" \ -X POST \ -H "Content-Type: application/json" \ -d '{"username": "${{ secrets.DOCKERHUB_USERNAME }}", "password": "${{ secrets.DOCKERHUB_TOKEN }}"}' \ @@ -172,7 +175,7 @@ jobs: exit 1 fi - RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \ + RESPONSE=$(curl -s --connect-timeout 10 --max-time 30 -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") @@ -186,6 +189,10 @@ jobs: exit 1 fi + - name: Set up QEMU + if: ${{ github.event.inputs.push_image == 'true' }} + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx if: ${{ github.event.inputs.push_image == 'true' }} uses: docker/setup-buildx-action@v3 @@ -230,5 +237,5 @@ jobs: echo "**Docker Image:** ${{ env.DOCKER_NAMESPACE }}/${{ env.DOCKER_IMAGE_NAME }}:${{ steps.get-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY echo "**Digest:** ${{ steps.build.outputs.digest }}" >> $GITHUB_STEP_SUMMARY else - echo "_Docker image was not pushed. Re-run with **push_image** checked to build and push._" >> $GITHUB_STEP_SUMMARY + echo "_Docker image was not pushed. To push, trigger a new run with **push_image** checked and a new version._" >> $GITHUB_STEP_SUMMARY fi diff --git a/.github/workflows/prod-release.yml b/.github/workflows/prod-release.yml index 1fae802d2..0bb775e9e 100644 --- a/.github/workflows/prod-release.yml +++ b/.github/workflows/prod-release.yml @@ -15,6 +15,10 @@ env: permissions: contents: write +concurrency: + group: docker-release + cancel-in-progress: false + jobs: promote: runs-on: ubuntu-latest @@ -66,7 +70,7 @@ jobs: run: | RC_TAG="${{ steps.validate.outputs.rc_tag }}" - LOGIN_RESPONSE=$(curl -s -w "\n%{http_code}" \ + LOGIN_RESPONSE=$(curl -s --connect-timeout 10 --max-time 30 -w "\n%{http_code}" \ -X POST \ -H "Content-Type: application/json" \ -d '{"username": "${{ secrets.DOCKERHUB_USERNAME }}", "password": "${{ secrets.DOCKERHUB_TOKEN }}"}' \ @@ -86,7 +90,7 @@ jobs: fi # Confirm RC image exists - RC_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \ + RC_RESPONSE=$(curl -s --connect-timeout 10 --max-time 30 -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/$RC_TAG") if [ "$RC_RESPONSE" -ne 200 ]; then @@ -97,7 +101,7 @@ jobs: # Confirm production tag does not already exist PROD_VERSION="${{ steps.validate.outputs.prod_version }}" - PROD_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \ + PROD_RESPONSE=$(curl -s --connect-timeout 10 --max-time 30 -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/$PROD_VERSION") if [ "$PROD_RESPONSE" -eq 200 ]; then @@ -106,6 +110,9 @@ jobs: fi echo "Production tag $PROD_VERSION not found on Docker Hub — safe to promote" + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 From 3c9e750f5f6faad88bab5ceb32505a186a425f31 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 11 May 2026 17:37:28 +0530 Subject: [PATCH 09/10] github actions updated - 10 --- .github/workflows/docker-image.yml | 32 +++++++++++++++++++++++++++--- .github/workflows/prod-release.yml | 6 +++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 17ed07727..7b1c90b02 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -85,9 +85,35 @@ jobs: if [ -n "$LATEST_RC" ]; then echo "Latest RC tag: $LATEST_RC" - BASE=$(echo "$LATEST_RC" | sed 's/-rc\.[0-9]*$//') - RC_NUM=$(echo "$LATEST_RC" | grep -oE '[0-9]+$') - VERSION="${BASE}-rc.$((RC_NUM + 1))" + EXISTING_BASE=$(echo "$LATEST_RC" | sed 's/-rc\.[0-9]*$//') + + # Compute the desired base version from latest stable tag + BUMP + LATEST_STABLE=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || true) + if [ -z "$LATEST_STABLE" ]; then + case "$BUMP" in + major) DESIRED_BASE="1.0.0" ;; + minor) DESIRED_BASE="0.1.0" ;; + *) DESIRED_BASE="0.0.1" ;; + esac + else + MAJOR=$(echo "$LATEST_STABLE" | cut -d. -f1) + MINOR=$(echo "$LATEST_STABLE" | cut -d. -f2) + PATCH=$(echo "$LATEST_STABLE" | cut -d. -f3) + case "$BUMP" in + major) DESIRED_BASE="$((MAJOR + 1)).0.0" ;; + minor) DESIRED_BASE="${MAJOR}.$((MINOR + 1)).0" ;; + *) DESIRED_BASE="${MAJOR}.${MINOR}.$((PATCH + 1))" ;; + esac + fi + + if [ "$EXISTING_BASE" == "$DESIRED_BASE" ]; then + # Same base — increment RC number + RC_NUM=$(echo "$LATEST_RC" | grep -oE '[0-9]+$') + VERSION="${EXISTING_BASE}-rc.$((RC_NUM + 1))" + else + # Different bump level requested — start a new RC series + VERSION="${DESIRED_BASE}-rc.1" + fi else # No existing RC — compute next release version from latest release tag and add -rc.1 LATEST=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || true) diff --git a/.github/workflows/prod-release.yml b/.github/workflows/prod-release.yml index 0bb775e9e..b5df3ac2a 100644 --- a/.github/workflows/prod-release.yml +++ b/.github/workflows/prod-release.yml @@ -107,8 +107,12 @@ jobs: if [ "$PROD_RESPONSE" -eq 200 ]; then echo "Error: Production tag $PROD_VERSION already exists on Docker Hub" exit 1 + elif [ "$PROD_RESPONSE" -eq 404 ]; then + echo "Production tag $PROD_VERSION not found on Docker Hub — safe to promote" + else + echo "Error: Unexpected HTTP $PROD_RESPONSE from Docker Hub production tag check; aborting to fail safe" + exit 1 fi - echo "Production tag $PROD_VERSION not found on Docker Hub — safe to promote" - name: Set up QEMU uses: docker/setup-qemu-action@v3 From 656547b3e0e8c25739187c8eba8a21f4acd634c3 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Tue, 12 May 2026 17:06:58 +0530 Subject: [PATCH 10/10] CR comments --- .github/workflows/prod-release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/prod-release.yml b/.github/workflows/prod-release.yml index b5df3ac2a..bbefea625 100644 --- a/.github/workflows/prod-release.yml +++ b/.github/workflows/prod-release.yml @@ -42,6 +42,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: + ref: ${{ steps.validate.outputs.rc_tag }} fetch-depth: 0 - name: Check RC tag exists in repository