diff --git a/.github/release-drafter-config.yml b/.github/release-drafter-config.yml new file mode 100644 index 000000000..417a84445 --- /dev/null +++ b/.github/release-drafter-config.yml @@ -0,0 +1,16 @@ +name-template: '$RESOLVED_VERSION' + +tag-template: '$RESOLVED_VERSION' + +categories: + - title: 'โญ Features' + label: 'type : feature' + - title: '๐Ÿงน Chores' + label: 'type : chore' + - title: '๐Ÿž Bugs' + label: 'type : bug' + +change-template: '- $TITLE' + +template: | + $CHANGES diff --git a/.github/workflows/draft-new-release.yml b/.github/workflows/draft-new-release.yml new file mode 100644 index 000000000..dd6e4e363 --- /dev/null +++ b/.github/workflows/draft-new-release.yml @@ -0,0 +1,42 @@ +name: Draft new release + +on: + push: + branches: + - main + +permissions: + contents: read + +jobs: + draft_new_release: + permissions: + contents: write + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install Kscript + run: | + curl -s "https://get.sdkman.io" | bash + source "$HOME/.sdkman/bin/sdkman-init.sh" + sdk install kotlin 1.6.21 + sdk install kscript 4.0.3 + echo $PATH >> $GITHUB_PATH + + - name: Get version from the latest commit message + working-directory: scripts + run: | + COMMIT_MESSAGE="${{ github.event.head_commit.message }}" + VERSION=$(kscript get_version.kts "$COMMIT_MESSAGE") + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - name: Draft release + uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + config-name: release-drafter-config.yml + version: ${{ env.VERSION }} diff --git a/.github/workflows/verify_newproject_script.yml b/.github/workflows/verify_newproject_script.yml index 029a85114..247bd29f7 100644 --- a/.github/workflows/verify_newproject_script.yml +++ b/.github/workflows/verify_newproject_script.yml @@ -30,8 +30,14 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - - name: Verify generating new project from RxTemplate - run: ./newproject.sh -t rx -p co.myproject.example -n "MyProjectExampleRx" + - name: Install Kscript + run: | + curl -s "https://get.sdkman.io" | bash + source "$HOME/.sdkman/bin/sdkman-init.sh" + sdk install kotlin 1.6.21 + sdk install kscript 4.0.3 + echo $PATH >> $GITHUB_PATH - name: Verify generating new project from CoroutineTemplate - run: ./newproject.sh -t crt -p co.myproject.example -n "MyProjectExampleCoroutine" + working-directory: scripts + run: kscript new_project.kts package-name=co.myproject.example app-name="My Project" diff --git a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/OkHttpClientModule.kt b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/OkHttpClientModule.kt index 5ecf3c6e0..338d28f6c 100644 --- a/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/OkHttpClientModule.kt +++ b/CoroutineTemplate/app/src/main/java/co/nimblehq/coroutine/di/modules/OkHttpClientModule.kt @@ -7,6 +7,9 @@ import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor +import java.util.concurrent.TimeUnit + +private const val READ_TIME_OUT = 30L @Module @InstallIn(SingletonComponent::class) @@ -18,6 +21,7 @@ class OkHttpClientModule { addInterceptor(HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }) + readTimeout(READ_TIME_OUT, TimeUnit.SECONDS) } }.build() } diff --git a/CoroutineTemplate/buildSrc/src/main/java/Versions.kt b/CoroutineTemplate/buildSrc/src/main/java/Versions.kt index 77cd0c998..50a27c8dd 100644 --- a/CoroutineTemplate/buildSrc/src/main/java/Versions.kt +++ b/CoroutineTemplate/buildSrc/src/main/java/Versions.kt @@ -6,7 +6,7 @@ object Versions { const val ANDROID_TARGET_SDK_VERSION = 30 const val ANDROID_VERSION_CODE = 1 - const val ANDROID_VERSION_NAME = "3.8.0" + const val ANDROID_VERSION_NAME = "3.9.0" // Dependencies (Alphabet sorted) const val ANDROID_COMMON_KTX_VERSION = "0.1.1" diff --git a/CoroutineTemplate/data/build.gradle.kts b/CoroutineTemplate/data/build.gradle.kts index c6b13c214..88f21ba99 100644 --- a/CoroutineTemplate/data/build.gradle.kts +++ b/CoroutineTemplate/data/build.gradle.kts @@ -19,11 +19,14 @@ android { buildTypes { getByName(BuildType.RELEASE) { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + isMinifyEnabled = true + proguardFiles( + getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + ) } getByName(BuildType.DEBUG) { + isMinifyEnabled = false /** * From AGP 4.2.0, Jacoco generates the report incorrectly, and the report is missing * some code coverage from module. On the new version of Gradle, they introduce a new diff --git a/README.md b/README.md index 1444f4264..9adcaeaa2 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,38 @@

- Nimble logo + + + + Nimble logo + +

--- -A collection of templates: - -* **[CoroutineTemplate](https://github.com/nimblehq/android-templates/tree/kotlin/CoroutineTemplate)** -* **[RxJavaTemplate[DEPRECATED]](https://github.com/nimblehq/android-templates/tree/kotlin/RxJavaTemplate)** +Our Android template: **[CoroutineTemplate](https://github.com/nimblehq/android-templates/tree/develop/CoroutineTemplate)** ## Setup 1. Clone or download this repository to your local machine, then extract and open the folder -2. Run `newproject.sh` script to create a new project with the following inputs: - -``` - -h, --help Display this usage message and exit - -t, --template [TEMPLATE] Select template: "rx" - RxJavaTemplate or "crt" - CoroutineTemplate (i.e. rx) - -p, --package-name [PACKAGE_NAME] New package name (i.e. com.example.package) - -n, --app-name [APP_NAME] New app name (i.e. MyApp, "My App") -``` - -Example: -- Init a new project with `RxJavaTemplate` - `./newproject.sh -t rx -p co.myproject.example -n "My Project"` +2. Install [Kscript](https://github.com/holgerbrandl/kscript#installation) +3. Run `kscript new_project.kts` to create a new project with the following arguments: + ``` + package-name= New package name (i.e. com.example.package) + app-name= New app name (i.e. MyApp, "My App") + ``` -- Init a new project with `CoroutineTemplate` - `./newproject.sh -t crt -p co.myproject.example -n "My Project"` + Example: `kscript new_project.kts package-name=co.myproject.example app-name="My Project"` -3. Update `android_version_code` and `android_version_name` - - `RxJavaTemplate[DEPRECATED]/build.gradle` - - `CoroutineTemplate/build.gradle` +4. Update `android_version_code` and `android_version_name` in `CoroutineTemplate/build.gradle` ## About -![Nimble](https://assets.nimblehq.co/logo/dark/logo-dark-text-160.png) + + + + Nimble logo + + This project is maintained and funded by Nimble. diff --git a/docs/Home.md b/docs/Home.md index decdcd818..9aa09a7da 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -2,7 +2,7 @@ Welcome to the android-templates wiki! This repository generates a new project based on our preferences, by running a simple script. -Example: `./newproject.sh -t crt -p co.myproject.example -n "MyProjectExampleCoroutine"` +Example: `kscript new_project.kts package-name=co.myproject.example app-name="My Project"` This script must include all essentials by default, while optional features can be appended with flags. To prevent this repository from becoming a dumping playground, features can be rejected too. @@ -45,4 +45,15 @@ Keep in mind, the features are based on _our team's_ requirements. In case the c Please note that the above examples are not definitive as new and existing libraries keep on emerging and evolving. +Before an issue can be worked on, it must go through our voting process. + +How do we vote on an issue? ๐Ÿ—ณ + +- It is the responsibility of the RFC creator to label their proposed change as **essential** or **optional**. +- If we agree with the RFC, we must react with ๐Ÿ‘. + - If there are 3 x ๐Ÿ‘, then the issue is approved. +- If we disagree with the RFC, we must react with ๐Ÿ‘Ž and leave a comment explaining why. + - If there are 3 x ๐Ÿ‘Ž, then the issue is rejected. +- If there are differing opinions, then the repository maintainer must resolve it. + Still unsure where your future contribution belongs? Let's discuss! ๐Ÿš€ diff --git a/newproject.sh b/newproject.sh deleted file mode 100755 index 375a4429a..000000000 --- a/newproject.sh +++ /dev/null @@ -1,260 +0,0 @@ -#!/bin/bash -set -e - -# Script inspired by https://gist.github.com/szeidner/613fe4652fc86f083cefa21879d5522b - -PROGNAME=$(basename $0) -WORKING_DIR=$(cd -P -- "$(dirname -- "$0")" && pwd -P) - -die() { - echo "$PROGNAME: $*" >&2 - exit 1 -} - -usage() { - if [ "$*" != "" ] ; then - echo "Error: $*" - fi - - cat << EOF -Usage: $PROGNAME --template [TEMPLATE] --package-name [PACKAGE_NAME] --app-name [APP_NAME] -Set up an Android app and package name. -Options: --h, --help display this usage message and exit --t, --template [TEMPLATE] Select template: "rx" - RxJavaTemplate or "crt" - CoroutineTemplate (i.e. rx) --p, --package-name [PACKAGE_NAME] new package name (i.e. com.example.package) --n, --app-name [APP_NAME] new app name (i.e. MyApp, "My App") -EOF - - exit 1 -} - -template="" -packagename="" -appname="" -while [ $# -gt 0 ] ; do - case "$1" in - -h|--help) - usage - ;; - -t|--template) - template="$2" - shift - ;; - -p|--package-name) - packagename="$2" - shift - ;; - -n|--app-name) - appname="$2" - shift - ;; - -*) - usage "Unknown option '$1'" - ;; - *) - usage "Too many arguments" - ;; - esac - shift -done - -OLD_APPNAME="" -OLD_NAME="" -OLD_PACKAGE="" - -# Path segments -FIRST_PACKAGE_SEGMENT="co" -SECOND_PACKAGE_SEGMENT="nimblehq" -THIRD_PACKAGE_SEGMENT="" -# Select template -case "$template" in - "crt") - OLD_APPNAME="Coroutine Template" - OLD_NAME="CoroutineTemplate" - OLD_PACKAGE="co.nimblehq.coroutine" - THIRD_PACKAGE_SEGMENT="coroutine" - ;; - "rx") - OLD_APPNAME="RxJava Template" - OLD_NAME="RxJavaTemplate[DEPRECATED]" - OLD_PACKAGE="co.nimblehq.rxjava" - THIRD_PACKAGE_SEGMENT="rxjava" - ;; - -*) - usage "Unknown template '$template'. Please use 'rx' for RxJavaTemplate or 'crt' for CoroutineTemplate" - ;; -esac - -if [ -z "$packagename" ] ; then - usage "No new package provided" -fi - -if [ -z "$appname" ] ; then - usage "No new app name provided" -fi - -# Enforce package name -regex='^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+[0-9a-z_]$' -if ! [[ "$packagename" =~ $regex ]]; then - die "Invalid Package Name: $packagename (needs to follow standard pattern {com.example.package})" -fi - -echo "=> ๐Ÿข Staring init $appname with $OLD_APPNAME..." - -# Trim spaces in APP_NAME -NAME_NO_SPACES=$(echo "$appname" | sed "s/ //g") - -# Copy main folder -cp -R $OLD_NAME $NAME_NO_SPACES - -# Clean the old build -./$NAME_NO_SPACES/gradlew -p ./$NAME_NO_SPACES clean -# Get rid of idea settings -rm -rf $NAME_NO_SPACES/.idea -# Get rid of gradle cache -rm -rf $NAME_NO_SPACES/.gradle -# Get rid of the git history -rm -rf $NAME_NO_SPACES/.git - -# Rename folder structure -renameFolderStructure() { - DIR="" - if [ "$*" != "" ] ; then - DIR="$*" - fi - ORIG_DIR=$DIR - - mv $NAME_NO_SPACES/$DIR/$FIRST_PACKAGE_SEGMENT/$SECOND_PACKAGE_SEGMENT/$THIRD_PACKAGE_SEGMENT $NAME_NO_SPACES/$DIR/ - rm -rf $NAME_NO_SPACES/$DIR/$FIRST_PACKAGE_SEGMENT/$SECOND_PACKAGE_SEGMENT - rm -rf $NAME_NO_SPACES/$DIR/$FIRST_PACKAGE_SEGMENT - cd $NAME_NO_SPACES/$DIR - IFS='.' read -ra packages <<< "$packagename" - for i in "${packages[@]}"; do - DIR="$DIR/$i" - mkdir $i - cd $i - done - mv $WORKING_DIR/$NAME_NO_SPACES/$ORIG_DIR/$THIRD_PACKAGE_SEGMENT/* ./ - rmdir $WORKING_DIR/$NAME_NO_SPACES/$ORIG_DIR/$THIRD_PACKAGE_SEGMENT - cd $WORKING_DIR - echo $DIR -} - -# Rename files structure -echo "=> ๐Ÿ”Ž Replacing files structure..." - -# Rename project folder structure -APP_PACKAGE_DIR="app/src/main/java" -APP_PACKAGE_DIR=$( renameFolderStructure $APP_PACKAGE_DIR ) - -DATA_PACKAGE_DIR="data/src/main/java" -DATA_PACKAGE_DIR=$( renameFolderStructure $DATA_PACKAGE_DIR ) - -DOMAIN_PACKAGE_DIR="domain/src/main/java" -DOMAIN_PACKAGE_DIR=$( renameFolderStructure $DOMAIN_PACKAGE_DIR ) - -# Rename android test folder structure -APP_ANDROIDTEST_DIR="app/src/androidTest/java" -if [ -d APP_ANDROIDTEST_DIR ] -then - APP_ANDROIDTEST_DIR=$( renameFolderStructure $APP_ANDROIDTEST_DIR ) -fi - -DATA_ANDROIDTEST_DIR="data/src/androidTest/java" -if [ -d DATA_ANDROIDTEST_DIR ] -then - DATA_ANDROIDTEST_DIR=$( renameFolderStructure $DATA_ANDROIDTEST_DIR ) -fi - -DOMAIN_ANDROIDTEST_DIR="domain/src/androidTest/java" -if [ -d DOMAIN_ANDROIDTEST_DIR ] -then - DOMAIN_ANDROIDTEST_DIR=$( renameFolderStructure $DOMAIN_ANDROIDTEST_DIR ) -fi - -# Rename test folder structure -APP_TEST_DIR="app/src/test/java" -if [ -d APP_TEST_DIR ] -then - APP_TEST_DIR=$( renameFolderStructure $APP_TEST_DIR ) -fi - -DATA_TEST_DIR="data/src/test/java" -if [ -d DATA_TEST_DIR ] -then - DATA_TEST_DIR=$( renameFolderStructure $DATA_TEST_DIR ) -fi - -DOMAIN_TEST_DIR="domain/src/test/java" -if [ -d DOMAIN_TEST_DIR ] -then - DOMAIN_TEST_DIR=$( renameFolderStructure $DOMAIN_TEST_DIR ) -fi - -# Rename common-rx module on RxTemplate -if [ $template = "rx" ] -then - # Rename package folder - COMMON_RX_PACKAGE_DIR="common-rx/src/main/java" - COMMON_RX_PACKAGE_DIR=$( renameFolderStructure $COMMON_RX_PACKAGE_DIR ) - - # Rename androidTest folder - COMMON_RX_ANDROIDTEST_DIR="common-rx/src/androidTest/java" - if [ -d COMMON_RX_ANDROIDTEST_DIR ] - then - COMMON_RX_ANDROIDTEST_DIR=$( renameFolderStructure $COMMON_RX_ANDROIDTEST_DIR ) - fi - - # Rename test folder - COMMON_RX_TEST_DIR="common-rx/src/test/java" - if [ -d COMMON_RX_TEST_DIR ] - then - COMMON_RX_TEST_DIR=$( renameFolderStructure $COMMON_RX_TEST_DIR ) - fi -fi - -echo "โœ… Completed" - -# Search and replace in files -echo "=> ๐Ÿ”Ž Replacing package and package name within files..." -PACKAGE_NAME_ESCAPED="${packagename//./\.}" -OLD_PACKAGE_NAME_ESCAPED="${OLD_PACKAGE//./\.}" -if [[ "$OSTYPE" == "darwin"* ]] # Mac OSX -then - LC_ALL=C find $WORKING_DIR/$NAME_NO_SPACES -type f -exec sed -i "" -e "s/$OLD_PACKAGE_NAME_ESCAPED/$PACKAGE_NAME_ESCAPED/g" {} + - LC_ALL=C find $WORKING_DIR/$NAME_NO_SPACES -type f -exec sed -i "" -e "s/$OLD_NAME/$NAME_NO_SPACES/g" {} + -else - LC_ALL=C find $WORKING_DIR/$NAME_NO_SPACES -type f -exec sed -i -e "s/$OLD_PACKAGE_NAME_ESCAPED/$PACKAGE_NAME_ESCAPED/g" {} + - LC_ALL=C find $WORKING_DIR/$NAME_NO_SPACES -type f -exec sed -i -e "s/$OLD_NAME/$NAME_NO_SPACES/g" {} + -fi -echo "โœ… Completed" - -# Search and replace files <...> -echo "=> ๐Ÿ”Ž Replacing app name in strings.xml..." -if [[ "$OSTYPE" == "darwin"* ]] # Mac OSX -then - sed -i "" -e "s/$OLD_APPNAME/$appname/" "$WORKING_DIR/$NAME_NO_SPACES/app/src/main/res/values/strings.xml" - sed -i "" -e "s/$OLD_APPNAME/$appname/" "$WORKING_DIR/$NAME_NO_SPACES/app/src/staging/res/values/strings.xml" -else - sed -i -e "s/$OLD_APPNAME/$appname/" "$WORKING_DIR/$NAME_NO_SPACES/app/src/main/res/values/strings.xml" - sed -i -e "s/$OLD_APPNAME/$appname/" "$WORKING_DIR/$NAME_NO_SPACES/app/src/staging/res/values/strings.xml" -fi -echo "โœ… Completed" - -echo "=> ๐Ÿ”Ž Replacing Application class..." -OLD_APPLICATION_CLASS_PATH=$(find $WORKING_DIR/$NAME_NO_SPACES -type f -iname "*Application.*";) -APPLICATION_CLASS_PATH="${OLD_APPLICATION_CLASS_PATH/$OLD_NAME/$NAME_NO_SPACES}" -mv $OLD_APPLICATION_CLASS_PATH $APPLICATION_CLASS_PATH -echo "โœ… Completed" - -echo "=> ๐Ÿ› ๏ธ Building generated project..." -./$NAME_NO_SPACES/gradlew -p ./$NAME_NO_SPACES assembleDebug -echo "โœ… Build success" - -echo "=> ๐Ÿš“ Executing all unit tests..." -./$NAME_NO_SPACES/gradlew -p ./$NAME_NO_SPACES testStagingDebugUnitTest -echo "โœ… All unit tests passed" - -# Done! -echo "=> ๐Ÿš€ Done! The project is ready for development ๐Ÿ™Œ" diff --git a/scripts/get_version.kts b/scripts/get_version.kts new file mode 100644 index 000000000..205186f6b --- /dev/null +++ b/scripts/get_version.kts @@ -0,0 +1,15 @@ +object GetVersion { + + private const val PATTERN_VERSION = "[0-9]+[.][0-9]+[.][0-9]+" + + fun search(commitMessage: String): String? { + return PATTERN_VERSION + .toRegex() + .find(commitMessage) + ?.value + } +} + +val version = GetVersion.search(commitMessage = args.first()) + +println(version) diff --git a/scripts/new_project.kts b/scripts/new_project.kts index 1d9a8bfc2..cd3fc7fa4 100644 --- a/scripts/new_project.kts +++ b/scripts/new_project.kts @@ -172,9 +172,9 @@ object NewProject { private fun buildProjectAndRunTests() { showMessage("=> ๐Ÿ› ๏ธ Building project...") - executeCommand("sh $projectPath${fileSeparator}gradlew -p /$projectPath assembleDebug") + executeCommand("sh $projectPath${fileSeparator}gradlew -p $fileSeparator$projectPath assembleDebug") showMessage("=> ๐Ÿš“ Running tests...") - executeCommand("sh $projectPath${fileSeparator}gradlew -p /$projectPath testStagingDebugUnitTest") + executeCommand("sh $projectPath${fileSeparator}gradlew -p $fileSeparator$projectPath testStagingDebugUnitTest") showMessage("=> ๐Ÿš€ Done! The project is ready for development") }