|
| 1 | +## 1. Build Configuration |
| 2 | + |
| 3 | +- [ ] 1.1 Add `minifyEnabled true` to the `release` build type in `owncloudApp/build.gradle` |
| 4 | +- [ ] 1.2 Add `proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'` to the `release` build type in `owncloudApp/build.gradle` |
| 5 | +- [ ] 1.3 Verify that the `debug` build type in `owncloudApp/build.gradle` has no `minifyEnabled` change (remains false by default) |
| 6 | + |
| 7 | +## 2. ProGuard Rules |
| 8 | + |
| 9 | +- [ ] 2.1 Create `owncloudApp/proguard-rules.pro` with keep rules for all `CoroutineWorker` subclasses in `com.owncloud.android.workers` (9 workers: `OldLogsCollectorWorker`, `AutomaticUploadsWorker`, `AvailableOfflinePeriodicWorker`, `DownloadFileWorker`, `RemoveLocallyFilesWithLastUsageOlderThanGivenTimeWorker`, `AccountDiscoveryWorker`, `UploadFileFromFileSystemWorker`, `RemoveSourceFileWorker`, `UploadFileFromContentUriWorker`) |
| 10 | +- [ ] 2.2 Add keep rules to `owncloudApp/proguard-rules.pro` for all Moshi `@JsonClass`-annotated response model classes in `owncloudComLibrary` (covering: `CommonOcsResponse`, `ShareeResponse`, `ShareItem`, `TokenResponse`, `ClientRegistrationResponse`, `OIDCDiscoveryResponse`, `WebFingerResponse`, `AppRegistryResponse`, `SpacesResponse`, `RoleResponse`, `CapabilityResponse`, `UserInfoResponse`, `MembersResponse`, and related) |
| 11 | +- [ ] 2.3 Add a class-level keep rule for any other classes instantiated by name via the Android framework (e.g. custom `View` subclasses inflated from XML, if any are identified) |
| 12 | + |
| 13 | +## 3. First Build and Rule Verification |
| 14 | + |
| 15 | +- [ ] 3.1 Run `./gradlew assembleOriginalRelease` and resolve any build errors |
| 16 | +- [ ] 3.2 Inspect `owncloudApp/build/outputs/mapping/originalRelease/configuration.txt` to verify that Room consumer rules and Coroutines rules were applied automatically, and that all custom keep rules appear in the merged output |
| 17 | +- [ ] 3.3 Inspect `owncloudApp/build/outputs/mapping/originalRelease/usage.txt` to check for any incorrectly removed classes and add additional keep rules if needed |
| 18 | +- [ ] 3.4 Confirm mapping file is present at `owncloudApp/build/outputs/mapping/originalRelease/mapping.txt` |
| 19 | + |
| 20 | +## 4. Verification |
| 21 | + |
| 22 | +- [ ] 4.1 Run `./gradlew testDebugUnitTest testMdmDebugUnitTest --continue` and confirm all unit tests pass |
| 23 | +- [ ] 4.2 Run `./gradlew detekt` and confirm zero issues |
| 24 | +- [ ] 4.3 Install the release APK on a device or emulator and perform the smoke test: login, file listing, upload, download |
| 25 | +- [ ] 4.4 Trigger a background sync (automatic upload) and confirm it completes without a `ClassNotFoundException` from WorkManager |
| 26 | + |
| 27 | +## 5. Changelog |
| 28 | + |
| 29 | +- [ ] 5.1 Create `changelog/unreleased/XXXX` (replace `XXXX` with the PR number once known) with the following content: |
| 30 | + |
| 31 | +``` |
| 32 | +Enhancement: Enable R8 code shrinking for release builds |
| 33 | +
|
| 34 | +R8 code shrinking has been enabled for release builds. The APK is now smaller and passes Google Play's DEX optimisation check. |
| 35 | +
|
| 36 | +https://github.com/owncloud/android/issues/5029 |
| 37 | +https://github.com/owncloud/android/pull/XXXX |
| 38 | +``` |
| 39 | + |
| 40 | +--- |
| 41 | + |
| 42 | +## QA |
| 43 | + |
| 44 | +### Test Plan |
| 45 | + |
| 46 | +| Test name | Steps to execute | Expected result | Result | Comments | |
| 47 | +|---|---|---|---|---| |
| 48 | +| Release build compiles | Run `./gradlew assembleOriginalRelease` | Build succeeds, APK produced | | | |
| 49 | +| Mapping file generated | Check `owncloudApp/build/outputs/mapping/originalRelease/mapping.txt` after release build | File exists and is non-empty | | | |
| 50 | +| Debug build unaffected | Run `./gradlew assembleOriginalDebug` | Build succeeds, no minification applied | | | |
| 51 | +| Unit tests pass | Run `./gradlew testDebugUnitTest testMdmDebugUnitTest` | All tests green | | | |
| 52 | +| Detekt zero issues | Run `./gradlew detekt` | Zero issues reported | | | |
| 53 | +| Login works in release APK | Install release APK, open app, log in to an ownCloud server | Login completes, files listed | | | |
| 54 | +| File listing works | Navigate through folders in release APK | Folders and files display correctly | | | |
| 55 | +| File upload works | Upload a file from the release APK | File appears on server | | | |
| 56 | +| File download works | Download a file in the release APK | File saved locally and opens correctly | | | |
| 57 | +| Background sync works | Trigger automatic upload via release APK | Upload worker completes with no `ClassNotFoundException` | | | |
| 58 | +| Moshi deserialization works | Perform any server request returning JSON (e.g. capabilities, spaces) in release APK | Response parsed correctly, no deserialization errors | | | |
| 59 | + |
| 60 | +### Gherkin Scenario Proposal (E2E suite) |
| 61 | + |
| 62 | +```gherkin |
| 63 | +Feature: Release build integrity with R8 optimisation |
| 64 | +
|
| 65 | + Scenario: User can log in and list files with a release build |
| 66 | + Given the ownCloud Android app is installed from a release APK with R8 optimisation enabled |
| 67 | + And a valid ownCloud server is accessible |
| 68 | + When the user enters their credentials and taps the login button |
| 69 | + Then the app navigates to the file list screen |
| 70 | + And files and folders from the server are displayed correctly |
| 71 | +
|
| 72 | + Scenario: Background worker completes without reflection errors |
| 73 | + Given the ownCloud Android app is running as a release build |
| 74 | + And automatic uploads are enabled for a local folder |
| 75 | + When a new file is added to the watched folder |
| 76 | + Then the AutomaticUploadsWorker is enqueued and executed by WorkManager |
| 77 | + And the file is uploaded to the ownCloud server without a ClassNotFoundException |
| 78 | +``` |
0 commit comments