Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 54 additions & 71 deletions .github/workflows/backend_ci.yml
Original file line number Diff line number Diff line change
@@ -1,91 +1,73 @@
# week07/.github/workflows/backend_ci.yml

name: Backend CI - Test, Build and Push Images to ACR

# Trigger the workflow on pushes to the 'main' branch
# You can also add 'pull_request:' to run on PRs
on:
# Manual trigger
workflow_dispatch:

# Automatically on pushes to main branch
push:
branches:
- main
paths: # Only trigger if changes are in backend directories
- 'backend/**'
- '.github/workflows/backend_ci.yml' # Trigger if this workflow file changes
branches: [ "main" ]
paths:
- "backend/**"
- ".github/workflows/backend_ci.yml"

# Define global environment variables that can be used across jobs
env:
# ACR Login Server (e.g., myregistry.azurecr.io)
# This needs to be set as a GitHub Repository Secret
# Secrets you must set in the repo:
# ACR_LOGIN_SERVER = ratish722acr.azurecr.io
# ACR_NAME = ratish722acr
ACR_LOGIN_SERVER: ${{ secrets.ACR_LOGIN_SERVER }}
# Dynamically generate image tags based on Git SHA and GitHub Run ID
# This provides unique, traceable tags for each image build
ACR_NAME: ${{ secrets.ACR_NAME }}
# Unique tag for traceability alongside 'latest'
IMAGE_TAG: ${{ github.sha }}-${{ github.run_id }}

jobs:
# Job 1: Run tests and linting for all backend services
test_and_lint_backends:
runs-on: ubuntu-latest # Use a GitHub-hosted runner
runs-on: ubuntu-latest

services:
# Product DB container
product_db:
image: postgres:15
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: products
# Make pg_isready available so the service is healthy before tests run
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

# Order DB

order_db:
image: postgres:15
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: orders
ports:
- 5433:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5433:5432

steps:
# 1. Checkout the repository code to the runner
- name: Checkout repository
uses: actions/checkout@v4 # Action to check out your repository code
uses: actions/checkout@v4

# 2. Set up Python environment
- name: Set up Python 3.10
uses: actions/setup-python@v5 # Action to set up Python environment
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: "3.10"

# 3. Install dependencies and run code quality checks
- name: Install dependencies
run: | # Use a multi-line script to install pip dependencies
run: |
pip install --upgrade pip
# Loop through each backend service folder
for req in backend/*/requirements.txt; do
echo "Installing $req"
pip install -r "$req"
done
# Install CI tools
pip install pytest httpx

# 5. Run tests for product service
- name: Run product_service tests
working-directory: backend/product_service
env:
Expand All @@ -94,10 +76,8 @@ jobs:
POSTGRES_DB: products
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
run: |
pytest tests --maxfail=1 --disable-warnings -q

# 6. Run tests for order service
run: pytest tests --maxfail=1 --disable-warnings -q

- name: Run order_service tests
working-directory: backend/order_service
env:
Expand All @@ -106,41 +86,44 @@ jobs:
POSTGRES_DB: orders
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
run: |
pytest tests --maxfail=1 --disable-warnings -q
run: pytest tests --maxfail=1 --disable-warnings -q

# Job 2: Build and Push Docker Images (runs only if tests pass)
build_and_push_images:
runs-on: ubuntu-latest
needs: test_and_lint_backends
permissions:
id-token: write
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4

# Azure login using a Service Principal secret
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }} # Needs to be set as a GitHub Secret (Service Principal JSON)

# Login to Azure Container Registry (ACR)
- name: Login to Azure Container Registry
run: az acr login --name ${{ env.ACR_LOGIN_SERVER }}

# Build and Push Docker image for Product Service
- name: Build and Push Product Service Image
run: |
docker build -t ${{ env.ACR_LOGIN_SERVER }}/product_service:latest ./backend/product_service/
docker push ${{ env.ACR_LOGIN_SERVER }}/product_service:latest

# Build and Push Docker image for Order Service
- name: Build and Push Order Service Image
run: |
docker build -t ${{ env.ACR_LOGIN_SERVER }}/order_service:latest ./backend/order_service/
docker push ${{ env.ACR_LOGIN_SERVER }}/order_service:latest

# Logout from Azure for security (runs even if image push fails)
- name: Logout from Azure
run: az logout
if: always()
- name: Checkout repository
uses: actions/checkout@v4

- name: Azure Login
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

# IMPORTANT: use the **registry name** (e.g. ratish722acr), not the login server
- name: Login to Azure Container Registry
run: az acr login --name ${{ env.ACR_NAME }}

# Build & push product_service with 'latest' and a unique tag
- name: Build and Push Product Service Image
run: |
docker build -t ${{ env.ACR_LOGIN_SERVER }}/product_service:latest ./backend/product_service/
docker tag ${{ env.ACR_LOGIN_SERVER }}/product_service:latest ${{ env.ACR_LOGIN_SERVER }}/product_service:${{ env.IMAGE_TAG }}
docker push ${{ env.ACR_LOGIN_SERVER }}/product_service:latest
docker push ${{ env.ACR_LOGIN_SERVER }}/product_service:${{ env.IMAGE_TAG }}

# Build & push order_service with 'latest' and a unique tag
- name: Build and Push Order Service Image
run: |
docker build -t ${{ env.ACR_LOGIN_SERVER }}/order_service:latest ./backend/order_service/
docker tag ${{ env.ACR_LOGIN_SERVER }}/order_service:latest ${{ env.ACR_LOGIN_SERVER }}/order_service:${{ env.IMAGE_TAG }}
docker push ${{ env.ACR_LOGIN_SERVER }}/order_service:latest
docker push ${{ env.ACR_LOGIN_SERVER }}/order_service:${{ env.IMAGE_TAG }}

- name: Logout from Azure
if: always()
run: az logout
1 change: 1 addition & 0 deletions TRIGGER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# CI trigger 12-09-2025 21:13:50.71
1 change: 1 addition & 0 deletions backend/product_service/CI_TRIGGER.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// trigger 12-09-2025 21:20:50.25