Hello everyone ![]()
Thanks to @Bruno_Lima’s recent question about updating the app through GitHub releases, I found the topic very interesting.
I experimented a bit and came up with a project that’s fairly functional and not too complex, which I wanted to share with all of you.
We’ll mainly use the following components:
- Web
- File
- Network
- TinyDB
- and the APKInstaller extension by our dear
@Riad_Developer 
We’ll have two functions
-
githubGetLatestRelease
Will be used in theScreen.Initializeevent and will make a request to the GitHub API, providing us with information about the latest release. -
githubVerifyRelease
Will be used as soon as we receive the information.
It will check the release name against the app version, and if they differ, it will download the updated version.
these functions were created just to be compressed and “forgotten” in the project without causing any clutter
In the same way, they can be used directly without having to call them through a function.
githubGetLatestRelease
Given the simplicity, I’ll just point out that Web.URL will be
where OWNER is the GitHub username and REPO is the repository name but later on, we’ll briefly see how to retrieve it.
githubVerifyRelease
This function will receive the responseContent from Web_GithubAppUpdate.GotText and format the response.
Below is an example that can be referred to.
response Content
{
"assets": [
{
"browser_download_url": "https://github.com/OWNER/REPO/releases/download/NAME(VERSION)/APPNAME.apk",
"content_type": "application/vnd.android.package-archive",
"created_at": "2025-10-31T18:49:13Z",
"digest": "sha256:bcb2df704fe29c2deeebeeb02603e91dra022e43ce414917abf511758b20525",
"download_count": 1,
"id": 309359408,
"label": "null",
"name": "APPNAME.apk",
"node_id": "RA_kwDOQKPENM2ScHMw",
"size": 10579386,
"state": "uploaded",
"updated_at": "2025-10-31T20:57:38Z",
"uploader": {
"avatar_url": "https://avatars.githubusercontent.com/u/104521385?v=4",
"events_url": "https://api.github.com/users/OWNER/events{/privacy}",
"followers_url": "https://api.github.com/users/OWNER/followers",
"following_url": "https://api.github.com/users/OWNER/following{/other_user}",
"gists_url": "https://api.github.com/users/OWNER/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/OWNER",
"id": 108671385,
"login": "OWNER",
"node_id": "U_kgD4BJjSCQ",
"organizations_url": "https://api.github.com/users/OWNER/orgs",
"received_events_url": "https://api.github.com/users/OWNER/received_events",
"repos_url": "https://api.github.com/users/OWNER/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/OWNER/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/OWNER/subscriptions",
"type": "User",
"url": "https://api.github.com/users/OWNER",
"user_view_type": "public"
},
"url": "https://api.github.com/repos/OWNER/REPO/releases/assets/309354408"
},
{
"browser_download_url": "https://github.com/OWNER/REPO/releases/download/NAME(VERSION)/something.txt",
"content_type": "text/plain",
"created_at": "2025-10-31T21:04:36Z",
"digest": "sha256:45aad2fe9636e92a19f6deeef9cb2392847ac33d6d3d4b1fb65eb9ef8c3d5a66",
"download_count": 1,
"id": 302295109,
"label": "null",
"name": "something.txt",
"node_id": "RA_kwDOTKPENM4ScP6l",
"size": 11,
"state": "uploaded",
"updated_at": "2025-10-31T21:04:37Z",
"uploader": {
"avatar_url": "https://avatars.githubusercontent.com/u/108584785?v=4",
"events_url": "https://api.github.com/users/OWNER/events{/privacy}",
"followers_url": "https://api.github.com/users/OWNER/followers",
"following_url": "https://api.github.com/users/OWNER/following{/other_user}",
"gists_url": "https://api.github.com/users/OWNER/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/OWNER",
"id": 108582355,
"login": "OWNER",
"node_id": "U_kgDOBnjICQ",
"organizations_url": "https://api.github.com/users/OWNER/orgs",
"received_events_url": "https://api.github.com/users/OWNER/received_events",
"repos_url": "https://api.github.com/users/OWNER/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/OWNER/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/OWNER/subscriptions",
"type": "User",
"url": "https://api.github.com/users/OWNER",
"user_view_type": "public"
},
"url": "https://api.github.com/repos/OWNER/REPO/releases/assets/309392909"
}
],
"assets_url": "https://api.github.com/repos/OWNER/REPO/releases/257322570/assets",
"author": {
"avatar_url": "https://avatars.githubusercontent.com/u/108671385?v=4",
"events_url": "https://api.github.com/users/OWNER/events{/privacy}",
"followers_url": "https://api.github.com/users/OWNER/followers",
"following_url": "https://api.github.com/users/OWNER/following{/other_user}",
"gists_url": "https://api.github.com/users/OWNER/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/OWNER",
"id": 108255385,
"login": "OWNER",
"node_id": "U_kgDHBnjSCQ",
"organizations_url": "https://api.github.com/users/OWNER/orgs",
"received_events_url": "https://api.github.com/users/OWNER/received_events",
"repos_url": "https://api.github.com/users/OWNER/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/OWNER/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/OWNER/subscriptions",
"type": "User",
"url": "https://api.github.com/users/OWNER",
"user_view_type": "public"
},
"body": "- Fixed some bugs\r\n- Better UI\r\n- Removed malware\r\n- Added something.txt",
"created_at": "2025-10-31T18:19:36Z",
"draft": false,
"html_url": "https://github.com/OWNER/REPO/releases/tag/NAME(VERSION)",
"id": 257602570,
"immutable": false,
"name": "NAME(VERSION)",
"node_id": "RE_kwDOQKPJNM4PWrQK",
"prerelease": false,
"published_at": "2025-10-31T18:20:51Z",
"tag_name": "NAME(VERSION)",
"tarball_url": "https://api.github.com/repos/OWNER/REPO/tarball/NAME(VERSION)",
"target_commitish": "main",
"updated_at": "2025-10-31T21:04:50Z",
"upload_url": "https://uploads.github.com/repos/OWNER/REPO/releases/257654570/assets{?name,label}",
"url": "https://api.github.com/repos/OWNER/REPO/releases/257690570",
"zipball_url": "https://api.github.com/repos/OWNER/REPO/zipball/NAME(VERSION)"
}
I’ll try to explain it briefly
-
If the version of our app differs from the one listed in the latest release,
- it saves the response containing all the information in TinyDB, adding a key
toRead = trueand a keyinfoscontaining theformattedResponse. - We then create the variable assets, which points to
assets(the list containing all the files in the release) from theformattedResponse. - When looping through it, if an asset with an
.apkextension is found, it downloads it toupdate/assetNameand stops, usingbreak(assuming there’s only one APK file)
- it saves the response containing all the information in TinyDB, adding a key
-
If the app version is already up to date, the function deletes the APK file from the app’s folder
- Here’s where
toReadcomes into play, since it’s set totrue, it triggers anifstatement that displaysinfos > bodyfrom theformattedResponsesaved in TinyDB, which represents the update details. - It then sets
toRead = falseand updatesupdateInfos. - So, if the version is up to date and there’s nothing to read in
updateInfos, we inform the user that there are no updates available.
- Here’s where
Web_GithubAppUpdate.GotText
Since we’ll only be downloading one APK, this block will simply call APKInstaller, where we’ll specify the file name, which in this case will be update/assetName.apk.
Github
let’s move on to GitHub by quickly creating a project.
We’ll start by creating a new repository.
The repository name will be the value we need to replace in the app as
REPO.
![]()
after creating a codespace, we’ll be able to create our first release
we fill in all the fields, add the APK file, and we’re done!
From now on, it will be enough to create a new release to have all our clients updated ![]()
For example, we could implement a block that forces the user to use the latest version.
AIA
GithubAppUpdate.aia (54.4 KB)
Notes
I’ve tested the extension on several devices and didn’t encounter any issues.
I haven’t been able to test it on Android 15 yet, but I hope it works.
Thanks again, Riad_Developer!
Take this project as a base to improve or modify,
it’s a starting point.
There are many other things you can add or do differently.
Happy
oding!






