Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,11 @@ local.properties
# Firebase config — each developer supplies their own (see README)
app/google-services.json

# Release signing — never commit the keystore or its credentials
app/keystore/
app/keystore.properties
*.jks
*.keystore

# Internal planning docs — not part of the public repo
docs/
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ An editorial cooking companion for Android. Browse, cook, and remember — the f
![Room](https://img.shields.io/badge/Room-2.7.1-48B983?style=flat-square)
![Koin](https://img.shields.io/badge/Koin-4.0.0-F88909?style=flat-square)
![Min SDK](https://img.shields.io/badge/minSdk-24-3DDC84?style=flat-square&logo=android&logoColor=white)
[![CI](https://github.com/whatsername0414/saffron/actions/workflows/ci.yml/badge.svg)](https://github.com/whatsername0414/saffron/actions/workflows/ci.yml)
[![CI](https://github.com/maceljonray/saffron/actions/workflows/ci.yml/badge.svg)](https://github.com/maceljonray/saffron/actions/workflows/ci.yml)
[![Latest release](https://img.shields.io/github/v/release/maceljonray/saffron?style=flat-square&color=C8860A&label=release)](https://github.com/maceljonray/saffron/releases/latest)

## Download

Grab a signed release build from the [Releases page](https://github.com/maceljonray/saffron/releases/latest) — no build required. This is a portfolio/demo app, not published on the Play Store, so you'll need to sideload the APK (enable "install from unknown sources" if prompted). Requires Android 7.0 (API 24) or higher.

## Screenshots

Expand Down
4 changes: 4 additions & 0 deletions app/keystore.properties.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
storeFile=keystore/release.jks
storePassword=changeme
keyAlias=saffron-release
keyPassword=changeme
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import org.gradle.api.JavaVersion
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import java.io.FileInputStream
import java.util.Properties

/**
* Convention plugin for the `:app` module: AGP application + Compose, SDK levels,
Expand All @@ -11,7 +13,9 @@ import org.gradle.kotlin.dsl.configure
* debug: `.debug` applicationIdSuffix/versionNameSuffix so it can install alongside release;
* requires a matching Firebase Android app (`com.saffron.cook.debug`) in `google-services.json`.
* release: R8 shrink+obfuscate enabled via `optimization { enable = true }`, picking up keep
* rules from every module's `src/main/keepRules/rules.keep`.
* rules from every module's `src/main/keepRules/rules.keep`. Signed via `app/keystore.properties`
* (gitignored, see `app/keystore.properties.example`) when present; falls back to the default
* (unsigned) release config otherwise, so a clone without the keystore still builds.
*
* Module-specific config (namespace, applicationId, versionCode/Name, testInstrumentationRunner)
* stays in `app/build.gradle.kts`.
Expand All @@ -24,6 +28,13 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
apply("saffron.android.compose")
}

val keystorePropertiesFile = target.file("keystore.properties")
val keystoreProperties = Properties()
val hasSigningConfig = keystorePropertiesFile.exists()
if (hasSigningConfig) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}

extensions.configure<ApplicationExtension> {
compileSdk = 37

Expand All @@ -41,6 +52,17 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
buildConfig = true
}

if (hasSigningConfig) {
signingConfigs {
create("release") {
storeFile = target.file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
}
}
}

buildTypes {
debug {
applicationIdSuffix = ".debug"
Expand All @@ -52,6 +74,9 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
optimization {
enable = true
}
if (hasSigningConfig) {
signingConfig = signingConfigs.getByName("release")
}
}
}
}
Expand Down
Loading