name: CI/CD Pipeline
on:
push:
branches: ['**']
pull_request:
branches: [main, dev]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check Python files exist
run: |
if ls *.py 2>/dev/null; then
echo "Python source files found"
else
echo "No Python source files found"
fi
- name: Check requirements.txt exists
run: |
if [ -f requirements.txt ]; then
echo "requirements.txt found"
else
echo "requirements.txt not found"
exit 1
fi
build-and-test:
needs: lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image for testing
uses: docker/build-push-action@v5
with:
context: .
push: false
load: true
tags: nstut/web-scout:build-test
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Verify Python syntax
run: |
docker run --rm nstut/web-scout:build-test python3 -m py_compile main.py utils/service_discovery.py 2>&1 || echo "Syntax check failed"
- name: Check dependencies installed
run: |
docker run --rm nstut/web-scout:build-test pip list 2>&1 | head -20
- name: Run container health check
run: |
# Run container (no special env required for health check)
docker run -d --rm --name web-scout-test \
-p 8000:8000 \
nstut/web-scout:build-test
# Wait for service to be ready (up to 15 seconds)
for i in {1..15}; do
if curl -s http://localhost:8000/api/health > /dev/null 2>&1; then
echo "✓ Health check passed - HTTP server is responding"
docker stop web-scout-test 2>/dev/null || true
exit 0
fi
sleep 1
done
echo "✗ Health check failed - HTTP server not responding"
docker stop web-scout-test 2>/dev/null || true
exit 1
- name: Run tests
run: |
docker run --rm \
-w /app/Web-Scout \
nstut/web-scout:build-test \
pytest tests/ -v
deploy:
needs: build-and-test
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Fetch Secrets from Key Vault
id: kv
uses: azure/CLI@v1
with:
inlineScript: |
DOCKER_USER=$(az keyvault secret show --vault-name nstutcommonkv --name dockerhub-username --query value -o tsv)
DOCKER_TOKEN=$(az keyvault secret show --vault-name nstutcommonkv --name dockerhub-token --query value -o tsv)
GH_PAT=$(az keyvault secret show --vault-name nstutcommonkv --name github-pat --query value -o tsv)
echo "::add-mask::$DOCKER_TOKEN"
echo "::add-mask::$GH_PAT"
echo "DOCKER_USER=$DOCKER_USER" >> $GITHUB_OUTPUT
echo "DOCKER_TOKEN=$DOCKER_TOKEN" >> $GITHUB_OUTPUT
echo "GH_PAT=$GH_PAT" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ steps.kv.outputs.DOCKER_USER }}
password: ${{ steps.kv.outputs.DOCKER_TOKEN }}
- name: Extract metadata for GitHub
id: meta
uses: docker/metadata-action@v5
with:
images: nstut/web-scout
tags: |
type=raw,value={{date 'YYYYMMDD-HHmmss'}}-{{sha}}
type=sha,prefix=
type=ref,event=branch
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Extract image tag
run: |
TAG=$(echo "${{ steps.meta.outputs.tags }}" | head -n1)
echo "IMAGE_TAG=$(basename $TAG)" >> $GITHUB_ENV
- name: Trigger main repo deployment
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ steps.kv.outputs.GH_PAT }}
repository: UpperMoon0/LilyIV
event-type: web-scout-pushed
client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "image_tag": "${{ env.IMAGE_TAG }}"}'