Files
pos-system/.github/workflows/docker-build.yml
Ho Ngoc Hai 7b92332710 fix(devops): resolve 4 P2 DevOps improvements (Wave 3 — TEC-263)
- DEVOPS-W-01: Add oliver006/redis_exporter to docker-compose.yml so
  the existing prometheus.yml scrape job (redis-exporter:9121) resolves
- DEVOPS-W-04: Add redis-sentinel.yaml with Redis Sentinel HA setup
  (1 master StatefulSet + 2 replica StatefulSet + 3 sentinel pods)
  replacing the single-instance SPOF redis.yaml in staging K8s
- DEVOPS-W-05: Add network-policy.yaml with default-deny-all NetworkPolicy
  + explicit allow rules for inter-service, Traefik ingress, Redis access,
  Prometheus scrape, and external egress (Neon PostgreSQL, AMQP)
- DEVOPS-M-01: Add aquasecurity/trivy-action to docker-build.yml to scan
  every built image for CRITICAL/HIGH CVEs; results uploaded to GitHub
  Security tab via SARIF

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-23 09:54:32 +07:00

134 lines
5.3 KiB
YAML

# EN: Build and push Docker images for all MVP services
# VI: Build va push Docker images cho tat ca MVP services
name: Docker Build
on:
push:
branches:
- main
- develop
paths:
- 'services/iam-service-net/**'
- 'services/merchant-service-net/**'
- 'services/order-service-net/**'
- 'services/fnb-engine-net/**'
- 'services/inventory-service-net/**'
- 'services/wallet-service-net/**'
- 'services/catalog-service-net/**'
- 'services/storage-service-net/**'
- 'apps/web-client-tpos-net/**'
workflow_dispatch:
inputs:
service:
description: 'Service to build (leave empty for changed only)'
required: false
default: ''
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Detect changed services
id: set-matrix
run: |
if [ -n "${{ github.event.inputs.service }}" ]; then
echo 'matrix={"include":[{"service":"${{ github.event.inputs.service }}"}]}' >> $GITHUB_OUTPUT
exit 0
fi
CHANGED=$(git diff --name-only HEAD~1 HEAD)
INCLUDES=()
declare -A SERVICES=(
["services/iam-service-net"]='{"service":"iam-service-net","context":"./services/iam-service-net","image":"goodgo/iam-service-net"}'
["services/merchant-service-net"]='{"service":"merchant-service-net","context":"./services/merchant-service-net","image":"goodgo/merchant-service-net"}'
["services/order-service-net"]='{"service":"order-service-net","context":"./services/order-service-net","image":"goodgo/order-service-net"}'
["services/fnb-engine-net"]='{"service":"fnb-engine-net","context":"./services/fnb-engine-net","image":"goodgo/fnb-engine-net"}'
["services/inventory-service-net"]='{"service":"inventory-service-net","context":"./services/inventory-service-net","image":"goodgo/inventory-service-net"}'
["services/wallet-service-net"]='{"service":"wallet-service-net","context":"./services/wallet-service-net","image":"goodgo/wallet-service-net"}'
["services/catalog-service-net"]='{"service":"catalog-service-net","context":"./services/catalog-service-net","image":"goodgo/catalog-service-net"}'
["services/storage-service-net"]='{"service":"storage-service-net","context":"./services/storage-service-net","image":"goodgo/storage-service-net"}'
["apps/web-client-tpos-net"]='{"service":"web-client-tpos-net","context":"./apps/web-client-tpos-net","image":"goodgo/web-client-tpos-net"}'
)
for path in "${!SERVICES[@]}"; do
if echo "$CHANGED" | grep -q "^${path}/"; then
INCLUDES+=("${SERVICES[$path]}")
fi
done
if [ ${#INCLUDES[@]} -eq 0 ]; then
echo 'matrix={"include":[]}' >> $GITHUB_OUTPUT
else
JOINED=$(IFS=,; echo "${INCLUDES[*]}")
echo "matrix={\"include\":[${JOINED}]}" >> $GITHUB_OUTPUT
fi
build:
needs: detect-changes
if: needs.detect-changes.outputs.matrix != '{"include":[]}'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.detect-changes.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set tags
id: tags
run: |
IMAGE="${{ matrix.image }}"
SHA="${{ github.sha }}"
BRANCH="${{ github.ref_name }}"
# EN: Never push :latest — use commit SHA only for main, :staging for develop
# VI: Khong bao gio push :latest — chi dung commit SHA cho main, :staging cho develop
if [ "$BRANCH" = "main" ]; then
echo "tags=${IMAGE}:${SHA}" >> $GITHUB_OUTPUT
else
echo "tags=${IMAGE}:staging,${IMAGE}:${SHA}" >> $GITHUB_OUTPUT
fi
- name: Build and push ${{ matrix.service }}
uses: docker/build-push-action@v5
with:
context: ${{ matrix.context }}
push: true
tags: ${{ steps.tags.outputs.tags }}
cache-from: type=registry,ref=${{ matrix.image }}:buildcache
cache-to: type=registry,ref=${{ matrix.image }}:buildcache,mode=max
# EN: Scan image for vulnerabilities with Trivy (DEVOPS-M-01)
# VI: Quet lo hong bao mat image bang Trivy (DEVOPS-M-01)
- name: Scan ${{ matrix.service }} image for vulnerabilities
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ matrix.image }}:${{ github.sha }}
format: 'sarif'
output: 'trivy-results-${{ matrix.service }}.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'
ignore-unfixed: true
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results-${{ matrix.service }}.sarif'
category: 'trivy-${{ matrix.service }}'