# Copyright (c) Abstract Machines # SPDX-License-Identifier: Apache-2.0 name: CI Pipeline on: push: branches: - main paths-ignore: - '**/*.md' - 'docs/**' - 'LICENSE' - 'MAINTAINERS' - 'CODEOWNERS' pull_request: branches: - main concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: lint-proto: name: Lint Proto runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v6 - name: Setup Go uses: actions/setup-go@v6 with: go-version-file: go.mod cache-dependency-path: "go.sum" - name: Install protolint run: | go install github.com/yoheimuta/protolint/cmd/protolint@latest - name: Lint Protobuf Files run: | protolint . lint-and-build: needs: [lint-proto] uses: ./.github/workflows/lint-and-build.yaml detect-changes: name: Detect Changes runs-on: ubuntu-latest outputs: modules: ${{ steps.set-matrix.outputs.modules }} steps: - name: Checkout uses: actions/checkout@v6 with: fetch-depth: 0 - name: Check for changes in specific paths uses: dorny/paths-filter@v4 id: changes with: filters: | workflow: - ".github/workflows/tests.yaml" auth: - "auth/**" - "cmd/auth/**" - "auth.proto" - "auth.pb.go" - "auth_grpc.pb.go" - "pkg/ulid/**" - "pkg/uuid/**" bootstrap: - "bootstrap/**" - "cmd/bootstrap/**" - "pkg/bootstrap/**" - "provision/**" - "pkg/sdk/**" channels: - "channels/**" - "cmd/channels/**" - "auth.pb.go" - "auth_grpc.pb.go" - "auth/**" - "pkg/sdk/**" - "clients/api/grpc/**" - "groups/api/grpc/**" - "domains/api/grpc/**" - "internal/grpc/**" cli: - "cli/**" - "cmd/cli/**" - "pkg/sdk/**" clients: - "clients/**" - "cmd/clients/**" - "auth.pb.go" - "auth_grpc.pb.go" - "auth/**" - "pkg/ulid/**" - "pkg/uuid/**" - "pkg/events/**" - "groups/api/grpc/**" - "channels/api/grpc/**" - "domains/api/grpc/**" - "internal/grpc/**" domains: - "domains/**" - "cmd/domains/**" - "auth.pb.go" - "auth_grpc.pb.go" - "auth/**" - "internal/grpc/**" groups: - "groups/**" - "cmd/groups/**" - "auth.pb.go" - "auth_grpc.pb.go" - "auth/**" - "pkg/ulid/**" - "pkg/uuid/**" - "clients/api/grpc/**" - "channels/api/grpc/**" - "domains/api/grpc/**" - "internal/grpc/**" internal: - "internal/**" journal: - "journal/**" - "cmd/journal/**" - "auth.pb.go" - "auth_grpc.pb.go" - "auth/**" - "pkg/events/**" logger: - "logger/**" pkg-errors: - "pkg/errors/**" pkg-events: - "pkg/events/**" - "pkg/messaging/**" pkg-grpcclient: - "pkg/grpcclient/**" pkg-messaging: - "pkg/messaging/**" pkg-sdk: - "pkg/sdk/**" - "pkg/errors/**" - "pkg/groups/**" - "auth/**" - "internal/*" - "clients/**" - "users/**" - "channels/**" - "domains/**" - "groups/**" - "journal/**" - "api/http/**" - "re/**" - "alarms/**" - "reports/**" pkg-transformers: - "pkg/transformers/**" pkg-ulid: - "pkg/ulid/**" pkg-uuid: - "pkg/uuid/**" users: - "users/**" - "cmd/users/**" - "auth.pb.go" - "auth_grpc.pb.go" - "auth/**" - "pkg/ulid/**" - "pkg/uuid/**" - "pkg/events/**" notifications: - "notifications/**" - "cmd/notifications/**" - "auth.pb.go" - "auth_grpc.pb.go" - "consumers/notifier.go" - "pkg/events/**" api: - "api/**" consumers: - "consumers/**" - "cmd/postgres-writer/**" - "cmd/timescale-writer/**" - "cmd/smpp-notifier/**" - "cmd/smtp-notifier/**" readers: - "readers/**" - "cmd/postgres-reader/**" - "cmd/timescale-reader/**" re: - "re/**" - "cmd/re/**" - "re/api/**" alarms: - "alarms/**" - "cmd/alarms/**" reports: - "reports/**" - "cmd/reports/**" - name: Set matrix for changed modules id: set-matrix run: | modules=() if [[ "${{ steps.changes.outputs.workflow }}" == "true" || "${{ steps.changes.outputs.pkg-errors }}" == "true" ]]; then # If workflow or pkg/errors changed, test everything modules=("auth" "bootstrap" "channels" "cli" "clients" "domains" "groups" "internal" "journal" "logger" "pkg-errors" "pkg-events" "pkg-grpcclient" "pkg-messaging" "pkg-sdk" "pkg-transformers" "pkg-ulid" "pkg-uuid" "users" "notifications" "api" "consumers" "readers" "re" "alarms" "reports") else # Add only changed modules [[ "${{ steps.changes.outputs.auth }}" == "true" ]] && modules+=("auth") [[ "${{ steps.changes.outputs.bootstrap }}" == "true" ]] && modules+=("bootstrap") [[ "${{ steps.changes.outputs.channels }}" == "true" ]] && modules+=("channels") [[ "${{ steps.changes.outputs.cli }}" == "true" ]] && modules+=("cli") [[ "${{ steps.changes.outputs.clients }}" == "true" ]] && modules+=("clients") [[ "${{ steps.changes.outputs.domains }}" == "true" ]] && modules+=("domains") [[ "${{ steps.changes.outputs.groups }}" == "true" ]] && modules+=("groups") [[ "${{ steps.changes.outputs.internal }}" == "true" ]] && modules+=("internal") [[ "${{ steps.changes.outputs.journal }}" == "true" ]] && modules+=("journal") [[ "${{ steps.changes.outputs.logger }}" == "true" ]] && modules+=("logger") [[ "${{ steps.changes.outputs.pkg-errors }}" == "true" ]] && modules+=("pkg-errors") [[ "${{ steps.changes.outputs.pkg-events }}" == "true" ]] && modules+=("pkg-events") [[ "${{ steps.changes.outputs.pkg-grpcclient }}" == "true" ]] && modules+=("pkg-grpcclient") [[ "${{ steps.changes.outputs.pkg-messaging }}" == "true" ]] && modules+=("pkg-messaging") [[ "${{ steps.changes.outputs.pkg-sdk }}" == "true" ]] && modules+=("pkg-sdk") [[ "${{ steps.changes.outputs.pkg-transformers }}" == "true" ]] && modules+=("pkg-transformers") [[ "${{ steps.changes.outputs.pkg-ulid }}" == "true" ]] && modules+=("pkg-ulid") [[ "${{ steps.changes.outputs.pkg-uuid }}" == "true" ]] && modules+=("pkg-uuid") [[ "${{ steps.changes.outputs.users }}" == "true" ]] && modules+=("users") [[ "${{ steps.changes.outputs.notifications }}" == "true" ]] && modules+=("notifications") [[ "${{ steps.changes.outputs.api }}" == "true" ]] && modules+=("api") [[ "${{ steps.changes.outputs.consumers }}" == "true" ]] && modules+=("consumers") [[ "${{ steps.changes.outputs.readers }}" == "true" ]] && modules+=("readers") [[ "${{ steps.changes.outputs.re }}" == "true" ]] && modules+=("re") [[ "${{ steps.changes.outputs.alarms }}" == "true" ]] && modules+=("alarms") [[ "${{ steps.changes.outputs.reports }}" == "true" ]] && modules+=("reports") fi # Convert to JSON array json_modules=$(printf '%s\n' "${modules[@]}" | jq -R . | jq -s -c .) echo "modules=$json_modules" >> $GITHUB_OUTPUT echo "Testing modules: $json_modules" run-tests: name: Test ${{ matrix.module }} runs-on: ubuntu-latest needs: [lint-and-build, detect-changes] if: needs.detect-changes.outputs.modules != '[]' strategy: fail-fast: true max-parallel: 20 matrix: module: ${{ fromJSON(needs.detect-changes.outputs.modules) }} steps: - name: Checkout uses: actions/checkout@v6 - name: Setup Go uses: actions/setup-go@v6 with: go-version-file: go.mod cache-dependency-path: "go.sum" - name: Verify dependencies run: | go mod download go mod verify - name: Run ${{ matrix.module }} tests run: | # Map module names to directories case "${{ matrix.module }}" in pkg-errors) dir="pkg/errors" ;; pkg-events) dir="pkg/events" ;; pkg-grpcclient) dir="pkg/grpcclient" ;; pkg-messaging) dir="pkg/messaging" ;; pkg-sdk) dir="pkg/sdk" ;; pkg-transformers) dir="pkg/transformers" ;; pkg-ulid) dir="pkg/ulid" ;; pkg-uuid) dir="pkg/uuid" ;; *) dir="${{ matrix.module }}" ;; esac go test -mod=readonly --race -v -count=1 -failfast -coverprofile=coverage-${{ matrix.module }}.out ./$dir/... - name: Upload coverage uses: actions/upload-artifact@v7 with: name: coverage-${{ matrix.module }} path: coverage-${{ matrix.module }}.out retention-days: 1 upload-coverage: name: Upload Coverage runs-on: ubuntu-latest needs: run-tests if: always() && needs.run-tests.result != 'cancelled' steps: - name: Checkout uses: actions/checkout@v6 - name: Download all coverage artifacts uses: actions/download-artifact@v8 with: pattern: coverage-* path: coverage merge-multiple: true - name: Upload coverage to Codecov uses: codecov/codecov-action@v6 with: token: ${{ secrets.CODECOV }} directory: ./coverage files: ./coverage/*.out fail_ci_if_error: false verbose: true