/ INTERNAL.md
INTERNAL.md
1 # Releasing a new version. 2 3 The steps taken for slicing an official release of Apktool. 4 5 ### Ensuring proper license headers 6 7 _Currently broken after movement to kotlin dsl._ 8 9 ### Tagging the release. 10 11 Inside `build.gradle` there are two lines. 12 13 version 14 suffix 15 16 The version variable should be left unchanged. If done correctly, it will already be the version 17 you are about to release. In this case `2.2.2`. The suffix variable should read `SNAPSHOT` as 18 the `2.2.2` release up until this point was `SNAPSHOT` releases (Unofficial). 19 20 We need to remove the `SNAPSHOT` portion and leave the minor version blank. An example can be 21 found [here](https://github.com/iBotPeaches/Apktool/commit/96b70d0be7513c5a1e5d3a3b9a75e4e2b076ad79). 22 23 After we remove `SNAPSHOT` we need to make the version commit. Organization and following patterns 24 is crucial here. This commit should have 1 change only - the change above. Now commit this change 25 with the commit message - `version bump (x.x.x)`. 26 27 At this point we now have the commit of the release, but we need to tag it using the following message. 28 29 git tag -a vx.x.x -m "changed version to vx.x.x" -s 30 31 For example for the `2.2.1` release. 32 33 git tag -a v2.2.1 -m "changed version to v2.2.1" -s 34 35 ### Prepare for publishing. 36 37 New to Apktool is publishing releases to Maven, so plugin authors can directly integrate. You 38 need a `gradle.properties` file in root with the structure: 39 40 ``` 41 signing.keyId={gpgKeyId} 42 signing.password={gpgPassphrase} 43 signing.secretKeyRingFile={gpgSecretKingRingLocation} 44 45 ossrhUsername={sonatypeUsername} 46 ossrhPassword={sonatypePassword} 47 ``` 48 49 Release with maven with `./gradlew build shadowJar release publish`. 50 51 ### Building the binary. 52 53 In order to maintain a clean slate. Run `gradlew clean` to start from a clean slate. Now lets build 54 the new binary version. We should not have any new commits since the tagged commit. 55 56 ./gradlew build shadowJar proguard release 57 58 The build should tell you what version you are building and it should match the commits you made previously. 59 60 ➜ Apktool git:(master) ./gradlew build shadowJar proguard release 61 Building RELEASE (master): 2.2.2 62 63 ### Testing the binary. 64 65 Now the release binary is built in the same location as all other builds. Run this version against 66 some of the fixed bugs in this release. This is a simple test to ensure the build had no errors. 67 68 Copy the jar to any location to prep for uploading. The pattern we name the jars is 69 70 apktool_x.x.x.jar 71 72 Or in the case of the last release - `apktool_2.2.1.jar` 73 74 Once you have the jar in this form. Record the md5 hash & sha256 hash of it. This can be done using `md5sum` 75 and `sha256sum` on unix systems. 76 77 This can be shown for the `2.2.2` release like so 78 79 ➜ Desktop md5sum apktool_2.2.2.jar 80 1e6be08d3f9bb4b442bb85cf4e21f1c1 apktool_2.2.2.jar 81 82 ➜ Desktop sha256sum apktool-2.2.2.jar 83 1f1f186edcc09b8677bc1037f3f812dff89077187b24c8558ca2a89186ea3251 apktool-2.2.2.jar 84 85 Remember these hashes. These are the local hashes. These are our master hashes. All others (Bitbucket, Backup) 86 must match these. If they do not - they are invalid. 87 88 ### Lets get uploading. 89 90 Lets make sure we actually pushed these release changes to the repo (Both Github & Bitbucket) 91 92 git push origin master 93 git push origin vx.x.x 94 95 git push bitbucket master 96 git push bitbucket vx.x.x 97 98 We upload the binaries into 3 places. 99 100 1. [Bitbucket Downloads](https://bitbucket.org/iBotPeaches/apktool/downloads) 101 2. [Github Releases](https://github.com/iBotPeaches/Apktool/releases) - Since `2.2.1`. 102 3. [Backup Mirror](https://connortumbleson.com/apktool/) 103 4. [Sonatype (Maven)](https://oss.sonatype.org) 104 105 #### Bitbucket 106 107 This one is pretty easy. Head to the URL attached to the hyperlink #1 above. There will be a "Add Files" 108 button on the top right of the page. Upload the `apktool_x.x.x.jar` file. 109 110 After it is uploaded. Immediately visit the page and download it. Check the `md5` for a match. 111 112 #### GitHub 113 114 This option will not work until the tag is pushed. You can head to this [page](https://github.com/iBotPeaches/Apktool/releases/new) 115 to draft a new release. The `Tag version` dropdown will have the new tag. In this case `v2.2.2`. 116 117 Select that option and make the title `Apktool vx.x.x`. There will be a description field on this release. 118 Hold tight, we link the release blog post in this field, but we can edit the release after the fact to add this. 119 120 Upload the binary `apktool_x.x.x.jar` and submit the release. 121 122 #### Backup Server 123 124 Access to this server is probably limited so this option may not be possible. SSH into the 125 `connortumbleson.com` server with username `connor`. Head to `public_html/apktool` and upload 126 the `apktool_x.x.x.jar` to it. 127 128 Now re-generate the md5/sha256 hashes for these files. 129 130 md5sum *.jar > md5.md5sum 131 sha256 *.jar > sha256.shasum 132 133 Check the `md5.md5sum` file for the hashes. The file will look something like this. 134 135 6de3e097943c553da5db2e604bced332 apktool_1.4.10.jar 136 ... 137 1e6be08d3f9bb4b442bb85cf4e21f1c1 apktool_2.2.2.jar 138 139 Additionally check the `sha256.shasum` file for the hashes. This file will look almost identical to the above 140 except for containing sha256 hashes. 141 142 The hashes match so we are good with the backup server. 143 144 #### Sonatype 145 146 You'll want to log in and view the Staging repositories and confirm you see the recently made build. You'll want to: 147 148 * Close it (Wait for audit report email) 149 * Release it (Drop the staging repository) 150 * Wait 20min - 2 hours for it to appear [here](https://mvnrepository.com/artifact/org.apktool/apktool-lib) 151 152 With those done, time to get writing the release post. 153 154 We currently blog the releases on the [Connor Tumbleson personal blog](https://connortumbleson.com/). 155 This may change and the formatting of these release posts change over time. 156 157 Some recent releases for understanding the pattern can be found below. 158 159 1. [2.2.1](https://connortumbleson.com/2016/10/18/apktool-v2-2-1-released/) 160 2. [2.2.0](https://connortumbleson.com/2016/08/07/apktool-v2-2-0-released/) 161 3. [2.0.2](https://connortumbleson.com/2015/10/12/apktool-v2-0-2-released/) 162 4. [2.0.0](https://connortumbleson.com/2015/04/20/apktool-v2-0-0-released/) 163 164 For obtaining commit authors and counts. The following command does the legwork: 165 166 git shortlog -s -n --all --no-merges --since="05 Sept 2018" 167 168 Obviously replacing the date with the release date of the last version. 169 170 So write the post. I tend to always include the following: 171 172 1. Image of release for featured image when reshared on socials. 173 2. Quick sentence or two for SEO to describe the meat of this release. 174 3. Commit count and total for this release with author names. 175 4. Changelog linking to the bugs that were fixed. 176 5. Download including the md5/sha256 hash. 177 6. Link dump to Project Site, GitHub, Bug Tracker and XDA Thread. 178 179 Now that you've written this post. We need to go post it in places and update places where 180 Apktool is released. 181 182 ### XDA Thread 183 184 We have a [thread](https://forum.xda-developers.com/showthread.php?t=1755243) on XDA Developers. 185 This thread follows the same pattern for all releases. 186 187 When writing a response to the XDA thread we follow another pattern of release notes. These examples 188 can be found below: 189 190 1. [2.2.2](https://forum.xda-developers.com/showpost.php?p=70687935&postcount=4635) 191 2. [2.2.1](http://forum.xda-developers.com/showpost.php?p=69188139&postcount=4478) 192 3. [2.0.0](http://forum.xda-developers.com/showpost.php?p=60255972&postcount=3063) 193 194 ### Apktool Website 195 196 The Apktool project website has a few locations to update: 197 198 1. The homepage intro 199 2. The download link in header 200 3. Migrating `unreleased.mx` to a new blog post. 201 202 The easiest way to describe this is to just link to a [previous release](https://github.com/iBotPeaches/Apktool/pull/3146/files). 203 204 ### Update Milestones 205 206 Now that we've released a version, we should hopefully have no more tickets in the release just published. 207 If there are, move those tickets to the next milestone. 208 209 You can head to [milestones](https://github.com/iBotPeaches/Apktool/milestones) to close the just 210 released version and create another. 211 212 I tend to create the next release (In this case `2.2.3`) with an ETA of 3 months in the future. This 213 is just a guideline but helps me to release a new version every 3 months. 214 215 ### Social Spam 216 217 The final step is to send this release into the wild via some social posting. Head to the blog 218 where the release post was and send that link to Twitter, Google and whatever else you use. 219 220 Relax and watch the bug tracker. 221 222 # Building aapt2 binaries. 223 224 > [!WARNING] 225 > aapt (aapt1) is deprecated and no longer receives updates. 226 227 The steps taken for building our modified aapt2 binaries for apktool. 228 229 ### Getting the modified `frameworks/base` repo. 230 First step is using the [platform_frameworks_base](https://github.com/iBotPeaches/platform_frameworks_base) repo. 231 232 While previously unorganized, the repo now follows the branch naming convention depending on the current Android version. 233 So `apktool_7.1` corresponds to the 7.1 Android release. This branch should work for all `android-7.1.x` tags for AOSP. 234 235 We didn't follow this naming convention until Android 7.1. So don't go looking for older versions. The current version 236 is `apktool-9.0.0`, which corresponds to the Android 9.0 (Pie) release. 237 238 This repo has a variety of changes applied. These changes range from disabling optimizations to lessening the rules 239 that aapt regularly has. We do this because apktool's job is to not fix apks, but rather keep them as close to the 240 original as they were. 241 242 ### First we need the AOSP source 243 244 As cheesy as it is, just follow this [downloading](https://source.android.com/source/downloading.html) link in order 245 to get the source downloaded. This is no small download, expect to use 150-250GB. 246 247 Some optimization techniques for a smaller clone: 248 249 * `~/bin/repo init -u https://android.googlesource.com/platform/manifest -b master --partial-clone` - Partial clone 250 * `repo sync -c` - Only current branch 251 252 After that, you need to build AOSP via this [documentation](https://source.android.com/source/building.html) guide. Now 253 we aren't building the entire AOSP package, the initial build is to just see if you are capable of building it. 254 255 We check out a certain tag or branch. Currently, we use 256 257 * aapt2 - `android-14.0.0_r54` 258 * aapt1 - `android-14.0.0_r2` (deprecated) 259 260 ### Including our modified `frameworks/base` package. 261 262 There is probably a more automated way to do this, but for now: 263 264 1. `cd frameworks/base` 265 2. `git remote add origin git@github.com:iBotPeaches/platform_frameworks_base.git` 266 3. `git fetch origin -v` 267 4. `git checkout origin/master` 268 269 #### Mac Patch 270 271 Normally you'll be building this on a recent Mac OS that isn't supported. You'll want to follow these steps: 272 273 1. `vim build/soong/cc/config/darwin_host.go` 274 2. Find `darwinSupportedSdkVersions` array. 275 3. Add number that corresponds to output of: `find /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs -iname "*.sdk"` 276 277 ### Building the aapt1 (Legacy) binary. 278 279 The steps below are different per flavor and operating system. 280 281 #### Linux / Windows 282 1. `source build/envsetup.sh` 283 2. `lunch aosp_arm64-trunk_staging-eng` 284 3. `m aapt` 285 4. `strip out/host/linux-x86/bin/aapt` 286 5. `strip out/host/linux-x86/bin/aapt_64` 287 6. `strip out/host/windows-x86/bin/aapt.exe` 288 7. `strip out/host/windows-x86/bin/aapt_64.exe` 289 290 #### Mac 291 1. `source build/envsetup.sh` 292 2. `m aapt` 293 3. `strip out/host/darwin-x86/bin/aapt_64` 294 295 32/64 bit binaries will be built for Linux and Windows. 296 297 ### Building the aapt2 binary. 298 299 The steps below are different per flavor and operating system. 300 301 #### Linux / Windows 302 1. `source build/envsetup.sh` 303 1. `lunch aosp_arm64-trunk_staging-eng` 304 1. `m aapt2` 305 1. `strip out/host/linux-x86/bin/aapt2` 306 1. `strip out/host/linux-x86/bin/aapt2_64` 307 1. `strip out/host/windows-x86/bin/aapt2.exe` 308 1. `strip out/host/windows-x86/bin/aapt2_64.exe` 309 310 #### Mac 311 1. `export ANDROID_JAVA_HOME=/Path/To/Jdk` 312 1. `source build/envsetup.sh` 313 1. `lunch aosp_arm64-trunk_staging-eng` 314 1. `m aapt2` 315 1. `strip out/host/darwin-x86/bin/aapt2_64` 316 317 #### Confirming aapt/aapt2 builds are static 318 319 There are some issues with some dependencies (namely `libc++`) in which they are built in the shared state. This is 320 alright in the scope and context of AOSP/Android Studio, but once you leave those two behind and start using aapt on 321 its own, you encounter some issues. The key is to force `libc++` to be built statically which takes some tweaks with the 322 AOSP build systems as that dependency isn't standard like `libz` and others. 323 324 You can test the finalized project using tools like `ldd` (unix) and `otool -L` (mac) for testing the binaries looking 325 for shared dependencies. 326 327 # Gradle Tips n Tricks 328 329 ./gradlew build shadowJar proguard -x test 330 331 This skips the testing suite (which currently takes 2-4 minutes). Use this when making quick builds and save the testing 332 suite before pushing to GitHub. 333 334 ./gradlew test --debug-jvm 335 336 This enables debugging on the test suite. This starts the debugger on port 5005 which you can connect with IntelliJ. 337 338 ./gradlew :brut.apktool:apktool-lib:test ---tests "*BuildAndDecodeTest" 339 340 This runs the library project of Apktool, selecting a specific test to run. Comes in handy when writing a new test and 341 only wanting to run that one. The asterisk is used to the full path to the test can be ignored. You can additionally 342 match this with the debugging parameter to debug a specific test. This command can be found below. 343 344 ./gradlew :brut.apktool:apktool-lib:test --tests "*BuildAndDecodeTest" --debug-jvm