samolego / Canta

Uninstall any Android app without root (Shizuku)!
https://f-droid.org/en/packages/org.samo_lego.canta/
GNU Lesser General Public License v3.0
1.31k stars 29 forks source link

[Feature Proposal] Automatic Update Integration from GitHub Releases #85

Open CodeWithTamim opened 3 months ago

CodeWithTamim commented 3 months ago

Hi I hope you're doing well. I’m considering adding a feature to the app that would allow it to show an update dialog when a new release is available on GitHub. The feature would also handle downloading and installing the update directly from within the app.

Would you be open to this enhancement? Please let me know if this is something you'd like to include.

Thank you!

Best regards, Tamim Hossain

samolego commented 3 months ago

Hi there, that would be awesome, especially since fdroid cannot reproduce builds (#49)

CodeWithTamim commented 3 months ago

Hi there, that would be awesome, especially since fdroid cannot reproduce builds (#49)

Okay bro pr coming soon

shuvashish76 commented 1 month ago

Requested at IzzyOnDroid : https://gitlab.com/IzzyOnDroid/repo/-/issues/636 BTW the app can co-exist on both the repos ;)

IzzySoft commented 1 month ago

Scanner results:

SigningBlock blobs:
-------------------
0x504b4453 (DEPENDENCY_INFO_BLOCK; GOOGLE)

Easily avoided with a minor addition to your build.gradle:

android {
    dependenciesInfo {
        // Disables dependency metadata when building APKs.
        includeInApk = false
        // Disables dependency metadata when building Android App Bundles.
        includeInBundle = false
    }
}

For some background: that BLOB is supposed to be just a binary representation of your app's dependency tree. But as it's encrypted with a public key belonging to Google, only Google can read it – and nobody else can even verify what it really contains. More details can be found e.g. here: Ramping up security: additional APK checks are in place with the IzzyOnDroid repo.

Integrating your app now, will report back when done.

IzzySoft commented 1 month ago

I can confirm the APK is NOT reproducible: classes.dex differs slightly in what looks like it could have been built by a JDK which slightly differs (assuming you've used your Github workflow to produce the APK attached to the release, we can rule out a build from a "dirty tree" with local changes). And looking at your workflow it seems you use JDK-19 – could that be? If so: could you switch to either 17 or 21 there? 19 is no LTS release and thus not even suitable for RB.

If you'd switch to JDK 21, make a test build (from a clean tree, i.e. all changes committed – can be inside a "test branch" but must be available here at Github), then attach the APK here (rename it to *.zip so you can attach it, please do NOT put it inside another ZIP) and name the commit you built it from, I can give it another try to see if that solves the issue.

Current APK diff:

  -rw-r--r--  0.0 unx      120 b-      118 defN 1981-01-01 01:01:02 e9680e28 META-INF/version-control-info.textproto
- -rw-r--r--  0.0 unx     3885 b-     3885 stor 1981-01-01 01:01:02 0b393429 assets/dexopt/baseline.prof
+ -rw-r--r--  0.0 unx     3885 b-     3885 stor 1981-01-01 01:01:02 8f7598cf assets/dexopt/baseline.prof
  -rw-r--r--  0.0 unx      498 b-      498 stor 1981-01-01 01:01:02 4012471a assets/dexopt/baseline.profm
- -rw-r--r--  0.0 unx  2208040 b-  2208040 stor 1981-01-01 01:01:02 f484b8be classes.dex
+ -rw-r--r--  0.0 unx  2208048 b-  2208048 stor 1981-01-01 01:01:02 8900aa05 classes.dex
  -rw----     2.0 fat     1738 b-      782 defN 1981-01-01 01:01:02 2d73be70 DebugProbesKt.bin

(baseline.prof differs because classes.dex differs). The dex diff:

       name          : '<init>'
-      type          : '(LO1/a;ZLY/e;LY/k;)V'
+      type          : '(LA/h;ZLY/e;LY/k;)V'
       access        : 0x10001 (PUBLIC CONSTRUCTOR)
       code          -
       registers     : 5
       ins           : 5
       outs          : 2
       insns size    : 13 16-bit code units
-| B.g.<init>:(LO1/a;ZLY/e;LY/k;)V
+| B.g.<init>:(LA/h;ZLY/e;LY/k;)V
 |: iput-object v1, v0, LB/g;.j:LO1/a;
 |: iput-boolean v2, v0, LB/g;.k:Z
 |: iput-object v3, v0, LB/g;.l:LY/e;
@@ -450983,14 +450983,14 @@
   Direct methods    -
     #0              : (in LB/h;)
       name          : '<init>'
-      type          : '(JLO1/a;Z)V'
+      type          : '(JLA/h;Z)V'
       access        : 0x10001 (PUBLIC CONSTRUCTOR)
       code          -
       registers     : 5
       ins           : 5
       outs          : 2
       insns size    : 11 16-bit code units
-| B.h.<init>:(JLO1/a;Z)V
+| B.h.<init>:(JLA/h;Z)V
 |: iput-wide v1, v0, LB/h;.j:J
 |: iput-object v3, v0, LB/h;.k:LO1/a;
 |: iput-boolean v4, v0, LB/h;.l:Z
@@ -451010,7 +451010,7 @@
       registers     : 10
       ins           : 2
       outs          : 5
-      insns size    : 67 16-bit code units
+      insns size    : 69 16-bit code units
 | B.h.k:(Ljava/lang/Object;)Ljava/lang/Object;
 |: check-cast v9, LV/c;
 |: iget-object v0, v9, LV/c;.i:LV/a;
@@ -451040,9 +451040,10 @@
 |: invoke-direct {v2, v4, v7}, Landroid/graphics/PorterDuffColorFilter;.<init>:(ILandroid/graphics/PorterDuff$Mode;)V
 |: invoke-direct {v1, v5, v6, v3, v2}, LY/k;.<init>:(JILandroid/graphics/ColorFilter;)V
 |: new-instance v2, LB/g;
-|: iget-object v3, v8, LB/h;.k:LO1/a;
-|: iget-boolean v4, v8, LB/h;.l:Z
-|: invoke-direct {v2, v3, v4, v0, v1}, LB/g;.<init>:(LO1/a;ZLY/e;LY/k;)V
+|: iget-boolean v3, v8, LB/h;.l:Z
+|: iget-object v4, v8, LB/h;.k:LO1/a;
+|: check-cast v4, LA/h;
+|: invoke-direct {v2, v4, v3, v0, v1}, LB/g;.<init>:(LA/h;ZLY/e;LY/k;)V
 |: invoke-virtual {v9, v2}, LV/c;.b:(LO1/c;)LV/f;
 |: move-result-object v9
 |: return-object v9
@@ -451101,7 +451102,7 @@
       registers     : 9
       ins           : 4
       outs          : 5
-      insns size    : 81 16-bit code units
+      insns size    : 83 16-bit code units
 | B.i.h:(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 |: check-cast v6, LS/o;
 |: check-cast v7, LG/q;
@@ -451130,9 +451131,10 @@
 |: move-result-object v4
 |: if-nez v8, 003b // +0006
 |: sget-object v8, LG/l;.a:LG/Y;
-|: if-ne v4, v8, 0043 // +000a
+|: if-ne v4, v8, 0045 // +000c
 |: new-instance v4, LB/h;
-|: invoke-direct {v4, v0, v1, v2, v3}, LB/h;.<init>:(JLO1/a;Z)V
+|: check-cast v2, LA/h;
+|: invoke-direct {v4, v0, v1, v2, v3}, LB/h;.<init>:(JLA/h;Z)V
 |: invoke-virtual {v7, v4}, LG/q;.g0:(Ljava/lang/Object;)V
IzzySoft commented 1 month ago

Update: Integration completed, Canta going live at IzzyOnDroid with the next sync around 6 pm UTC:

image

Be welcome to pick a badge to link there e.g. from your Readme :smiley:

We will establish RB as soon as we can rebuild, see previous comment.

shuvashish76 commented 1 month ago

Added IzzyOnDroid badge with #107. Removed the "Fdroid has old versions only" warning as the version can be viewed from the Readme itself and the specific is already pinned at issue tracker anyway.

The IzzyOnDroid query color looks orange even though I explicitly mentioned it as blue &color=blue. Probably it's orange because currently resource not found, I hope it'll change back to blue with live on IzzyOnDroid.

IzzySoft commented 1 month ago

@shuvashish76 check again, it's blue now that the sync is through. And thanks! Any idea why F-Droid and Github badges have a V in front of the version? Ah, you've explicitly specified that with the API call. Looks a bit weird. Not my decision, but maybe skip the /v/ for the other two badges so it is more "streamlined"?

And @samolego, any word on the RB proposal? No pressure, just for orientation on my end? Thanks in advance!

shuvashish76 commented 1 month ago

maybe skip the /v/ for the other two badges so it is more "streamlined"?

For some reason it doesn't work for F-Droid if I remove that...but works for GitHub. I think Better to keep them that way as that's what it auto-generate from official https://shields.io/badges/f-droid-version and https://shields.io/badges/git-hub-release

IzzySoft commented 1 month ago

that's a bit stupid IMHO as it falsifies the versionName – but if that's the only way it works :man_shrugging:

PS: Wonder how that looks like for e.g. versionName: "v1.2.3". Would it then be "vv1.2.3"?

samolego commented 1 month ago

Hi, I'll take a look tomorrow, thanks for all the info but it's quite late here. :)

samolego commented 1 month ago

app-release.zip This was built using JDK 21 @IzzySoft

samolego commented 1 month ago

from https://github.com/samolego/Canta/tree/d0b7c6d163f4485d07bc72722f706d89f80d311f

IzzySoft commented 1 month ago

Unfortunately…

- -rw-r--r--  0.0 unx       56 b-       52 defN 1981-01-01 01:01:02 002514c6 META-INF/com/android/build/gradle/app-metadata.properties
- -rw-r--r--  0.0 unx      120 b-      118 defN 1981-01-01 01:01:02 edfd0d39 META-INF/version-control-info.textproto
- -rw-r--r--  0.0 unx     4186 b-     4186 stor 1981-01-01 01:01:02 c6a7ee79 assets/dexopt/baseline.prof
- -rw-r--r--  0.0 unx      525 b-      525 stor 1981-01-01 01:01:02 fc94c430 assets/dexopt/baseline.profm
- -rw-r--r--  0.0 unx  2159292 b-  2159292 stor 1981-01-01 01:01:02 6ba4a6c7 classes.dex
+ Archive:  7b50007f251d4f1c0262575ba32624592e298ceb9281ab1a59e78d2b6c811580-org.samo_lego.canta-d0b7c6d163f4485d07bc72722f706d89f80d311f-unsigned.apk
+ Zip file size: 2513888 bytes, number of entries: 127
+ -rw-r--r--  0.0 unx       56 b-       51 defN 1981-01-01 01:01:02 b337ed0c META-INF/com/android/build/gradle/app-metadata.properties
+ -rw-r--r--  0.0 unx      120 b-      118 defN 1981-01-01 01:01:02 4a2e1217 META-INF/version-control-info.textproto
+ -rw-r--r--  0.0 unx     3884 b-     3884 stor 1981-01-01 01:01:02 d0ac15a4 assets/dexopt/baseline.prof
+ -rw-r--r--  0.0 unx      498 b-      498 stor 1981-01-01 01:01:02 4012471a assets/dexopt/baseline.profm
+ -rw-r--r--  0.0 unx  2208052 b-  2208052 stor 1981-01-01 01:01:02 f7176bca classes.dex
  -rw----     2.0 fat     1738 b-      782 defN 1981-01-01 01:01:02 2d73be70 DebugProbesKt.bin
  -rw----     2.0 fat        6 b-        8 defN 1981-01-01 01:01:02 996dd6a3 META-INF/androidx.activity_activity-compose.version
  -rw----     2.0 fat        6 b-        8 defN 1981-01-01 01:01:02 996dd6a3 META-INF/androidx.activity_activity-ktx.version
@@ -59,8 +59,8 @@
  -rw----     2.0 fat        6 b-        8 defN 1981-01-01 01:01:02 5cd9fe4c META-INF/androidx.versionedparcelable_versionedparcelable.version
  -rw----     2.0 fat        5 b-        7 defN 1981-01-01 01:01:02 6a2f0318 META-INF/kotlinx_coroutines_android.version
  -rw----     2.0 fat        5 b-        7 defN 1981-01-01 01:01:02 6a2f0318 META-INF/kotlinx_coroutines_core.version
- -rw----     2.0 fat        5 b-        7 defN 1981-01-01 01:01:02 814bf0d3 META-INF/services/V1.u
- -rw----     2.0 fat        5 b-        7 defN 1981-01-01 01:01:02 aa66a310 META-INF/services/W1.a
+ -rw----     2.0 fat        5 b-        7 defN 1981-01-01 01:01:02 031b6702 META-INF/services/W1.v
+ -rw----     2.0 fat        5 b-        7 defN 1981-01-01 01:01:02 283634c1 META-INF/services/X1.a
  -rw----     2.0 fat      625 b-      278 defN 1981-01-01 01:01:02 0a447903 kotlin-tooling-metadata.json
  -rw----     2.0 fat      928 b-      561 defN 1981-01-01 01:01:02 8e787046 kotlin/annotation/annotation.kotlin_builtins
  -rw----     2.0 fat     3685 b-     1521 defN 1981-01-01 01:01:02 f41c30cf kotlin/collections/collections.kotlin_builtins
@@ -126,5 +126,5 @@
  -rw----     0.0 fat     4160 b-     4160 stor 1981-01-01 01:01:02 acdf06d3 res/yn.png
  -rw----     0.0 fat      221 b-      221 stor 1981-01-01 01:01:02 9944f31a res/z-.9.png
  -rw----     0.0 fat      532 b-      532 stor 1981-01-01 01:01:02 77b9176f res/zr.png
- -rw----     0.0 fat   165916 b-   165916 stor 1981-01-01 01:01:02 854707d8 resources.arsc
+ -rw----     0.0 fat   165916 b-   165916 stor 1981-01-01 01:01:02 e1399cb1 resources.arsc

Hm, META-INF/version-control-info.textproto differs? Interesting. Your APK claims to have been built from 7fb7af8336c2066342c950d6d4fcc7110df4c472 – that's 1 commit after the one you named. Let's try with that… and, surprise:

    "upstream_signed_apk_sha256": "2a462721b6437bfd9f8b4dc322e4f840c576d1ccdad9737adf7241a89615715f",
    "built_unsigned_apk_sha256": "6c3f242ce0fd8e44f56e8a0ef682d194c745c63501248d543332c9040468543e",
    "signature_copied_apk_sha256": "2a462721b6437bfd9f8b4dc322e4f840c576d1ccdad9737adf7241a89615715f"

That means it's RB! :partying_face: The hashes of the signed APKs match. Cool, we made it! Just make sure with the next release the APK was really built from (a clean tree at) the commit the tag points to, please – then give me a ping once it's there, and I set it up in my builder.

samolego commented 1 month ago

Oh sorry, idk how I messed that up. Thanks for all the help!

The released APKs get built from GH actions, so there shouldn't be an issue :).

IzzySoft commented 3 weeks ago

Will we have a proper one for testing before you make the next release? Just to be sure we're on the "safe side"?

samolego commented 3 weeks ago

You mean prerelease? Sure

IzzySoft commented 3 weeks ago

Can also be an APK attached here (renamed to *.zip) with the commit it was built from mentioned.

samolego commented 3 weeks ago

Could you try https://github.com/samolego/Canta/actions/runs/11581259212

It's zipped twice as I still have to fix the workflow, but otherwise it's the same as it will be on GH

IzzySoft commented 3 weeks ago

Passed RB :partying_face:

Btw: renaming the APK to *.zip was just for Github allowing you to attach it in an issue. No need to do what in the workflow :wink:

Give me a ping when the release is ready for pickup, will you?

samolego commented 3 weeks ago

Sure!

I know, but I thought that having 1 archived file with zip extensions will not rezip it when uploading artifact 😛 .

samolego commented 1 week ago

@IzzySoft 2.2.2 is out :tada:.

CodeWithTamim commented 1 week ago

@samolego do you have interest related to proxy in android?

samolego commented 1 week ago

@CodeWithTamim huh?

CodeWithTamim commented 1 week ago

@CodeWithTamim huh?

proxy/vpn

samolego commented 1 week ago

Uhm not really, haven't developed anything regarding that ...

IzzySoft commented 1 week ago

2.2.2 is out 🎉.

Funny, the release is not marked "latest" :thinking: Running the build now…

Pointer (just a warning in the logs), in case you missed it:

> Task :app:compileReleaseJavaWithJavac
Java compiler version 21 has deprecated support for compiling with source/target version 8.
Try one of the following options:
    1. [Recommended] Use Java toolchain with a lower language version
    2. Set a higher source/target version
    3. Use a lower version of the JDK running the build (if you're not using Java toolchain)
For more details on how to configure these settings, see https://developer.android.com/build/jdks.

Apart from that: it's RB :partying_face: So let's prepare the welcome toot:

image

Btw, for the initial question by @CodeWithTamim: you're aware that self-updaters are violating the inclusion policy at IzzyOnDroid (as well as on F-Droid)? There's a small "gray zone": it's tolerated if the update check is strictly opt-in (i.e. not enabled by default and clearly points out the implications, namely that those updates would bypass the additional checks performed at IzzyOnDroid (or F-Droid). So please keep that in mind. Also note that updates here at Github usually show up at IzzyOnDroid within 24h, so you'd get your update notification from your F-Droid client :wink: