You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ad...@apache.org on 2025/09/18 07:55:14 UTC
(fineract) 01/01: FINERACT-2326: Publish commits to DockerHub
This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch FINERACT-2326/publish-commit-to-docker
in repository https://gitbox.apache.org/repos/asf/fineract.git
commit da2e94e03b90747dacf1482f12ce0257b0cc416f
Author: Adam Saghy <ad...@gmail.com>
AuthorDate: Thu Sep 18 09:54:42 2025 +0200
FINERACT-2326: Publish commits to DockerHub
---
.github/workflows/build-cucumber.yml | 114 ---------------
.github/workflows/build-docker.yml | 55 --------
.github/workflows/build-documentation.yml | 35 -----
.github/workflows/build-e2e-tests.yml | 183 -------------------------
.github/workflows/build-mariadb.yml | 162 ----------------------
.github/workflows/build-mysql.yml | 162 ----------------------
.github/workflows/build-postgresql.yml | 163 ----------------------
.github/workflows/publish-commit-dockerhub.yml | 54 ++++++++
.github/workflows/publish-dockerhub.yml | 48 -------
.github/workflows/smoke-messaging.yml | 62 ---------
.github/workflows/sonarqube.yml | 38 -----
.github/workflows/stale.yml | 26 ----
12 files changed, 54 insertions(+), 1048 deletions(-)
diff --git a/.github/workflows/build-cucumber.yml b/.github/workflows/build-cucumber.yml
deleted file mode 100644
index d35727a964..0000000000
--- a/.github/workflows/build-cucumber.yml
+++ /dev/null
@@ -1,114 +0,0 @@
-name: Fineract Build & Cucumber tests (without E2E tests)
-
-on: [push, pull_request]
-
-permissions:
- contents: read
-
-jobs:
- verify:
- runs-on: ubuntu-24.04
- timeout-minutes: 60
-
- strategy:
- fail-fast: false
- matrix:
- include:
- - task: build-core
- job_type: main
- - task: cucumber
- job_type: main
- - task: build-progressive-loan
- job_type: progressive-loan
-
- env:
- TZ: Asia/Kolkata
- DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
-
- steps:
- - name: Checkout
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
- fetch-tags: true
-
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
-
- - name: Cache Gradle dependencies
- uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # 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@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- with:
- validate-wrappers: true
-
- - name: Run Gradle Task
- if: matrix.job_type == 'main'
- run: |
- set -e # Fail the script if any command fails
-
- case "${{ matrix.task }}" in
- build-core)
- ./gradlew --no-daemon build -x test -x cucumber -x doc
- ;;
- cucumber)
- ./gradlew --no-daemon cucumber -x :fineract-e2e-tests-runner:cucumber -x checkstyleJmh -x checkstyleMain -x checkstyleTest -x spotlessCheck -x spotlessApply -x spotbugsMain -x spotbugsTest -x javadoc -x javadocJar -x modernizer
- ;;
- esac
-
- - name: Build and Test Progressive Loan
- if: matrix.job_type == 'progressive-loan'
- run: |
- # Build the JAR
- ./gradlew --no-daemon --console=plain :fineract-progressive-loan-embeddable-schedule-generator:shadowJar
-
- # Store the JAR filename in an environment variable
- EMBEDDABLE_JAR_FILE=$(ls fineract-progressive-loan-embeddable-schedule-generator/build/libs/*-all.jar | head -n 1)
- echo "EMBEDDABLE_JAR_FILE=$EMBEDDABLE_JAR_FILE" >> $GITHUB_ENV
- echo "JAR file: $EMBEDDABLE_JAR_FILE"
-
- # Run unit tests
- ./gradlew --no-daemon --console=plain :fineract-progressive-loan-embeddable-schedule-generator:test
-
- # Build and run sample application
- mkdir -p sample-app
- javac -cp "$EMBEDDABLE_JAR_FILE" -d sample-app fineract-progressive-loan-embeddable-schedule-generator/misc/Main.java
- java -cp "$EMBEDDABLE_JAR_FILE:sample-app" Main
- java -cp "$EMBEDDABLE_JAR_FILE:sample-app" Main 25
-
- - name: Archive test results
- if: always()
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: test-results-${{ matrix.task }}
- path: |
- **/build/reports/
- **/fineract-progressive-loan-embeddable-schedule-generator/build/reports/
- if-no-files-found: ignore
- retention-days: 5
-
- - name: Archive Progressive Loan JAR
- if: matrix.job_type == 'progressive-loan' && always()
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: progressive-loan-jar
- path: ${{ env.EMBEDDABLE_JAR_FILE }}
- retention-days: 5
- if-no-files-found: ignore
-
- - name: Archive server logs
- if: always()
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: server-logs-${{ matrix.task }}
- path: '**/build/cargo/'
- retention-days: 5
diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml
deleted file mode 100644
index 299295d8da..0000000000
--- a/.github/workflows/build-docker.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-name: Fineract Docker Builds
-
-on: [push, pull_request]
-
-permissions:
- contents: read
-
-jobs:
- build:
- runs-on: ubuntu-24.04
- timeout-minutes: 60
- strategy:
- fail-fast: false
- matrix:
- db_type: [mariadb, postgresql]
- include:
- - db_type: mariadb
- compose_file: docker-compose.yml
- check_worker_health: true
- - db_type: postgresql
- compose_file: docker-compose-postgresql.yml
- check_worker_health: false
-
- env:
- DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- IMAGE_NAME: fineract
-
- steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
-
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
-
- - name: Setup Gradle
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
-
- - name: Build the image
- run: ./gradlew --no-daemon --console=plain :fineract-provider:jibDockerBuild -Djib.to.image=$IMAGE_NAME -x test -x cucumber
-
- - name: Start the ${{ matrix.db_type }} stack
- run: docker compose -f ${{ matrix.compose_file }} up -d
-
- - name: Check the stack
- run: docker ps
-
- - name: Check health Manager
- run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
-
- - name: Check info Manager
- run: (( $(curl -f -k --retry 5 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
diff --git a/.github/workflows/build-documentation.yml b/.github/workflows/build-documentation.yml
deleted file mode 100644
index eb97e02e1e..0000000000
--- a/.github/workflows/build-documentation.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-name: Fineract Documentation build
-on: [push, pull_request]
-permissions:
- contents: read
-jobs:
- build:
- runs-on: ubuntu-24.04
- timeout-minutes: 60
- env:
- DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- steps:
- - name: Checkout
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
- - name: Setup Gradle
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
- with:
- node-version: 22
- - name: Congfigure vega-cli
- run: npm i -g vega-cli --unsafe
- - name: Validate Gradle wrapper
- uses: gradle/actions/wrapper-validation@v4
- - name: Install additional software
- run: |
- sudo apt-get update
- sudo apt-get install ghostscript graphviz -y
- - name: Documentation build
- run: ./gradlew --no-daemon --console=plain doc
diff --git a/.github/workflows/build-e2e-tests.yml b/.github/workflows/build-e2e-tests.yml
deleted file mode 100644
index 9623d2ccd4..0000000000
--- a/.github/workflows/build-e2e-tests.yml
+++ /dev/null
@@ -1,183 +0,0 @@
-name: Fineract E2E Tests
-
-on: [push, pull_request]
-
-permissions:
- contents: read
-
-jobs:
- test:
- name: E2E Tests (Shard ${{ matrix.shard_index }} of ${{ matrix.total_shards }})
- runs-on: ubuntu-24.04
- timeout-minutes: 60
-
- strategy:
- fail-fast: false
- matrix:
- # Define the number of shards (1-based indexing)
- shard_index: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- total_shards: [10]
-
- env:
- DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- IMAGE_NAME: fineract
- BASE_URL: https://localhost:8443
- TEST_USERNAME: mifos
- TEST_PASSWORD: password
- TEST_STRONG_PASSWORD: A1b2c3d4e5f$
- TEST_TENANT_ID: default
- INITIALIZATION_ENABLED: true
- EVENT_VERIFICATION_ENABLED: true
- ACTIVEMQ_BROKER_URL: tcp://localhost:61616
- ACTIVEMQ_TOPIC_NAME: events
-
- steps:
- - name: Checkout code
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
-
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
-
- - name: Setup Gradle
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
-
- - name: Make scripts executable
- run: chmod +x scripts/split-features.sh
-
- - name: Split feature files into shards
- id: split-features
- run: |
- ./scripts/split-features.sh ${{ matrix.total_shards }} ${{ matrix.shard_index }}
- echo "Shard ${{ matrix.shard_index }} feature files:"
- cat feature_shard_${{ matrix.shard_index }}.txt
-
- - name: Build the image
- run: ./gradlew --no-daemon --console=plain :fineract-provider:jibDockerBuild -Djib.to.image=$IMAGE_NAME -x test -x cucumber
-
- - name: Start the Fineract stack
- run: docker compose -f docker-compose-postgresql-test-activemq.yml up -d
-
- - name: Check the stack
- run: docker ps
-
- - name: Wait for Manager to be ready
- run: |
- # Wait for the container to be running
- echo "Waiting for Manager container to be ready..."
- timeout 300 bash -c 'until docker ps --filter "health=healthy" --filter "name=fineract" --format "{{.Status}}" | grep -q "healthy"; do
- if docker ps --filter "name=fineract" --format "{{.Status}}" | grep -q "unhealthy"; then
- echo "Container is unhealthy. Stopping..."
- docker ps -a
- docker logs $(docker ps -q --filter name=fineract) || true
- exit 1
- fi
- echo "Waiting for Manager to be ready..."
- sleep 5
- done'
-
- # Check the health endpoint
- echo "Checking Manager health endpoint..."
- curl -f -k --retry 30 --retry-all-errors --connect-timeout 10 --retry-delay 10 \
- https://localhost:8443/fineract-provider/actuator/health
-
- - name: Execute tests for shard ${{ matrix.shard_index }}
- id: tests
- run: |
- # Initialize failure flag
- FAILED=0
-
- # Create necessary directories
- mkdir -p "allure-results-shard-${{ matrix.shard_index }}"
- mkdir -p "allure-results-merged"
-
- # Read feature files from the shard file
- if [ ! -s "feature_shard_${{ matrix.shard_index }}.txt" ]; then
- echo "No features to test in this shard. Skipping..."
- exit 0
- fi
-
- # Read each feature file path and run tests one by one
- while IFS= read -r feature_file || [ -n "$feature_file" ]; do
- # Skip empty lines
- [ -z "$feature_file" ] && continue
-
- # Create a safe filename for the results
- safe_name=$(echo "$feature_file" | tr '/' '-' | tr ' ' '_')
-
- echo "::group::Testing feature: $feature_file"
-
- # Run tests with individual allure results directory
- if ! ./gradlew --no-daemon --console=plain \
- :fineract-e2e-tests-runner:cucumber \
- -Pcucumber.features="$feature_file" \
- -Dallure.results.directory="allure-results-shard-${{ matrix.shard_index }}/$safe_name" \
- allureReport; then
-
- echo "::error::Test failed for $feature_file"
- FAILED=1
- fi
-
- echo "::endgroup::"
-
- # Copy the results to a merged directory
- if [ -d "allure-results-shard-${{ matrix.shard_index }}/$safe_name" ]; then
- cp -r "allure-results-shard-${{ matrix.shard_index }}/$safe_name/." "allure-results-merged/" || true
- fi
- done < "feature_shard_${{ matrix.shard_index }}.txt"
-
- # Generate individual report for this shard
- if [ -d "allure-results-merged" ] && [ "$(ls -A allure-results-merged)" ]; then
- echo "Generating Allure report..."
- mkdir -p "allure-report-shard-${{ matrix.shard_index }}"
- ./fineract-e2e-tests-runner/build/allure/commandline/bin/allure generate "allure-results-merged" --clean -o "allure-report-shard-${{ matrix.shard_index }}" || \
- echo "::warning::Failed to generate Allure report for shard ${{ matrix.shard_index }}"
- fi
-
- # Exit with failure status if any test failed
- if [ "$FAILED" -eq 1 ]; then
- echo "::error::Some tests failed in this shard"
- exit 1
- fi
-
- - name: Upload test results
- if: always()
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: allure-results-shard-${{ matrix.shard_index }}
- path: |
- allure-results-shard-${{ matrix.shard_index }}
- allure-results-merged
- **/build/allure-results
- **/build/reports/tests/test
- **/build/test-results/test
- retention-days: 5
-
- - name: Upload Allure Report
- if: always()
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: allure-report-shard-${{ matrix.shard_index }}
- path: allure-report-shard-${{ matrix.shard_index }}
- retention-days: 5
-
- - name: Upload logs
- if: always()
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: logs-shard-${{ matrix.shard_index }}
- path: |
- **/build/reports/tests/
- **/logs/
- **/out/
- retention-days: 5
-
- - name: Clean up
- if: always()
- run: |
- docker compose -f docker-compose-postgresql-test-activemq.yml down -v
- docker system prune -f
diff --git a/.github/workflows/build-mariadb.yml b/.github/workflows/build-mariadb.yml
deleted file mode 100644
index 108911226c..0000000000
--- a/.github/workflows/build-mariadb.yml
+++ /dev/null
@@ -1,162 +0,0 @@
-name: Fineract Cargo & Unit- & Integration tests - MariaDB
-
-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, test-twofactor, test-oauth2]
-
- services:
- mariadb:
- image: mariadb:11.5.2
- ports:
- - 3306:3306
- env:
- MARIADB_ROOT_PASSWORD: mysql
- options: --health-cmd="healthcheck.sh --su-mysql --connect --innodb_initialized" --health-interval=5s --health-timeout=2s --health-retries=3
-
- mock-oauth2-server:
- image: ghcr.io/navikt/mock-oauth2-server:2.1.10
- 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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
- fetch-tags: true
-
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
-
- - name: Cache Gradle dependencies
- uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # 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@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- with:
- validate-wrappers: true
-
- - name: Verify MariaDB connection
- run: |
- while ! mysqladmin ping -h"127.0.0.1" -P3306 ; do
- sleep 1
- done
-
- - name: Initialise databases
- run: |
- ./gradlew --no-daemon -q createDB -PdbName=fineract_tenants
- ./gradlew --no-daemon -q createDB -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-twofactor)
- if ! ./gradlew --no-daemon :twofactor-tests:test -x checkstyleJmh -x checkstyleMain -x checkstyleTest -x spotlessCheck -x spotlessApply -x spotbugsMain -x spotbugsTest -x javadoc -x javadocJar -x modernizer; then
- echo "::error::Two-factor tests failed"
- FAILED=1
- fi
- ;;
- test-oauth2)
- if ! ./gradlew --no-daemon :oauth2-tests:test -x checkstyleJmh -x checkstyleMain -x checkstyleTest -x spotlessCheck -x spotlessApply -x spotbugsMain -x spotbugsTest -x javadoc -x javadocJar -x modernizer; then
- echo "::error::OAuth2 tests failed"
- FAILED=1
- fi
- ;;
- 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 -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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: test-results-${{ matrix.task }}
- path: '**/build/reports/'
- retention-days: 5
-
- - name: Archive server logs
- if: always()
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: server-logs-${{ matrix.task }}
- path: '**/build/cargo/'
- retention-days: 5
diff --git a/.github/workflows/build-mysql.yml b/.github/workflows/build-mysql.yml
deleted file mode 100644
index cd0b96a8d8..0000000000
--- a/.github/workflows/build-mysql.yml
+++ /dev/null
@@ -1,162 +0,0 @@
-name: Fineract Cargo & Unit- & Integration tests - MySQL
-
-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, test-twofactor, test-oauth2]
-
- services:
- mysql:
- image: mysql:9.1
- ports:
- - 3306:3306
- env:
- MYSQL_ROOT_PASSWORD: mysql
- options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
-
- mock-oauth2-server:
- image: ghcr.io/navikt/mock-oauth2-server:2.1.10
- 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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
- fetch-tags: true
-
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
-
- - name: Cache Gradle dependencies
- uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # 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@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- with:
- validate-wrappers: true
-
- - name: Verify MySQL connection
- run: |
- while ! mysqladmin ping -h"127.0.0.1" -P3306 ; do
- sleep 1
- done
-
- - name: Initialise databases
- run: |
- ./gradlew --no-daemon -q createMySQLDB -PdbName=fineract_tenants
- ./gradlew --no-daemon -q createMySQLDB -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-twofactor)
- if ! ./gradlew --no-daemon :twofactor-tests:test -PdbType=mysql -x checkstyleJmh -x checkstyleMain -x checkstyleTest -x spotlessCheck -x spotlessApply -x spotbugsMain -x spotbugsTest -x javadoc -x javadocJar -x modernizer; then
- echo "::error::Two-factor tests failed"
- FAILED=1
- fi
- ;;
- test-oauth2)
- if ! ./gradlew --no-daemon :oauth2-tests:test -PdbType=mysql -x checkstyleJmh -x checkstyleMain -x checkstyleTest -x spotlessCheck -x spotlessApply -x spotbugsMain -x spotbugsTest -x javadoc -x javadocJar -x modernizer; then
- echo "::error::OAuth2 tests failed"
- FAILED=1
- fi
- ;;
- 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=mysql -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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: test-results-${{ matrix.task }}
- path: '**/build/reports/'
- retention-days: 5
-
- - name: Archive server logs
- if: always()
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: server-logs-${{ matrix.task }}
- path: '**/build/cargo/'
- retention-days: 5
diff --git a/.github/workflows/build-postgresql.yml b/.github/workflows/build-postgresql.yml
deleted file mode 100644
index 7f5f6b1a40..0000000000
--- a/.github/workflows/build-postgresql.yml
+++ /dev/null
@@ -1,163 +0,0 @@
-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, test-twofactor, test-oauth2]
-
- 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:2.1.10
- 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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
- fetch-tags: true
-
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
-
- - name: Cache Gradle dependencies
- uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # 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@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- 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-twofactor)
- if ! ./gradlew --no-daemon :twofactor-tests:test -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::Two-factor tests failed"
- FAILED=1
- fi
- ;;
- test-oauth2)
- if ! ./gradlew --no-daemon :oauth2-tests:test -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::OAuth2 tests failed"
- FAILED=1
- fi
- ;;
- 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: test-results-${{ matrix.task }}
- path: '**/build/reports/'
- retention-days: 5
-
- - name: Archive server logs
- if: always()
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: server-logs-${{ matrix.task }}
- path: '**/build/cargo/'
- retention-days: 5
diff --git a/.github/workflows/publish-commit-dockerhub.yml b/.github/workflows/publish-commit-dockerhub.yml
new file mode 100644
index 0000000000..722a6e5fc7
--- /dev/null
+++ b/.github/workflows/publish-commit-dockerhub.yml
@@ -0,0 +1,54 @@
+name: Fineract Rebuild Commits
+
+on:
+ workflow_dispatch: # run manually
+
+permissions:
+ contents: read
+
+jobs:
+ rebuild:
+ runs-on: ubuntu-24.04
+ timeout-minutes: 360
+ env:
+ DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
+ steps:
+ - name: Checkout Source Code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # we need full history
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'zulu'
+
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
+
+ - name: Get list of commits after 9f4f1d4f
+ id: commits
+ run: |
+ git fetch origin develop
+ commits=$(git rev-list --reverse 9f4f1d4f..origin/develop)
+ echo "commits=$commits" >> $GITHUB_OUTPUT
+
+ - name: Loop through commits and build
+ run: |
+ for commit in ${{ steps.commits.outputs.commits }}; do
+ echo "Building commit $commit"
+ git checkout $commit
+
+ short_hash=$(git rev-parse --short $commit)
+ long_hash=$commit
+
+ ./gradlew --no-daemon --console=plain :fineract-provider:jib -x test -x cucumber \
+ -Djib.to.auth.username=${{secrets.DOCKERHUB_USER}} \
+ -Djib.to.auth.password=${{secrets.DOCKERHUB_TOKEN}} \
+ -Djib.from.platforms=linux/amd64,linux/arm64 \
+ -Djib.to.image=apache/fineract \
+ -Djib.to.tags=$short_hash,$long_hash
+
+ echo "Finished building $commit"
+ done
diff --git a/.github/workflows/publish-dockerhub.yml b/.github/workflows/publish-dockerhub.yml
deleted file mode 100644
index 062c1eb109..0000000000
--- a/.github/workflows/publish-dockerhub.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-name: Fineract Publish to DockerHub
-on:
- push:
- branches:
- - develop
- tags:
- - 1.*
-permissions:
- contents: read
-jobs:
- build:
- runs-on: ubuntu-24.04
- timeout-minutes: 60
- env:
- DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- steps:
- - name: Checkout Source Code
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
-
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
-
- - name: Setup Gradle
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
-
- - name: Get Git Hashes
- run: |
- echo "short_hash=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- echo "long_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- id: git_hashes
-
- - name: Build the Apache Fineract image
- run: |
- TAGS=${{ github.ref_name }}
- if [ "${{ github.ref_name }}" == "develop" ]; then
- TAGS="$TAGS,${{ steps.git_hashes.outputs.short_hash }},${{ steps.git_hashes.outputs.long_hash }}"
- fi
- ./gradlew --no-daemon --console=plain :fineract-provider:jib -x test -x cucumber \
- -Djib.to.auth.username=${{secrets.DOCKERHUB_USER}} \
- -Djib.to.auth.password=${{secrets.DOCKERHUB_TOKEN}} \
- -Djib.from.platforms=linux/amd64,linux/arm64 \
- -Djib.to.image=apache/fineract \
- -Djib.to.tags=$TAGS
diff --git a/.github/workflows/smoke-messaging.yml b/.github/workflows/smoke-messaging.yml
deleted file mode 100644
index d94d988275..0000000000
--- a/.github/workflows/smoke-messaging.yml
+++ /dev/null
@@ -1,62 +0,0 @@
-name: Fineract Messaging Smoke Tests
-
-on: [push, pull_request]
-
-permissions:
- contents: read
-
-jobs:
- smoke-test:
- name: Smoke Test with ${{ matrix.messaging }}
- runs-on: ubuntu-24.04
- timeout-minutes: 60
- strategy:
- fail-fast: false
- matrix:
- include:
- - messaging: ActiveMQ
- compose_file: docker-compose-postgresql-activemq.yml
- - messaging: Kafka
- compose_file: docker-compose-postgresql-kafka.yml
-
- env:
- DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- IMAGE_NAME: fineract
-
- steps:
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
-
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
-
- - name: Setup Gradle
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
-
- - name: Build the image
- run: ./gradlew --no-daemon --console=plain :fineract-provider:jibDockerBuild -Djib.to.image=$IMAGE_NAME -x test -x cucumber
-
- - name: Start the ${{ matrix.messaging }} Stack
- run: docker compose -f ${{ matrix.compose_file }} up --scale fineract-worker=1 -d
-
- - name: Check the stack
- run: docker ps
-
- - name: Check health Manager
- run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
-
- - name: Check health Worker1
- run: curl -f -k --retry 60 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/health
-
- - name: Check info Manager
- run: (( $(curl -f -k --retry 5 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/info | wc --chars) > 100 ))
-
- - name: Check info Worker1
- run: (( $(curl -f -k --retry 5 --retry-all-errors --connect-timeout 30 --retry-delay 30 https://localhost:8444/fineract-provider/actuator/info | wc --chars) > 100 ))
-
- - name: Run Smoke Test with Remote COB
- run: ./gradlew --no-daemon --console=plain :integration-tests:cleanTest :integration-tests:test --tests "org.apache.fineract.integrationtests.investor.externalassetowner.InitiateExternalAssetOwnerTransferTest.saleActiveLoanToExternalAssetOwnerAndBuybackADayLater" -PcargoDisabled
diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml
deleted file mode 100644
index a12a559596..0000000000
--- a/.github/workflows/sonarqube.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: Fineract Sonarqube
-on:
- push:
- branches:
- - develop
-permissions:
- contents: read
-jobs:
- build:
- runs-on: ubuntu-24.04
- timeout-minutes: 60
- env:
- TZ: Asia/Kolkata
- SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }}
- SONAR_PROJECT_KEY: ${{ secrets.SONAR_PROJECT_KEY }}
- SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}
- DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- JAVA_BINARIES: .
- steps:
- - name: Checkout
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- with:
- fetch-depth: 0
- - name: Set up JDK 21
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v4
- with:
- java-version: '21'
- distribution: 'zulu'
- - name: Setup Gradle and Validate Wrapper
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- with:
- validate-wrappers: true
- - name: Build
- run: ./gradlew --no-daemon --console=plain :fineract-provider:build -x test -x cucumber
- - name: Sonar
- run: ./gradlew --no-daemon --console=plain -Dsonar.verbose=true -Dsonar.token=$SONAR_TOKEN -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.java.binaries=$JAVA_BINARIES --info --stacktrace sonar
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
deleted file mode 100644
index e6fb9696b5..0000000000
--- a/.github/workflows/stale.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-# https://github.com/marketplace/actions/close-stale-issues
-# https://github.com/actions/stale/blob/master/action.yml
-# https://github.com/actions/stale
-name: Mark stale issues and pull requests
-on:
- schedule:
- - cron: "0 0 * * *"
-permissions:
- contents: read
-jobs:
- stale:
- permissions:
- issues: write # for actions/stale to close stale issues
- pull-requests: write # for actions/stale to close stale PRs
- runs-on: ubuntu-latest
- timeout-minutes: 60
- steps:
- - uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v9
- with:
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- # stale-issue-message: 'Stale issue message'
- # stale-issue-label: 'no-issue-activity'
- stale-pr-message: 'This pull request seems to be stale. Are you still planning to work on it? We will automatically close it in 30 days.'
- stale-pr-label: 'stale'
- days-before-stale: 30
- days-before-close: 30