diff --git a/NOTICE_RELEASE b/NOTICE_RELEASE index 10dfd7f96..083abdfe5 100644 --- a/NOTICE_RELEASE +++ b/NOTICE_RELEASE @@ -1,5 +1,5 @@ Apache Fineract -Copyright 2008-2021 The Apache Software Foundation +Copyright 2008-2025 The Apache Software Foundation This product includes software developed by The Apache Software Foundation (http://www.apache.org/). diff --git a/NOTICE_SOURCE b/NOTICE_SOURCE index 57c087f09..869b39afa 100644 --- a/NOTICE_SOURCE +++ b/NOTICE_SOURCE @@ -1,5 +1,5 @@ Apache Fineract -Copyright 2008-2021 The Apache Software Foundation +Copyright 2008-2025 The Apache Software Foundation This product includes software developed by The Apache Software Foundation (http://www.apache.org/). diff --git a/README.md b/README.md index 5b158a371..5a653ca02 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,8 @@ Additionally, IDEs such as IntelliJ are useful for editing the AsciiDoc source f HTML rendered from the AsciiDoc source files is also available online at . +A release version is derived from source control. The version will include `-SNAPSHOT` unless the current branch looks like a release or release maintenance branch. See `gitVersioning` settings in `build.gradle` for details. + Connection pool configuration ============================= diff --git a/build.gradle b/build.gradle index a8a58ad68..66046387f 100644 --- a/build.gradle +++ b/build.gradle @@ -107,6 +107,10 @@ plugins { id 'net.ltgt.errorprone' version '4.1.0' apply false id 'io.swagger.core.v3.swagger-gradle-plugin' version '2.2.23' apply false id 'com.gorylenko.gradle-git-properties' version '2.4.2' apply false + // can't upgrade to 4.x because of one of these: + // https://github.com/asciidoctor/asciidoctorj-pdf/issues/25 + // https://github.com/jruby/jruby/issues/5573 + // https://github.com/asciidoctor/asciidoctorj-pdf/issues/16 id 'org.asciidoctor.jvm.convert' version '3.3.2' apply false id 'org.asciidoctor.jvm.pdf' version '3.3.2' apply false id 'com.google.cloud.tools.jib' version '3.4.5' apply false diff --git a/buildSrc/src/main/resources/email/release.step03.branch.message.ftl b/buildSrc/src/main/resources/email/release.step03.branch.message.ftl index 0c5665e82..a6f3667b2 100644 --- a/buildSrc/src/main/resources/email/release.step03.branch.message.ftl +++ b/buildSrc/src/main/resources/email/release.step03.branch.message.ftl @@ -24,7 +24,7 @@ Hello everyone, You can continue working and merging PRs to the develop branch for future releases, as always. -The DRAFT release notes are on https://cwiki.apache.org/confluence/display/FINERACT/${project['fineract.release.version']}+-+Apache+Fineract. Does anyone see anything missing? +The DRAFT release notes are on https://cwiki.apache.org/confluence/display/FINERACT/${project['fineract.release.version']}+-+Apache+Fineract . Does anyone see anything missing? Does anyone have any last minutes changes they would like to see cherry-picked to branch ${project['fineract.release.version']}, or are we good go and actually cut the release based on this branch as it is? diff --git a/buildSrc/src/main/resources/email/release.step10.vote.message.ftl b/buildSrc/src/main/resources/email/release.step10.vote.message.ftl index 31d5b36ae..8be7ff5d0 100644 --- a/buildSrc/src/main/resources/email/release.step10.vote.message.ftl +++ b/buildSrc/src/main/resources/email/release.step10.vote.message.ftl @@ -30,7 +30,7 @@ Tagged as ${project['fineract.release.version']} Committer PGP keys, including the release signing key: https://dist.apache.org/repos/dist/dev/fineract/KEYS -Note that this release contains source and binary artifacts. +Note that this release candidate contains source and binary artifacts. This vote will be open for 72 hours: @@ -38,7 +38,7 @@ This vote will be open for 72 hours: [ ] +0 no opinion [ ] -1 disapprove (and reason why) -Please indicate if you are a binding vote (member of the PMC). +Please indicate if you are a binding vote (member of the PMC). Note: PMC members are required to download, compile, and test the artifacts before submitting their +1 vote. Please also indicate with "Tested: YES/NO/PARTIAL" if you have locally built and/or tested these artifacts and/or a clone of the code checked out to the release commit, following the form: diff --git a/buildSrc/src/main/resources/instructions/step13.txt.ftl b/buildSrc/src/main/resources/instructions/step13.txt.ftl index 64f6ff9bc..3a734bc71 100644 --- a/buildSrc/src/main/resources/instructions/step13.txt.ftl +++ b/buildSrc/src/main/resources/instructions/step13.txt.ftl @@ -26,13 +26,9 @@ As discussed in https://issues.apache.org/jira/browse/FINERACT-1154, now that ev and make sure that everything on the release tag is merged to develop and that e.g. git describe works: >> git checkout develop ->> git branch -D ${project['fineract.release.version']} ->> git push origin :${project['fineract.release.version']} ->> git checkout develop ->> git checkout -b merge-${project['fineract.release.version']} ->> git merge -s recursive -Xignore-all-space ${project['fineract.release.version']} ->> git commit ->> git push ->> hub pull-request +>> git merge release/${project['fineract.release.version']} +>> git push origin develop +>> git branch -D release/${project['fineract.release.version']} +>> git push origin :release/${project['fineract.release.version']} [INSTRUCTIONS:END] diff --git a/buildSrc/src/main/resources/instructions/step9.txt.ftl b/buildSrc/src/main/resources/instructions/step9.txt.ftl index 70ddb63cf..5d2cae8d9 100644 --- a/buildSrc/src/main/resources/instructions/step9.txt.ftl +++ b/buildSrc/src/main/resources/instructions/step9.txt.ftl @@ -26,7 +26,7 @@ Following are the typical things we need to verify before voting on a release ca Make sure release artifacts are hosted at https://dist.apache.org/repos/dist/dev/fineract -* Release candidates should be in format apache-fineract-${project['fineract.release.version']}-binary.tar.gz +* Release candidates should be in format apache-fineract-bin-${project['fineract.release.version']}.tar.gz * Verify signatures and hashes. You may have to import the public key of the release manager to verify the signatures. (gpg --import KEYS or gpg --recv-key ) * Git tag matches the released bits (diff -rf) * Can compile docs and code successfully from source diff --git a/fineract-doc/build.gradle b/fineract-doc/build.gradle index 67ce8887d..41710c31b 100644 --- a/fineract-doc/build.gradle +++ b/fineract-doc/build.gradle @@ -19,9 +19,9 @@ apply plugin: 'org.asciidoctor.jvm.convert' apply plugin: 'org.asciidoctor.jvm.pdf' -asciidoctorj { - version = '2.5.3' +// see also: https://asciidoctor.github.io/asciidoctor-gradle-plugin/master/user-guide/ +asciidoctorj { attributes = [ version: "${project.version}", docdate: new Date(), @@ -35,16 +35,23 @@ asciidoctorj { ] modules { - pdf.version '1.6.2' - diagram.version '2.2.1' - epub.version '1.5.1' - // revealjs.version '4.1.0' + diagram.use() } fatalWarnings ~/include file not found|missing callout|image to embed not found or not readable/ fatalWarnings missingIncludes() } +task copyImages(type: Copy) { + from "${projectDir}/src/docs/en/images" + into "${buildDir}/generated/images" +} + +task copyDiagrams(type: Copy) { + from "${projectDir}/src/docs/en/diagrams" + into "${buildDir}/generated/diagrams" +} + asciidoctor { languages 'en' @@ -57,19 +64,11 @@ asciidoctor { logging.captureStandardError LogLevel.INFO + dependsOn copyImages, copyDiagrams + dependsOn(':fineract-client:clean', ':fineract-client:buildAsciidoc') } -task copyImages(type: Copy) { - from "${projectDir}/src/docs/en/images" - into "${buildDir}/generated/images" -} - -task copyDiagrams(type: Copy) { - from "${projectDir}/src/docs/en/diagrams" - into "${buildDir}/generated/diagrams" -} - asciidoctorPdf { languages 'en' diff --git a/fineract-doc/src/docs/en/chapters/architecture/batch-jobs.adoc b/fineract-doc/src/docs/en/chapters/architecture/batch-jobs.adoc index 8a08a7df5..9b920edf3 100644 --- a/fineract-doc/src/docs/en/chapters/architecture/batch-jobs.adoc +++ b/fineract-doc/src/docs/en/chapters/architecture/batch-jobs.adoc @@ -213,7 +213,7 @@ The business steps are configurable through APIs: Retrieving the configuration for a job: -[source] +[source,text] ---- GET /fineract-provider/api/v1/jobs/{jobName}/steps?tenantIdentifier={tenantId} HTTP 200 @@ -235,7 +235,7 @@ HTTP 200 Updating the business step configuration for a job: -[source] +[source,text] ---- PUT /fineract-provider/api/v1/jobs/{jobName}/steps?tenantIdentifier={tenantId} @@ -274,7 +274,7 @@ When the Inline job gets triggered then the corresponding existing job will run Triggering the Inline Loan COB Job: -[source] +[source,text] ---- POST /fineract-provider/api/v1/jobs/LOAN_COB/inline?tenantIdentifier={tenantId} diff --git a/fineract-doc/src/docs/en/chapters/architecture/persistence.adoc b/fineract-doc/src/docs/en/chapters/architecture/persistence.adoc index 75e816d56..320939f64 100644 --- a/fineract-doc/src/docs/en/chapters/architecture/persistence.adoc +++ b/fineract-doc/src/docs/en/chapters/architecture/persistence.adoc @@ -33,22 +33,32 @@ The actual code can be found in the `DatabaseTypeResolver` class. == Tenant database security -The tenant database schema password is stored in the `tenant_server_connections` table in the tenant database. -The password and the read only schema password are encrypted using the `fineract.tenant.master-password` property. -By default, the database property will be encrypted in the first start from a plane text. +The tenant database schema password is stored in the `tenant_server_connections` table in the tenant database. The password and the read only schema password are encrypted using the `fineract.tenant.master-password` property. By default, the database property will be encrypted in the first start from a plain text. When you want to generate a new encrypted password, you can use the `org.apache.fineract.infrastructure.core.service.database.DatabasePasswordEncryptor` class. === Database password encryption usage -``` -java -cp fineract-provider.jar -Dloader.main=org.apache.fineract.infrastructure.core.service.database.DatabasePasswordEncryptor org.springframework.boot.loader.PropertiesLauncher -``` + +[%nowrap,bash] +---- +java -cp fineract-provider.jar \ + -Dloader.main=org.apache.fineract.infrastructure.core.service.database.DatabasePasswordEncryptor \ + org.springframework.boot.loader.PropertiesLauncher \ + \ + +---- For example: -``` -java -cp fineract-provider-0.0.0-48f7e315.jar -Dloader.main=org.apache.fineract.infrastructure.core.service.database.DatabasePasswordEncryptor org.springframework.boot.loader.PropertiesLauncher fineract-master-password fineract-tenant-password + +[%nowrap,text] +---- +java -cp fineract-provider-0.0.0-48f7e315.jar \ + -Dloader.main=org.apache.fineract.infrastructure.core.service.database.DatabasePasswordEncryptor \ + org.springframework.boot.loader.PropertiesLauncher \ + fineract-master-password \ + fineract-tenant-password The encrypted password: VLwGl7vOP/q275ZTku+PNGWnGwW4mzzNHSNaO9Pr67WT5/NZMpBr9tGYYiYsqwL1eRew2jl7O3/N1EFbLlXhSA== -``` +---- == Data-access layer @@ -85,38 +95,38 @@ The switch from Flyway (1.6.x) to Liquibase (1.7.x) was planned to be as smooth === Troubleshooting 1. During upgrade from Fineract 1.5.0 to 1.6.0, Liquibase fails - ++ After dropping the flyway migrations table (schema_version), Liquibase runs its own migrations which fails (in recreating tables which already exist) because we are aiming to re-use DB with existing data from Fineract 1.5.0. - ++ Solution: The latest release version (1.6.0) doesn't have Liquibase at all, it still runs Flyway migrations. Only the develop branch (later to be 1.7.0) got switched to Liquibase. Do not pull the develop before upgrading your instance. - ++ Make sure first you upgrade your instance (aka database schema with Fineract 1.6.0). Then upgrade with the current develop branch. Check if some migration scripts did not run which led to some operations failing due to slight differences in schema. Try with running the missing migrations manually. - ++ Note: develop is considered unstable until released. 2. Upgrading database from MySQL 5.7 as advised to Maria DB 10.6, fails. If we use data from version 18.03.01 it fails to migrate the data. If we use databases running on 1.5.0 release it completes the startup but the system login fails. - ++ Solution: A database upgrade is separate thing to take care of. 3. We are getting `ScehmaUpgradeNeededException: Make sure to upgrade to Fineract 1.6 first and then to a newer version` error while upgrading to `tag 1.6`. - ++ 1.6 version shouldn't include Liquibase. It will only be released after 1.6. Make sure Liquibase is dropping `schema_version` table, as there is no Flyway it is not required. Drop Flyway and use Liquibase for both migrations and database independence. In case, if you still get errors, you can use git SHA `746c589a6e809b33d68c0596930fcaa7338d5270` and Flyway migration will be done to the latest. - ++ ``` TENANT_LATEST_FLYWAY_VERSION = 392; TENANT_LATEST_FLYWAY_SCRIPT_NAME = diff --git a/fineract-doc/src/docs/en/chapters/architecture/reliable-event-framework.adoc b/fineract-doc/src/docs/en/chapters/architecture/reliable-event-framework.adoc index 8a6bdcb10..ea6efe17d 100644 --- a/fineract-doc/src/docs/en/chapters/architecture/reliable-event-framework.adoc +++ b/fineract-doc/src/docs/en/chapters/architecture/reliable-event-framework.adoc @@ -156,7 +156,7 @@ For example the OfficeDataV1 Avro schema looks the following: .`OfficeDataV1.avsc` [%collapsible] ==== -[source,avroschema] +[source,json] ---- include::{rootdir}/fineract-avro-schemas/src/main/avro/office/v1/OfficeDataV1.avsc[] ---- @@ -175,7 +175,7 @@ This implies that for putting a single event message onto a message queue for ex The message schema looks the following: .`MessageV1.avsc` -[source,avroschema] +[source,json] ---- include::{rootdir}/fineract-avro-schemas/src/main/avro/MessageV1.avsc[] ---- @@ -370,7 +370,7 @@ New Avro schemas can be easily created. Just create a new Avro schema file in th === BigDecimal support in Avro schemas Apache Avro by default doesn't support complex types like a BigDecimal. It has to be implemented using a custom snippet like this: -[source,avroschema] +[source,json] ---- include::{rootdir}/fineract-avro-schemas/src/main/resources/avro-templates/bigdecimal.avsc[] ---- @@ -380,7 +380,7 @@ It's a 20 precision and 8 scale BigDecimal. Obviously it's quite challenging to copy-paste this snippet to every single BigDecimal field, so there's a customization in place for Fineract. The type `bigdecimal` is supported natively, and you're free to use it like this: -[source,avroschema] +[source,json] ---- { "default": null, diff --git a/fineract-doc/src/docs/en/chapters/custom/intro.adoc b/fineract-doc/src/docs/en/chapters/custom/intro.adoc index 54ea099a2..ad72bc6ae 100644 --- a/fineract-doc/src/docs/en/chapters/custom/intro.adoc +++ b/fineract-doc/src/docs/en/chapters/custom/intro.adoc @@ -37,6 +37,7 @@ include::{rootdir}/custom/acme/note/service/build.gradle[lines=19..] NOTE: You don't need to edit `settings.gradle` to add your modules/libraries. If you follow above convention they'll get included automatically. + 5. The dependency.gradle file could look something like this: ++ [source,groovy] ---- include::{rootdir}/custom/acme/note/service/dependencies.gradle[lines=19..] diff --git a/fineract-doc/src/docs/en/chapters/release/configuration-gpg.adoc b/fineract-doc/src/docs/en/chapters/release/configuration-gpg.adoc index 9605661f9..d85d07d1a 100644 --- a/fineract-doc/src/docs/en/chapters/release/configuration-gpg.adoc +++ b/fineract-doc/src/docs/en/chapters/release/configuration-gpg.adoc @@ -13,26 +13,25 @@ gpg --version ---- + .Output GPG version -[source,bash] +[source,text] ---- -gpg (GnuPG) 2.2.27 -libgcrypt 1.9.4 -Copyright (C) 2021 Free Software Foundation, Inc. +gpg (GnuPG) 2.4.4 +libgcrypt 1.10.3 +Copyright (C) 2024 g10 Code GmbH License GNU GPL-3.0-or-later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. -Home: /home/aleks/.gnupg +Home: /home/user/.gnupg Supported algorithms: Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256 Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 Compression: Uncompressed, ZIP, ZLIB, BZIP2 - ---- + -CAUTION: The insecure hash algorithm SHA1 is still supported in version 2.2.27. SHA1 is obsolete and you don't want to use it to generate your signature. +CAUTION: The insecure hash algorithm SHA1 is still supported in version 2.4.4. SHA1 is obsolete and you don't want to use it to generate your signature. 2. Generate your GPG key pair: + @@ -43,60 +42,61 @@ gpg --full-gen-key ---- + .Output generate GPG key pair (step 1: key type selection) -[source,bash] +[source,text] ---- -gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc. -This is free software: you are free to change and redistribute it. -There is NO WARRANTY, to the extent permitted by law. - Please select what kind of key you want: - (1) RSA and RSA (default) + (1) RSA and RSA (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) + (9) ECC (sign and encrypt) *default* + (10) ECC (sign only) (14) Existing key from card +Your selection? +---- ++ +Choose the default. ++ +.Output generate GPG key pair (step 2: elliptic curve selection) +[source,text] +---- +Please select which elliptic curve you want: + (1) Curve 25519 *default* + (4) NIST P-384 + (6) Brainpool P-256 Your selection? ---- + -There are four options. The default is to use RSA to create the key pair. Good enough for us. -+ -.Output generate GPG key pair (step 2: key length selection) -[source,bash] ----- -RSA keys may be between 1024 and 4096 bits long. -What keysize do you want? (2048) ----- -+ -The default key length is 2048 bits. 1024 is obsolete and a longer 4096 RSA key will not provide more security than 2048 RSA key. Use the default. +Again, choose the default. + .Output generate GPG key pair (step 3: validity selection) -[source,bash] +[source,text] ---- -Requested keysize is 2048 bits Please specify how long the key should be valid. - 0 = key does not expire - = key expires in n days - w = key expires in n weeks - m = key expires in n months - y = key expires in n years -Key is valid for? (0)2y + 0 = key does not expire + = key expires in n days + w = key expires in n weeks + m = key expires in n months + y = key expires in n years +Key is valid for? (0) 2y ---- + 2 years for the validity of your keys should be fine. You can always update the expiration time later on. + .Output generate GPG key pair (step 4: confirmation) -[source,bash] +[source,text] ---- Key expires at Sun 16 Apr 2024 08:10:24 PM UTC -Is this correct? (y/N)y +Is this correct? (y/N) y ---- + Confirm if everything is correct. + .Output generate GPG key pair (step 5: provide user details) -[source,bash] +[source,text] ---- GnuPG needs to construct a user ID to identify your key. + Real name: Aleksandar Vidakovic Email address: aleks@apache.org Comment: @@ -105,7 +105,7 @@ Comment: Provide your user details for the key. This is important because this information will be included in our key. It's one way of indicating who is owner of this key. The email address is a unique identifier for a person. You can leave Comment blank. + .Output generate GPG key pair (step 6: user ID selection) -[source,bash] +[source,text] ---- You selected this USER-ID: "Aleksandar Vidakovic " @@ -119,7 +119,7 @@ After the selection of your user ID GPG will ask for a passphrase to protect you CAUTION: Don't lose your private key password. You won't be able to unlock and use your private key without it. + .Output generate GPG key pair (step 7: gpg key pair generation) -[source,bash] +[source,text] ---- We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the @@ -130,7 +130,7 @@ generator a better chance to gain enough entropy. Generating the GPG keys will take a while. + .Output generate GPG key pair (step 8: gpg key pair finished) -[source,bash] +[source,text] ---- gpg: key 7890ABCD marked as ultimately trusted <1> gpg: directory '/home/aleks/.gnupg/openpgp-revocs.d' created @@ -141,21 +141,23 @@ gpg: checking the trustdb gpg: marginals needed: 3 completes needed: 1 trust model: PGP gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u gpg: next trustdb check due at 2024-04-16 -pub rsa2048/7890ABCD 2022-04-16 [S] [expires: 2024-04-16] <3> +pub ed25519/7890ABCD 2022-04-16 [SC] [expires: 2024-04-16] <3> Key fingerprint = ABCD EFGH IJKL MNOP QRST UVWX YZ12 3456 7890 ABCD <4> uid [ultimate] Aleksandar Vidakovic <5> -sub rsa2048/4FGHIJ56 2022-04-16 [] [expires: 2024-04-16] +sub cv25519/4FGHIJ56 2022-04-16 [E] [expires: 2024-04-16] <6> ---- + -<1> GPG created a unique identifier in HEX format for your public key. When someone wants to download your public key, they can refer to it either with your email address or this HEX value. +<1> GPG created a unique identifier in hexadecimal format for your public key. When someone wants to download your public key, they can refer to it either with your email address or this hex value. The hex value is sometimes prefixed with `0x` as is commonly done with hexadecimal numbers. + -<2> GPG created a revocation certificate and its directory. You should never share your private key. If your private key is compromised, you need to use your revocation certificate to revoke your key. +<2> GPG created a revocation certificate and its directory. If your private key is compromised, you need to use your revocation certificate to revoke your key. + -<3> The public key is 2048 bits using RSA algorithm and shows the expiration date of 16 Apr 2024. The public key ID `7890ABCD` matches the last 8 bits of key fingerprint. +<3> The public key uses the Ed25519 ECC (Elliptic Curve Cryptography) algorithm and shows the expiration date of 16 Apr 2024. The public key ID `0x7890ABCD` matches the last 8 characters of key fingerprint. The `[SC]` indicates this key is used to sign (prove authorship) and certify (issue subkeys for encryption, signature and authentication operations). <4> The key fingerprint (`ABCD EFGH IJKL MNOP QRST UVWX YZ12 3456 7890 ABCD`) is a hash of your public key. + <5> Your name and your email address are shown with information about the subkey. + +<6> This Curve25519 subkey is used for encryption. ++ Now you can find that there are two files created under ~/.gnupg/private-keys-v1.d/ directory. These two files are binary files with .key extension. 3. Export your public key: @@ -177,7 +179,7 @@ gpg --export-secret-keys --armor aleks@apache.org > privkey.asc Your private key should be kept in a safe place, like an encrypted flash drive. Treat it like your house key. Only you can have it and don't lose it. And you must remember your passphrase, otherwise you can't unlock your private key. + You should protect your revocation certificate. Anyone in possession of your revocation certificate, could immediately revoke your public/private key pair and generate fake ones. - ++ IMPORTANT: Please contact a PMC member to add your GPG public key in Fineract's Subversion repository. This is necessary to be able to validate published releases. 1. Upload your GPG key to a keyserver: @@ -189,7 +191,7 @@ gpg --send-keys ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCD + Before doing this, make sure that your default keyserver is hkp://keyserver.ubuntu.com/. You can do this by changing the default keyserver in ~/.gnupg/dirmngr.conf: + -[source,bash] +[source,text] ---- keyserver hkp://keyserver.ubuntu.com/ ---- @@ -198,7 +200,9 @@ Alternatively you can provide the keyserver with the send command: + [source,bash] ---- -gpg --keyserver 'hkp://keyserver.ubuntu.com:11371' --send-keys ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCD +gpg \ + --keyserver 'hkp://keyserver.ubuntu.com:11371' \ + --send-keys ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCD ---- + Another option to publish your key is to submit an armored public key directly at https://keyserver.ubuntu.com/. You can create the necessary data with this command by providing the email address that you used when you created your key pair: @@ -210,7 +214,7 @@ gpg --armor --export aleks@apache.org + Output: + -[source,bash] +[source,text] ---- -----BEGIN PGP PUBLIC KEY BLOCK----- @@ -222,4 +226,3 @@ gXXeWjafxBmHT1cM8hoBZBYzgTu9nK5UnllWunfaHXiCBG4oQQ== =85/F -----END PGP PUBLIC KEY BLOCK----- ---- -+ diff --git a/fineract-doc/src/docs/en/chapters/release/process-step01.adoc b/fineract-doc/src/docs/en/chapters/release/process-step01.adoc index e4491c22b..b847af602 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step01.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step01.adoc @@ -22,5 +22,5 @@ include::{rootdir}/buildSrc/src/main/resources/email/release.step01.headsup.mess .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep1 -Pfineract.release.issue=1234 -Pfineract.releaseBranch.date="Monday, April 25, 2022" -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep1 -Pfineract.release.issue=1234 -Pfineract.releaseBranch.date="Monday, April 25, 2022" -Pfineract.release.version={revnumber} ---- diff --git a/fineract-doc/src/docs/en/chapters/release/process-step02.adoc b/fineract-doc/src/docs/en/chapters/release/process-step02.adoc index b126d0fa1..22056cd87 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step02.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step02.adoc @@ -28,7 +28,7 @@ Finally, check out the output of the JIRA release note tool to see which tickets .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep2 -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep2 -Pfineract.release.version={revnumber} ---- CAUTION: This task is not yet automated! diff --git a/fineract-doc/src/docs/en/chapters/release/process-step03.adoc b/fineract-doc/src/docs/en/chapters/release/process-step03.adoc index 2d9ead3d1..48e39e5e9 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step03.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step03.adoc @@ -10,30 +10,30 @@ You do not need to ask committers to hold off any commits until you have branche + [source,bash] ---- -% git clone git@github.com:apache/fineract.git -% cd fineract +git clone git@github.com:apache/fineract.git +cd fineract ---- 2. Check that current HEAD points to commit on which you want to base new release branch. Checkout a particular earlier commit if not. + [source,bash] ---- -% git log <1> +git log <1> ---- <1> Check current branch history. HEAD should point to commit that you want to be base for your release branch -3. Create a new release branch with name "$Version" +3. Create a new release branch using the version number + [source,bash,subs="attributes+,+macros"] ---- -% git checkout -b {revnumber} +git checkout -b release/{revnumber} ---- 4. Push new branch to Apache Fineract repository + [source,bash,subs="attributes+,+macros"] ---- -% git push origin {revnumber} +git push origin release/{revnumber} ---- 5. Add new release notes in Release Folders. The change list can be swiped from the JIRA release note tool (use the "text" format for the change log). See JIRA Cleanup above to ensure that the release notes generated by this tool are what you are expecting. @@ -52,5 +52,5 @@ include::{rootdir}/buildSrc/src/main/resources/email/release.step03.branch.messa .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep3 -Pfineract.release.date="Monday, May 10, 2022" -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep3 -Pfineract.release.date="Monday, May 10, 2022" -Pfineract.release.version={revnumber} ---- diff --git a/fineract-doc/src/docs/en/chapters/release/process-step04.adoc b/fineract-doc/src/docs/en/chapters/release/process-step04.adoc index 41dc3cf89..eeb8f47bc 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step04.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step04.adoc @@ -9,7 +9,7 @@ You first need to close the release in JIRA so that the about to be released ver .Command [source,bash] ---- -% ./gradlew fineractReleaseStep4 +./gradlew fineractReleaseStep4 ---- CAUTION: This task is not yet automated! diff --git a/fineract-doc/src/docs/en/chapters/release/process-step05.adoc b/fineract-doc/src/docs/en/chapters/release/process-step05.adoc index 844434ede..9a7a0b77c 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step05.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step05.adoc @@ -6,12 +6,12 @@ Next, you create a git tag from the HEAD of the release's git branch. [source,bash,subs="attributes+,+macros"] ---- -% git checkout {revnumber} -% ./gradlew clean integrationTests <1> -% git tag -a {revnumber} -m "Fineract {revnumber} release" -% git push origin tag {revnumber} +git checkout -b release/{revnumber} <1> +git tag -a {revnumber} -m "Fineract {revnumber} release" -s <2> +git push origin tag {revnumber} ---- -<1> Run additonally manual tests with the community app. +<1> Ensure all tests pass for this commit both in CI and locally. +<2> `-s` is optional but recommended: GPG signatures on tags are useful for trust and integrity. CAUTION: It is important to create so called annotated tags (vs. lightweight) for releases. @@ -20,5 +20,5 @@ CAUTION: It is important to create so called annotated tags (vs. lightweight) fo .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep5 -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep5 -Pfineract.release.version={revnumber} ---- diff --git a/fineract-doc/src/docs/en/chapters/release/process-step06.adoc b/fineract-doc/src/docs/en/chapters/release/process-step06.adoc index 89378d18b..d967baba7 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step06.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step06.adoc @@ -4,10 +4,13 @@ Create source and binary tarballs. +// FIXME - clean this up? focus on what commands should actually be run + [source,bash,subs="attributes+"] ---- -% ./gradlew build -x test +./gradlew --rerun-tasks srcDistTar binaryDistTar <1> ---- +<1> The source tarball might not be created if `--rerun-tasks` is omitted. Look in `fineract-war/build/distributions/` for the tarballs. @@ -15,23 +18,34 @@ Make sure to do some sanity checks. The source tarball and the code in the relea [source,bash,subs="attributes+"] ---- -% cd /fineract-release-preparations -% tar -xvf path/to/apache-fineract-src-{revnumber}.tar.gz -% git clone git@github.com:apache/fineract.git -% cd fineract/ -% git checkout tags/{revnumber} -% cd .. -% diff -r fineract apache-fineract-src-{revnumber} +cd /fineract-release-preparations +tar -xvf path/to/apache-fineract-src-{revnumber}.tar.gz +git clone git@github.com:apache/fineract.git +cd fineract/ +git checkout tags/{revnumber} +cd .. +diff -r fineract apache-fineract-src-{revnumber} ---- -Make sure the code compiles and tests pass on the uncompressed source. Do as much testing as you can and share what you did. Ideally you'd build code and docs and run every possible test and check, but https://github.com/apache/fineract/actions[running everything has complex dependencies, caches, and takes many hours]. It is rarely done in practice offline / local / on developer machines. But please, go ahead and run the test and doc tasks, and more! Grab a cup of coffee and run everything you can. See the various builds in `.github/workflows/` and try the same things on your own. We should all hammer on a release candidate as much as we can to see if it breaks and fix it if so. All that of course improves our final release. +// FIXME - add output example -Finally, inspect `apache-fineract-{revnumber}-binary.tar.gz`. Make sure the `fineract-provider-{revnumber}.jar` can be run directly, and the `fineract-provider.war` can be run with Tomcat. +Make sure the code compiles and tests pass on the uncompressed source. Do as much testing as you can and share what you did. Here's the bare minimum check: + +[source,bash,subs="attributes+"] +---- +./gradlew build -x test -x doc +---- + +Ideally you'd build code and docs and run every possible test and check, but https://github.com/apache/fineract/actions[running everything has complex dependencies, caches, and takes many hours]. It is rarely done in practice offline / local / on developer machines. But please, go ahead and run the test and doc tasks, and more! Grab a cup of coffee and run everything you can. See the various builds in `.github/workflows/` and try the same things on your own. We should all hammer on a release candidate as much as we can to see if it breaks and fix it if so. All that of course improves our final release. + +Finally, inspect `apache-fineract-bin-{revnumber}.tar.gz`. Make sure the `fineract-provider-{revnumber}.jar` can be run directly, and the `fineract-provider.war` can be run with Tomcat. == Gradle Task .Command [source,bash] ---- -% ./gradlew fineractReleaseStep6 +./gradlew fineractReleaseStep6 ---- + +CAUTION: This task doesn't work. Build release artifacts manually as indicated above. diff --git a/fineract-doc/src/docs/en/chapters/release/process-step07.adoc b/fineract-doc/src/docs/en/chapters/release/process-step07.adoc index 1d5bd257d..1d47c6794 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step07.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step07.adoc @@ -6,10 +6,17 @@ Release source and binary tarballs must be checksummed and signed. In order to s [source,bash,subs="attributes+,+macros"] ---- -% gpg --armor --output apache-fineract-src-{revnumber}.tar.gz.asc --detach-sig apache-fineract-src-{revnumber}.tar.gz -% gpg --print-md SHA512 apache-fineract-src-{revnumber}.tar.gz > apache-fineract-src-{revnumber}.tar.gz.sha512 -% gpg --armor --output apache-fineract-bin-{revnumber}.tar.gz.asc --detach-sig apache-fineract-bin-{revnumber}.tar.gz -% gpg --print-md SHA512 apache-fineract-bin-{revnumber}.tar.gz > apache-fineract-bin-{revnumber}.tar.gz.sha512 +# sign +gpg --armor --output apache-fineract-src-{revnumber}.tar.gz.asc \ + --detach-sig apache-fineract-src-{revnumber}.tar.gz +gpg --armor --output apache-fineract-bin-{revnumber}.tar.gz.asc \ + --detach-sig apache-fineract-bin-{revnumber}.tar.gz + +# hash +gpg --print-md SHA512 apache-fineract-src-{revnumber}.tar.gz \ + > apache-fineract-src-{revnumber}.tar.gz.sha512 +gpg --print-md SHA512 apache-fineract-bin-{revnumber}.tar.gz \ + > apache-fineract-bin-{revnumber}.tar.gz.sha512 ---- == Gradle Task @@ -17,5 +24,5 @@ Release source and binary tarballs must be checksummed and signed. In order to s .Command [source,bash] ---- -% ./gradlew fineractReleaseStep7 +./gradlew fineractReleaseStep7 ---- diff --git a/fineract-doc/src/docs/en/chapters/release/process-step08.adoc b/fineract-doc/src/docs/en/chapters/release/process-step08.adoc index 0af567e8d..05a73770b 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step08.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step08.adoc @@ -17,11 +17,11 @@ Upload these files to ASF's distribution dev (staging) area: [source,bash,subs="attributes+"] ---- -% svn co https://dist.apache.org/repos/dist/dev/fineract/ fineract-dist-dev -% mkdir fineract-dist-dev/{revnumber} -% cp path/to/files/* fineract-dist-dev/{revnumber}/ -% cd fineract-dist-dev -% svn commit +svn mkdir https://dist.apache.org/repos/dist/dev/fineract/{revnumber} +svn checkout https://dist.apache.org/repos/dist/dev/fineract/{revnumber} +cp path/to/files/* {revnumber}/ +cd {revnumber}/ +svn add * && svn commit ---- NOTE: You will need your ASF Committer credentials to be able to access the Subversion host at `dist.apache.org`. @@ -31,5 +31,7 @@ NOTE: You will need your ASF Committer credentials to be able to access the Subv .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep8 -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep8 -Pfineract.release.version={revnumber} ---- + +CAUTION: This task is inefficient. Follow `svn mkdir` and other manual steps above. diff --git a/fineract-doc/src/docs/en/chapters/release/process-step09.adoc b/fineract-doc/src/docs/en/chapters/release/process-step09.adoc index 9dd65d149..e532f3ad7 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step09.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step09.adoc @@ -13,14 +13,79 @@ Make sure release artifacts are hosted at https://dist.apache.org/repos/dist/dev * Verify DISCLAIMER, NOTICE and LICENSE (year etc) * All files have correct headers (Rat check should be clean - `./gradlew rat`) * No jar files in the source artifacts -* Integration tests should work +* All tests pass both in CI and locally + +=== Artifact verification + +[source,bash,subs="attributes+"] +---- +# source tarball signature and checksum verification steps +# we'll check the source tarball first +version={revnumber} +src=apache-fineract-src-$version.tar.gz + +# upon success: prints "Good signature" and returns successful exit code +# upon failure: prints "BAD signature" and returns error exit code +gpg --verify $src.asc + +# upon success: prints nothing and returns successful exit code +# upon failure: prints checksum differences and returns error exit code +gpg --print-md SHA512 $src | diff - $src.sha512 + +# binary tarball signature and checksum verification steps and outputs are similar +bin=apache-fineract-bin-$version.tar.gz +gpg --verify $bin.asc +gpg --print-md SHA512 $bin | diff - $bin.sha512 +---- + +For folks new to https://www.gnupg.org/[GnuPG], there are a couple things to note. First, if it says the source or binary tarball detached signature is correct, that's great! That's the most important part. + +Second, if you've imported `KEYS` but gpg warns you the key used for signing is not trusted, you can tell gpg you trust the key to squelch the warning. Ideally you meet the alleged key owner in person and check their ID first. Once you trust their identity matches, you then indicate your trust for their key. + +Start with `gpg --edit-key KEYID`, substituting the signing key id for `KEYID`. At the `gpg>` prompt, run the `trust` command and choose `4` (I trust fully). You could also choose `3` (marginal), but do _not_ choose `5` (ultimate). + +TIP: Consider also https://en.wikipedia.org/wiki/Key_signing_party[signing] and https://en.wikipedia.org/wiki/Web_of_trust[uploading] each other's keys. + +=== Build from source + +[source,bash] +---- +tar -xzf $src +cd apache-fineract-src-$version +gradle build -x test -x doc +cd .. +---- + +=== Run from binary + +Before running this you must first start a database server and ensure the `fineract_default` and `fineract_tenant` databases exist. Then: + +[source,bash] +---- +tar -xzf $bin +cd apache-fineract-bin-$version +cat << 'EndOfRcenv' >> rcenv +FINERACT_SERVER_SSL_ENABLED=false +FINERACT_SERVER_PORT=8080 +BACKEND_PROTOCOL=http +BACKEND_PORT=$FINERACT_SERVER_PORT +EndOfRcenv +docker run --rm -it -v "$(pwd):/usr/local/tomcat/webapps" \ + --net=host --env-file=rcenv tomcat:jre21 +---- + +Confirm the following: + +. http://localhost:8080/fineract-provider/actuator/health works +. http://localhost:8080/fineract-provider/actuator/info displays the expected information +. API calls work against http://localhost:8080/fineract-provider/api/v1 == Gradle Task .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep9 -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep9 -Pfineract.release.version={revnumber} ---- CAUTION: This task is not yet automated! diff --git a/fineract-doc/src/docs/en/chapters/release/process-step10.adoc b/fineract-doc/src/docs/en/chapters/release/process-step10.adoc index eb36cdc23..5a1a82a70 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step10.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step10.adoc @@ -16,5 +16,5 @@ include::{rootdir}/buildSrc/src/main/resources/email/release.step10.vote.message .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep10 -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep10 -Pfineract.release.version={revnumber} ---- diff --git a/fineract-doc/src/docs/en/chapters/release/process-step11.adoc b/fineract-doc/src/docs/en/chapters/release/process-step11.adoc index 01134f86b..62aab040e 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step11.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step11.adoc @@ -16,5 +16,5 @@ include::{rootdir}/buildSrc/src/main/resources/email/release.step11.vote.message .Command [source,text,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep11 -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep11 -Pfineract.release.version={revnumber} ---- diff --git a/fineract-doc/src/docs/en/chapters/release/process-step12.adoc b/fineract-doc/src/docs/en/chapters/release/process-step12.adoc index 0cdb8b0f0..0bcc44bdd 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step12.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step12.adoc @@ -6,9 +6,11 @@ Move the release candidate from the dev area to the release area using a Subvers [source,bash,subs="attributes+"] ---- -% svn mv https://dist.apache.org/repos/dist/dev/fineract/{revnumber} https://dist.apache.org/repos/dist/release/fineract/ +svn mv https://dist.apache.org/repos/dist/dev/fineract/{revnumber} https://dist.apache.org/repos/dist/release/fineract/ ---- +NOTE: https://www.apache.org/legal/release-policy.html#upload-ci[This must be done by a Fineract PMC member]. + You will now get an automated email from the Apache Reporter Service (no-reply@reporter.apache.org), subject "Please add your release data for 'fineract'" to add the release data (version and date) to the database on https://reporter.apache.org/addrelease.html?fineract (requires PMC membership). == Gradle Task @@ -16,7 +18,7 @@ You will now get an automated email from the Apache Reporter Service (no-reply@r .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep12 -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep12 -Pfineract.release.version={revnumber} ---- CAUTION: This task is not yet automated! diff --git a/fineract-doc/src/docs/en/chapters/release/process-step13.adoc b/fineract-doc/src/docs/en/chapters/release/process-step13.adoc index 131f1cbad..30f55afcf 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step13.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step13.adoc @@ -2,28 +2,26 @@ == Description -As discussed in https://issues.apache.org/jira/browse/FINERACT-1154[FINERACT-1154], now that everything is final, please do the following to remove the release branch (and just keep the tag), and make sure that everything on the release tag is merged to develop and that e.g. git describe works: +As discussed in https://issues.apache.org/jira/browse/FINERACT-1154[FINERACT-1154], now that everything is final, please do the following to remove the release branch (and just keep the tag), and make sure that everything on the release tag is merged to develop and that e.g. `git describe` works: [source,bash,subs="attributes+,+macros"] ---- -% git checkout develop -% git branch -D {revnumber} -% git push origin :{revnumber} -% git checkout develop -% git checkout -b merge-{revnumber} -% git merge -s recursive -Xignore-all-space {revnumber} <1> -% git commit -% git push $USER -% hub pull-request +git checkout develop +git merge release/{revnumber} <1> +git push origin develop +git branch -D release/{revnumber} +git push origin :release/{revnumber} +git describe <2> ---- -<1> Manually resolve merge conflicts, if any +<1> This merge is necessary for posterity: It's how we're able to preserve and trace lineage from releases to descendent commit. Note this is a traditional merge. This is for simplicity, and is an exception to our otherwise https://github.com/apache/fineract#merge-strategy[flat git commit history]. +<2> The output must refer to the most recent release. For example, if your working copy is checked out to the `develop` branch, the current commit is `0762a012e`, and the latest release tag (28 commits ago) was `1.12.1`, the output of `git describe` would be `1.12.1-28-g0762a012e`. == Gradle Task .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep13 -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep13 -Pfineract.release.version={revnumber} ---- CAUTION: This task is not yet automated! diff --git a/fineract-doc/src/docs/en/chapters/release/process-step14.adoc b/fineract-doc/src/docs/en/chapters/release/process-step14.adoc index eccf77602..a3b444507 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step14.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step14.adoc @@ -11,7 +11,7 @@ CAUTION: This step is not yet automated. We are working on a static site generat .Command [source,bash] ---- -% ./gradlew fineractReleaseStep14 <1> +./gradlew fineractReleaseStep14 <1> ---- <1> Currently doing nothing. Will trigger in the future the static site generator and publish on Github. diff --git a/fineract-doc/src/docs/en/chapters/release/process-step15.adoc b/fineract-doc/src/docs/en/chapters/release/process-step15.adoc index 8ccc7d1e8..4f199a9b0 100644 --- a/fineract-doc/src/docs/en/chapters/release/process-step15.adoc +++ b/fineract-doc/src/docs/en/chapters/release/process-step15.adoc @@ -16,5 +16,5 @@ include::{rootdir}/buildSrc/src/main/resources/email/release.step15.announce.mes .Command [source,bash,subs="attributes+,+macros"] ---- -% ./gradlew fineractReleaseStep15 -Pfineract.release.version={revnumber} +./gradlew fineractReleaseStep15 -Pfineract.release.version={revnumber} ---- diff --git a/fineract-doc/src/docs/en/chapters/security/harden.adoc b/fineract-doc/src/docs/en/chapters/security/harden.adoc index 172da42da..ba1c646aa 100644 --- a/fineract-doc/src/docs/en/chapters/security/harden.adoc +++ b/fineract-doc/src/docs/en/chapters/security/harden.adoc @@ -18,7 +18,7 @@ Also, we recommend you familiarize yourself with the OWASP foundation and the "C In the world of Microfinance or small banking operations (in some geographies), it is possible that you can run Fineract on a private network, or isolated from the internet by being hosted locally and securing all connections. This could involve establishing a VPN with limited ports open, and only accepting connections within that VPN. At the far end of this spectrum, is running it isolated and air-gapped as a backend accounting system, where there is no internet connection on that device. In such scenarios, you are limiting the vectors of attack to just those employees you give access to. You are also limiting the functionality to accounting and basic operations, so this is rarely appropriate. Even in these scenarios, it is important that you establish reviews of logs and accounts on a periodic basis to determine if any internal fraud is occurring. Such things should be part of your operational manual. There are a number of resources available for this topic, please find them online. For Fineract in particular, be mindful of the set up of approvals and and the access you give to each person or role in your organization -=== Running it connected but behind a firewalls +=== Running it connected but behind a firewall It should be clear that running it on the internet directly, without API monitoring and filtering, is a bad idea. This is especially true if your Fineract instance is connected to a payment mechanism of any kind. Imagine an exploit being used to gain access and then to send funds from an account to an outside merchant or bank. An attacker could drain an account before you can detect the issue. And, then it will depend on the payment scheme rules whether any of those funds are recoverable. @@ -46,7 +46,7 @@ There is a way to run those APIs endpoint (re-written but consistent) in a separ === User Education and Training -Educating and training your team is another limb of your organizational cybersecurity defense. Equipped with engaging security awareness training sessions, end-users can be prepared with both knowledge and skills on how to identify potential security threats and react to them. You can get more information from some of the resources offered in the course during CISA Training: https://www.cisa.gov/c +Educating and training your team is another limb of your organizational cybersecurity defense. Equipped with engaging security awareness training sessions, end-users can be prepared with both knowledge and skills on how to identify potential security threats and react to them. You can get more information from some of the resources offered in the course during CISA Training: https://www.cisa.gov === Regular Security Audits and Compliance Checks diff --git a/fineract-doc/src/docs/en/config.adoc b/fineract-doc/src/docs/en/config.adoc index 06eb05e5b..1bc515b5f 100644 --- a/fineract-doc/src/docs/en/config.adoc +++ b/fineract-doc/src/docs/en/config.adoc @@ -1,20 +1,14 @@ :doctype: book -:compat-mode!: -:optimize: printer -:media: printer :compress: -:pdf-page-size: LETTER :experimental: -:pdf-version: 1.8 :page-layout: base :toc-title: Table of Contents :toc: left :toclevels: 2 :icons: font -:source-highlighter: coderay +:source-highlighter: rouge :experimental: :source-language: java -:years: 2015-2024 :lang: en :encoding: utf-8 :linkattrs: diff --git a/fineract-doc/src/docs/en/diagrams/architecture-overview.puml b/fineract-doc/src/docs/en/diagrams/architecture-overview.puml deleted file mode 100644 index febbbf163..000000000 --- a/fineract-doc/src/docs/en/diagrams/architecture-overview.puml +++ /dev/null @@ -1,3 +0,0 @@ -@startuml -Bob -> Alice : Hello -@enduml \ No newline at end of file diff --git a/fineract-doc/src/docs/en/diagrams/release-schedule.puml b/fineract-doc/src/docs/en/diagrams/release-schedule.puml index 32c0c80b2..1939ef287 100644 --- a/fineract-doc/src/docs/en/diagrams/release-schedule.puml +++ b/fineract-doc/src/docs/en/diagrams/release-schedule.puml @@ -1,6 +1,6 @@ @startgantt [Heads up email] lasts 1 day -[Open release branch] lasts 7 day +[Open release branch] lasts 7 days [Prepare distribution for staging] lasts 2 days [Vote for distribution on staging] lasts 3 days [Prepare distribution for release] lasts 2 days