Closer/docs/release/internal-testing-checklist.md

7.6 KiB
Raw Blame History

Closer — Internal Testing Build Checklist [SUPERSEDED]

Status (stamped 2026-07-11): SUPERSEDED by docs/release/store-assets.md (§5 signing, §8 pre-launch) and the ship-readiness plan (release_guide.md, Phases 12b), which reflect the current release-guard build config, keystore plan, and Play internal-testing path. Also note a factual error below: the applicationId is closer.appapp.closer is the code namespace (the same swap that produced the Manage-subscription deep-link bug fixed in 4e807cb0). Kept as historical context only.

Steps to prepare, sign, and distribute an internal testing build for the private MVP. Assumes Android Gradle Plugin 8.7.3, Kotlin 2.0.21, minSdk 26, targetSdk/compileSdk 35, and app.closer closer.app applicationId.

Internal testing should verify the product goal: private, mutual-reveal relationship questions with real encryption and calmer UX.


1. Pre-build Checklist

1.1 Source readiness

  • All feature branches for the MVP merged into the internal testing branch.
  • No unintended TODO / FIXME blockers in release code (documented in docs/qa/private-mvp-checklist.md).
  • No com.couplesconnect package references remain (verified via grep -RIn across app/src).
  • No debug-only logging left in non-debug code paths (verbose/debug logs removed; error logging acceptable).
  • Version matches private MVP: versionName should be 0.1.x and versionCode incremented for each distributed build.
  • local.properties contains required secrets but is not committed to git.

1.2 Secrets and API keys

  • google-services.json is present in app/ and matches the internal testing package (app.closer).
  • RevenueCat API key defined in local.properties as RC_API_KEY.
  • Firebase App Check debug token removed or disabled for release.
  • No hardcoded API keys, tokens, or credentials in Kotlin/XML source.

1.3 Build configuration

  • build.gradle.kts has isMinifyEnabled = true and isShrinkResources = true for release.
  • ProGuard rules file (proguard-rules.pro) reviewed for Compose, Hilt, Room, Firebase, RevenueCat, and Navigation.
  • compileSdk = 35, targetSdk = 35, minSdk = 26.
  • namespace = "app.closer" and applicationId = "app.closer".
  • Kotlin jvmTarget = "17" and Java 17 compatibility set.
  • buildConfig = true and compose = true enabled.

2. Signing Config Checklist

2.1 Keystore

  • Internal testing keystore generated or available (.jks / .keystore).
  • Keystore password, key alias, and key password stored securely in CI or password manager — not in repo.
  • Keystore used for signing is backed up in a secure location (1Password, team vault, hardware token).
  • Key validity period covers expected lifetime of the app (Google Play requires validity past 22 Oct 2033 for app signing key uploads).

2.2 Gradle signing configuration

  • signingConfigs block in app/build.gradle.kts configured:
    signingConfigs {
        create("release") {
            storeFile = file(System.getenv("KEYSTORE_PATH") ?: "release.keystore")
            storePassword = System.getenv("KEYSTORE_PASSWORD")
            keyAlias = System.getenv("KEY_ALIAS")
            keyPassword = System.getenv("KEY_PASSWORD")
        }
    }
    
  • buildTypes.release references signingConfigs.getByName("release").
  • Local debug builds still use the default debug keystore.

2.3 Verify signed APK/AAB

  • Build release APK or AAB: ./gradlew :app:assembleRelease or :app:bundleRelease.
  • Confirm output is signed: apksigner verify --verbose app-release.apk.
  • Check certificate fingerprints and expiration.
  • Verify v1 (JAR) and v2/v3 APK signatures are present.

3. Firebase / Production Environment Checklist

3.1 Firebase project

  • Internal testing Firebase project created/separate from production.
  • app.closer Android app registered with correct SHA-1/SHA-256 certificates.
  • google-services.json downloaded and placed in app/.

3.2 Firebase services

  • Authentication: Email/password provider enabled (and any OAuth providers used in the app).
  • Firestore: Security rules reviewed; internal testing rules should match expected MVP rules.
  • Cloud Messaging: Server key / FCM v1 credentials available for backend/push testing.
  • Crashlytics: Crashlytics plugin applied and mapping file upload enabled.
  • Analytics: No PII logged; events reviewed.
  • Remote Config: Default values in-app handle absent remote values.
  • App Check: Play Integrity provider configured for release builds; debug provider only for debug/internal.

3.3 Firebase secrets

  • No Firebase API keys or FCM tokens committed.
  • CI injects google-services.json or uses environment-based substitution.

4. Test Account Setup

4.1 Device / emulator accounts

  • At least two test user accounts available (User A and User B) for couple pairing flows.
  • Test accounts use + or tagged email addresses for isolation (e.g., qa+a@closer.app, qa+b@closer.app).
  • Passwords stored in team vault; accounts enabled in Firebase Auth allowlist if applicable.

4.2 Data seeding

  • Seed questions and categories in Firestore/remote config for internal testing.
  • Seed at least one premium category and one free category.
  • Prepare test RevenueCat products with sandbox pricing.
  • Ensure test accounts have predictable subscription states (free, premium, expired).

4.3 Test scenarios matrix

Scenario User A User B
Unpaired new install fresh account fresh account
Paired couple paired with B paired with A
Premium unlock subscribed not subscribed
Different answer states answered daily not answered
Invite expiry create invite accept after expiry

5. Distribution Checklist

5.1 Firebase App Distribution

  • Firebase App Distribution Gradle plugin applied (optional but recommended).
  • App Distribution configured with tester groups (e.g., mvp-internal, qa-team).
  • Build variant selected: release (signed).
  • Distribution command run: ./gradlew :app:assembleRelease :app:appDistributionUploadRelease.
  • Testers receive email/notification with download link.
  • APK install succeeds and app launches.

5.2 Alternative distribution

  • If not using App Distribution, use internal Google Play track with closed testing.
  • Signed AAB uploaded to Play Console internal testing track.
  • Testers added to internal testing list.
  • Play Console review status tracked (internal tests may be immediately available).

5.3 Verification after install

  • App installs and opens on target device.
  • Onboarding flow reachable.
  • Auth and pairing flows tested end-to-end on distributed build.
  • Push notification received and quiet-hours suppression works.
  • Paywall loads products in sandbox (where RevenueCat configured).
  • Crashlytics reports non-fatal test event and appears in console.

6. Build Commands Reference

# Debug compile (fast smoke test)
./gradlew :app:compileDebugKotlin

# Debug install
./gradlew :app:installDebug

# Release APK (signed)
./gradlew :app:assembleRelease

# Release AAB (signed)
./gradlew :app:bundleRelease

# Firebase App Distribution upload
./gradlew :app:assembleRelease :app:appDistributionUploadRelease

7. Sign-off

Role Name Date Notes
Build engineer
QA lead
Product owner