name: Fineract Cargo & Unit- & Integration tests - PostgreSQL on: [push, pull_request] permissions: contents: read jobs: test: runs-on: ubuntu-24.04 timeout-minutes: 60 strategy: fail-fast: false matrix: task: [test-core-1, test-core-2, test-core-3, test-core-4, test-core-5] services: postgresql: image: postgres:17.4 ports: - 5432:5432 env: POSTGRES_USER: root POSTGRES_PASSWORD: postgres options: --health-cmd="pg_isready -q -d postgres -U root" --health-interval=5s --health-timeout=2s --health-retries=3 mock-oauth2-server: image: ghcr.io/navikt/mock-oauth2-server:3.0.1 ports: - 9000:9000 env: SERVER_PORT: 9000 JSON_CONFIG: '{ "interactiveLogin": true, "httpServer": "NettyWrapper", "tokenCallbacks": [ { "issuerId": "auth/realms/fineract", "tokenExpiry": 120, "requestMappings": [{ "requestParam": "scope", "match": "fineract", "claims": { "sub": "mifos", "scope": [ "test" ] } } ] } ] }' env: TZ: Asia/Kolkata DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} AWS_ENDPOINT_URL: http://localhost:4566 AWS_ACCESS_KEY_ID: localstack AWS_SECRET_ACCESS_KEY: localstack AWS_REGION: us-east-1 FINERACT_REPORT_EXPORT_S3_ENABLED: true FINERACT_REPORT_EXPORT_S3_BUCKET_NAME: fineract-reports steps: - name: Checkout uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v5 with: fetch-depth: 0 fetch-tags: true - name: Set up JDK 21 uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5 with: java-version: '21' distribution: 'zulu' - name: Cache Gradle dependencies uses: actions/cache@a7833574556fa59680c1b7cb190c1735db73ebf0 # v4 with: path: | ~/.gradle/caches ~/.gradle/wrapper key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - name: Setup Gradle and Validate Wrapper uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0 with: validate-wrappers: true - name: Verify PostgreSQL connection run: | while ! pg_isready -d postgres -U root -h 127.0.0.1 -p 5432 ; do sleep 1 done - name: Initialise databases run: | ./gradlew --no-daemon -q createPGDB -PdbName=fineract_tenants ./gradlew --no-daemon -q createPGDB -PdbName=fineract_default - name: Start LocalStack run: | docker run -d --name localstack -p 4566:4566 -p 4510-4559:4510-4559 localstack/localstack:2.1 sleep 10 docker exec localstack awslocal s3api create-bucket --bucket fineract-reports - name: Generate test class list (only for test-core-X) if: startsWith(matrix.task, 'test-core-') run: | chmod +x scripts/split-tests.sh SHARD_INDEX=$(echo "${{ matrix.task }}" | awk -F'-' '{print $3}') ./scripts/split-tests.sh 5 $SHARD_INDEX cat "shard-tests_${SHARD_INDEX}.txt" - name: Run Gradle Task run: | set -e # Fail the script if any command fails SHARD_INDEX=$(echo "${{ matrix.task }}" | awk -F'-' '{print $3}') FAILED=0 case "${{ matrix.task }}" in test-core-*) echo "Grouping test classes by module..." declare -A module_tests while IFS=, read -r module class; do module_tests["$module"]+="$class " done < "shard-tests_${SHARD_INDEX}.txt" for module in "${!module_tests[@]}"; do echo "::group::Running tests in $module" for class in ${module_tests[$module]}; do echo " - $class" done # Build test args test_args=$(for class in ${module_tests[$module]}; do echo --tests "$class"; done | xargs) # Run test task for this module if ! ./gradlew "$module:test" $test_args -PdbType=postgresql -x checkstyleJmh -x checkstyleMain -x checkstyleTest -x spotlessCheck -x spotlessApply -x spotbugsMain -x spotbugsTest -x javadoc -x javadocJar -x modernizer; then echo "::error::Tests failed in module $module" FAILED=1 fi echo "::endgroup::" done ;; esac # Exit with failure status if any test failed if [ "$FAILED" -eq 1 ]; then echo "::error::Some tests failed in this job" exit 1 fi - name: Archive test results if: always() uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v4 with: name: test-results-${{ matrix.task }} path: '**/build/reports/' retention-days: 5 - name: Archive server logs if: always() uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v4 with: name: server-logs-${{ matrix.task }} path: '**/build/cargo/' retention-days: 5