feat(woodpecker): update CI pipeline with change detection and selective builds

- Update .woodpecker.yml with change detection step

- Add optimized Dockerfile.optimized support

- Add deployment step to Kubernetes

- Add woodpecker-local-build.sh for local testing

- Only build and deploy services with code changes

- Skip unchanged services for faster pipelines
This commit is contained in:
Ashwin Kumar 2026-04-10 05:17:56 +02:00
parent dbe1706a07
commit e39ed36fcc
2 changed files with 251 additions and 11 deletions

View file

@ -1,5 +1,5 @@
when:
branch: high-performance
branch: [main, high-performance]
event: push
matrix:
@ -24,24 +24,127 @@ matrix:
- cron
steps:
- name: build-and-push
# Step 1: Detect if this service needs building
- name: detect-changes
image: alpine/git
commands:
- apk add --no-cache bash
- |
#!/bin/bash
set -e
# Get changed files from last commit
CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD || echo "")
# Convert matrix SERVICE to path format
SERVICE_PATH=$(echo "${SERVICE}" | tr '_' '-')
# Check if shared crates changed (triggers all services)
SHARED_CHANGED=false
if echo "$CHANGED_FILES" | grep -q "^crates/"; then
SHARED_CHANGED=true
echo "⚠️ Shared crates changed - will build all services"
fi
# Check if this specific service changed
SERVICE_CHANGED=false
if echo "$CHANGED_FILES" | grep -q "^apps/${SERVICE_PATH}/"; then
SERVICE_CHANGED=true
echo "✅ Service ${SERVICE} has code changes"
fi
# Create marker file
if [ "$SHARED_CHANGED" = "true" ] || [ "$SERVICE_CHANGED" = "true" ]; then
echo "SHOULD_BUILD=true" > .build-${SERVICE}
echo "🚀 Will build ${SERVICE}"
else
echo "SHOULD_BUILD=false" > .build-${SERVICE}
echo "⏭️ Skipping ${SERVICE} - no changes detected"
fi
# Export for other steps
cat .build-${SERVICE} >> ${CI_ENV}
# Step 2: Build optimized Docker image (only if changed)
- name: build
image: woodpeckerci/plugin-docker-buildx:5.0.0
settings:
registry: ghcr.io
repo: ghcr.io/traceworks2023/nxtgauge-rust-${SERVICE}
context: .
dockerfile: apps/${SERVICE}/Dockerfile
dockerfile: Dockerfile.optimized
build_args:
- SERVICE_NAME=${SERVICE}
tags:
- ${CI_COMMIT_SHA}
- latest
- high-performance-latest
logins:
- registry: https://index.docker.io/v1/
- registry: https://ghcr.io
username:
from_secret: DOCKERHUB_USERNAME
from_secret: GHCR_USERNAME
password:
from_secret: DOCKERHUB_TOKEN
username:
from_secret: GHCR_USERNAME
password:
from_secret: GHCR_TOKEN
from_secret: GHCR_TOKEN
platforms: linux/amd64
when:
- evaluate: 'env.SHOULD_BUILD == "true"'
# Step 3: Deploy to Kubernetes (only if changed and on main/high-performance)
- name: deploy
image: bitnami/kubectl:latest
secrets: [kube_config]
commands:
- |
#!/bin/bash
set -e
# Check if we should deploy
if [ "${SHOULD_BUILD}" != "true" ]; then
echo "⏭️ Skipping deployment for ${SERVICE} - no changes"
exit 0
fi
# Setup kubeconfig
mkdir -p ~/.kube
echo "$KUBE_CONFIG" | base64 -d > ~/.kube/config
chmod 600 ~/.kube/config
# Convert service name to Kubernetes deployment name
DEPLOYMENT_NAME=$(echo "${SERVICE}" | tr '_' '-')
NAMESPACE="nxtgauge"
echo "🚀 Deploying ${SERVICE} (deployment: nxtgauge-rust-${DEPLOYMENT_NAME})..."
# Trigger rolling restart to pick up new image
kubectl rollout restart deployment/nxtgauge-rust-${DEPLOYMENT_NAME} -n ${NAMESPACE}
# Wait for rollout to complete (with timeout)
echo "⏳ Waiting for rollout to complete..."
kubectl rollout status deployment/nxtgauge-rust-${DEPLOYMENT_NAME} -n ${NAMESPACE} --timeout=300s
echo "✅ ${SERVICE} deployed successfully!"
# Show deployment status
kubectl get deployment/nxtgauge-rust-${DEPLOYMENT_NAME} -n ${NAMESPACE}
when:
- evaluate: 'env.SHOULD_BUILD == "true"'
- branch: [main, high-performance]
# Step 4: Notify on success
- name: notify-success
image: alpine:latest
commands:
- echo "✅ Pipeline completed successfully for ${SERVICE}"
when:
- evaluate: 'env.SHOULD_BUILD == "true"'
- status: success
# Step 5: Notify on failure
- name: notify-failure
image: alpine:latest
commands:
- echo "❌ Pipeline failed for ${SERVICE}"
- echo "Check logs for details"
when:
- evaluate: 'env.SHOULD_BUILD == "true"'
- status: failure

137
scripts/woodpecker-local-build.sh Executable file
View file

@ -0,0 +1,137 @@
#!/bin/bash
# woodpecker-local-build.sh - Local testing of Woodpecker pipeline
# Builds only changed services locally (no Woodpecker server needed)
set -e
REGISTRY="ghcr.io/traceworks2023"
VERSION=${VERSION:-$(git rev-parse --short HEAD)}
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
SERVICES=(
"gateway"
"users"
"companies"
"job_seekers"
"customers"
"payments"
"employees"
"photographers"
"makeup_artists"
"tutors"
"developers"
"video_editors"
"graphic_designers"
"social_media_managers"
"fitness_trainers"
"catering_services"
"ugc_content_creators"
"cron"
)
echo -e "${BLUE}🔍 Nxtgauge Local Build Script (Woodpecker Compatible)${NC}"
echo "============================================="
# Get changed files
CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || echo "")
if [ -z "$CHANGED_FILES" ]; then
echo -e "${YELLOW}⚠️ No changes detected. Building all services...${NC}"
BUILD_ALL=true
else
BUILD_ALL=false
echo "Changed files:"
echo "$CHANGED_FILES" | head -10
if [ $(echo "$CHANGED_FILES" | wc -l) -gt 10 ]; then
echo "... and more"
fi
fi
# Check if shared crates changed
SHARED_CHANGED=false
if echo "$CHANGED_FILES" | grep -q "^crates/"; then
SHARED_CHANGED=true
echo -e "${YELLOW}⚠️ Shared crates changed - will build all services${NC}"
BUILD_ALL=true
fi
# Function to build a service
build_service() {
local service=$1
local tag="${REGISTRY}/nxtgauge-rust-${service}:${VERSION}"
local latest="${REGISTRY}/nxtgauge-rust-${service}:latest"
echo ""
echo -e "${BLUE}🔨 Building ${service}...${NC}"
# Build with optimized Dockerfile
if docker build \
--build-arg SERVICE_NAME=${service} \
-f Dockerfile.optimized \
-t ${tag} \
-t ${latest} \
. 2>&1; then
echo -e "${GREEN}${service} built successfully${NC}"
echo " Image: ${tag}"
# Show image size
SIZE=$(docker images --format "{{.Size}}" ${tag})
echo " Size: ${SIZE}"
return 0
else
echo -e "${RED}${service} build failed${NC}"
return 1
fi
}
# Track results
BUILT=0
SKIPPED=0
FAILED=0
# Build each service
for service in "${SERVICES[@]}"; do
SERVICE_PATH=$(echo "$service" | tr '_' '-')
if [ "$BUILD_ALL" = true ]; then
SHOULD_BUILD=true
else
# Check if this service changed
if echo "$CHANGED_FILES" | grep -q "^apps/${SERVICE_PATH}/"; then
SHOULD_BUILD=true
else
SHOULD_BUILD=false
fi
fi
if [ "$SHOULD_BUILD" = true ]; then
if build_service "$service"; then
BUILT=$((BUILT + 1))
else
FAILED=$((FAILED + 1))
fi
else
echo -e "${YELLOW}⏭️ ${service} - no changes, skipping${NC}"
SKIPPED=$((SKIPPED + 1))
fi
done
echo ""
echo "============================================="
echo -e "${GREEN}✅ Built: ${BUILT}${NC}"
echo -e "${YELLOW}⏭️ Skipped: ${SKIPPED}${NC}"
if [ $FAILED -gt 0 ]; then
echo -e "${RED}❌ Failed: ${FAILED}${NC}"
exit 1
else
echo -e "${GREEN}🎉 All builds successful!${NC}"
fi