diff --git a/.github/actions/create-release-notes/action.yml b/.github/actions/create-release-notes/action.yml
new file mode 100644
index 000000000..dce0e7be5
--- /dev/null
+++ b/.github/actions/create-release-notes/action.yml
@@ -0,0 +1,56 @@
+name: 'Create Release Notes'
+description: 'Creates the current releases release notes'
+inputs:
+ tag-name:
+ description: 'Name of the tag that will be used for this release'
+ required: true
+ gh-token:
+ description: 'The GitHub token used to get details from the API'
+ required: true
+runs:
+ using: 'composite'
+ steps:
+ - name: Get Previous Release Tag
+ uses: actions/github-script@v7
+ id: latest-release-tag
+ with:
+ github-token: ${{ inputs.gh-token }}
+ result-encoding: string
+ script: |
+ const { data } = await github.rest.repos.getLatestRelease({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ })
+ return data.tag_name
+ - name: Get Generated Release Notes
+ uses: actions/github-script@v7
+ id: generate-notes
+ with:
+ github-token: ${{ inputs.gh-token }}
+ result-encoding: string
+ script: |
+ const { data } = await github.rest.repos.generateReleaseNotes({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ tag_name: '${{ inputs.tag-name }}',
+ target_commitish: 'dev',
+ previous_tag_name: '${{ steps.latest-release-tag.outputs.result }}',
+ })
+ return data.body.replaceAll('`', '\'').replaceAll('"', '\'')
+ - name: Generate Release Notes
+ id: version-generator
+ shell: bash
+ run: |
+ mkdir -p ./app/build/outputs/
+
+ echo "Previous Release Tag:"
+ echo "${{ steps.latest-release-tag.outputs.result }}"
+
+ echo "Full Changelog:"
+ CHANGELOG="${{ steps.generate-notes.outputs.result }}"
+ echo -e "$CHANGELOG"
+ printf "$CHANGELOG" > ./mifospay/build/outputs/changelogGithub
+
+ echo "Beta Changelog:"
+ git log --format="* %s" HEAD^..HEAD
+ git log --format="* %s" HEAD^..HEAD > ./mifospay/build/outputs/changelogBeta
diff --git a/.github/actions/create-release-number/action.yml b/.github/actions/create-release-number/action.yml
new file mode 100644
index 000000000..d9d16cf61
--- /dev/null
+++ b/.github/actions/create-release-number/action.yml
@@ -0,0 +1,27 @@
+name: 'Create Release Numbers'
+description: 'Creates the current release number based on checked out code'
+outputs:
+ version-code:
+ description: 'The numeric app version'
+ value: ${{ steps.version-generator.outputs.version-code }}
+ version:
+ description: 'The app version'
+ value: ${{ steps.version-generator.outputs.version }}
+runs:
+ using: 'composite'
+ steps:
+ - name: Set Build Number
+ id: version-generator
+ shell: bash
+ run: |
+ ./gradlew versionFile
+ COMMITS=`git rev-list --count HEAD`
+ TAGS=`git tag | grep -v beta | wc -l`
+ VC=$((((COMMITS+TAGS) * 3) << 1))
+ echo Number Commits $COMMITS
+ echo Number Tags $TAGS
+ echo Version Code $VC
+ echo "version-code=$VC" >> $GITHUB_OUTPUT
+ VERSION=`cat version.txt`
+ echo Version $VERSION
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
diff --git a/.github/actions/inflate-secrets/action.yml b/.github/actions/inflate-secrets/action.yml
new file mode 100644
index 000000000..d9a013eda
--- /dev/null
+++ b/.github/actions/inflate-secrets/action.yml
@@ -0,0 +1,41 @@
+name: 'Inflate Secrets'
+description: 'Inflates the secret values into the appropriate files'
+inputs:
+ keystore:
+ description: 'The keystore to inflate'
+ required: true
+ google-services:
+ description: 'The google-services.json to inflate'
+ required: true
+ playstore-creds:
+ description: 'The playstore credentials to inflate'
+ required: true
+runs:
+ using: 'composite'
+ steps:
+ - name: Mock debug google-services.json
+ shell: bash
+ run: |
+ cp .github/mock-google-services.json mifospay/src/demo/google-services.json
+ cp .github/mock-google-services.json mifospay/src/prod/google-services.json
+
+ - name: Inflate release_keystore.keystore
+ shell: bash
+ env:
+ KEYSTORE: ${{ inputs.keystore }}
+ run: |
+ echo $KEYSTORE | base64 --decode > mifospay/release_keystore.keystore
+
+ - name: Inflate google-services.json
+ shell: bash
+ env:
+ GOOGLE_SERVICES: ${{ inputs.google-services }}
+ run: |
+ echo $GOOGLE_SERVICES > mifospay/google-services.json
+
+ - name: Inflate playStorePublishServiceCredentialsFile.json
+ shell: bash
+ env:
+ CREDS: ${{ inputs.playstore-creds }}
+ run: |
+ echo $CREDS > mifospay/playStorePublishServiceCredentialsFile.json
diff --git a/.github/mock-google-services.json b/.github/mock-google-services.json
new file mode 100644
index 000000000..2f054dffe
--- /dev/null
+++ b/.github/mock-google-services.json
@@ -0,0 +1,63 @@
+{
+ "project_info": {
+ "project_number": "project_number",
+ "firebase_url": "firebase_url",
+ "project_id": "project_id",
+ "storage_bucket": "storage_bucket"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "mobilesdk_app_id",
+ "android_client_info": {
+ "package_name": "org.mifospay"
+ }
+ },
+ "api_key": [
+ {
+ "current_key": "current_key"
+ }
+ ]
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "mobilesdk_app_id",
+ "android_client_info": {
+ "package_name": "org.mifospay.demo.debug"
+ }
+ },
+ "api_key": [
+ {
+ "current_key": "current_key"
+ }
+ ]
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "mobilesdk_app_id",
+ "android_client_info": {
+ "package_name": "org.mifospay.demo"
+ }
+ },
+ "api_key": [
+ {
+ "current_key": "current_key"
+ }
+ ]
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "mobilesdk_app_id",
+ "android_client_info": {
+ "package_name": "org.mifospay.debug"
+ }
+ },
+ "api_key": [
+ {
+ "current_key": "current_key"
+ }
+ ]
+ }
+ ],
+ "configuration_version": "1"
+}
diff --git a/.github/workflows/monthly.yaml b/.github/workflows/monthly.yaml
new file mode 100644
index 000000000..9f173e9ed
--- /dev/null
+++ b/.github/workflows/monthly.yaml
@@ -0,0 +1,21 @@
+name: Bump our Calendar Version
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: '30 3 1 * *'
+jobs:
+ tag:
+ name: Tag Monthly Release
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Get Current Time
+ uses: josStorer/get-current-time@v2.1.2
+ id: current-time
+
+ - name: Bump Calendar Version
+ uses: rickstaa/action-create-tag@v1.7.2
+ with:
+ tag: ${{ steps.current-time.outputs.year }}.${{ steps.current-time.outputs.month }}.0
diff --git a/.github/workflows/onPush.yml b/.github/workflows/onPush.yml
new file mode 100644
index 000000000..791b679e2
--- /dev/null
+++ b/.github/workflows/onPush.yml
@@ -0,0 +1,154 @@
+name: On Push
+
+on:
+ workflow_dispatch:
+ inputs:
+ beta:
+ description: 'true if this is a beta release'
+ required: false
+ default: 'false'
+ push:
+ branches:
+ - master
+
+env:
+ SUPPLY_UPLOAD_MAX_RETRIES: 5
+
+jobs:
+ app_build:
+ name: Github, Firebase, and Sentry Release
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4.2.2
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.2'
+ bundler-cache: true
+
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
+
+ - uses: ./.github/actions/create-release-number
+ name: Create Release Number
+ id: rel_number
+
+ - uses: ./.github/actions/inflate-secrets
+ name: Inflate Secrets
+ with:
+ keystore: ${{ secrets.ORIGINAL_KEYSTORE_FILE }}
+ google-services: ${{ secrets.GOOGLESERVICES }}
+ playstore-creds: ${{ secrets.PLAYSTORECREDS }}
+
+ - uses: ./.github/actions/create-release-notes
+ name: Create Release Notes
+ with:
+ tag-name: ${{ steps.rel_number.outputs.version }}
+ gh-token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Build Release
+ env:
+ KEYSTORE_PASSWORD: ${{ secrets.ORIGINAL_KEYSTORE_FILE_PASSWORD }}
+ KEYSTORE_ALIAS: ${{ secrets.ORIGINAL_KEYSTORE_ALIAS }}
+ KEYSTORE_ALIAS_PASSWORD: ${{ secrets.ORIGINAL_KEYSTORE_ALIAS_PASSWORD }}
+ VERSION_CODE: ${{ steps.rel_number.outputs.version-code }}
+ run: |
+ ./gradlew :mifospay:assembleRelease
+
+ - name: Archive Build
+ uses: actions/upload-artifact@v4
+ with:
+ path: ./**/*.apk
+
+ - name: Create Version File
+ if: github.event.inputs.beta == 'true'
+ shell: bash
+ env:
+ VERSION_CODE: ${{ steps.rel_number.outputs.version-code }}
+ run: |
+ echo $VERSION_CODE > ./app/build/outputs/version_code.txt
+
+ - name: Create Github Pre-Release
+ if: github.event.inputs.beta == 'true'
+ uses: softprops/action-gh-release@v2.0.8
+ with:
+ tag_name: ${{ steps.rel_number.outputs.version }}
+ body_path: ./app/build/outputs/changelogGithub
+ draft: false
+ prerelease: true
+ files: |
+ ./mifospay/build/outputs/apk/demo/release/mifospay-demo-release.apk
+ ./mifospay/build/outputs/apk/prod/release/mifospay-prod-release.apk
+ ./mifospay/build/outputs/version_code.txt
+
+ - name: Print `git status`
+ run: git status
+
+ play_publish:
+ name: Play Publish
+ runs-on: ubuntu-latest
+ concurrency:
+ group: playstore_deploy
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4.2.2
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.2'
+ bundler-cache: true
+
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
+
+ - uses: ./.github/actions/create-release-number
+ name: Create Release Number
+ id: rel_number
+
+ - uses: ./.github/actions/inflate-secrets
+ name: Inflate Secrets
+ with:
+ keystore: ${{ secrets.UPLOAD_KEYSTORE_FILE }}
+ google-services: ${{ secrets.GOOGLESERVICES }}
+ playstore-creds: ${{ secrets.PLAYSTORECREDS }}
+
+ - uses: ./.github/actions/create-release-notes
+ name: Create Release Notes
+ with:
+ tag-name: ${{ steps.rel_number.outputs.version }}
+ gh-token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Build Release
+ env:
+ KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_FILE_PASSWORD }}
+ KEYSTORE_ALIAS: ${{ secrets.UPLOAD_KEYSTORE_ALIAS }}
+ KEYSTORE_ALIAS_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_ALIAS_PASSWORD }}
+ VERSION_CODE: ${{ steps.rel_number.outputs.version-code }}
+ run: |
+ ./gradlew :mifospay:bundleRelease
+
+ - name: Deploy to Playstore Internal
+ run: bundle exec fastlane deploy_internal
+
+ - name: Promote Internal to Beta
+ if: github.event.inputs.beta == 'true'
+ run: bundle exec fastlane promote_to_beta
diff --git a/.github/workflows/release_to_production.yml b/.github/workflows/release_to_production.yml
new file mode 100644
index 000000000..347ccc4ba
--- /dev/null
+++ b/.github/workflows/release_to_production.yml
@@ -0,0 +1,31 @@
+name: Production Deploy
+
+on:
+ workflow_dispatch:
+ release:
+ types: [ released ]
+
+env:
+ SUPPLY_UPLOAD_MAX_RETRIES: 5
+
+jobs:
+ play_promote_production:
+ name: Play Publish Production
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.2'
+ bundler-cache: true
+
+ - uses: ./.github/actions/inflate-secrets
+ name: Inflate Secrets
+ with:
+ keystore: ${{ secrets.ORIGINAL_KEYSTORE_FILE }}
+ google-services: ${{ secrets.GOOGLESERVICES }}
+ playstore-creds: ${{ secrets.PLAYSTORECREDS }}
+
+ - name: Promote Beta to Production Play Store
+ run: bundle exec fastlane promote_to_production
diff --git a/.github/workflows/weekly.yaml b/.github/workflows/weekly.yaml
new file mode 100644
index 000000000..2e5281576
--- /dev/null
+++ b/.github/workflows/weekly.yaml
@@ -0,0 +1,39 @@
+name: Tag Weekly Release
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: '0 4 * * 0'
+jobs:
+ tag:
+ name: Tag Weekly Release
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4.2.2
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+
+ - name: Tag Weekly Release
+ env:
+ GITHUB_TOKEN: ${{ secrets.TAG_PUSH_TOKEN }}
+ run: ./gradlew :reckonTagPush -Preckon.stage=final
+
+ - name: Trigger Workflow
+ uses: actions/github-script@v7
+ with:
+ script: |
+ github.rest.actions.createWorkflowDispatch({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ workflow_id: 'onPush.yml',
+ ref: 'master',
+ inputs: {
+ "beta": "true",
+ },
+ })
diff --git a/.gitignore b/.gitignore
index 1696ea9b4..510626127 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,3 +55,14 @@ app/manifest-merger-release-report.txt
# Exclude Google services from prod flavour
mifospay/src/prod/google-services.json
+
+#*.keystore
+
+version.txt
+
+firebaseAppDistributionServiceCredentialsFile.json
+playStorePublishServiceCredentialsFile.json
+
+# Ruby stuff we don't care about
+.bundle/
+vendor/
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 000000000..1e4d11c03
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,6 @@
+source "https://rubygems.org"
+
+gem "fastlane"
+
+plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
+eval_gemfile(plugins_path) if File.exist?(plugins_path)
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 000000000..fe069a866
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,219 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ CFPropertyList (3.0.7)
+ base64
+ nkf
+ rexml
+ addressable (2.8.7)
+ public_suffix (>= 2.0.2, < 7.0)
+ artifactory (3.0.17)
+ atomos (0.1.3)
+ aws-eventstream (1.3.0)
+ aws-partitions (1.971.0)
+ aws-sdk-core (3.203.0)
+ aws-eventstream (~> 1, >= 1.3.0)
+ aws-partitions (~> 1, >= 1.651.0)
+ aws-sigv4 (~> 1.9)
+ jmespath (~> 1, >= 1.6.1)
+ aws-sdk-kms (1.89.0)
+ aws-sdk-core (~> 3, >= 3.203.0)
+ aws-sigv4 (~> 1.5)
+ aws-sdk-s3 (1.160.0)
+ aws-sdk-core (~> 3, >= 3.203.0)
+ aws-sdk-kms (~> 1)
+ aws-sigv4 (~> 1.5)
+ aws-sigv4 (1.9.1)
+ aws-eventstream (~> 1, >= 1.0.2)
+ babosa (1.0.4)
+ base64 (0.2.0)
+ claide (1.1.0)
+ colored (1.2)
+ colored2 (3.1.2)
+ commander (4.6.0)
+ highline (~> 2.0.0)
+ declarative (0.0.20)
+ digest-crc (0.6.5)
+ rake (>= 12.0.0, < 14.0.0)
+ domain_name (0.6.20240107)
+ dotenv (2.8.1)
+ emoji_regex (3.2.3)
+ excon (0.111.0)
+ faraday (1.10.3)
+ faraday-em_http (~> 1.0)
+ faraday-em_synchrony (~> 1.0)
+ faraday-excon (~> 1.1)
+ faraday-httpclient (~> 1.0)
+ faraday-multipart (~> 1.0)
+ faraday-net_http (~> 1.0)
+ faraday-net_http_persistent (~> 1.0)
+ faraday-patron (~> 1.0)
+ faraday-rack (~> 1.0)
+ faraday-retry (~> 1.0)
+ ruby2_keywords (>= 0.0.4)
+ faraday-cookie_jar (0.0.7)
+ faraday (>= 0.8.0)
+ http-cookie (~> 1.0.0)
+ faraday-em_http (1.0.0)
+ faraday-em_synchrony (1.0.0)
+ faraday-excon (1.1.0)
+ faraday-httpclient (1.0.1)
+ faraday-multipart (1.0.4)
+ multipart-post (~> 2)
+ faraday-net_http (1.0.2)
+ faraday-net_http_persistent (1.2.0)
+ faraday-patron (1.0.0)
+ faraday-rack (1.0.0)
+ faraday-retry (1.0.3)
+ faraday_middleware (1.2.0)
+ faraday (~> 1.0)
+ fastimage (2.3.1)
+ fastlane (2.222.0)
+ CFPropertyList (>= 2.3, < 4.0.0)
+ addressable (>= 2.8, < 3.0.0)
+ artifactory (~> 3.0)
+ aws-sdk-s3 (~> 1.0)
+ babosa (>= 1.0.3, < 2.0.0)
+ bundler (>= 1.12.0, < 3.0.0)
+ colored (~> 1.2)
+ commander (~> 4.6)
+ dotenv (>= 2.1.1, < 3.0.0)
+ emoji_regex (>= 0.1, < 4.0)
+ excon (>= 0.71.0, < 1.0.0)
+ faraday (~> 1.0)
+ faraday-cookie_jar (~> 0.0.6)
+ faraday_middleware (~> 1.0)
+ fastimage (>= 2.1.0, < 3.0.0)
+ gh_inspector (>= 1.1.2, < 2.0.0)
+ google-apis-androidpublisher_v3 (~> 0.3)
+ google-apis-playcustomapp_v1 (~> 0.1)
+ google-cloud-env (>= 1.6.0, < 2.0.0)
+ google-cloud-storage (~> 1.31)
+ highline (~> 2.0)
+ http-cookie (~> 1.0.5)
+ json (< 3.0.0)
+ jwt (>= 2.1.0, < 3)
+ mini_magick (>= 4.9.4, < 5.0.0)
+ multipart-post (>= 2.0.0, < 3.0.0)
+ naturally (~> 2.2)
+ optparse (>= 0.1.1, < 1.0.0)
+ plist (>= 3.1.0, < 4.0.0)
+ rubyzip (>= 2.0.0, < 3.0.0)
+ security (= 0.1.5)
+ simctl (~> 1.6.3)
+ terminal-notifier (>= 2.0.0, < 3.0.0)
+ terminal-table (~> 3)
+ tty-screen (>= 0.6.3, < 1.0.0)
+ tty-spinner (>= 0.8.0, < 1.0.0)
+ word_wrap (~> 1.0.0)
+ xcodeproj (>= 1.13.0, < 2.0.0)
+ xcpretty (~> 0.3.0)
+ xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
+ fastlane-plugin-increment_version_code (0.4.3)
+ gh_inspector (1.1.3)
+ google-apis-androidpublisher_v3 (0.54.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-core (0.11.3)
+ addressable (~> 2.5, >= 2.5.1)
+ googleauth (>= 0.16.2, < 2.a)
+ httpclient (>= 2.8.1, < 3.a)
+ mini_mime (~> 1.0)
+ representable (~> 3.0)
+ retriable (>= 2.0, < 4.a)
+ rexml
+ google-apis-iamcredentials_v1 (0.17.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-playcustomapp_v1 (0.13.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-storage_v1 (0.31.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-cloud-core (1.7.1)
+ google-cloud-env (>= 1.0, < 3.a)
+ google-cloud-errors (~> 1.0)
+ google-cloud-env (1.6.0)
+ faraday (>= 0.17.3, < 3.0)
+ google-cloud-errors (1.4.0)
+ google-cloud-storage (1.47.0)
+ addressable (~> 2.8)
+ digest-crc (~> 0.4)
+ google-apis-iamcredentials_v1 (~> 0.1)
+ google-apis-storage_v1 (~> 0.31.0)
+ google-cloud-core (~> 1.6)
+ googleauth (>= 0.16.2, < 2.a)
+ mini_mime (~> 1.0)
+ googleauth (1.8.1)
+ faraday (>= 0.17.3, < 3.a)
+ jwt (>= 1.4, < 3.0)
+ multi_json (~> 1.11)
+ os (>= 0.9, < 2.0)
+ signet (>= 0.16, < 2.a)
+ highline (2.0.3)
+ http-cookie (1.0.7)
+ domain_name (~> 0.5)
+ httpclient (2.8.3)
+ jmespath (1.6.2)
+ json (2.7.2)
+ jwt (2.8.2)
+ base64
+ mini_magick (4.13.2)
+ mini_mime (1.1.5)
+ multi_json (1.15.0)
+ multipart-post (2.4.1)
+ nanaimo (0.3.0)
+ naturally (2.2.1)
+ nkf (0.2.0)
+ optparse (0.5.0)
+ os (1.1.4)
+ plist (3.7.1)
+ public_suffix (6.0.1)
+ rake (13.2.1)
+ representable (3.2.0)
+ declarative (< 0.1.0)
+ trailblazer-option (>= 0.1.1, < 0.2.0)
+ uber (< 0.2.0)
+ retriable (3.1.2)
+ rexml (3.3.7)
+ rouge (2.0.7)
+ ruby2_keywords (0.0.5)
+ rubyzip (2.3.2)
+ security (0.1.5)
+ signet (0.19.0)
+ addressable (~> 2.8)
+ faraday (>= 0.17.5, < 3.a)
+ jwt (>= 1.5, < 3.0)
+ multi_json (~> 1.10)
+ simctl (1.6.10)
+ CFPropertyList
+ naturally
+ terminal-notifier (2.0.0)
+ terminal-table (3.0.2)
+ unicode-display_width (>= 1.1.1, < 3)
+ trailblazer-option (0.1.2)
+ tty-cursor (0.7.1)
+ tty-screen (0.8.2)
+ tty-spinner (0.9.3)
+ tty-cursor (~> 0.7)
+ uber (0.1.0)
+ unicode-display_width (2.5.0)
+ word_wrap (1.0.0)
+ xcodeproj (1.25.0)
+ CFPropertyList (>= 2.3.3, < 4.0)
+ atomos (~> 0.1.3)
+ claide (>= 1.0.2, < 2.0)
+ colored2 (~> 3.1)
+ nanaimo (~> 0.3.0)
+ rexml (>= 3.3.2, < 4.0)
+ xcpretty (0.3.0)
+ rouge (~> 2.0.7)
+ xcpretty-travis-formatter (1.0.1)
+ xcpretty (~> 0.2, >= 0.0.7)
+
+PLATFORMS
+ x64-mingw-ucrt
+
+DEPENDENCIES
+ fastlane
+ fastlane-plugin-increment_version_code
+
+BUNDLED WITH
+ 2.5.18
diff --git a/build.gradle.kts b/build.gradle.kts
index 064849ef6..455b4e37b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -34,4 +34,11 @@ plugins {
alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.wire) apply false
+}
+
+tasks.register("versionFile").configure {
+ group = "publishing"
+ doLast {
+ File(projectDir, "version.txt").writeText(project.version.toString())
+ }
}
\ No newline at end of file
diff --git a/fastlane/AppFile b/fastlane/AppFile
new file mode 100644
index 000000000..d85271893
--- /dev/null
+++ b/fastlane/AppFile
@@ -0,0 +1,2 @@
+json_key_file("") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
+package_name(ENV["STAGING_PACKAGE_NAME"]) # e.g. org.mifospay.demo
\ No newline at end of file
diff --git a/fastlane/FastFile b/fastlane/FastFile
new file mode 100644
index 000000000..00428123f
--- /dev/null
+++ b/fastlane/FastFile
@@ -0,0 +1,60 @@
+default_platform(:android)
+
+platform :android do
+ desc "Deploy internal tracks to Google Play"
+ lane :deploy_internal do
+ supply(
+ track: 'internal',
+ aab: 'app/build/outputs/bundle/prod/app-prod-release.aab',
+ skip_upload_metadata: true,
+ skip_upload_images: true,
+ skip_upload_screenshots: true,
+ )
+ end
+
+ desc "Promote internal tracks to beta on Google Play"
+ lane :promote_to_beta do
+ supply(
+ track: 'internal',
+ track_promote_to: 'beta',
+ skip_upload_changelogs: true,
+ skip_upload_metadata: true,
+ skip_upload_images: true,
+ skip_upload_screenshots: true,
+ )
+ end
+
+ desc "Promote beta tracks to production on Google Play"
+ lane :promote_to_production do
+ supply(
+ track: 'beta',
+ track_promote_to: 'production',
+ skip_upload_changelogs: true,
+ sync_image_upload: true,
+ )
+ end
+
+ desc "Prep Amazon Appstore submission"
+ lane :prep_amazon do
+ amazon_app_submission(
+ client_id: ENV["AMAZON_APPSTORE_CLIENT_ID"],
+ client_secret: ENV["AMAZON_APPSTORE_CLIENT_SECRET"],
+ app_id: ENV["AMAZON_APPSTORE_APP_ID"],
+ apk_path: "app/build/outputs/apk/prod/release/app-prod-release.apk",
+ upload_apk: true,
+ changelogs_path: "fastlane/metadata/android/en-US/changelogs/",
+ upload_changelogs: true,
+ submit_for_review: false
+ )
+ end
+
+ desc "Submit to Amazon Appstore"
+ lane :submit_amazon do
+ amazon_app_submission(
+ client_id: ENV["AMAZON_APPSTORE_CLIENT_ID"],
+ client_secret: ENV["AMAZON_APPSTORE_CLIENT_SECRET"],
+ app_id: ENV["AMAZON_APPSTORE_APP_ID"],
+ submit_for_review: true
+ )
+ end
+end
\ No newline at end of file
diff --git a/fastlane/PluginFile b/fastlane/PluginFile
new file mode 100644
index 000000000..32ea0b1fb
--- /dev/null
+++ b/fastlane/PluginFile
@@ -0,0 +1,5 @@
+# Autogenerated by fastlane
+#
+# Ensure this file is checked in to source control!
+
+gem 'fastlane-plugin-increment_version_code'
\ No newline at end of file
diff --git a/mifospay/build.gradle.kts b/mifospay/build.gradle.kts
index ef519cd2b..4460c2e83 100644
--- a/mifospay/build.gradle.kts
+++ b/mifospay/build.gradle.kts
@@ -9,6 +9,16 @@
*/
import org.mifospay.MifosBuildType
+/*
+ * Copyright 2024 Mifos Initiative
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See https://github.com/openMF/mobile-wallet/blob/master/LICENSE.md
+ */
+
plugins {
alias(libs.plugins.mifospay.android.application)
alias(libs.plugins.mifospay.android.application.compose)
@@ -21,29 +31,39 @@ plugins {
android {
namespace = "org.mifospay"
+
defaultConfig {
applicationId = "org.mifospay"
- versionCode = 1
- versionName = "1.0"
+ versionName = project.version.toString()
+ versionCode = System.getenv("VERSION_CODE")?.toIntOrNull() ?: 1
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
+
+ signingConfigs {
+ create("release") {
+ storeFile = file(System.getenv("KEYSTORE_PATH") ?: "release_keystore.keystore")
+ storePassword = System.getenv("KEYSTORE_PASSWORD") ?: "Mifospay"
+ keyAlias = System.getenv("KEYSTORE_ALIAS") ?: "key0"
+ keyPassword = System.getenv("KEYSTORE_ALIAS_PASSWORD") ?: "Mifos@123"
+ enableV1Signing = true
+ enableV2Signing = true
+ }
+ }
+
buildTypes {
debug {
- // applicationIdSuffix = MifosBuildType.DEBUG.applicationIdSuffix
+ applicationIdSuffix = MifosBuildType.DEBUG.applicationIdSuffix
}
+
release {
isMinifyEnabled = true
- // applicationIdSuffix = MifosBuildType.RELEASE.applicationIdSuffix
- proguardFiles(
- getDefaultProguardFile("proguard-android-optimize.txt"),
- "proguard-rules.pro"
- )
-
- // To publish on the Play store a private signing key is required, but to allow anyone
- // who clones the code to sign and run the release variant, use the debug signing key.
- // TODO: Abstract the signing configuration to a separate file to avoid hardcoding this.
- signingConfig = signingConfigs.getByName("debug")
+ applicationIdSuffix = MifosBuildType.RELEASE.applicationIdSuffix
+ isShrinkResources = true
+ isDebuggable = false
+ isJniDebuggable = false
+ signingConfig = signingConfigs.getByName("release")
+ proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
@@ -57,6 +77,7 @@ android {
excludes.add("/META-INF/{AL2.0,LGPL2.1}")
}
}
+
testOptions {
unitTests {
isIncludeAndroidResources = true
@@ -146,4 +167,4 @@ dependencyGuard {
modules = true
tree = true
}
-}
+}
\ No newline at end of file
diff --git a/mifospay/google-services.json b/mifospay/google-services.json
index 585a9d112..9a4001bd2 100644
--- a/mifospay/google-services.json
+++ b/mifospay/google-services.json
@@ -9,7 +9,7 @@
"client_info": {
"mobilesdk_app_id": "1:728434912738:android:49282a75468730891a1dbb",
"android_client_info": {
- "package_name": "org.mifos.pisp.android"
+ "package_name": "org.mifospay"
}
},
"oauth_client": [
@@ -38,7 +38,7 @@
"client_info": {
"mobilesdk_app_id": "1:728434912738:android:ef7156e455c6a1a41a1dbb",
"android_client_info": {
- "package_name": "org.mifos.pisp.android.debug"
+ "package_name": "org.mifospay.demo.debug"
}
},
"oauth_client": [
@@ -67,7 +67,7 @@
"client_info": {
"mobilesdk_app_id": "1:728434912738:android:0490c291986f0a691a1dbb",
"android_client_info": {
- "package_name": "org.mifospay"
+ "package_name": "org.mifospay.debug"
}
},
"oauth_client": [
diff --git a/mifospay/prodRelease-badging.txt b/mifospay/prodRelease-badging.txt
index 88d68cddf..8cdf267e8 100644
--- a/mifospay/prodRelease-badging.txt
+++ b/mifospay/prodRelease-badging.txt
@@ -1,4 +1,4 @@
-package: name='org.mifospay' versionCode='1' versionName='1.0' platformBuildVersionName='14' platformBuildVersionCode='34' compileSdkVersion='34' compileSdkVersionCodename='14'
+package: name='org.mifospay' versionCode='1' versionName='0.0.1-beta.0.833+20240905T230255Z' platformBuildVersionName='14' platformBuildVersionCode='34' compileSdkVersion='34' compileSdkVersionCodename='14'
sdkVersion:'26'
targetSdkVersion:'34'
uses-permission: name='android.permission.INTERNET'
@@ -115,13 +115,11 @@ application-label-zh-CN:'Mifos Pay'
application-label-zh-HK:'Mifos Pay'
application-label-zh-TW:'Mifos Pay'
application-label-zu:'Mifos Pay'
-application-icon-120:'res/mipmap/ic_launcher.png'
application-icon-160:'res/mipmap/ic_launcher.png'
application-icon-240:'res/mipmap/ic_launcher.png'
application-icon-320:'res/mipmap/ic_launcher.png'
application-icon-480:'res/mipmap/ic_launcher.png'
application-icon-640:'res/mipmap/ic_launcher.png'
-application-icon-65534:'res/mipmap/ic_launcher.png'
application: label='Mifos Pay' icon='res/mipmap/ic_launcher.png'
launchable-activity: name='org.mifospay.MainActivity' label='' icon=''
property: name='android.adservices.AD_SERVICES_CONFIG' resource='res/xml/ga_ad_services_config.xml'
@@ -141,5 +139,5 @@ other-services
supports-screens: 'small' 'normal' 'large' 'xlarge'
supports-any-density: 'true'
locales: '--_--' 'af' 'am' 'ar' 'as' 'az' 'be' 'bg' 'bn' 'bs' 'ca' 'cs' 'da' 'de' 'de-DE' 'el' 'en-AU' 'en-CA' 'en-GB' 'en-IN' 'en-XC' 'eo' 'es' 'es-US' 'et' 'eu' 'fa' 'fi' 'fr' 'fr-CA' 'ga' 'gd' 'gl' 'gu' 'hi' 'hr' 'hu' 'hy' 'in' 'in-ID' 'is' 'it' 'it-IT' 'iw' 'ja' 'jv' 'ka' 'kk' 'km' 'kn' 'ko' 'ku' 'ky' 'lb' 'lo' 'lt' 'lv' 'mk' 'ml' 'mn' 'mr' 'ms' 'my' 'nb' 'ne' 'nl' 'no' 'or' 'pa' 'pl' 'pt' 'pt-BR' 'pt-PT' 'ro' 'ru' 'ru-RU' 'si' 'sk' 'sl' 'so' 'sq' 'sr' 'sr-Latn' 'sv' 'sw' 'ta' 'te' 'th' 'tl' 'tr' 'tr-TR' 'uk' 'ur' 'uz' 'vi' 'zh' 'zh-CN' 'zh-HK' 'zh-TW' 'zu'
-densities: '120' '160' '240' '320' '480' '640' '65534'
+densities: '160' '240' '320' '480' '640'
native-code: 'arm64-v8a' 'armeabi-v7a' 'x86' 'x86_64'
diff --git a/mifospay/release_keystore.keystore b/mifospay/release_keystore.keystore
new file mode 100644
index 000000000..0ba61aef4
Binary files /dev/null and b/mifospay/release_keystore.keystore differ
diff --git a/mifospay/src/main/res/values/splash.xml b/mifospay/src/main/res/values/splash.xml
index c3208953d..9bcf80035 100644
--- a/mifospay/src/main/res/values/splash.xml
+++ b/mifospay/src/main/res/values/splash.xml
@@ -12,13 +12,14 @@
diff --git a/scripts/pre-commit.sh b/scripts/pre-commit.sh
index 9ddd35a29..c49bfe109 100644
--- a/scripts/pre-commit.sh
+++ b/scripts/pre-commit.sh
@@ -37,16 +37,19 @@ run_spotless_checks() {
# Function to run ktlint checks
run_dependency_guard() {
printf "\nš Brace yourself! We're about to generate dependency guard baseline!"
- ./gradlew dependencyGuardBaseline
+ ./gradlew dependencyGuardBaseline > /tmp/dependency-result
KT_EXIT_CODE=$?
if [ ${KT_EXIT_CODE} -ne 0 ]; then
+ cat /tmp/dependency-result
+ rm /tmp/dependency-result
printf "\n*********************************************************************************"
echo " š„ Oh no! Something went wrong! š„"
echo " š” Unable to generate dependency baseline. š ļø"
printf "*********************************************************************************\n"
exit ${KT_EXIT_CODE}
else
+ rm /tmp/dependency-result
echo "š Bravo! Dependency baseline has been generated successfully! Keep rocking that clean code! šš«"
fi
}
@@ -74,16 +77,19 @@ run_detekt_checks() {
# Function to run Version Catalog checks
run_version_catalog_checks() {
echo "\nš Version catalog linter is now analyzing your catalog for potential issues!"
- ./gradlew formatVersionCatalog
+ ./gradlew formatVersionCatalog > /tmp/catalog-result
DETEKT_EXIT_CODE=$?
if [ ${DETEKT_EXIT_CODE} -ne 0 ]; then
+ cat /tmp/catalog-result
+ rm /tmp/catalog-result
echo "\n*********************************************************************************"
echo " š„ Oh no! Version Catalog found issues in the code! Time to fix those issues! š„"
echo " š” Tip: Review the Version Catalog logs to resolve these issues. š ļø"
echo "*********************************************************************************"
exit ${DETEKT_EXIT_CODE}
else
+ rm /tmp/catalog-result
echo "š Fantastic work! Your Version catalog has been formatted successfully šš"
fi
}
diff --git a/scripts/pre-push.sh b/scripts/pre-push.sh
index d2c0f6779..cad5ba9a1 100644
--- a/scripts/pre-push.sh
+++ b/scripts/pre-push.sh
@@ -28,7 +28,9 @@ run_spotless_checks() {
echo " š” Tip: Check the reported issues and fix formatting errors. š ļø"
echo "*********************************************************************************"
echo "š Attempting to apply Spotless formatting fixes..."
- ./gradlew spotlessApply --daemon
+ ./gradlew spotlessApply --daemon > /tmp/spotless-result
+ rm /tmp/spotless-result
+ echo "š Stellar job! Your code is pristine and has passed Spotless's formatting checks without a hitch! Keep shining bright! āØš"
else
rm /tmp/spotless-result
echo "š Stellar job! Your code is pristine and has passed Spotless's formatting checks without a hitch! Keep shining bright! āØš"
@@ -58,36 +60,46 @@ run_detekt_checks() {
# Function to run ktlint checks
run_dependency_guard() {
printf "\nš Brace yourself! We're about to generate dependency guard baseline!"
- ./gradlew dependencyGuard
+ ./gradlew dependencyGuard > /tmp/dependency-result
KT_EXIT_CODE=$?
if [ ${KT_EXIT_CODE} -ne 0 ]; then
+ cat /tmp/dependency-result
+ rm /tmp/dependency-result
printf "\n*********************************************************************************"
echo " š„ Oh no! Something went wrong! š„"
echo " š” Unable to generate dependency baseline. š ļø"
printf "*********************************************************************************\n"
echo "š Attempting to generate dependency baseline again..."
- ./gradlew dependencyGuardBaseline
- else
+ ./gradlew dependencyGuardBaseline > /tmp/dependency-result
+ rm /tmp/dependency-result
echo "š Bravo! Dependency baseline has been generated successfully! Keep rocking that clean code! šš«"
+ else
+ rm /tmp/dependency-result
+ echo "š Bravo! Dependency baseline has been checked successfully! Keep rocking that clean code! šš«"
fi
}
# Function to run Version Catalog checks
run_version_catalog_checks() {
echo "\nš Version catalog linter is now analyzing your catalog for potential issues!"
- ./gradlew checkVersionCatalog
+ ./gradlew checkVersionCatalog > /tmp/catalog-result
DETEKT_EXIT_CODE=$?
if [ ${DETEKT_EXIT_CODE} -ne 0 ]; then
+ cat /tmp/catalog-result
+ rm /tmp/catalog-result
echo "\n*********************************************************************************"
echo " š„ Oh no! Version Catalog found issues in the code! Time to fix those issues! š„"
echo " š” Tip: Review the Version Catalog logs to resolve these issues. š ļø"
echo "*********************************************************************************"
echo "š Attempting to format the Version Catalog again..."
- ./gradlew formatVersionCatalog
- else
+ ./gradlew formatVersionCatalog > /tmp/catalog-result
+ rm /tmp/catalog-result
echo "š Fantastic work! Your Version catalog has been formatted successfully šš"
+ else
+ rm /tmp/catalog-result
+ echo "š Fantastic work! Your Version catalog has been formatted properly šš"
fi
}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 3b96a9751..f43a17c79 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -19,6 +19,16 @@ dependencyResolutionManagement {
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version("0.8.0")
+ id("org.ajoberstar.reckon.settings") version("0.18.3")
+}
+
+extensions.configure {
+ setDefaultInferredScope("patch")
+ stages("beta", "rc", "final")
+ setScopeCalc { java.util.Optional.of(org.ajoberstar.reckon.core.Scope.PATCH) }
+ setScopeCalc(calcScopeFromProp().or(calcScopeFromCommitMessages()))
+ setStageCalc(calcStageFromProp())
+ setTagWriter { it.toString() }
}
rootProject.name = "mobile-wallet"