Skip to content

Commit

Permalink
Start using flavours
Browse files Browse the repository at this point in the history
Currently, this just allows us to remove the donation button on Google
Play without using the deprecated installer APIs.

In the future, this should allow us to also release multiple versions of
Catima (for example: WearOS is a commonly requested feature, but this
needs non-free dependencies, which may not be okay to all users).
  • Loading branch information
TheLastProject committed Dec 24, 2024
1 parent e8c11de commit 91551bf
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 68 deletions.
76 changes: 41 additions & 35 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,39 +30,45 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
api-level: [ 21, 34 ]
flavor: [Foss, Gplay]
steps:
- uses: actions/checkout@v4.2.2
- name: Fail on bad translations
run: if grep -ri "<xliff" app/src/main/res/values*/strings.xml; then echo "Invalidly escaped translations found"; exit 1; fi
- uses: gradle/actions/wrapper-validation@v4
- name: set up OpenJDK 17
run: |
sudo apt-get update
sudo apt-get install -y openjdk-17-jdk-headless
sudo update-alternatives --auto java
- name: Build
run: ./gradlew assembleRelease
- name: Check lint
run: ./gradlew lintRelease
- name: Run unit tests
run: timeout 5m ./gradlew testReleaseUnitTest || { ./gradlew --stop && timeout 5m ./gradlew testReleaseUnitTest; }
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run instrumented tests
uses: ReactiveCircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
arch: x86_64
script: ./gradlew connectedCheck
- name: SpotBugs
run: ./gradlew spotbugsRelease
- name: Archive test results
if: always()
uses: actions/upload-artifact@v4.5.0
with:
name: test-results-api${{ matrix.api-level }}
path: app/build/reports
- uses: actions/checkout@v4.2.2
- name: Fail on bad translations
run: if grep -ri "<xliff" app/src/main/res/values*/strings.xml; then echo "Invalidly escaped translations found"; exit 1; fi
- uses: gradle/actions/wrapper-validation@v4
- name: set up OpenJDK 17
run: |
sudo apt-get update
sudo apt-get install -y openjdk-17-jdk-headless
sudo update-alternatives --auto java
- name: Build
run: ./gradlew assemble${{ matrix.flavor }}Release
- name: Check lint
run: ./gradlew lint${{ matrix.flavor }}Release
- name: Run unit tests
run: timeout 5m ./gradlew test${{ matrix.flavor }}ReleaseUnitTest || { ./gradlew --stop && timeout 5m ./gradlew test${{ matrix.flavor }}ReleaseUnitTest; }
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run instrumented tests (API 21)
uses: ReactiveCircus/android-emulator-runner@v2
with:
api-level: 21
arch: x86_64
script: ./gradlew connected${{ matrix.flavor }}DebugAndroidTest
- name: Run instrumented tests (API 34)
uses: ReactiveCircus/android-emulator-runner@v2
with:
api-level: 34
arch: x86_64
script: ./gradlew connected${{ matrix.flavor }}DebugAndroidTest
- name: SpotBugs
run: ./gradlew spotbugs${{ matrix.flavor }}Release
- name: Archive test results
if: always()
uses: actions/upload-artifact@v4.5.0
with:
name: test-results-flavor${{ matrix.flavor }}
path: app/build/reports
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@
/.bundle/
/vendor/bundle
/lib/bundler/man/

# Catima-specific
SHA256SUMS
18 changes: 18 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ android {
resourceConfigurations += listOf("ar", "bg", "bn", "bn-rIN", "bs", "cs", "da", "de", "el-rGR", "en", "eo", "es", "es-rAR", "et", "fi", "fr", "gl", "he-rIL", "hi", "hr", "hu", "in-rID", "is", "it", "ja", "ko", "lt", "lv", "nb-rNO", "nl", "oc", "pl", "pt-rBR", "pt-rPT", "ro-rRO", "ru", "sk", "sl", "sr", "sv", "ta", "tr", "uk", "vi", "zh-rCN", "zh-rTW")

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

buildConfigField("boolean", "showDonate", "true")
buildConfigField("boolean", "showRateOnGooglePlay", "false")
}

buildTypes {
Expand All @@ -51,6 +54,21 @@ android {
viewBinding = true
}

flavorDimensions.add("type")
productFlavors {
create("foss") {
dimension = "type"
isDefault = true
}
create("gplay") {
dimension = "type"

// Google doesn't allow donation links
buildConfigField("boolean", "showDonate", "false")
buildConfigField("boolean", "showRateOnGooglePlay", "true")
}
}

bundle {
language {
enableSplit = false
Expand Down
5 changes: 2 additions & 3 deletions app/src/main/java/protect/card_locker/AboutActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@ protected void onCreate(Bundle savedInstanceState) {
binding.rate.setTag("https://play.google.com/store/apps/details?id=me.hackerchick.catima");
binding.donate.setTag("https://catima.app/donate");

boolean installedFromGooglePlay = Utils.installedFromGooglePlay(this);
// Hide Google Play rate button if not on Google Play
binding.rate.setVisibility(installedFromGooglePlay ? View.VISIBLE : View.GONE);
binding.rate.setVisibility(BuildConfig.showRateOnGooglePlay ? View.VISIBLE : View.GONE);
// Hide donate button on Google Play (Google Play doesn't allow donation links)
binding.donate.setVisibility(installedFromGooglePlay ? View.GONE : View.VISIBLE);
binding.donate.setVisibility(BuildConfig.showDonate ? View.VISIBLE : View.GONE);

bindClickListeners();
}
Expand Down
15 changes: 0 additions & 15 deletions app/src/main/java/protect/card_locker/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -1032,21 +1032,6 @@ public static int setIconOrTextWithBackground(Context context, LoyaltyCard loyal
return headerColor;
}

public static boolean installedFromGooglePlay(Context context) {
try {
String packageName = context.getPackageName();
String installer;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
installer = context.getPackageManager().getInstallSourceInfo(packageName).getInstallingPackageName();
} else {
installer = context.getPackageManager().getInstallerPackageName(packageName);
}
return installer.equals("com.android.vending");
} catch (Throwable ignored) {
return false;
}
}

public static int getHeaderColor(Context context, LoyaltyCard loyaltyCard) {
return loyaltyCard.headerColor != null ? loyaltyCard.headerColor : LetterBitmap.getDefaultColor(context, loyaltyCard.store);
}
Expand Down
38 changes: 26 additions & 12 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -euo pipefail
IFS=$'\n\t'

### build.sh
### Builds Catima the same way F-Droid does for reproducible builds
### Builds Catima the same way rbtlog/IzzyOnDroid does for reproducible builds

if [ -z "${ANDROID_SDK_ROOT:-}" ]; then
echo "ANDROID_SDK_ROOT is not set, setting to $HOME/Android/Sdk";
Expand All @@ -25,7 +25,11 @@ echo "Starting build"
./gradlew clean assembleRelease

echo "Build finished (unsigned)"
echo "Your build is at app/build/outputs/apk/release/app-release-unsigned.apk"
flavourDirs=$(find app/build/outputs/apk/ -mindepth 1 -maxdepth 1 -type d)
for flavourDir in $flavourDirs; do
flavourName="$(basename "$flavourDir")"
echo "Your $flavourName flavour is at $flavourDir/release/app-$flavourName-release-unsigned.apk"
done

if [ -z "${KEYSTORE:-}" ]; then
echo "KEYSTORE not set, skipping signing..."
Expand All @@ -36,16 +40,26 @@ else
fi

apksigner_version="$(ls -1 "$HOME/Android/Sdk/build-tools/" | tail -n 1)"
cp app/build/outputs/apk/release/app-release-unsigned.apk app/build/outputs/apk/release/app-release.apk
"$HOME/Android/Sdk/build-tools/$apksigner_version/apksigner" sign -v --ks "$KEYSTORE" --ks-key-alias "$KEYSTORE_ALIAS" app/build/outputs/apk/release/app-release.apk

echo "Build finished (signed)"
echo "Your build is at app/build/outputs/apk/release/app-release.apk"
fi
for flavourDir in $flavourDirs; do
flavourName="$(basename "$flavourDir")"
echo "Signing $flavourName flavour..."
cp "$flavourDir/release/app-$flavourName-release-unsigned.apk" "$flavourDir/release/app-$flavourName-release.apk"
"$HOME/Android/Sdk/build-tools/$apksigner_version/apksigner" sign -v --ks "$KEYSTORE" --ks-key-alias "$KEYSTORE_ALIAS" "$flavourDir/release/app-$flavourName-release.apk"

echo "Build finished (signed)"
echo "Your $flavourName flavour is at $flavourDir/release/app-$flavourName-release.apk"
done

pushd app/build/outputs/apk/release/
sha256sum -- *.apk > SHA256SUMS
popd
shasumPath="$(pwd)/SHA256SUMS"
echo "" > "$shasumPath"

echo "SHA256SUMS generated"
echo "Your SHA256SUMS is at app/build/outputs/apk/release/SHA256SUMS"
for flavourDir in $flavourDirs; do
pushd "$flavourDir/release/"
sha256sum -- *.apk >> "$shasumPath"
popd
done

echo "SHA256SUMS generated"
echo "Your SHA256SUMS are at SHA256SUMS"
fi
6 changes: 3 additions & 3 deletions docs/RELEASE_STEPS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
3. Update `CHANGELOG.md` with the new version name and the release date
4. Update `app/build.gradle.kts` with the new `versionCode` and `versionName`
5. Create a commit for the new release: `git add CHANGELOG.md app/build.gradle.kts && git commit -m "Release Catima <VERSION>"`
6. Build a new .apk: `KEYSTORE=/path/to/keystore KEYSTORE_ALIAS=catima ./build.sh`
7. Upload the APK to Google Play Open Testing
6. Build the new .apks: `KEYSTORE=/path/to/keystore KEYSTORE_ALIAS=catima ./build.sh`
7. Upload `app/build/outputs/apk/gplay/release/app-gplay-release.apk` to Google Play Open Testing
8. Push the version update commit: `git push`
9. Create a new release on GitHub and attach the `app-release.apk` and `SHA256SUMS` files
9. Create a new release on GitHub and attach the `app/build/outputs/apk/foss/release/app-foss-release.apk` and `SHA256SUMS` files
10. After the release has been approved on Google Play Production, update the metadata there: `bundle exec fastlane supply --version_code <VERSION_CODE>`

0 comments on commit 91551bf

Please sign in to comment.