feat: implement raw material grouping and cost management modules with associated gRPC services and database migrations #86
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Finance Service CI/CD | |
| on: | |
| push: | |
| branches: [main, develop] | |
| paths: | |
| - 'services/finance/**' | |
| - 'gen/**' | |
| - '.github/workflows/finance-service.yml' | |
| - '.golangci.yml' | |
| pull_request: | |
| branches: [main, develop] | |
| paths: | |
| - 'services/finance/**' | |
| - 'gen/**' | |
| - '.golangci.yml' | |
| workflow_dispatch: | |
| env: | |
| GO_VERSION: '1.24' | |
| GOLANGCI_LINT_VERSION: 'v2.3.0' | |
| SERVICE_NAME: finance-service | |
| WORKING_DIR: ./services/finance | |
| jobs: | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache: false # Disable built-in cache, use golangci cache instead | |
| - name: Run golangci-lint | |
| uses: golangci/golangci-lint-action@v8 | |
| with: | |
| version: ${{ env.GOLANGCI_LINT_VERSION }} | |
| working-directory: ${{ env.WORKING_DIR }} | |
| args: --timeout=5m | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| # Runs in parallel with lint job | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: finance | |
| POSTGRES_PASSWORD: finance123 | |
| POSTGRES_DB: finance_db_test | |
| ports: | |
| - 5434:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| redis: | |
| image: redis:7-alpine | |
| ports: | |
| - 6379:6379 | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache: true | |
| cache-dependency-path: '**/go.sum' | |
| - name: Download dependencies | |
| working-directory: ${{ env.WORKING_DIR }} | |
| run: go mod download | |
| - name: Run unit tests | |
| working-directory: ${{ env.WORKING_DIR }} | |
| run: go test -v -race -short ./internal/... | |
| - name: Install golang-migrate | |
| run: | | |
| curl -L https://github.com/golang-migrate/migrate/releases/download/v4.18.1/migrate.linux-amd64.tar.gz | tar xvz | |
| sudo mv migrate /usr/local/bin/migrate | |
| migrate --version | |
| - name: Run database migrations | |
| working-directory: ${{ env.WORKING_DIR }} | |
| run: | | |
| migrate -path migrations/postgres \ | |
| -database "postgres://finance:finance123@localhost:5434/finance_db_test?sslmode=disable" \ | |
| up | |
| - name: Run integration tests | |
| working-directory: ${{ env.WORKING_DIR }} | |
| env: | |
| INTEGRATION_TEST: true | |
| TEST_DB_HOST: localhost | |
| TEST_DB_PORT: 5434 | |
| TEST_DB_USER: finance | |
| TEST_DB_PASSWORD: finance123 | |
| TEST_DB_NAME: finance_db_test | |
| run: go test -v -race ./internal/infrastructure/... | |
| - name: Run tests with coverage | |
| working-directory: ${{ env.WORKING_DIR }} | |
| run: | | |
| go test -v -race -coverprofile=coverage.out -covermode=atomic ./... | |
| go tool cover -func=coverage.out | tail -1 | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| file: ${{ env.WORKING_DIR }}/coverage.out | |
| flags: ${{ env.SERVICE_NAME }} | |
| fail_ci_if_error: false | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| needs: [lint, test] # Wait for both lint and test to pass | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache: true | |
| cache-dependency-path: '**/go.sum' | |
| - name: Build binary | |
| working-directory: ${{ env.WORKING_DIR }} | |
| run: | | |
| CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ | |
| -ldflags="-s -w -X main.Version=${{ github.sha }}" \ | |
| -o ./bin/${{ env.SERVICE_NAME }} \ | |
| ./cmd/server/main.go | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.SERVICE_NAME }}-binary | |
| path: ${{ env.WORKING_DIR }}/bin/${{ env.SERVICE_NAME }} | |
| retention-days: 7 | |
| docker: | |
| name: Docker Build & Push | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ghcr.io/${{ github.repository_owner }}/${{ env.SERVICE_NAME }} | |
| tags: | | |
| type=sha,prefix= | |
| type=ref,event=branch | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ${{ env.WORKING_DIR }}/Dockerfile | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| build-args: | | |
| VERSION=${{ github.sha }} | |
| BUILD_TIME=${{ github.event.head_commit.timestamp }} | |
| e2e: | |
| name: E2E Tests | |
| runs-on: ubuntu-latest | |
| needs: docker | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache: true | |
| cache-dependency-path: '**/go.sum' | |
| - name: Start infrastructure with Docker Compose | |
| working-directory: ${{ env.WORKING_DIR }} | |
| run: | | |
| docker compose -f deployments/docker-compose.yaml up -d postgres redis | |
| echo "Waiting for PostgreSQL to be healthy..." | |
| sleep 10 | |
| - name: Install golang-migrate | |
| run: | | |
| curl -L https://github.com/golang-migrate/migrate/releases/download/v4.18.1/migrate.linux-amd64.tar.gz | tar xvz | |
| sudo mv migrate /usr/local/bin/migrate | |
| - name: Run database migrations | |
| working-directory: ${{ env.WORKING_DIR }} | |
| run: | | |
| migrate -path migrations/postgres \ | |
| -database "postgres://finance:finance123@localhost:5434/finance_db?sslmode=disable" \ | |
| up | |
| - name: Build and start finance service | |
| working-directory: ${{ env.WORKING_DIR }} | |
| run: | | |
| go build -o ./bin/finance-service ./cmd/server/main.go | |
| ./bin/finance-service & | |
| echo "Waiting for service to start..." | |
| sleep 5 | |
| env: | |
| APP_ENV: test | |
| DATABASE_HOST: localhost | |
| DATABASE_PORT: 5434 | |
| DATABASE_USER: finance | |
| DATABASE_PASSWORD: finance123 | |
| DATABASE_NAME: finance_db | |
| REDIS_HOST: localhost | |
| REDIS_PORT: 6379 | |
| JWT_ACCESS_SECRET: e2e-test-jwt-secret | |
| - name: Run E2E tests | |
| working-directory: ${{ env.WORKING_DIR }} | |
| env: | |
| E2E_TEST: true | |
| GRPC_ADDR: localhost:50051 | |
| JWT_ACCESS_SECRET: e2e-test-jwt-secret | |
| run: go test -v ./tests/e2e/... | |
| - name: Stop services | |
| working-directory: ${{ env.WORKING_DIR }} | |
| if: always() | |
| run: docker compose -f deployments/docker-compose.yaml down | |
| deploy-staging: | |
| name: Deploy to Staging | |
| runs-on: [self-hosted, staging, goapps-runner] | |
| needs: e2e | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| environment: | |
| name: staging | |
| url: https://staging-goapps.mutugading.com | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Notify ArgoCD to sync | |
| run: | | |
| echo "Staging deployment triggered via ArgoCD auto-sync" | |
| echo "Image: ghcr.io/mutugading/${{ env.SERVICE_NAME }}:${{ github.sha }}" | |
| # ArgoCD will auto-sync when it detects new image | |
| deploy-production: | |
| name: Deploy to Production | |
| runs-on: [self-hosted, production, goapps-runner] | |
| needs: deploy-staging | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| environment: | |
| name: production | |
| url: https://goapps.mutugading.com | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Trigger Production Deploy via ArgoCD | |
| run: | | |
| echo "Production deployment requires manual ArgoCD sync" | |
| echo "Image: ghcr.io/mutugading/${{ env.SERVICE_NAME }}:${{ github.sha }}" | |
| # Manual sync required in ArgoCD dashboard |