/ 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