Skip to content

Commit 529ecaa

Browse files
Enhance Docker build and deployment workflow with detailed job descriptions and improved image tag handling
1 parent 79c2884 commit 529ecaa

1 file changed

Lines changed: 153 additions & 69 deletions

File tree

.github/workflows/deploy-Parameterized.yml

Lines changed: 153 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,95 @@ env:
6868
BUILD_DOCKER_IMAGE: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.build_docker_image || false) || false }}
6969

7070
jobs:
71+
docker-build:
72+
# ============================================================================
73+
# DOCKER BUILD JOB - When does it run?
74+
# ============================================================================
75+
# ✅ RUNS ONLY WHEN:
76+
# - Trigger = Manual (workflow_dispatch)
77+
# AND "Build and push Docker image" checkbox = ✅ CHECKED
78+
#
79+
# ❌ SKIPPED WHEN:
80+
# - Any automatic trigger (Pull Request, Schedule, Workflow Run)
81+
# - Manual trigger but "Build and push Docker image" = ❌ UNCHECKED
82+
# - Manual trigger but checkbox not provided (defaults to false)
83+
#
84+
# SIMPLE RULE: Only builds Docker when you manually trigger AND check the box!
85+
# ============================================================================
86+
if: github.event_name == 'workflow_dispatch' && github.event.inputs.build_docker_image == 'true'
87+
runs-on: ubuntu-latest
88+
outputs:
89+
IMAGE_TAG: ${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}
90+
steps:
91+
- name: Checkout Code
92+
uses: actions/checkout@v4
93+
94+
- name: Generate Unique Docker Image Tag
95+
id: generate_docker_tag
96+
run: |
97+
echo "🔨 Building new Docker image - generating unique tag..."
98+
# Generate unique tag for manual deployment runs
99+
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
100+
RUN_ID="${{ github.run_id }}"
101+
BRANCH_NAME="${{ github.head_ref || github.ref_name }}"
102+
# Sanitize branch name for Docker tag (replace invalid characters with hyphens)
103+
CLEAN_BRANCH_NAME=$(echo "$BRANCH_NAME" | sed 's/[^a-zA-Z0-9._-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')
104+
UNIQUE_TAG="${CLEAN_BRANCH_NAME}-${TIMESTAMP}-${RUN_ID}"
105+
echo "IMAGE_TAG=$UNIQUE_TAG" >> $GITHUB_ENV
106+
echo "IMAGE_TAG=$UNIQUE_TAG" >> $GITHUB_OUTPUT
107+
echo "Generated unique Docker tag: $UNIQUE_TAG"
108+
109+
- name: Set up Docker Buildx
110+
uses: docker/setup-buildx-action@v3
111+
112+
- name: Log in to Azure Container Registry
113+
uses: azure/docker-login@v2
114+
with:
115+
login-server: ${{ secrets.ACR_TEST_LOGIN_SERVER }}
116+
username: ${{ secrets.ACR_TEST_USERNAME }}
117+
password: ${{ secrets.ACR_TEST_PASSWORD }}
118+
119+
- name: Build and Push Docker Image
120+
id: build_push_image
121+
uses: docker/build-push-action@v6
122+
with:
123+
context: ./src
124+
file: ./src/WebApp.Dockerfile
125+
push: true
126+
tags: |
127+
${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}
128+
${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}_${{ github.run_number }}
129+
130+
- name: Verify Docker Image Build
131+
run: |
132+
echo "✅ Docker image successfully built and pushed"
133+
echo "Image tag: ${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}"
134+
echo "Run number: ${{ github.run_number }}"
135+
71136
deploy:
72-
# Skip deployment if an existing webapp URL is provided
73-
if: github.event_name != 'workflow_dispatch' || github.event.inputs.existing_webapp_url == '' || github.event.inputs.existing_webapp_url == null
137+
# ============================================================================
138+
# DEPLOY JOB - When does it run?
139+
# ============================================================================
140+
# ✅ RUNS WHEN:
141+
# - ANY automatic trigger (Pull Request, Schedule, Workflow Run) = ALWAYS RUNS
142+
# - Manual trigger with "Existing WebApp URL" = EMPTY/BLANK
143+
# - Manual trigger with "Existing WebApp URL" = NOT PROVIDED
144+
#
145+
# ❌ SKIPPED WHEN:
146+
# - Manual trigger with "Existing WebApp URL" = PROVIDED/FILLED
147+
# (Why skip? Because you want to test existing app, not deploy new one!)
148+
#
149+
# SIMPLE RULE: Deploys new infrastructure unless you provide existing webapp URL!
150+
# ============================================================================
151+
if: always() && (github.event_name != 'workflow_dispatch' || github.event.inputs.existing_webapp_url == '' || github.event.inputs.existing_webapp_url == null)
152+
needs: [docker-build] # Add dependency on docker-build job (will be skipped if not needed)
74153
runs-on: ubuntu-latest
75154
outputs:
76155
RESOURCE_GROUP_NAME: ${{ steps.check_create_rg.outputs.RESOURCE_GROUP_NAME }}
77156
WEBAPP_URL: ${{ steps.get_output.outputs.WEBAPP_URL }}
78157
ENV_NAME: ${{ steps.generate_env_name.outputs.ENV_NAME }}
79158
AZURE_LOCATION: ${{ steps.set_region.outputs.AZURE_LOCATION }}
80-
IMAGE_TAG: ${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}
159+
IMAGE_TAG: ${{ steps.determine_image_tag.outputs.IMAGE_TAG }}
81160
env:
82161
# For automatic triggers: force Non-WAF + Non-EXP, for manual dispatch: use inputs
83162
WAF_ENABLED: ${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.waf_enabled || false) || false }}
@@ -245,21 +324,18 @@ jobs:
245324
echo "SOLUTION_PREFIX=${UNIQUE_SOLUTION_PREFIX}" >> $GITHUB_ENV
246325
echo "Generated SOLUTION_PREFIX: ${UNIQUE_SOLUTION_PREFIX}"
247326
248-
- name: Generate Unique Docker Image Tag
249-
id: generate_docker_tag
327+
- name: Determine Docker Image Tag
328+
id: determine_image_tag
250329
run: |
251330
if [[ "${{ env.BUILD_DOCKER_IMAGE }}" == "true" ]]; then
252-
echo "🔨 Building new Docker image - generating unique tag..."
253-
# Generate unique tag for manual deployment runs
254-
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
255-
RUN_ID="${{ github.run_id }}"
256-
BRANCH_NAME="${{ env.BRANCH_NAME }}"
257-
# Sanitize branch name for Docker tag (replace invalid characters with hyphens)
258-
CLEAN_BRANCH_NAME=$(echo "$BRANCH_NAME" | sed 's/[^a-zA-Z0-9._-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')
259-
UNIQUE_TAG="${CLEAN_BRANCH_NAME}-${TIMESTAMP}-${RUN_ID}"
260-
echo "IMAGE_TAG=$UNIQUE_TAG" >> $GITHUB_ENV
261-
echo "IMAGE_TAG=$UNIQUE_TAG" >> $GITHUB_OUTPUT
262-
echo "Generated unique Docker tag: $UNIQUE_TAG"
331+
# Use the tag from docker-build job if it was built
332+
if [[ "${{ needs.docker-build.result }}" == "success" ]]; then
333+
IMAGE_TAG="${{ needs.docker-build.outputs.IMAGE_TAG }}"
334+
echo "🔗 Using Docker image tag from build job: $IMAGE_TAG"
335+
else
336+
echo "❌ Docker build job failed or was skipped, but BUILD_DOCKER_IMAGE is true"
337+
exit 1
338+
fi
263339
else
264340
echo "🏷️ Using existing Docker image based on branch..."
265341
BRANCH_NAME="${{ env.BRANCH_NAME }}"
@@ -280,41 +356,11 @@ jobs:
280356
echo "Using default for branch '$BRANCH_NAME' - image tag: latest_waf"
281357
fi
282358
283-
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
284-
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_OUTPUT
285359
echo "Using existing Docker image tag: $IMAGE_TAG"
286360
fi
287-
288-
- name: Set up Docker Buildx
289-
if: env.BUILD_DOCKER_IMAGE == 'true'
290-
uses: docker/setup-buildx-action@v3
291-
292-
- name: Log in to Azure Container Registry
293-
if: env.BUILD_DOCKER_IMAGE == 'true'
294-
uses: azure/docker-login@v2
295-
with:
296-
login-server: ${{ secrets.ACR_TEST_LOGIN_SERVER }}
297-
username: ${{ secrets.ACR_TEST_USERNAME }}
298-
password: ${{ secrets.ACR_TEST_PASSWORD }}
299-
300-
- name: Build and Push Docker Image
301-
if: env.BUILD_DOCKER_IMAGE == 'true'
302-
id: build_push_image
303-
uses: docker/build-push-action@v6
304-
with:
305-
context: ./src
306-
file: ./src/WebApp.Dockerfile
307-
push: true
308-
tags: |
309-
${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}
310-
${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:${{ steps.generate_docker_tag.outputs.IMAGE_TAG }}_${{ github.run_number }}
311-
312-
- name: Verify Docker Image Build
313-
if: env.BUILD_DOCKER_IMAGE == 'true'
314-
run: |
315-
echo "✅ Docker image successfully built and pushed"
316-
echo "Image tag: ${{ env.IMAGE_TAG }}"
317-
echo "Run number: ${{ github.run_number }}"
361+
362+
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
363+
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_OUTPUT
318364
319365
- name: Generate Unique Environment Name
320366
id: generate_env_name
@@ -345,9 +391,9 @@ jobs:
345391
- name: Display Docker Image Tag
346392
run: |
347393
echo "=== Docker Image Information ==="
348-
echo "Docker Image Tag: ${{ env.IMAGE_TAG }}"
394+
echo "Docker Image Tag: ${{ steps.determine_image_tag.outputs.IMAGE_TAG }}"
349395
echo "Registry: ${{ secrets.ACR_TEST_LOGIN_SERVER }}"
350-
echo "Full Image: ${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:${{ env.IMAGE_TAG }}"
396+
echo "Full Image: ${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:${{ steps.determine_image_tag.outputs.IMAGE_TAG }}"
351397
echo "================================"
352398
353399
- name: Deploy using azd up and extract values (${{ github.event.inputs.waf_enabled == 'true' && 'WAF' || 'Non-WAF' }}+${{ (github.event.inputs.EXP == 'true' || github.event.inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID != '' || github.event.inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID != '') && 'EXP' || 'Non-EXP' }})
@@ -357,7 +403,7 @@ jobs:
357403
echo "Starting azd deployment..."
358404
echo "WAF Enabled: ${{ env.WAF_ENABLED }}"
359405
echo "EXP: ${{ env.EXP }}"
360-
echo "Using Docker Image Tag: ${{ env.IMAGE_TAG }}"
406+
echo "Using Docker Image Tag: ${{ steps.determine_image_tag.outputs.IMAGE_TAG }}"
361407
362408
# Install azd (Azure Developer CLI)
363409
curl -fsSL https://aka.ms/install-azd.sh | bash
@@ -376,7 +422,7 @@ jobs:
376422
azd env set AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}"
377423
azd env set AZURE_ENV_OPENAI_LOCATION="$AZURE_LOCATION"
378424
azd env set AZURE_RESOURCE_GROUP="$RESOURCE_GROUP_NAME"
379-
azd env set AZURE_ENV_IMAGETAG="${{ env.IMAGE_TAG }}"
425+
azd env set AZURE_ENV_IMAGETAG="${{ steps.determine_image_tag.outputs.IMAGE_TAG }}"
380426
azd env set AZURE_DEV_COLLECT_TELEMETRY="no"
381427
382428
# Set ACR name only when building Docker image
@@ -496,9 +542,21 @@ jobs:
496542
echo "Logged out from Azure."
497543
498544
e2e-test:
499-
# Run e2e tests only when deploy succeeds or when using existing webapp URL
500-
# Skip if deploy job failed (for both automatic and manual triggers)
501-
# Respect the run_e2e_tests checkbox - skip if explicitly unchecked
545+
# ============================================================================
546+
# E2E TEST JOB - When does it run?
547+
# ============================================================================
548+
# ✅ RUNS WHEN:
549+
# - Deploy job succeeded AND "Run end-to-end tests" = ✅ CHECKED (default)
550+
# - Manual trigger with "Existing WebApp URL" provided AND tests = ✅ CHECKED
551+
# - Any automatic trigger (tests always run by default if deploy succeeds)
552+
#
553+
# ❌ SKIPPED WHEN:
554+
# - Deploy job failed or was skipped
555+
# - Manual trigger with "Run end-to-end tests" = ❌ UNCHECKED
556+
# - No webapp available (neither deployed nor existing URL provided)
557+
#
558+
# SIMPLE RULE: Tests run against any available webapp unless you uncheck the box!
559+
# ============================================================================
502560
if: (needs.deploy.result == 'success' || github.event.inputs.existing_webapp_url != '') && (github.event_name != 'workflow_dispatch' || github.event.inputs.run_e2e_tests == 'true' || github.event.inputs.run_e2e_tests == null)
503561
needs: [deploy]
504562
uses: ./.github/workflows/test-automation.yml
@@ -507,10 +565,25 @@ jobs:
507565
secrets: inherit
508566

509567
cleanup-deployment:
510-
# Cleanup when deploy succeeded and cleanup is not explicitly disabled
511-
# Skip if webapp URL is provided (no resources to cleanup) or cleanup checkbox is unchecked
512-
if: needs.deploy.result == 'success' && needs.deploy.outputs.RESOURCE_GROUP_NAME != '' && github.event.inputs.existing_webapp_url == '' && (github.event_name != 'workflow_dispatch' || github.event.inputs.cleanup_resources == 'true' || github.event.inputs.cleanup_resources == null)
513-
needs: [deploy, e2e-test]
568+
# ============================================================================
569+
# CLEANUP JOB - When does it run?
570+
# ============================================================================
571+
# ✅ RUNS WHEN:
572+
# - Deploy job succeeded (created new resources to clean up)
573+
# - Resource group was created (has RESOURCE_GROUP_NAME output)
574+
# - "Existing WebApp URL" = EMPTY (means we deployed new stuff to clean)
575+
# - "Cleanup deployed resources" = ✅ CHECKED (default) OR not manual trigger
576+
#
577+
# ❌ SKIPPED WHEN:
578+
# - Deploy job failed (nothing to clean up)
579+
# - "Existing WebApp URL" provided (didn't deploy new resources)
580+
# - Manual trigger with "Cleanup deployed resources" = ❌ UNCHECKED
581+
# - No resource group name available (deployment didn't create resources)
582+
#
583+
# SIMPLE RULE: Cleans up newly deployed resources unless you uncheck the box!
584+
# ============================================================================
585+
if: always() && needs.deploy.result == 'success' && needs.deploy.outputs.RESOURCE_GROUP_NAME != '' && github.event.inputs.existing_webapp_url == '' && (github.event_name != 'workflow_dispatch' || github.event.inputs.cleanup_resources == 'true' || github.event.inputs.cleanup_resources == null)
586+
needs: [docker-build, deploy, e2e-test]
514587
runs-on: ubuntu-latest
515588
env:
516589
RESOURCE_GROUP_NAME: ${{ needs.deploy.outputs.RESOURCE_GROUP_NAME }}
@@ -546,22 +619,33 @@ jobs:
546619
set -e
547620
echo "🗑️ Cleaning up Docker images from Azure Container Registry..."
548621
549-
if [[ -n "${{ env.IMAGE_TAG }}" && "${{ env.IMAGE_TAG }}" != "latest_waf" ]]; then
550-
echo "Deleting Docker images with tag: ${{ env.IMAGE_TAG }}"
622+
# Determine the image tag to delete - check if docker-build job ran
623+
if [[ "${{ needs.docker-build.result }}" == "success" ]]; then
624+
IMAGE_TAG="${{ needs.docker-build.outputs.IMAGE_TAG }}"
625+
echo "Using image tag from docker-build job: $IMAGE_TAG"
626+
else
627+
IMAGE_TAG="${{ needs.deploy.outputs.IMAGE_TAG }}"
628+
echo "Using image tag from deploy job: $IMAGE_TAG"
629+
fi
630+
631+
if [[ -n "$IMAGE_TAG" && "$IMAGE_TAG" != "latest_waf" && "$IMAGE_TAG" != "dev" && "$IMAGE_TAG" != "demo" ]]; then
632+
echo "Deleting Docker images with tag: $IMAGE_TAG"
551633
552634
# Delete the main image
553-
echo "Deleting image: ${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:${{ env.IMAGE_TAG }}"
635+
echo "Deleting image: ${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:$IMAGE_TAG"
554636
az acr repository delete --name $(echo "${{ secrets.ACR_TEST_LOGIN_SERVER }}" | cut -d'.' -f1) \
555-
--image webapp:${{ env.IMAGE_TAG }} --yes || echo "Warning: Failed to delete main image or image not found"
637+
--image webapp:$IMAGE_TAG --yes || echo "Warning: Failed to delete main image or image not found"
556638
557-
# Delete the image with run number suffix
558-
echo "Deleting image: ${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:${{ env.IMAGE_TAG }}_${{ github.run_number }}"
559-
az acr repository delete --name $(echo "${{ secrets.ACR_TEST_LOGIN_SERVER }}" | cut -d'.' -f1) \
560-
--image webapp:${{ env.IMAGE_TAG }}_${{ github.run_number }} --yes || echo "Warning: Failed to delete run-numbered image or image not found"
639+
# Delete the image with run number suffix (only if it was a custom build)
640+
if [[ "${{ needs.docker-build.result }}" == "success" ]]; then
641+
echo "Deleting image: ${{ secrets.ACR_TEST_LOGIN_SERVER }}/webapp:${IMAGE_TAG}_${{ github.run_number }}"
642+
az acr repository delete --name $(echo "${{ secrets.ACR_TEST_LOGIN_SERVER }}" | cut -d'.' -f1) \
643+
--image webapp:${IMAGE_TAG}_${{ github.run_number }} --yes || echo "Warning: Failed to delete run-numbered image or image not found"
644+
fi
561645
562646
echo "✅ Docker images cleanup completed"
563647
else
564-
echo "⚠️ Skipping Docker image cleanup (using latest_waf or no custom image tag)"
648+
echo "⚠️ Skipping Docker image cleanup (using standard branch image: $IMAGE_TAG)"
565649
fi
566650
567651
- name: Select Environment

0 commit comments

Comments
 (0)