Skip to content

feat(ci-cd): refactor testing steps to handle multiple modules in a s… #23

feat(ci-cd): refactor testing steps to handle multiple modules in a s…

feat(ci-cd): refactor testing steps to handle multiple modules in a s… #23

Workflow file for this run

name: ci-cd
on:
push:
branches: [ dev, master ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
DOCKER_REGISTRY: docker.io
DOCKER_REPOSITORY: marcofontana17/cce_prototipo
jobs:
build-and-test:
name: Run Tests
runs-on: ${{ matrix.os }}
# Force Bash for every `run:` step
defaults:
run:
shell: bash
strategy:
matrix:
os:
- ubuntu-22.04
- windows-2022
- macos-12
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.24'
check-latest: true
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Test all modules on ${{ matrix.os }}
run: |
# Define modules
modules=("api_gateway:./api_gateway" "service:./service" "utils:./utils")
# Initialize variables for summary
total_coverage=0
module_count=0
failed_modules=()
echo "=== Testing all modules on ${{ matrix.os }} ==="
echo ""
# Loop through each module
for module_info in "${modules[@]}"; do
module_name="${module_info%%:*}"
module_path="${module_info##*:}"
echo "========================================"
echo "Testing module: $module_name"
echo "Path: $module_path"
echo "========================================"
cd "$module_path"
# Download and verify dependencies
echo "Downloading dependencies..."
if ! go mod download; then
echo "Failed to download dependencies for $module_name"
failed_modules+=("$module_name:deps")
cd - > /dev/null
continue
fi
echo "Verifying dependencies..."
if ! go mod verify; then
echo "Failed to verify dependencies for $module_name"
failed_modules+=("$module_name:verify")
cd - > /dev/null
continue
fi
# Run basic tests
echo "Running tests..."
if ! go test -v ./...; then
echo "Tests failed for $module_name"
failed_modules+=("$module_name:tests")
cd - > /dev/null
continue
fi
# Run tests with race detector
echo "Running tests with race detector..."
if ! go test -race -short ./...; then
echo "Race detector tests failed for $module_name"
failed_modules+=("$module_name:race")
cd - > /dev/null
continue
fi
# Run tests with coverage
echo "Running tests with coverage..."
if go test -coverprofile=coverage.out ./...; then
if [ -f coverage.out ]; then
echo "Coverage report for $module_name:"
go tool cover -func=coverage.out
# Extract coverage percentage
coverage=$(go tool cover -func=coverage.out | grep total | awk '{print substr($3, 1, length($3)-1)}')
if [ -n "$coverage" ]; then
echo "Total coverage for $module_name: ${coverage}%"
# Add to total for average calculation
total_coverage=$(echo "$total_coverage + $coverage" | bc -l)
module_count=$((module_count + 1))
else
echo "Could not extract coverage percentage for $module_name"
fi
else
echo "No coverage file generated for $module_name"
fi
else
echo "Coverage tests failed for $module_name"
failed_modules+=("$module_name:coverage-tests")
fi
echo "Completed testing $module_name"
echo ""
cd - > /dev/null
done
# Summary
echo "========================================"
echo "TEST SUMMARY for ${{ matrix.os }}"
echo "========================================"
if [ ${#failed_modules[@]} -eq 0 ]; then
echo "All modules passed all tests!"
else
echo "Some modules had failures:"
for failure in "${failed_modules[@]}"; do
echo " - $failure"
done
fi
if [ $module_count -gt 0 ]; then
average_coverage=$(echo "scale=2; $total_coverage / $module_count" | bc -l)
echo "Average coverage across all modules: ${average_coverage}%"
fi
echo "========================================"
# Exit with error if any module failed
if [ ${#failed_modules[@]} -gt 0 ]; then
echo "Build failed due to module failures"
exit 1
fi
echo "All tests passed successfully!"
# Optional: Upload coverage reports (commented out as in your example)
# - name: Upload coverage reports
# run: |
# modules=("api_gateway:./api_gateway" "service:./service" "utils:./utils")
# for module_info in "${modules[@]}"; do
# module_name="${module_info%%:*}"
# module_path="${module_info##*:}"
# if [ -f "$module_path/coverage.out" ]; then
# echo "Uploading coverage for $module_name"
# # Upload logic here
# fi
# done
push-docker-images:
runs-on: ubuntu-latest
name: Build and Push Docker Images
needs: build-and-test # This ensures tests must pass before building
strategy:
matrix:
service:
- name: "api_gateway"
dockerfile: "./api_gateway/Dockerfile"
suffix: "api_gateway"
- name: "service"
dockerfile: "./service/Dockerfile"
suffix: "service"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Extract metadata for ${{ matrix.service.name }}
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_REPOSITORY }}
tags: |
type=raw,value=${{ matrix.service.suffix }}-latest,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=${{ matrix.service.suffix }}-dev-latest,enable=${{ github.ref == 'refs/heads/dev' }}
type=sha,prefix=${{ github.ref_name }}-,suffix=-${{ matrix.service.suffix }}
- name: Build and push ${{ matrix.service.name }}
uses: docker/build-push-action@v5
with:
context: .
file: ${{ matrix.service.dockerfile }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max