FINERACT-1470: Fineract release plugin

This commit is contained in:
Aleksandar Vidakovic
2022-05-04 15:11:53 +02:00
committed by Aleksandar Vidakovic
parent b185937962
commit 40eb547a5c
160 changed files with 4954 additions and 638 deletions
@@ -0,0 +1,28 @@
= Email
Official communication related to releases needs to be done with an Apache email address. The Apache Foundation doesn't provide any real email inboxes anymore and just relays emails to your configured private account (GMail etc.).
IMPORTANT: At the moment we are supporting only GMail accounts. Please let us know if you have other configuration recipes for other email providers.
== GMail
You can configure your GMail account and add another profile to use the Apache relay server if you need to send official messages. Please follow these instructions:
TBD.
See also: https://gmail.googleblog.com/2009/07/send-mail-from-another-address-without.html[Send mail from another address without "on behalf of"]
To be able to send emails via SMTP with your GMail account you probably need to create an app password. Please follow these instructions:
1. Go to your Google Account.
1. Select Security.
1. Under "Signing in to Google," select App Passwords. You may need to sign in. If you don't have this option, it might be because:
1. 2-Step Verification is not set up for your account.
1. 2-Step Verification is only set up for security keys.
1. Your account is through work, school, or other organization.
1. You turned on Advanced Protection.
1. At the bottom, choose Select app and choose the app you using and then Select device and choose the device you're using and then Generate.
1. Follow the instructions to enter the App Password. The App Password is the 16-character code in the yellow bar on your device.
1. Tap Done.
See also: https://support.google.com/accounts/answer/185833?p=InvalidSecondFactor&visit_id=637856439524128323-869822459&rd=1[Google Support: Sign in with App Passwords] for more details.
@@ -0,0 +1,225 @@
= GPG
Generate GPG key pairs if you don't already have them and publish them. Please use your Apache email address when creating your GPG keypair. If you already have configured GPG and associated your keypair with a non-Apache email address then please consider creating a separate one just for all things related to Fineract (or Apache in general).
Instructions:
1. Check your GPG version:
+
.Input GPG version
[source,bash]
----
gpg --version
----
+
.Output GPG version
[source,bash]
----
gpg (GnuPG) 2.2.27
libgcrypt 1.9.4
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
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
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.
1. Generate your GPG key pair:
+
.Input generate GPG key pair
[source,bash]
----
gpg --full-gen-key
----
+
.Output generate GPG key pair (step 1: key type selection)
[source,bash]
----
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)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(14) Existing key from card
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.
+
.Output generate GPG key pair (step 3: validity selection)
[source,bash]
----
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>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]
----
Key expires at Sun 16 Apr 2024 08:10:24 PM UTC
Is this correct? (y/N)y
----
+
Confirm if everything is correct.
+
.Output generate GPG key pair (step 5: provide user details)
[source,bash]
----
GnuPG needs to construct a user ID to identify your key.
Real name: Aleksandar Vidakovic
Email address: aleks@apache.org
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]
----
You selected this USER-ID:
"Aleksandar Vidakovic <aleks@apache.org>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
----
+
Select `Okay`.
+
After the selection of your user ID GPG will ask for a passphrase to protect your private key. Maybe time to open your password manager and generate a secure one and save it in your vault. Once you've confirmed your password GPG will start to generate your keys.
+
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]
----
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
disks) during the prime generation; this gives the random number
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]
----
gpg: key 7890ABCD marked as ultimately trusted <1>
gpg: directory '/home/aleks/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/aleks/.gnupg/openpgp-revocs.d/ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCD.rev' <2>
public and secret key created and signed.
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>
Key fingerprint = ABCD EFGH IJKL MNOP QRST UVWX YZ12 3456 7890 ABCD <4>
uid [ultimate] Aleksandar Vidakovic <aleks@apache.org> <5>
sub rsa2048/4FGHIJ56 2022-04-16 [] [expires: 2024-04-16]
----
+
<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.
+
<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.
+
<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.
<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.
+
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.
1. Export your public key:
+
[source,bash]
----
gpg --armor --export aleks@apache.org > pubkey.asc
----
1. Export Your Private Key:
+
[source,bash]
----
gpg --export-secret-keys --armor aleks@apache.org > privkey.asc
----
1. Protect Your Private Key and Revocation Certificate
+
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 posession 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:
+
[source,bash]
----
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]
----
keyserver hkp://keyserver.ubuntu.com/
----
+
Alternatively you can provide the keyserver whith the send command:
+
[source,bash]
----
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:
+
[source,bash]
----
gpg --armor --export aleks@apache.org
----
+
Output:
+
[source,bash]
----
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBF8iGq0BEADGRqeSsOoNDc1sV3L9sQ34KhmoQrACnMYGztx33TD98aWplul+
jm8uGtMmBus4DJJJap1bVQ1oMehw2mscmDHpfJjLNZ/q+vUqbExx1/CER7XvLryN
<--- snip --->
2nHBuBftxDRpDHQ+O5XYwSDSTDMmthPjx0vJGBH4K1kO8XK99e01A6/oYLV2SMKp
gXXeWjafxBmHT1cM8hoBZBYzgTu9nK5UnllWunfaHXiCBG4oQQ==
=85/F
-----END PGP PUBLIC KEY BLOCK-----
----
+
@@ -0,0 +1,38 @@
= Gradle
TBD
== User Properties
There are a couple of properties that contain committer/release manager related secrets. Please add the following properties to your personal global Gradle properties (you will find them at `~/.gradle/gradle.properties` in your home folder).
[source,properties]
----
fineract.config.gnupg.keyName=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCD<1>
fineract.config.gnupg.password=******
fineract.config.gnupg.publicKeyring=~/.gnupg/pubring.kbx<2>
fineract.config.gnupg.secretKeyring=~/.gnupg/secring.gpg
fineract.config.smtp.username=aleks@gmail.com <3>
fineract.config.smtp.password=******
fineract.config.name=Aleksandar Vidakovic
fineract.config.email=aleks@apache.org
fineract.config.username=aleks <4>
fineract.config.password=******
----
<1> Make sure you use the full GPG key name (you can list yours via `gpg --list-secret-keys --keyid-format=long`)
<2> GnuPG has it's own kbx format to store the public key ring. At the moment we are only supporting this format
<3> Currently we only have instructions for GMail
<4> Apache committer credentials
CAUTION: **Never** add any personal secrets in the project gradle.properties. Double check that you are not accidentally committing them to Git!
== Release Plugin
Creating Apache Fineract releases was a very manual and tedious procedure before we created the Gradle release plugin. It was easy - even with documentation - to forget a detail. Some ideas are borrowed from the excellent https://jreleaser.org[JReleaser] tool. Unfortunately at the moment we can't use it for the full release process. Being an Apache project we have certain requirements that are not fully covered by https://jreleaser.org[JReleaser].
=== Release Plugin Configuration
[source,groovy]
----
include::{rootdir}/buildSrc/src/main/groovy/org.apache.fineract.release.gradle[lines=32..105]
----
@@ -0,0 +1,37 @@
= Secrets
TBD
== Infrastructure Team
A couple of secrets for third party services are automatically configured by the infrastructure team at The Apache Foundation for the Fineract Github account. At the moment this includes environment variables for:
* Github token (e. g. to publish Github Pages, use the Github API in Github Actions)
* Docker Hub token (to publish our Docker images)
* Sonar Cloud token (for our code quality reports)
See also:
* https://infra.apache.org/github-pages.html
* https://cwiki.apache.org/confluence/display/INFRA/Github+Actions+to+DockerHub
* https://github.com/apache/jmeter-site-preview
* https://github.com/apache/fineract-site
* https://github.com/apache/systemds-website/blob/main/.asf.yaml
== Lastpass
It seems that Apache has some kind of org account or similar. Popped up a couple of times in the infrastructure documentation.
TBD
== 1Password
Other Fineract development related secrets, e. g. for deployments of demo systems on Google Cloud, AWS etc. are managed in a team account at 1Password. At the moment the following committers are members of the 1Password team account:
* mailto:edcable@apache.org[Ed Cable]
* mailto:vorburger@apache.org[Michael Vorburger]
* mailto:ptuomola@apache.org[Petri Tuomola]
* mailto:arnold@apache.org[Arnold Galovics]
* mailto:aleks@apache.org[Aleksandar Vidakovic]
NOTE: If you need access or have any questions related to those secrets then please reach out to one of the team members.
@@ -0,0 +1,20 @@
= Configuration
Before you can start using the Fineract release plugin to create releases you have to configure and setup a couple of things first.
* All official communication concerning releases happens on the mailto:dev@fineract.apache.org[mailing list]. Every release manager needs to be a member of and engaging on the mailing list for credibility.
* Make sure you have edit permissions on the https://cwiki.apache.org/confluence/display/FINERACT[Apache Confluence Wiki]
* You need full permissions on https://issues.apache.org/jira[Apache JIRA] to be able to move issues to the next release
* Git committer privileges to be allowed to create tags and the release branch
* Familiarity with building Fineract locally and creating release distributions is required
* You need to be a member of the PMC to be able to upload release artifacts; this task can be delegated though
* A general Familiarity with PGP/GPG is recommended (at least to setup your keypairs), but the release plugin does most of the heavy lifting
* Make sure to read the release plugin documentation for troubleshooting
include::configuration-secrets.adoc[leveloffset=+1]
include::configuration-gpg.adoc[leveloffset=+1]
include::configuration-email.adoc[leveloffset=+1]
include::configuration-gradle.adoc[leveloffset=+1]
@@ -0,0 +1,13 @@
= Releases
https://cwiki.apache.org/confluence/x/DRwIB[How to Release Apache Fineract] documents the process how we make the source code that is available here in this Git repository into a binary release tar.gz available on http://fineract.apache.org.
.Release Schedule
[plantuml, format=svg]
----
include::{diagramsdir}/release-schedule.puml[]
----
include::configuration.adoc[leveloffset=+1]
include::process.adoc[leveloffset=+1]
@@ -0,0 +1,26 @@
= Step 1: Heads-Up Email
== Description
The RM should, if one doesn't already exist, first create a new release umbrella issue in JIRA. This issue is dedicated to tracking (a summary of) any discussion related to the planned new release. An example of such an issue is FINERACT-873 - Release Apache Fineract v1.4.0 RESOLVED.
The RM then creates an list of resolved issues & features through an initial check in JIRA for already resolved issues for the release, and then setup a timeline for release branch point. The time for the day the issue list is created to the release branch point must be at least two weeks in order to give the community a chance to prioritize and commit any last minute features and issues they would like to see in the upcoming release.
The RM must then send the pointer to the umbrella issue along with the tentative timeline for branch point to the developer lists. Any work identified as release related that needs to be completed should be added as a sub tasks of the umbrella issue to allow all developers and users to see the overall release progress in one place. The umbrella issue shall also link to any issues still requiring clarification whether or not they will make it into the release.
The RM should then inform users when the git branch is planned to be created, by sending an email based on this template:
[source,text]
----
include::{rootdir}/buildSrc/src/main/resources/email/release.step01.headsup.subject.ftl[]
include::{rootdir}/buildSrc/src/main/resources/email/release.step01.headsup.message.ftl[]
----
== Gradle Task
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep1 -Pfineract.release.issue=1234 -Pfineract.release.date="Monday, April 25, 2022" -Pfineract.release.version={revnumber}
----
@@ -0,0 +1,34 @@
= Step 2: Clean Up JIRA
== Description
Before a release is done, make sure that any issues that are fixed have their fix version setup correctly.
[source,text]
----
project = FINERACT and resolution = fixed and fixVersion is empty
----
Move all unresolved JIRA issues which have this release as Fix Version to the next release
[source,text,subs="attributes"]
----
project = FINERACT and fixVersion = {revnumber} and status not in ( Resolved, Done, Accepted, Closed )
----
You can also run the following query to make sure that the issues fixed for the to-be-released version look accurate:
[source,text,subs="attributes"]
----
project = FINERACT and fixVersion = {revnumber}
----
Finally, check out the output of the JIRA release note tool to see which tickets are included in the release, in order to do a sanity check.
== Gradle Task
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep2 -Pfineract.release.version={revnumber}
----
CAUTION: This task is not yet automated!
@@ -0,0 +1,56 @@
= Step 3: Create Release Branch
== Description
Communicate with the community. You do not need to start a new email thread on the developer mailing list to notify that you are about to branch, just do it ca. 2 weeks after the initial email, or later, based on the discussion on the initial email.
You do not need to ask committers to hold off any commits until you have branched finished, as it's always possible to fast-forward the branch to latest develop, or cherry-pick last minute changes to it. People should be able to continue working on the develop branch on bug fixes and great new features for the next release while the release process for the current release is being worked through.
1. Clone fresh repository copy
+
[source,bash]
----
% git clone git@github.com:apache/fineract.git
% cd fineract
----
1. 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>
----
<1> Check current branch history. HEAD should point to commit that you want to be base for your release branch
1. Create a new release branch with name "$Version"
+
[source,bash,subs="attributes"]
----
% git checkout -b {revnumber}
----
1. Push new branch to Apache Fineract repository
+
[source,bash,subs="attributes"]
----
% git push origin {revnumber}
----
1. 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.
1. Send en email announcing the new release branch on the earlier email thread
+
[source,text]
----
include::{rootdir}/buildSrc/src/main/resources/email/release.step03.branch.subject.ftl[]
include::{rootdir}/buildSrc/src/main/resources/email/release.step03.branch.message.ftl[]
----
== Gradle Task
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep3 -Pfineract.release.date="Monday, May 10, 2022" -Pfineract.release.version={revnumber}
----
@@ -0,0 +1,15 @@
= Step 4: Freeze JIRA
== Description
You first need to close the release in JIRA so that the about to be released version cannot be used as "fixVersion" for new bugs anymore. Go to JIRA "Administer project" page and follow "Versions" in left menu. Table with list of all releases should appear, click on additional menu on the right of your release and choose "Release" option. Submit release date and you're done.
== Gradle Task
.Command
[source,bash]
----
% ./gradlew fineractReleaseStep4
----
CAUTION: This task is not yet automated!
@@ -0,0 +1,24 @@
= Step 5: Create Release Tag
== Description
Next, you create a git tag from the HEAD of the release's git branch.
[source,bash,subs="attributes"]
----
% git checkout {revnumber}
% ./gradlew clean integrationTests <1>
% git tag -a {revnumber} -m "Fineract {revnumber} release"
% git push origin {revnumber}
----
<1> Run additonally manual tests with the community app.
CAUTION: It is important to create so called annotated tags (vs. lightweight) for releases.
== Gradle Task
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep5 -Pfineract.release.version={revnumber}
----
@@ -0,0 +1,39 @@
= Step 6: Create Distribution
== Description
Create source and binary artifacts. Make sure to do some sanity checks. The tar and the release branch should match.
[source,bash,subs="attributes"]
----
% cd /fineract-release-preparations <1>
% tar -xvf apache-fineract-{revnumber}-src.tar.gz
% git clone https://git-wip-us.apache.org/repos/asf/fineract.git
% cd fineract/
% git checkout tags/{revnumber}
% cd ..
% diff -r fineract apache-fineract-{revnumber}-src
----
<1> Do a fresh clone of the tag.
Make sure code compiles and tests pass on the uncompressed source.
[source,bash,subs="attributes"]
----
% cd apache-fineract-{revnumber}-src/fineract-provider <1>
% gradlew clean integrationTest <2>
% gradlew clean build <3>
% gradlew rat <4>
----
<1> Make sure prerequisites are met before running these commands.
<2> For running integration tests
<3> For building deploy able war
<4> For RAT checks
== Gradle Task
.Command
[source,bash]
----
% ./gradlew fineractReleaseStep6
----
@@ -0,0 +1,23 @@
= Step 7: Sign Distribution
== Description
All release artifacts must be signed. In order to sign a release you will need a PGP key. You should get your key signed by a few other people. You will also need to receive their keys from a public key server. See the Apache release signing page for more details. Please follow the steps defined in Release Sign.
[source,bash,subs="attributes"]
----
% gpg --armor --output apache-fineract-{revnumber}-src.tar.gz.asc --detach-sig apache-fineract-{revnumber}-src.tar.gz
% gpg --print-md MD5 apache-fineract-{revnumber}-src.tar.gz > apache-fineract-{revnumber}-src.tar.gz.md5
% gpg --print-md SHA512 apache-fineract-{revnumber}-src.tar.gz > apache-fineract-{revnumber}-src.tar.gz.sha512
% gpg --armor --output apache-fineract-{revnumber}--binary.tar.gz.asc --detach-sig apache-fineract-{revnumber}-binary.tar.gz
% gpg --print-md MD5 apache-fineract-{revnumber}-binary.tar.gz > apache-fineract-{revnumber}-binary.tar.gz.md5
% gpg --print-md SHA512 apache-fineract-{revnumber}-binary.tar.gz > apache-fineract-{revnumber}-binary.tar.gz.sha512
----
== Gradle Task
.Command
[source,bash]
----
% ./gradlew fineractReleaseStep7
----
@@ -0,0 +1,34 @@
= Step 8: Upload Distribution Staging
== Description
Finally create a directory with release name ({revnumber} in this example) in https://dist.apache.org/repos/dist/dev/fineract and add the following files in this new directory:
* apache-fineract-{revnumber}-binary.tar.gz.sha
* apache-fineract-{revnumber}-binary.tar.gz
* apache-fineract-{revnumber}-binary.tar.gz.asc
* apache-fineract-{revnumber}-binary.tar.gz.md5
* apache-fineract-{revnumber}-src.tar.gz.sha
* apache-fineract-{revnumber}-src.tar.gz
* apache-fineract-{revnumber}-src.tar.gz.asc
* apache-fineract-{revnumber}-src.tar.gz.md5
Upload binary and source archives 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 fineract/build/distributions/* fineract-dist-dev/{revnumber}/
% svn commit
----
NOTE: You will need your ASF Committer credentials to be able to access the Subversion host https://dist.apache.org via.
== Gradle Task
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep8 -Pfineract.release.version={revnumber}
----
@@ -0,0 +1,26 @@
= Step 9: Verify Distribution Staging
== Description
Following are the typical things we need to verify before voting on a release candidate. And the release manager should verify them too before calling out a vote.
Make sure release artifacts are hosted at https://dist.apache.org/repos/dist/dev/fineract
* Release candidates should be in format apache-fineract-{revnumber}-binary.tar.gz
* Verify signatures and hashes. You may have to import the public key of the release manager to verify the signatures. (`gpg --recv-key <key id>`)
* Git tag matches the released bits (diff -rf)
* Can compile successfully from source
* 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
== Gradle Task
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep9 -Pfineract.release.version={revnumber}
----
CAUTION: This task is not yet automated!
@@ -0,0 +1,20 @@
= Step 10: Start Vote
== Description
Voting has to be done on dev@fineract.apache.org. You can close the vote after voting period expires (72 hours) and you accumulate sufficient votes (minimum 3 x +1 PMC votes).
[source,text]
----
include::{rootdir}/buildSrc/src/main/resources/email/release.step10.vote.subject.ftl[]
include::{rootdir}/buildSrc/src/main/resources/email/release.step10.vote.message.ftl[]
----
== Gradle Task
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep10 -Pfineract.release.version={revnumber}
----
@@ -0,0 +1,20 @@
= Step 11: Finish Vote
== Description
Upon receiving 3 x +1 from the PMC, or after 72 hours (whichever one comes first), reply to the voting thread and add the prefix "[RESULT]" to the subject line with the results, as follows:
[source,text]
----
include::{rootdir}/buildSrc/src/main/resources/email/release.step11.vote.subject.ftl[]
include::{rootdir}/buildSrc/src/main/resources/email/release.step11.vote.message.ftl[]
----
== Gradle Task
.Command
[source,text,subs="attributes"]
----
% ./gradlew fineractReleaseStep11 -Pfineract.release.version={revnumber}
----
@@ -0,0 +1,24 @@
= Step 12: Upload Distribution Release
== Description
In order to release you have to checkout release repository located on https://dist.apache.org/repos/dist/release/fineract and add release artifacts there.
[source,bash,subs="attributes"]
----
% svn co https://dist.apache.org/repos/dist/release/fineract fineract-release
% mkdir fineract-release/{revnumber}/
% cp fineract-dist-dev/{revnumber}/* fineract-release/{revnumber}/
% svn add fineract-release/{revnumber}/
% svn commit -m "Fineract Release {revnumber}" fineract-release/{revnumber}/
----
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
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep12 -Pfineract.release.version={revnumber}
----
@@ -0,0 +1,29 @@
= Step 13: Close Release Branch
== 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:
[source,bash,subs="attributes"]
----
% 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
----
<1> Manually resolve merge conflicts, if any
== Gradle Task
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep13 -Pfineract.release.version={revnumber}
----
CAUTION: This task is not yet automated!
@@ -0,0 +1,18 @@
= Step 14: Update website
== Description
Finally update the https://fineract.apache.org website with the latest release details. The website's HTML source code is available at https://github.com/apache/fineract-site.
CAUTION: This step is not yet updated. We are working on a static site generator setup.
== Gradle Task
.Command
[source,bash]
----
% ./gradlew fineractReleaseStep14 <1>
----
<1> Currently doing nothing. Will trigger in the future the static site generator and publish on Github.
CAUTION: This task is not yet automated!
@@ -0,0 +1,20 @@
= Step 15: Announcement Email
== Description
Send an email to announce@apache.org (sender address must be @apache.org):
[source,text]
----
include::{rootdir}/buildSrc/src/main/resources/email/release.step15.announce.subject.ftl[]
include::{rootdir}/buildSrc/src/main/resources/email/release.step15.announce.message.ftl[]
----
== Gradle Task
.Command
[source,bash,subs="attributes"]
----
% ./gradlew fineractReleaseStep15 -Pfineract.release.version={revnumber}
----
@@ -0,0 +1,47 @@
= Release Process
TODO:
* create "Jira anchor ticket" with all issues linked that are going into this release.
* maintenance: continuously update the "Jira anchor ticket" to make sure we catch all ticket changes
* maintenance: list tickets that have discrepancies, e. g. tickets still open while associated PR merged, ticket on wrong version (i. e. associated PR already merged before with another release).
TBD
CAUTION: Consider the Gradle plugin commands an experimental feature!
.Release Process Diagram
[plantuml,format=svg]
----
include::{diagramsdir}/release-process.puml[]
----
include::process-step01.adoc[leveloffset=+1]
include::process-step02.adoc[leveloffset=+1]
include::process-step03.adoc[leveloffset=+1]
include::process-step04.adoc[leveloffset=+1]
include::process-step05.adoc[leveloffset=+1]
include::process-step06.adoc[leveloffset=+1]
include::process-step07.adoc[leveloffset=+1]
include::process-step08.adoc[leveloffset=+1]
include::process-step09.adoc[leveloffset=+1]
include::process-step10.adoc[leveloffset=+1]
include::process-step11.adoc[leveloffset=+1]
include::process-step12.adoc[leveloffset=+1]
include::process-step13.adoc[leveloffset=+1]
include::process-step14.adoc[leveloffset=+1]
include::process-step15.adoc[leveloffset=+1]