From 8281a1a68e16991a425f257360d490be69a17633 Mon Sep 17 00:00:00 2001 From: smk762 Date: Mon, 30 Oct 2023 16:42:47 +0800 Subject: [PATCH 01/28] update rates url --- lib/app_config/app_config.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/app_config/app_config.dart b/lib/app_config/app_config.dart index 57d6eadc2..9a0edb0c5 100644 --- a/lib/app_config/app_config.dart +++ b/lib/app_config/app_config.dart @@ -188,7 +188,7 @@ class AppConfig { // endpoint source code: // https://github.com/KomodoPlatform/mobile_endpoints_proxy/blob/main/main.py#L113 String get fiatPricesEndpoint => - 'https://rates.komodo.earth/api/v1/usd_rates'; + 'https://defi-stats.komodo.earth/api/v3/rates/fixer_io'; // endpoint source code: // https://github.com/KomodoPlatform/mobile_endpoints_proxy/blob/main/main.py#L95 From 523e7c11640b3a2f58d558a3a35349ef86c1bf1b Mon Sep 17 00:00:00 2001 From: Francois Date: Sun, 10 Mar 2024 20:43:33 +0200 Subject: [PATCH 02/28] Add docker image and devcontainer Only Linux and WSL on x86 are supported at the moment --- .devcontainer/devcontainer.json | 14 ++ .docker/android-apk-build.dockerfile | 46 ++++++ .docker/android-dev.dockerfile | 27 ++++ .docker/build_config.json | 29 ++++ .docker/requirements.txt | 3 + .docker/update_api.py | 229 +++++++++++++++++++++++++++ 6 files changed, 348 insertions(+) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .docker/android-apk-build.dockerfile create mode 100644 .docker/android-dev.dockerfile create mode 100644 .docker/build_config.json create mode 100644 .docker/requirements.txt create mode 100644 .docker/update_api.py diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..f76a922fb --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,14 @@ +{ + "name": "flutter_docker", + "context": "..", + "dockerFile": "../.docker/android-dev.dockerfile", + "remoteUser": "mobiledevops", + "settings": { + "terminal.integrated.shell.linux": null + }, + "runArgs": [ + "--privileged" + ], + "workspaceMount": "source=${localWorkspaceFolder},target=/home/mobiledevops/workspace,type=bind,consistency=delegated", + "workspaceFolder": "/home/mobiledevops/workspace" +} \ No newline at end of file diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile new file mode 100644 index 000000000..d87b152c0 --- /dev/null +++ b/.docker/android-apk-build.dockerfile @@ -0,0 +1,46 @@ +FROM ubuntu:latest as build + +RUN apt update && apt upgrade -y && apt install -y python3 python3-pip git curl && \ + mkdir -p /home/mobiledevops && \ + git clone https://github.com/KomodoPlatform/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile && \ + cd /home/mobiledevops/komodo-wallet-mobile && \ + curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins && \ + curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json && \ + mkdir -p android/app/src/main/cpp/libs/armeabi-v7a && \ + mkdir -p android/app/src/main/cpp/libs/arm64-v8a && \ + python3 -m pip install -r .docker/requirements.txt && \ + python3 .docker/update_api.py --force + +FROM mobiledevops/android-sdk-image:34.0.0-jdk17 as final + +ENV FLUTTER_VERSION="2.8.1" +ENV FLUTTER_HOME "/home/mobiledevops/.flutter-sdk" +ENV USER="mobiledevops" +ENV PATH $PATH:$FLUTTER_HOME/bin + +# Download and extract Flutter SDK +RUN mkdir $FLUTTER_HOME \ + && cd $FLUTTER_HOME \ + && curl --fail --remote-time --silent --location -O https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ + && tar xf flutter_linux_${FLUTTER_VERSION}-stable.tar.xz --strip-components=1 \ + && rm flutter_linux_${FLUTTER_VERSION}-stable.tar.xz + +ENV ANDROID_HOME "/opt/android-sdk-linux" +ENV ANDROID_SDK_ROOT $ANDROID_HOME +ENV PATH $PATH:$ANDROID_HOME/cmdline-tools:$ANDROID_HOME/cmdline-tools/bin:$ANDROID_HOME/platform-tools + +RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --update && \ + sdkmanager --install "cmdline-tools;latest" --sdk_root=${ANDROID_SDK_ROOT} && \ + sdkmanager --install "platform-tools" --sdk_root=${ANDROID_SDK_ROOT} + +RUN flutter config --no-analytics --android-sdk=$ANDROID_HOME \ + && flutter precache \ + && yes "y" | flutter doctor --android-licenses \ + && flutter doctor \ + && flutter update-packages + +COPY --from=build /home/mobiledevops/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile + +WORKDIR /home/$USER/komodo-wallet-mobile + +CMD [ "flutter", "build", "apk", "--release" ] \ No newline at end of file diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile new file mode 100644 index 000000000..4c2d327b1 --- /dev/null +++ b/.docker/android-dev.dockerfile @@ -0,0 +1,27 @@ +FROM mobiledevops/android-sdk-image:34.0.0-jdk17 as final + +ENV FLUTTER_VERSION="2.8.1" +ENV FLUTTER_HOME "/home/mobiledevops/.flutter-sdk" +ENV USER="mobiledevops" +ENV PATH $PATH:$FLUTTER_HOME/bin + +# Download and extract Flutter SDK +RUN mkdir $FLUTTER_HOME \ + && cd $FLUTTER_HOME \ + && curl --fail --remote-time --silent --location -O https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ + && tar xf flutter_linux_${FLUTTER_VERSION}-stable.tar.xz --strip-components=1 \ + && rm flutter_linux_${FLUTTER_VERSION}-stable.tar.xz + +ENV ANDROID_HOME "/opt/android-sdk-linux" +ENV ANDROID_SDK_ROOT $ANDROID_HOME +ENV PATH $PATH:$ANDROID_HOME/cmdline-tools:$ANDROID_HOME/cmdline-tools/bin:$ANDROID_HOME/platform-tools + +RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --update && \ + sdkmanager --install "cmdline-tools;latest" --sdk_root=${ANDROID_SDK_ROOT} && \ + sdkmanager --install "platform-tools" --sdk_root=${ANDROID_SDK_ROOT} + +RUN flutter config --no-analytics --android-sdk=$ANDROID_HOME \ + && flutter precache \ + && yes "y" | flutter doctor --android-licenses \ + && flutter doctor \ + && flutter update-packages diff --git a/.docker/build_config.json b/.docker/build_config.json new file mode 100644 index 000000000..d0cb91a42 --- /dev/null +++ b/.docker/build_config.json @@ -0,0 +1,29 @@ +{ + "api": { + "version": "b0fd99e", + "should_update": true, + "base_url": "https://sdk.devbuilds.komodo.earth", + "default_branch": "main", + "platforms": { + "ios": { + "keywords": [ + "ios", + "aarch64" + ], + "path": "ios" + }, + "android-armv7": { + "keywords": [ + "android-armv7" + ], + "path": "android/app/src/main/cpp/libs/armeabi-v7a" + }, + "android-aarch64": { + "keywords": [ + "android-aarch64" + ], + "path": "android/app/src/main/cpp/libs/arm64-v8a" + } + } + } +} \ No newline at end of file diff --git a/.docker/requirements.txt b/.docker/requirements.txt new file mode 100644 index 000000000..6a46b2c28 --- /dev/null +++ b/.docker/requirements.txt @@ -0,0 +1,3 @@ +requests==2.31.0 +beautifulsoup4==4.12.2 + diff --git a/.docker/update_api.py b/.docker/update_api.py new file mode 100644 index 000000000..dd160b489 --- /dev/null +++ b/.docker/update_api.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python3 +import os +import re +import sys +import json +import shutil +import zipfile +import requests +import argparse +import subprocess +from pathlib import Path +from datetime import datetime +from bs4 import BeautifulSoup + + +class UpdateAPI(): + '''Updates the API module version for all or a specified platform.''' + def __init__(self, version=None, platform=None, force=False): + self.version = version + self.platform = platform + self.force = force + + # Get the absolute path of the project root directory + self.project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + self.config_file = os.path.join(self.project_root, ".docker/build_config.json") + + # Load the build_config.json + with open(self.config_file, "r") as f: + self.config = json.load(f) + + # Use version from build_config.json if version is not specified + if not self.version: + self.version = self.config["api"]["version"] + + # Get the platforms config + self.platforms_config = self.config["api"]["platforms"] + + # Get the base URL and branch for the API module + self.base_url = self.config["api"]["base_url"] + self.api_branch = self.config["api"]["default_branch"] + + + def get_platform_destination_folder(self, platform): + '''Returns the destination folder for the specified platform.''' + if platform in self.platforms_config: + return os.path.join(self.project_root, self.platforms_config[platform]["path"]) + else: + raise ValueError(f"Invalid platform: {platform}. Please select a valid platform from the following list: {', '.join(self.platforms_config.keys())}") + + def get_zip_file_url(self, platform, branch): + '''Returns the URL of the zip file for the requested version / branch / platform.''' + response = requests.get(f"{self.base_url}/{branch}/") + response.raise_for_status() + + # Configure the HTML parser + soup = BeautifulSoup(response.text, "html.parser") + search_parameters = self.platforms_config[platform] + keywords = search_parameters["keywords"] + extensions = [".zip"] # Assuming that the extensions are the same for all platforms + + # Parse the HTML and search for the zip file + for link in soup.find_all("a"): + file_name = link.get("href") + if all(keyword in file_name for keyword in keywords) \ + and any(file_name.endswith(ext) for ext in extensions) \ + and self.version in file_name: + return f"{self.base_url}/{branch}/{file_name}" + return None + + def download_api_file(self, platform): + '''Downloads the API version zip file for a specific platform.''' + # Get the URL of the zip file in the main directory + zip_file_url = self.get_zip_file_url(platform, self.api_branch) + + # If the zip file is not found in the main directory, search in all directories + if not zip_file_url: + response = requests.get(self.base_url) + response.raise_for_status() + soup = BeautifulSoup(response.text, "html.parser") + + for link in soup.find_all("a"): + branch = link.get("href") + zip_file_url = self.get_zip_file_url(platform, branch) + + if zip_file_url: + print(f"'{platform}': Found zip file in '{branch}' folder.") + break + + if not zip_file_url: + raise ValueError(f"Could not find zip file for version '{self.version}' on '{platform}' platform!") + + # Download the zip file + print(f"Downloading '{self.version}' API module for [{platform}]...") + response = requests.get(zip_file_url, stream=True) + response.raise_for_status() + + destination_folder = self.get_platform_destination_folder(platform) + zip_file_name = os.path.basename(zip_file_url) + destination_path = os.path.join(destination_folder, zip_file_name) + + # Save the zip file to the specified folder + with open(destination_path, "wb") as file: + response.raw.decode_content = True + shutil.copyfileobj(response.raw, file) + + print(f"Saved to '{destination_path}'") + return destination_path + + def update_documentation(self): + '''Updates the API version in the documentation.''' + documentation_file = f"{self.project_root}/docs/UPDATE_API_MODULE.md" + + # Read the existing documentation file + with open(documentation_file, "r") as f: + content = f.read() + + # Update the version information in the documentation + updated_content = re.sub( + r"(Current api module version is) `([^`]+)`", + f"\\1 `{self.version}`", + content + ) + + # Write the updated content back to the documentation file + with open(documentation_file, "w") as f: + f.write(updated_content) + + print(f"API version in documentation updated to {self.version}") + + def update_api(self): + '''Updates the API module.''' + if self.config["api"]["should_update"]: + version = self.config["api"]["version"][:7] + platforms = self.config["api"]["platforms"] + + # If a platform is specified, only update that platform + if self.platform: + platforms = {self.platform: platforms[self.platform]} + + for platform, platform_info in platforms.items(): + # Set the api module destination folder + destination_folder = self.get_platform_destination_folder(platform) + + # Check if .api_last_updated file exists + last_api_update_file = os.path.join(destination_folder, ".api_last_updated") + + is_outdated = True + + if not self.force and os.path.exists(last_api_update_file): + with open(last_api_update_file, "r") as f: + last_api_update = json.load(f) + if last_api_update.get("version") == version: + print(f"{platform} API module is up to date ({version}).") + is_outdated = False + + if is_outdated: + # Download the API file for the platform + zip_file_path = self.download_api_file(platform) + + # Unzip the downloaded file + print(f"Extracting...") + with zipfile.ZipFile(zip_file_path, 'r') as zip_ref: + zip_ref.extractall(destination_folder) + + # Update wasm module + if platform == 'web': + print(f"Updating WASM module...") + npm_exec = "npm.cmd" if sys.platform == "win32" else "npm" + # If we dont do this first, we might get stuck at the `npm run build` step as there + # appears to be no "non-interactive" flag to accept installing deps with `npm run build` + result = subprocess.run([npm_exec, "install"], capture_output=True, text=True) + if result.returncode == 0: + print("npm install completed.") + else: + print("npm install failed. Please make sure you are using nodejs 18, e.g. `nvm use 18`.)") + print(result.stderr) + sys.exit(1) + + result = subprocess.run([npm_exec, "run", "build"], capture_output=True, text=True) + if result.returncode == 0: + print("Done.") + else: + print("npm run build failed. Please make sure you are using nodejs 18, e.g. `nvm use 18`.)") + print(result.stderr) + sys.exit(1) + + # Make mm2 file executable for Linux + if platform == 'linux': + print("Make mm2 file executable for Linux") + os.chmod(os.path.join(destination_folder, "mm2"), 0o755) + + # Delete the zip file after extraction + os.remove(zip_file_path) + + # Update .api_last_updated file + with open(last_api_update_file, "w") as f: + current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + json.dump({"version": version, "timestamp": current_timestamp}, f) + + # Update the API version in documentation + # self.update_documentation() + + def update_build_config_version(self): + '''Updates the API version in build_config.json.''' + self.config["api"]["version"] = self.version + + with open(self.config_file, "w") as f: + json.dump(self.config, f, indent=4) + + print(f"Version in build_config.json updated to {self.version}.") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Download API module file for specified version and platform.") + # Optional arguments + parser.add_argument("-a", "--api", help="version of the API module to download.", default=None) + parser.add_argument("-p", "--platform", help="platform for which the API module should be downloaded.", default=None) + parser.add_argument("--force", action="store_true", help="force update, ignoring .api_last_updated.", default=False) + args = parser.parse_args() + + try: + updateAPI = UpdateAPI(args.api, args.platform, args.force) + # Update the API version in build_config.json if the API version is specified + if args.api: + updateAPI.update_build_config_version() + updateAPI.update_api() + + except Exception as e: + print(f"Error: {e}") \ No newline at end of file From 69d98b2a2856f0b8983b373e79ff829ffef0c0b2 Mon Sep 17 00:00:00 2001 From: Kadan Stadelmann Date: Mon, 13 May 2024 12:25:31 +0200 Subject: [PATCH 03/28] SSL migration (#143) * Update coins to SSL config * Rename references to SSL coin config * Prefer SSL, but fall back to TCP if not available. `coins_config_ssl` delists coins without SSL support whereas `coins_config_tcp` favours SSL but falls back to TCP if not available. * Sync latest TCP file from coins repo * bump target SDK https://developer.android.com/google/play/requirements/target-sdk Signed-off-by: Kadan Stadelmann * Bump app build Signed-off-by: Charl (Nitride) <77973576+CharlVS@users.noreply.github.com> --------- Signed-off-by: Kadan Stadelmann Signed-off-by: Charl (Nitride) <77973576+CharlVS@users.noreply.github.com> Co-authored-by: CharlVS <77973576+CharlVS@users.noreply.github.com> --- android/app/build.gradle | 2 +- assets/coin-icons/aibc.png | Bin 12796 -> 0 bytes assets/coins.json | 19 + ...oins_config.json => coins_config_tcp.json} | 8130 +---------------- coins_ci.json | 2 +- ios/Runner.xcodeproj/project.pbxproj | 4 +- lib/app_config/coins_updater.dart | 7 +- pubspec.yaml | 4 +- 8 files changed, 265 insertions(+), 7903 deletions(-) delete mode 100644 assets/coin-icons/aibc.png rename assets/{coins_config.json => coins_config_tcp.json} (83%) diff --git a/android/app/build.gradle b/android/app/build.gradle index 43fa59080..d57a5e436 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -38,7 +38,7 @@ android { defaultConfig { applicationId "com.komodoplatform.atomicdex" minSdkVersion 28 - targetSdkVersion 31 + targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName buildConfigField "Long", "BUILD_TIME", "" + System.currentTimeMillis() + "L" diff --git a/assets/coin-icons/aibc.png b/assets/coin-icons/aibc.png deleted file mode 100644 index 28f17e26bf3885027d9eb039e3224152f9f991e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12796 zcmZ`=Wmp_N*T&rnTPPG+U~zYMch>^Ny|@-z+@ZL;m14yT6kFWg-J!UJCie!s>(8$Xhdi*Fff>MvXbi1((Av3f&|U^%(iI9h4mkcahgKrH$tg)8|AWQF;Xn@0oJWCyVLg_U6w~xt zKF#s;GMLMF7r9q<%p|mtCb~6RGjC~H?C)O$qcR!Gn(A|dT8F|w<^hLUby;glfl9%9 za!X3$;7L<^j6bl!wX3yz^m>VNK7?{J&+VNe)%FxIUHx^8cpVe2WFoGWEvFpkbm!g^ zJ_yx{s9=YiNjPcXXIeOyKw=1DG0YIy{MU`q>HXA52hDz-L0C z-I3Q#vRx@dx@kCSNDN#JZaShOJQ{44J`fTA?ka|$klMwNOe_m-`VDD`crHRfD>Z=9l_Zr=F`*mAS%MkCsVgu zuYX5(lPd=nUZBAUnuvwZ)CoT#q|F8sLzK(J0Emp1B-|CSS#zSldc;c^B4aqw=RrbU zq7m!D*g1wh4IUU%vqzkg66$X>r$XH$Tw^BI zxy)jX1B(?}IyY6dRB0n+H0HDvS;@j`XK+zt`z+7h%+wY&E|%GB1zQ$pdW`K2KNo)$ zT9tIDJQWZH4h60b167V1KPf_zsyl%Art& zck_r>^|S@|Tk?D}Bn=bV;&mck3^83B0K)>ETfWjNVnOJEc%tN8gI)gH=63&dNP;rCc5LQED_b`v zJJ*1*uc%VSIv@?iDX3WJsZDw%u0AenoRQ$9c8C80u7VilM~`4UxxnEEx+T*;@Eezi z)hK6Z?;9U>+tbSv>y9EVx3-<|PmWc;lJuIHpt&k0@6)KMS(k8bh^ralw(#LIa>GXy zx&Y&ZGkI-mDGX1AlRJ_kv@5772f~0+z@MTxVpKtlwBfY4H_|re7t@P^iW2o%fBVIb zJ|pwZu}f0q8qaGIpj%n|$g`jVL`^U9OWt-d$7K_PK1H<#>I9C_YI$J;U)y2uRloOC z1ZD-MAmt46IhIDxjkwSaH|?PIdLPS*)Mzzv@ct_)ob1iE8Pe2ROjoxrDF&hzDaC_f z=sy~%#Ei!Q%a);ICy_2uhXgt8Z|vMkgcRWdjVCKI^pAKoEP_SF!w&b#N7ECf#e*6Y zKT}tHzy+dHOo=9kX-Ld+W2m}ThWjB4@M^CF%hi}3W;5<9Do`%{DybUjIrb4)@@tMa z<`rf|d-4X1V6k>dR7D~&!bF1w0_TVt(|LR{C7Sn^#pTgX8r+_|%^Z1J?>x<>6)My7 zy0?D;EVUPDnSSSU*oaZ##&$>QV+Z%B{W&`_>-}6*!XYZ7@}pmS1G%H6&{x1hiVg(I zcp(;m>V;hm9p#t}dDeg&)^kSK0uk#{fwul;0sW0;|aXOr}T&F5EANj(Sc;GfB< z)4e{D(-Wa(78x^j2DD8Yu%RMwHxeNmtrFP*55aQZB4f^TLw$6W&}O#DYw2%&G<^88 ztP+09tu4XGK8T|V6bUFJ6)TZWH3=9)iFZ7K?5H^X8jEMaIq=#kIc*-#ObBF>Q!z1O z*RBYBo}VZw9u3V`Cs$x)2W)#8lFj*KdY^?BH8k9CG!BkOc^_&5^vi{~M)6p!@LO+9>C-rf$2^K$%(+KN}ZJPD<-q{xJm(N zBBt*bqS&r%PW;A8NpN)_N|hmb9MAVi8s>Njxgz`wjT9w^xSUl+fxP!{soh2wNk-o3%7}}%tJHL-{5CZqdQ97R#cqZEUA)8M2)4|ZDElDy6 zxz9R1Q9akW(~`|O3ibOYog&tJvL2@5d1j_(dtS=9&svzn!#v13eM>XO-<%M<2p`Cu ztlQ2N+)>Ayh#w+>PIEW7(fb>n25~*rJIL|b<_iU|4!ViG0V3%mL4^3D(p-T*M#m*c zt6#gFJ;?6ZcO$?4;l48k#8Nx8!fT%M^>G9UMNIuHX{N<&9g`IEr?1dfrUaxc-pErT z+pRHXTOK?imN(oZ%?U{)m;##Y8HQu#o7=&c2$hJ{$fW9#n$-qBDBg}mQYV*5wm06( zVDnf;vCk$p0|gAtOAkM2Q6MWL==x5m<$8I8$S*7{fbJUi?sI zz+ZQ9&%7v6IjH^Cl=bzsB_&()qsY50x1ES(kG1B^JjtH9T}0zo{vn7{w(QL?^0RW^ z4sK0{(a2XGQi?g7lAnX2eWv-9oWb6%(R}`OX#`&#rBbPcTj)tXg!EVEQ|A64C~O!Q z6MZo~Hxq>U4E_Sn`*dS^M^oeOyrD$+;_b>3us%C9%tuZ7Q|%icpNX0&9apdCh1Bqw8=8Cw}+j?cu{BSgI0QiX}()3aJj@i9qR zN4*3buA-=WXM%vV8yn3+|?*)B=rW)lvo{8Iw?mHvl#{T~MH}af9Vxgas zSlK8p*TG6|w*#`i%}a4=oJ0qGX;|0$? zhJF@yP$mN+hptr%6^L3Qj-E_m>{O{y{Vivsm-7A!r>y9dT@B8xwbl9j2>8pD5%AcM zgpr0dOVMfvxB6Ixzx=%>LNr35@Xep)8Jm;MRhk(~2A8`v0Ud7P z@G?0UvBE>^rZE&Pg=Wh3Olto<9;beXy7ARN zqk+nlPIZ*_u{68#fU-g4Bf|h32plWkL#;H^sBUX7v;Q4FL1#cg9@CryX|qrU%W5i= zD`9V42=RhD`&sdKlT#u#Mf%hR4o&eATuj9!`g9B<-PY3_-}Fh5f>RHgW@l#3cj7GQ zK)8vMlON@jWdZP9v}`5>#n^DXpC1zB%^$brqo2BN4+Wo(a3(tV2M-+Tt{{KS)f2gH zT6bQKYGpG`!F>hvJXP+qP*JW|I>bgP+cg>!-Iy}ySv8`OKMU_a{~ruCZZ#Vp@h zmWhsX)v5})hs9oGqCdtKKIq2#@wl|($C&+VXG1tkJXJyA-8ks02*)Vp1a^RV%Rxax z0u0xG99p7f80od2RntDnub3H&c5FyIRjs!z&G5S=R{}DAEb4XYbniIm#DPQyo=3nT zer=hN^Ue)Ce=Q9+=McP^z#2w(%g6OPHU8l!%n$i-e{N0emhfN4>pG${IM9d2TutXu zlL<6ZW1s&uee4$LFm9{Z1qUcYxDfZF7njr|M#g7 z`f57HToX}M)Du43{pw}ThEKN+x z6!>Z7#}WLn=)d7D_WFE|d|}@yojg4-kZ+N2#DXFA*C|Y zQ*iZ(#*N6ToTJp7o>Og`md;%HKn{nS&=_*+a8_e+`6E8Y#@^!uMVLx zr&ci;(OJMN-d%nB*}#tLcfSLE%Yi=hAym~B+^vzO47!OqAiU5S0(=iy7m4HR!@&x# za~-l?SauAk!(~E|KMZ6f4A|^%k)A%K2XoQJjF;cTWk=#RW#12JS(cjljPH1>e;_D7!nY7`D$+FB z+Qa7ieO!vVOr5x}bi{_?`tq+@%~*MmL0htz6LE|g+bXASB_{4Qrq0JdhvoI(;CC0 ziWeC+Qz3!R2afc9V_@f7Brb6Tb=9Gf1c6CH^_~PepB=zua0`1S6+h|coqh|;b5hrP zB*X!-28U8VW!;BF`pR0qhYbA&-}wO|sTZ5uLzBiR7e|RwCtQr#54|hsZ$dR_|*AkKeRzi=v znvn?LaZ>kOfGUb&B$df*Z#X4gk@|0ItM}Cqjg6xSOXnMv7AJM>P8BKEyd_7y=)ks( zcCJrRT9TpjFuP{49^#YWm40&Hw}FjQV%tqDV6FLIY5yl5ZtpqboVGf7%7xc1=8@Lv z-REkqK_V`8U*34Tns)8#^74e8%Vx%rx|93oy#cZS0}o!}wAXbQy(;`&ftsOInLkyj zcK#ePZx7w(-qLaM{wKmoZEXfjMF}^-h@UUJ^vXUuvh{zv&dZ}~)wQs+yee1miy9st=CGhn ziu~fx5{mhm`?pCC()Q(uKmu<3NW(1x6eePX$30qD8VPWYI*FRfr$!lKInkEVu}#ztwvv5(uQ@xL z&)o@|lb8)dbW~LH?fjR4Q~g8`x!k$%&Gn=2j<$wDC0qdlO=b$$w1pl&JvzpTV^oqU z{*dwqu|pXp36t+gzX_>KC1{7#$)lXwsHC-OGb=ei6kb^zep`3y!5mFz+cA8faAD zOH*9SzIj4K;$#)Cp@djwCgrK~bRqyE%7>;QCONdIkNPu58@5bo)7mw=5F?>m@uRvd zHBr{XllSA*o?;gF>8O=lqSs+b8VbVtxQB85l5T_bR61E#A3bj5=B3vsLc*?t>)0Qz6?%eR&0i0k>*tY3YX^vNur$g^~1eRXsgI2JOn`)pMWj+pEA2{!eZM->YQ( ze-X(A!PZE2NQl;mi4OHv;Hhb&DA#}ba5XJ?w1THQ1}Bw4fpXEG@JVS6?~BM+*D)?A z8(b8Za)o@Lecgft!kdLL=;`V0EHC{{bo*;GrlPf_h+BT1BHI+C7Y?3InvbF#YCu=| z9?01$Dp4kxsRZ1hGWv6~@bTkEb1SR7$81@U*M5f8Ct~8=^0Hha4*RJ?H%)DAbxln- z!mqb`Q~5N?8?xC3;ZcBS*%5He42AI|TK?`NcNFcCQzdl0b0ojn5NTdUPf5G=TKK15 z52{{_hJOJ$%ATc_Wo6;;$XGa7;e1{fz}wqfv;LC3y}e4K_NQQjv#9y3f!CLb5s3&m z-XzIoBoHw^E4}w=m1rso0KQNRnNBTaIN)xwu?q)af$zqqDR@AP|^*nDu67 z%C9fm1kU_9^5Sa78QdzE1=5jly z6HixBQL!^yu3=>awbO2HZmJp@J##u={g9mGD=@LxqpcCwEb3251fUc`q83Gv8ZxCnVU9G! zH2XocA2yga$cSMRJ5V2C?ZNwPT;Y3r?yq0;2FwfTS5TjqZ8i|se(bsGz|;A> zb{-);pd3`GTN~8kdZ2s)Z(unDR;J3wC&x{jqTh0bLHfXo0*ruzPL}P*f9~BO+yak} zkE{OAr)I<7eSB|cO+|Y_=DAsDgYzdX3Qu~b#KTdA$j)VKB=jWvco0)X>9OZ!l;k#Nkp{-8j za;ZLB3vUdODinDWMsi9cq;qpyTYAqmcLM#YJ4HP~QY$ES$mVxH66!p@{l4_qox$jQ zv6lmCVT_+{4)I<d_cOW&(vYW)hA0^>u%3>_>y6!$T8j zFU*G7IXKEIDJfYvo&I2--ovGskym61(tRNiRFEDaV(1QVXi!uZK^zq| z$b_(742YkG8b*Wkd(3jDG|PcV10MxpvEApMFI?talb3kEs%gEj-ql|E#b%~7=eFnZ zw>%8ohYV{tMg0gmunFKol_Ky2J8-V}rn^my+500C3S4MtsHT=yES;mZ_2$Fn4uMQ|_#m{Y<-cF2G$6HS9$=IZ-$$SQLncic0ti7uHiS@C1E`HxZ%xL&k@9 zo6hr+R=WD7(Wl#EwhTqHVbAk*Kkck1e_KaKtC>g|{6IFb|ksR|VoWs(HQ+ zX2S^k6(nMNm-REkQ@F*Ce9kXYVt)sJc>0!MK+z0?PBn;w*Txph^D`s$8FEBGJNo1Rr;k1g{1u4@i2ewb6Tb%me~zbz`{f<}V=d*grBezn2QK zu*CO86I`FvPbd#-p^<5p$?%;9Fydp93WfBs@2n<$@_-F?i8b@V}Zbn zGT1J`-tj}xIW=mZG*YZ7q#tBF8LuM17)8Oe>I83D@2%)9Apu|0`SygEqdH2O};*AXEhE`&V`9=0|HU8&}u~uc)jK<98ZRBH-LGhsxHHkpl;9AmM=z z`7)&oOd48+rL`PgLvaWwaGB0WvQ}1B9DYwXY;&$aocuq3?t%z(M%WKl(atZndfeP% zl)7!}mma3mI^5)_fe2#dYSb>7bEcX}mJ5@!&|M9d@nrjtXJB?x=_SQu)*`S)@|xh$ zQ#h6WGsrT<+WIuD{F?%p(e--3E!q65;GWNUds;(71Dl1PpI_U@g1_xrP{zML@|(w7vjfWLGX{ZT^7Qh6NiY7ALHE>DH()EqkOTS_PJ%}pRn+eJ5(H>zX%Eq*u_2~mBAPL;NX zo}PDV^o_i_e^|nbjyc5;JB>h3wlz9Old4jUOsStLl0|)-S&T#bb(8xX@IoF~3^EvU ziYTV4SahWb^N}@`ONsN|Bbp@xJ44qJ78Vv(p?k9n3!RR-<9*gp7jkodpZCa!0(W?L zxazs#hqo=&3K(|!r^m+gQ3W{O)en?KMVrx_y_dy6GzaUb>cW}9V#BV$9$ISaXo#x1nzW+!UpoV8iqF;>Izj#8y!8rP zF%Kpak-S^^qir@sm8Ix*5o4Ad=mgBYmi0MwNfsGzZ~nOfZ;uLpZH=9rpk{$6sH@2{ zPpw=tIV~-(5eY4s{v{{1YRa1VF=X(Oo~5U^v$6&VNcd@UGc*6$+@m0DoIFxvIE+?C z?NctHYsU=BB9?ukIekTZ-%t7}wi@w~YXM4wCe?ukijR4QcH3V%FWGkmL|FB!Qe!{! zsB37r_Ul{dl{PlIi?_+E2woyUS8eHvr5qxqx{T7a0RCggcw)Y8m4K(2dToLZ*Td00 z)jF+#r_b^cG$8(`9($q9Qcgpuze;@^K1CrPu}`SS&3Y;;0!f3h9=BL@_s9a)scF7Q zK2Fu>?hZ0A^ZntFU>;UCylaaMaFj9eNIY4pHzM`ArGDhu_?i68GUWwARP>VPscW94 z_9HM?&BN@*K`3?yvagEpXF-y7e4e#Lv?uRRnDwbbe(Ki7dA*U7mLFRt@yFf0q`AU9 zfp=a4xx_<4jOzswA@e1~;d)MD>nQfZ(RYV^!@ALq&zq#ipIKj?3Q%5qa4QZ7ZT=;D zy{d*dN$&SoV61j@M_2~Uv!ZrqG;*Ias0qGzw&NDh{cJwow^?;_C%+8oeOo5?AR{rC zYl(BhSpOLdhf%~TzyP>4Fbi#ma0kd*&Qt?Aq8gG9Y`kwmfv0}X4Uja)dSjw8xrqBD zP#!A0-`An($M@3|V6@(dUz1J{aFXNG{yX=dA2tN(88v%je+O+AcDVtTR)+@Q6*a~6 z*Wo}Ml2>Qpj$X-)-=lanVHb!NQT20z&yLC%N%jqw()*z$ERAp*G#>67=HmF1*~pcS=Q$2S@8Qe@eN+4eu7g~%kTTy z$xeclWLQXhvG**}-V@=#f zGB+T;>fHFTO1dvT?_%dpws=XB`<*v-w>Tac-^6a9E!<&A&!3a|;cJLYF0VX2f&lPvn;<_&2qHAFKe8z3$+a4KO@;%Cc=`wLbegP})O7b-~LF&pyf%D;hO8F>mj zz=`I5&F7>3M+9G3|JN)YukStN^W)rXWs8vbT<4uTDqKi3B!D&UOB=G9xTqzfcw$8n z%kV3Yz^5yD`^Bvu2Q{`LRT-l{sl%r5KJlTSZWPA_N0PMA_tUPHCX6H;s)KcTM_oVP zU6WxuT3A*`wQ4VV@0O6;W_IT*()wcadJ7-4|7hv-0Mu-~R0pQB<$|9bJzNU;y8Cm4 zuV%P3cdds;rZf_24vfF02PVV=^WyQDY4-}k&n(to*mu3Mzts@$XKnbznSV>KS>4^; zYihG!+>uHol(g~86WMV6`ft~P9X zL<1o%_X6xWZm%?Pbo}ItnY`7Wpim1KO`V0STSp-=YcDXequidRXY#-wj1Q4RVw?An z01l!mXW_r95Vm}LT4fL||2jZj3-GDgAu>nj?s3tbQ&#Rzs$g1bkbzJM-*+rOgvabm zk(%_p*Bb|XX7wQQyHmT}FB|?rf5PxPeCwlSHMa>^Za7XO?C&-HG%J z=nUW5bcMP*cEr%w8+ThdcMtw$Xq%hgC%~M=^BWbH=sk|}IPAVnRGD@avda#htgS$r zI-ddI*t1tEb~8>?c8|BE!pa^Y7KB9LngT^?gNuvZV7OE@ZK^-;=&QNSRppeU&}I~V z0Tle}`&E=PQ-j=?9{IjorVz1x)|~wl!aTyvoFvx5hvk1!({z#XTusr*ib+R(xj)X| z@pwwZ=Uth=vYsxMsxeTM^__2;STfN@Ch(a)058my{BOFo2dcF+Yrlbq0zz& z?$n9K>t$i=FCIQl%Ul4fqoIi@j@H%Qs1|LbUw1ed@2@c_i22R5u_CYM2f8gTL`dza zx}04KU$C#=J1!A~sz`hf_Z5k?G2fd9 zZgpIPtL54bx@V>v&LR`v$i%B~X(y(VOcxTf%B`F&a6fxu;6?d9kXL9@AR;Q~KJ*-9 z2$bQ(N{23d-k(s>zOFidL*)CnWq0ht_D|Bky&#%$4Ava+Y#|Vn)^0%f;dWq)aGN%_ zn%nqnQ+D)w^SX>pZiYb3NO7%D@65`o8+L!Xwl&07J>hWL`4v|HDJROT432D>UVvd{ zJm7Vu%J=y*kE&WOVx6K&UK-iEJ%@;o7l$5qM$JaX#BZMd0FebTKN+0IQ(JF%oWIQi zpU5B=+`H8I)5j{s#Js{3pcT&503Xt>h|y9K2M^+_guL>eltL;Yt%2HS@{Sg9(+h zovs=Yxd2ZQPotcnQwDbLr$%P~dsCWqQHsE61%Dh1xPa9^nXQ^)T3QfKFjo+``d4@V zg2^?&D~uwm(^9B5f&at;ckutQXj16FsJymm{5=wa*VYb&3dm zk(UyilU^GuB{7*Ja2;^IL{6YDjlRx)Yzzb?^?PGRx!x@~A5JR z0t5=QGIB6m_~K_hhkL*N&-7HC262gc)Dkm-LgvW#Rof+$e>%QMcGuL47k@4vGO0!=Jasa$vJ7*8y@-doEv zzWIEYmF-o{tQ$~;L1sRy9upg+|uOY$;G3+lq2Rlva=rBpm-J)i^CH@X(}io z#YVhHBNzzXG-_*E7@J}7+(PfSIYVLHjhvoj@7NO87|G_HtW9@cb(i_bL0_+0 z&IJ?|#1dK~ja#^_w{v6&So4ipKO-+qEBVlnT(g0+WGtE{eNZ66Ev6CwcZs%IM;J8#j#NTiF7Wk?l|E%Kun0cJYeE^;g3V5k zSAfLCjpkIdEOOKh{mS~s>#vf~-9750l&qNbVq`rzG@eDWd}vfE<$%vpV@=ADP*rb{ z8oqW3N9VLu^@yZZP5hX^@}g^To-8MMk)((NY_2G3ea3H(eHX?n9M$FhImj499%2Ix zV&q~<(Nb`wV^$6@J`DM1bAQzOs9l=2Ov|EJ*Z`4t_(NE4h#iry9>@p= zPOp&kp2k7rjlEn0SfG6mqAj$SqyWMXaluRX=84mNg{Lv*q%MZRrMus4>w@nkgusXiZsKlbHc!_+2jBMkWFHFLp}cQ*p%t zG(smY_3lHaez?u)#pEh~FEr+?+d#mT0s0M8w$D_PV;fatg%`5kvzBd7L;;Wk*DY^q zC4WR-QJcpwOf7(z>z0qF3!C6N z?O6hAPc8~&F6-GA4*VHTmvKzPEQnq{TaiVjsBJJ3sDKfRVB_$4``?i85fSp?kwCq( z1y59ogOsy@TLCYaIg1*8b4DFjIk{>m4aP389IRi3KjcQ0ko2vHRU|aAP}9IhJ9`{7 zOTT9f;s$*+OLZW8IkB9m>~~Jx*=*}I!ksA``!KGADOm2hlA8aY4zV6>0@j5ua{tp@HB0v7&;x5Dr{puf>V{6@{;PX>rx${H;RG z;c!sCIAbFxB$q_vP6j4kmE9LhJsOP^bR_~)UZhM5>w*F zeZY`HMJPfDRs&I`1;?0{yVGjx$C{Q0(~A8|;toAEM}BFVF1+a&1Ec>$uq*(xAlMg8 zxbEXfiK&)LiUFh~)rN{G@+T8Pa;cyUN%2G~Isc{xR7%=@`5NBMQ&wS=${Z&Zc@5#<|b|y{AMl|&;o{?m7SA`m5qswSCfsK vpNoy3m6L&$m7kRrr2k_2e+a%gn%h`<|NjJ9$dc<&0vI_dWyxxB - '$coinsRepoUrl/$coinsRepoBranch/utils/coins_config.json'; + '$coinsRepoUrl/$coinsRepoBranch/utils/coins_config_tcp.json'; String get remotePathCoins => '$coinsRepoUrl/$coinsRepoBranch/coins'; String _cachedConfig; diff --git a/pubspec.yaml b/pubspec.yaml index a259b9c6a..a4298030e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,7 +7,7 @@ description: Multicoin Wallet with DEX gateway # Both the version and the builder number may be overridden in flutter # build by specifying --build-name and --build-number, respectively. # Read more about versioning at semver.org. -version: 0.9.1+0 +version: 0.9.1+1 publish_to: none @@ -207,7 +207,7 @@ flutter: - assets/svg_light/ - assets/swap_share/ - assets/coins.json - - assets/coins_config.json + - assets/coins_config_tcp.json - assets/rebranding/ # The following line ensures that the Material Icons font is From 0bde503ad4170019a0ede05915aad88cbb831810 Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 21 May 2024 10:17:15 +0200 Subject: [PATCH 04/28] Replace python script with new dart version Also update dockerfile --- .docker/android-apk-build.dockerfile | 9 +- .docker/requirements.txt | 3 - .docker/update_api.dart | 261 +++++++++++++++++++++++++++ .docker/update_api.py | 229 ----------------------- 4 files changed, 265 insertions(+), 237 deletions(-) delete mode 100644 .docker/requirements.txt create mode 100644 .docker/update_api.dart delete mode 100644 .docker/update_api.py diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index d87b152c0..ba9538014 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -1,15 +1,13 @@ FROM ubuntu:latest as build -RUN apt update && apt upgrade -y && apt install -y python3 python3-pip git curl && \ +RUN apt update && apt upgrade -y && apt install -y python3 python3-pip git curl nodejs && \ mkdir -p /home/mobiledevops && \ git clone https://github.com/KomodoPlatform/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile && \ cd /home/mobiledevops/komodo-wallet-mobile && \ curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins && \ curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json && \ mkdir -p android/app/src/main/cpp/libs/armeabi-v7a && \ - mkdir -p android/app/src/main/cpp/libs/arm64-v8a && \ - python3 -m pip install -r .docker/requirements.txt && \ - python3 .docker/update_api.py --force + mkdir -p android/app/src/main/cpp/libs/arm64-v8a FROM mobiledevops/android-sdk-image:34.0.0-jdk17 as final @@ -37,7 +35,8 @@ RUN flutter config --no-analytics --android-sdk=$ANDROID_HOME \ && flutter precache \ && yes "y" | flutter doctor --android-licenses \ && flutter doctor \ - && flutter update-packages + && flutter update-packages \ + && dart .docker/update_api.dart COPY --from=build /home/mobiledevops/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile diff --git a/.docker/requirements.txt b/.docker/requirements.txt deleted file mode 100644 index 6a46b2c28..000000000 --- a/.docker/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -requests==2.31.0 -beautifulsoup4==4.12.2 - diff --git a/.docker/update_api.dart b/.docker/update_api.dart new file mode 100644 index 000000000..289d23596 --- /dev/null +++ b/.docker/update_api.dart @@ -0,0 +1,261 @@ +// ignore_for_file: avoid_print + +import 'dart:convert'; +import 'dart:io'; +import 'package:http/http.dart' as http; +import 'package:path/path.dart' as path; +import 'package:html/parser.dart' as parser; +import 'package:archive/archive_io.dart'; + +import 'build_steps.dart'; + +class UpdateAPIStep extends BuildStep { + final String projectRoot; + late Map config; + late String apiVersion; + late Map platformsConfig; + late String baseUrl; + late String apiBranch; + String? selectedPlatform; + bool forceUpdate = false; + + UpdateAPIStep(this.projectRoot) { + _loadConfig(); + _loadArguments(); + } + + @override + Future build() async { + if (!config['api']['should_update']) { + print('API update is not enabled in the configuration.'); + return; + } + try { + await updateAPI(); + } catch (e) { + print('Error updating API: $e'); + } + } + + @override + bool canSkip() { + // TODO: Add skip logic + return false; + } + + @override + Future revert() async { + print('Reverting changes made by UpdateAPIStep...'); + // TODO: Add revert logic + } + + void _loadConfig() { + final configFile = File('$projectRoot/app_build/build_config.json'); + config = json.decode(configFile.readAsStringSync()); + apiVersion = config['api']['version']; + platformsConfig = config['api']['platforms']; + baseUrl = config['api']['base_url']; + apiBranch = config['api']['default_branch']; + } + + void _loadArguments() { + final args = config['api']['arguments']; + if (args != null) { + selectedPlatform = args['platform']; + forceUpdate = args['force'] ?? false; + } + } + + Future updateAPI() async { + if (config['api']['should_update']) { + Iterable platformsToUpdate; + if (selectedPlatform != null && + platformsConfig.containsKey(selectedPlatform)) { + platformsToUpdate = [selectedPlatform!]; + } else { + platformsToUpdate = platformsConfig.keys; + } + + for (final platform in platformsToUpdate) { + await _updatePlatform(platform); + } + _updateDocumentation(); + } else { + print('API update is not enabled in the configuration.'); + } + } + + Future _updatePlatform(String platform) async { + print('Updating $platform platform...'); + final destinationFolder = _getPlatformDestinationFolder(platform); + final isOutdated = await _checkIfOutdated(platform, destinationFolder); + + if (forceUpdate || isOutdated) { + final zipFileUrl = await _findZipFileUrl(platform); + await _downloadAndExtract(zipFileUrl, destinationFolder, platform); + _updateLastUpdatedFile(platform, destinationFolder); + print('$platform platform update completed.'); + } else { + print('$platform platform is up to date.'); + } + } + + Future _checkIfOutdated( + String platform, String destinationFolder) async { + final lastUpdatedFilePath = + path.join(destinationFolder, '.api_last_updated'); + final lastUpdatedFile = File(lastUpdatedFilePath); + + if (!lastUpdatedFile.existsSync()) { + return true; + } + + try { + final lastUpdatedData = json.decode(lastUpdatedFile.readAsStringSync()); + if (lastUpdatedData['version'] == apiVersion) { + print("version: $apiVersion"); + return false; + } + } catch (e) { + print('Error reading or parsing .api_last_updated: $e'); + } + + return true; + } + + Future _updateWebPlatform() async { + print('Updating Web platform...'); + final installResult = + await Process.run('npm', ['install'], workingDirectory: projectRoot); + if (installResult.exitCode != 0) { + throw Exception('npm install failed: ${installResult.stderr}'); + } + + final buildResult = await Process.run('npm', ['run', 'build'], + workingDirectory: projectRoot); + if (buildResult.exitCode != 0) { + throw Exception('npm run build failed: ${buildResult.stderr}'); + } + + print('Web platform updated successfully.'); + } + + Future _updateLinuxPlatform(String destinationFolder) async { + print('Updating Linux platform...'); + final mm2FilePath = path.join(destinationFolder, 'mm2'); + await Process.run('chmod', ['+x', mm2FilePath]); + print('Linux platform updated successfully.'); + } + + String _getPlatformDestinationFolder(String platform) { + if (platformsConfig.containsKey(platform)) { + return path.join(projectRoot, platformsConfig[platform]['path']); + } else { + throw ArgumentError('Invalid platform: $platform'); + } + } + + Future _findZipFileUrl(String platform) async { + final url = '$baseUrl/$apiBranch/'; + final response = await http.get(Uri.parse(url)); + _checkResponseSuccess(response); + + final document = parser.parse(response.body); + final searchParameters = platformsConfig[platform]; + final keywords = searchParameters['keywords']; + final extensions = ['.zip']; + + for (final element in document.querySelectorAll('a')) { + final href = element.attributes['href']; + if (href != null && + keywords.any((keyword) => href.contains(keyword)) && + extensions.any((extension) => href.endsWith(extension)) && + href.contains(apiVersion)) { + return '$baseUrl/$apiBranch/$href'; + } + } + + throw Exception('Zip file not found for platform $platform'); + } + + void _checkResponseSuccess(http.Response response) { + if (response.statusCode != 200) { + throw HttpException( + 'Failed to fetch data: ${response.statusCode} ${response.reasonPhrase}'); + } + } + + Future _downloadAndExtract( + String url, String destinationFolder, String platform) async { + print('Downloading $url...'); + final response = await http.get(Uri.parse(url)); + _checkResponseSuccess(response); + + final zipFileName = path.basename(url); + final zipFilePath = path.join(destinationFolder, zipFileName); + + // Ensure the destination folder exists + final directory = Directory(destinationFolder); + if (!await directory.exists()) { + await directory.create(recursive: true); + } + + final zipFile = File(zipFilePath); + try { + await zipFile.writeAsBytes(response.bodyBytes); + } catch (e) { + print('Error writing file: $e'); + rethrow; + } + + print('Downloaded $zipFileName'); + + await _extractZipFile(zipFilePath, destinationFolder); + zipFile.deleteSync(); + + if (platform == 'web') { + await _updateWebPlatform(); + } else if (platform == 'linux') { + await _updateLinuxPlatform(destinationFolder); + } + } + + Future _extractZipFile( + String zipFilePath, String destinationFolder) async { + final bytes = File(zipFilePath).readAsBytesSync(); + final archive = ZipDecoder().decodeBytes(bytes); + + for (final file in archive) { + final filename = file.name; + if (file.isFile) { + final data = file.content as List; + File(path.join(destinationFolder, filename)) + ..createSync(recursive: true) + ..writeAsBytesSync(data); + } else { + Directory(path.join(destinationFolder, filename)) + .create(recursive: true); + } + } + print('Extraction completed.'); + } + + void _updateLastUpdatedFile(String platform, String destinationFolder) { + final lastUpdatedFile = + File(path.join(destinationFolder, '.api_last_updated')); + final currentTimestamp = DateTime.now().toIso8601String(); + lastUpdatedFile.writeAsStringSync( + json.encode({'version': apiVersion, 'timestamp': currentTimestamp})); + print('Updated last updated file for $platform.'); + } + + void _updateDocumentation() { + final documentationFile = File('$projectRoot/docs/UPDATE_API_MODULE.md'); + final content = documentationFile.readAsStringSync().replaceAllMapped( + RegExp(r'(Current api module version is) `([^`]+)`'), + (match) => '${match[1]} `$apiVersion`', + ); + documentationFile.writeAsStringSync(content); + print('Updated API version in documentation.'); + } +} diff --git a/.docker/update_api.py b/.docker/update_api.py deleted file mode 100644 index dd160b489..000000000 --- a/.docker/update_api.py +++ /dev/null @@ -1,229 +0,0 @@ -#!/usr/bin/env python3 -import os -import re -import sys -import json -import shutil -import zipfile -import requests -import argparse -import subprocess -from pathlib import Path -from datetime import datetime -from bs4 import BeautifulSoup - - -class UpdateAPI(): - '''Updates the API module version for all or a specified platform.''' - def __init__(self, version=None, platform=None, force=False): - self.version = version - self.platform = platform - self.force = force - - # Get the absolute path of the project root directory - self.project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - self.config_file = os.path.join(self.project_root, ".docker/build_config.json") - - # Load the build_config.json - with open(self.config_file, "r") as f: - self.config = json.load(f) - - # Use version from build_config.json if version is not specified - if not self.version: - self.version = self.config["api"]["version"] - - # Get the platforms config - self.platforms_config = self.config["api"]["platforms"] - - # Get the base URL and branch for the API module - self.base_url = self.config["api"]["base_url"] - self.api_branch = self.config["api"]["default_branch"] - - - def get_platform_destination_folder(self, platform): - '''Returns the destination folder for the specified platform.''' - if platform in self.platforms_config: - return os.path.join(self.project_root, self.platforms_config[platform]["path"]) - else: - raise ValueError(f"Invalid platform: {platform}. Please select a valid platform from the following list: {', '.join(self.platforms_config.keys())}") - - def get_zip_file_url(self, platform, branch): - '''Returns the URL of the zip file for the requested version / branch / platform.''' - response = requests.get(f"{self.base_url}/{branch}/") - response.raise_for_status() - - # Configure the HTML parser - soup = BeautifulSoup(response.text, "html.parser") - search_parameters = self.platforms_config[platform] - keywords = search_parameters["keywords"] - extensions = [".zip"] # Assuming that the extensions are the same for all platforms - - # Parse the HTML and search for the zip file - for link in soup.find_all("a"): - file_name = link.get("href") - if all(keyword in file_name for keyword in keywords) \ - and any(file_name.endswith(ext) for ext in extensions) \ - and self.version in file_name: - return f"{self.base_url}/{branch}/{file_name}" - return None - - def download_api_file(self, platform): - '''Downloads the API version zip file for a specific platform.''' - # Get the URL of the zip file in the main directory - zip_file_url = self.get_zip_file_url(platform, self.api_branch) - - # If the zip file is not found in the main directory, search in all directories - if not zip_file_url: - response = requests.get(self.base_url) - response.raise_for_status() - soup = BeautifulSoup(response.text, "html.parser") - - for link in soup.find_all("a"): - branch = link.get("href") - zip_file_url = self.get_zip_file_url(platform, branch) - - if zip_file_url: - print(f"'{platform}': Found zip file in '{branch}' folder.") - break - - if not zip_file_url: - raise ValueError(f"Could not find zip file for version '{self.version}' on '{platform}' platform!") - - # Download the zip file - print(f"Downloading '{self.version}' API module for [{platform}]...") - response = requests.get(zip_file_url, stream=True) - response.raise_for_status() - - destination_folder = self.get_platform_destination_folder(platform) - zip_file_name = os.path.basename(zip_file_url) - destination_path = os.path.join(destination_folder, zip_file_name) - - # Save the zip file to the specified folder - with open(destination_path, "wb") as file: - response.raw.decode_content = True - shutil.copyfileobj(response.raw, file) - - print(f"Saved to '{destination_path}'") - return destination_path - - def update_documentation(self): - '''Updates the API version in the documentation.''' - documentation_file = f"{self.project_root}/docs/UPDATE_API_MODULE.md" - - # Read the existing documentation file - with open(documentation_file, "r") as f: - content = f.read() - - # Update the version information in the documentation - updated_content = re.sub( - r"(Current api module version is) `([^`]+)`", - f"\\1 `{self.version}`", - content - ) - - # Write the updated content back to the documentation file - with open(documentation_file, "w") as f: - f.write(updated_content) - - print(f"API version in documentation updated to {self.version}") - - def update_api(self): - '''Updates the API module.''' - if self.config["api"]["should_update"]: - version = self.config["api"]["version"][:7] - platforms = self.config["api"]["platforms"] - - # If a platform is specified, only update that platform - if self.platform: - platforms = {self.platform: platforms[self.platform]} - - for platform, platform_info in platforms.items(): - # Set the api module destination folder - destination_folder = self.get_platform_destination_folder(platform) - - # Check if .api_last_updated file exists - last_api_update_file = os.path.join(destination_folder, ".api_last_updated") - - is_outdated = True - - if not self.force and os.path.exists(last_api_update_file): - with open(last_api_update_file, "r") as f: - last_api_update = json.load(f) - if last_api_update.get("version") == version: - print(f"{platform} API module is up to date ({version}).") - is_outdated = False - - if is_outdated: - # Download the API file for the platform - zip_file_path = self.download_api_file(platform) - - # Unzip the downloaded file - print(f"Extracting...") - with zipfile.ZipFile(zip_file_path, 'r') as zip_ref: - zip_ref.extractall(destination_folder) - - # Update wasm module - if platform == 'web': - print(f"Updating WASM module...") - npm_exec = "npm.cmd" if sys.platform == "win32" else "npm" - # If we dont do this first, we might get stuck at the `npm run build` step as there - # appears to be no "non-interactive" flag to accept installing deps with `npm run build` - result = subprocess.run([npm_exec, "install"], capture_output=True, text=True) - if result.returncode == 0: - print("npm install completed.") - else: - print("npm install failed. Please make sure you are using nodejs 18, e.g. `nvm use 18`.)") - print(result.stderr) - sys.exit(1) - - result = subprocess.run([npm_exec, "run", "build"], capture_output=True, text=True) - if result.returncode == 0: - print("Done.") - else: - print("npm run build failed. Please make sure you are using nodejs 18, e.g. `nvm use 18`.)") - print(result.stderr) - sys.exit(1) - - # Make mm2 file executable for Linux - if platform == 'linux': - print("Make mm2 file executable for Linux") - os.chmod(os.path.join(destination_folder, "mm2"), 0o755) - - # Delete the zip file after extraction - os.remove(zip_file_path) - - # Update .api_last_updated file - with open(last_api_update_file, "w") as f: - current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - json.dump({"version": version, "timestamp": current_timestamp}, f) - - # Update the API version in documentation - # self.update_documentation() - - def update_build_config_version(self): - '''Updates the API version in build_config.json.''' - self.config["api"]["version"] = self.version - - with open(self.config_file, "w") as f: - json.dump(self.config, f, indent=4) - - print(f"Version in build_config.json updated to {self.version}.") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Download API module file for specified version and platform.") - # Optional arguments - parser.add_argument("-a", "--api", help="version of the API module to download.", default=None) - parser.add_argument("-p", "--platform", help="platform for which the API module should be downloaded.", default=None) - parser.add_argument("--force", action="store_true", help="force update, ignoring .api_last_updated.", default=False) - args = parser.parse_args() - - try: - updateAPI = UpdateAPI(args.api, args.platform, args.force) - # Update the API version in build_config.json if the API version is specified - if args.api: - updateAPI.update_build_config_version() - updateAPI.update_api() - - except Exception as e: - print(f"Error: {e}") \ No newline at end of file From 2e31b5a6f72a1a88619a207a1af8e92679f3e05c Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 21 May 2024 11:16:55 +0200 Subject: [PATCH 05/28] Fix issues with new dart script as when used via CLI --- .docker/android-apk-build.dockerfile | 96 +++++++++++++++------------- .docker/update_api.dart | 13 ++-- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index ba9538014..a7b30bec1 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -1,45 +1,51 @@ -FROM ubuntu:latest as build - -RUN apt update && apt upgrade -y && apt install -y python3 python3-pip git curl nodejs && \ - mkdir -p /home/mobiledevops && \ - git clone https://github.com/KomodoPlatform/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile && \ - cd /home/mobiledevops/komodo-wallet-mobile && \ - curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins && \ - curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json && \ - mkdir -p android/app/src/main/cpp/libs/armeabi-v7a && \ - mkdir -p android/app/src/main/cpp/libs/arm64-v8a - -FROM mobiledevops/android-sdk-image:34.0.0-jdk17 as final - -ENV FLUTTER_VERSION="2.8.1" -ENV FLUTTER_HOME "/home/mobiledevops/.flutter-sdk" -ENV USER="mobiledevops" -ENV PATH $PATH:$FLUTTER_HOME/bin - -# Download and extract Flutter SDK -RUN mkdir $FLUTTER_HOME \ - && cd $FLUTTER_HOME \ - && curl --fail --remote-time --silent --location -O https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ - && tar xf flutter_linux_${FLUTTER_VERSION}-stable.tar.xz --strip-components=1 \ - && rm flutter_linux_${FLUTTER_VERSION}-stable.tar.xz - -ENV ANDROID_HOME "/opt/android-sdk-linux" -ENV ANDROID_SDK_ROOT $ANDROID_HOME -ENV PATH $PATH:$ANDROID_HOME/cmdline-tools:$ANDROID_HOME/cmdline-tools/bin:$ANDROID_HOME/platform-tools - -RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --update && \ - sdkmanager --install "cmdline-tools;latest" --sdk_root=${ANDROID_SDK_ROOT} && \ - sdkmanager --install "platform-tools" --sdk_root=${ANDROID_SDK_ROOT} - -RUN flutter config --no-analytics --android-sdk=$ANDROID_HOME \ - && flutter precache \ - && yes "y" | flutter doctor --android-licenses \ - && flutter doctor \ - && flutter update-packages \ - && dart .docker/update_api.dart - -COPY --from=build /home/mobiledevops/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile - -WORKDIR /home/$USER/komodo-wallet-mobile - -CMD [ "flutter", "build", "apk", "--release" ] \ No newline at end of file +FROM ubuntu:latest as build + +ARG BRANCH="feature/docker-build" + +RUN apt update && apt upgrade -y && apt install -y git curl nodejs && \ + mkdir -p /home/mobiledevops && \ + git clone https://github.com/KomodoPlatform/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile && \ + cd /home/mobiledevops/komodo-wallet-mobile && \ + git checkout origin/$BRANCH &&\ + curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins && \ + curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json && \ + mkdir -p android/app/src/main/cpp/libs/armeabi-v7a && \ + mkdir -p android/app/src/main/cpp/libs/arm64-v8a && \ + cp -R ./.docker ./docker + +ADD .docker docker + +FROM mobiledevops/android-sdk-image:34.0.0-jdk17 as final + +ENV FLUTTER_VERSION="2.8.1" +ENV FLUTTER_HOME "/home/mobiledevops/.flutter-sdk" +ENV USER="mobiledevops" +ENV PATH $PATH:$FLUTTER_HOME/bin + +# Download and extract Flutter SDK +RUN mkdir $FLUTTER_HOME \ + && cd $FLUTTER_HOME \ + && curl --fail --remote-time --silent --location -O https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ + && tar xf flutter_linux_${FLUTTER_VERSION}-stable.tar.xz --strip-components=1 \ + && rm flutter_linux_${FLUTTER_VERSION}-stable.tar.xz + +ENV ANDROID_HOME "/opt/android-sdk-linux" +ENV ANDROID_SDK_ROOT $ANDROID_HOME +ENV PATH $PATH:$ANDROID_HOME/cmdline-tools:$ANDROID_HOME/cmdline-tools/bin:$ANDROID_HOME/platform-tools + +RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --update && \ + sdkmanager --install "cmdline-tools;latest" --sdk_root=${ANDROID_SDK_ROOT} && \ + sdkmanager --install "platform-tools" --sdk_root=${ANDROID_SDK_ROOT} + +COPY --from=build /home/mobiledevops/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile + +WORKDIR /home/$USER/komodo-wallet-mobile + +RUN flutter config --no-analytics --android-sdk=$ANDROID_HOME \ + && flutter precache \ + && yes "y" | flutter doctor --android-licenses \ + && flutter doctor \ + && flutter update-packages \ + && dart run docker/update_api.dart + +CMD [ "flutter", "build", "apk", "--release" ] diff --git a/.docker/update_api.dart b/.docker/update_api.dart index 289d23596..467083485 100644 --- a/.docker/update_api.dart +++ b/.docker/update_api.dart @@ -1,5 +1,3 @@ -// ignore_for_file: avoid_print - import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart' as http; @@ -7,9 +5,13 @@ import 'package:path/path.dart' as path; import 'package:html/parser.dart' as parser; import 'package:archive/archive_io.dart'; -import 'build_steps.dart'; +Future main(List arguments) async { + final UpdateAPIStep updateApiStep = UpdateAPIStep('./'); + await updateApiStep.build(); +} + -class UpdateAPIStep extends BuildStep { +class UpdateAPIStep { final String projectRoot; late Map config; late String apiVersion; @@ -24,7 +26,6 @@ class UpdateAPIStep extends BuildStep { _loadArguments(); } - @override Future build() async { if (!config['api']['should_update']) { print('API update is not enabled in the configuration.'); @@ -37,13 +38,11 @@ class UpdateAPIStep extends BuildStep { } } - @override bool canSkip() { // TODO: Add skip logic return false; } - @override Future revert() async { print('Reverting changes made by UpdateAPIStep...'); // TODO: Add revert logic From 40599419732e43ede10caacba8c73c385621dc08 Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 21 May 2024 11:29:44 +0200 Subject: [PATCH 06/28] Revert "Replace python script with new dart version" This reverts commit 0bde503ad4170019a0ede05915aad88cbb831810. --- .docker/android-apk-build.dockerfile | 10 +- .docker/requirements.txt | 3 + .docker/update_api.dart | 260 --------------------------- .docker/update_api.py | 229 +++++++++++++++++++++++ 4 files changed, 236 insertions(+), 266 deletions(-) create mode 100644 .docker/requirements.txt delete mode 100644 .docker/update_api.dart create mode 100644 .docker/update_api.py diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index a7b30bec1..1b3f7f76e 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -1,8 +1,6 @@ FROM ubuntu:latest as build -ARG BRANCH="feature/docker-build" - -RUN apt update && apt upgrade -y && apt install -y git curl nodejs && \ +RUN apt update && apt upgrade -y && apt install -y python3 python3-pip git curl && \ mkdir -p /home/mobiledevops && \ git clone https://github.com/KomodoPlatform/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile && \ cd /home/mobiledevops/komodo-wallet-mobile && \ @@ -11,7 +9,8 @@ RUN apt update && apt upgrade -y && apt install -y git curl nodejs && \ curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json && \ mkdir -p android/app/src/main/cpp/libs/armeabi-v7a && \ mkdir -p android/app/src/main/cpp/libs/arm64-v8a && \ - cp -R ./.docker ./docker + python3 -m pip install -r .docker/requirements.txt && \ + python3 .docker/update_api.py --force ADD .docker docker @@ -45,7 +44,6 @@ RUN flutter config --no-analytics --android-sdk=$ANDROID_HOME \ && flutter precache \ && yes "y" | flutter doctor --android-licenses \ && flutter doctor \ - && flutter update-packages \ - && dart run docker/update_api.dart + && flutter update-packages CMD [ "flutter", "build", "apk", "--release" ] diff --git a/.docker/requirements.txt b/.docker/requirements.txt new file mode 100644 index 000000000..6a46b2c28 --- /dev/null +++ b/.docker/requirements.txt @@ -0,0 +1,3 @@ +requests==2.31.0 +beautifulsoup4==4.12.2 + diff --git a/.docker/update_api.dart b/.docker/update_api.dart deleted file mode 100644 index 467083485..000000000 --- a/.docker/update_api.dart +++ /dev/null @@ -1,260 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'package:http/http.dart' as http; -import 'package:path/path.dart' as path; -import 'package:html/parser.dart' as parser; -import 'package:archive/archive_io.dart'; - -Future main(List arguments) async { - final UpdateAPIStep updateApiStep = UpdateAPIStep('./'); - await updateApiStep.build(); -} - - -class UpdateAPIStep { - final String projectRoot; - late Map config; - late String apiVersion; - late Map platformsConfig; - late String baseUrl; - late String apiBranch; - String? selectedPlatform; - bool forceUpdate = false; - - UpdateAPIStep(this.projectRoot) { - _loadConfig(); - _loadArguments(); - } - - Future build() async { - if (!config['api']['should_update']) { - print('API update is not enabled in the configuration.'); - return; - } - try { - await updateAPI(); - } catch (e) { - print('Error updating API: $e'); - } - } - - bool canSkip() { - // TODO: Add skip logic - return false; - } - - Future revert() async { - print('Reverting changes made by UpdateAPIStep...'); - // TODO: Add revert logic - } - - void _loadConfig() { - final configFile = File('$projectRoot/app_build/build_config.json'); - config = json.decode(configFile.readAsStringSync()); - apiVersion = config['api']['version']; - platformsConfig = config['api']['platforms']; - baseUrl = config['api']['base_url']; - apiBranch = config['api']['default_branch']; - } - - void _loadArguments() { - final args = config['api']['arguments']; - if (args != null) { - selectedPlatform = args['platform']; - forceUpdate = args['force'] ?? false; - } - } - - Future updateAPI() async { - if (config['api']['should_update']) { - Iterable platformsToUpdate; - if (selectedPlatform != null && - platformsConfig.containsKey(selectedPlatform)) { - platformsToUpdate = [selectedPlatform!]; - } else { - platformsToUpdate = platformsConfig.keys; - } - - for (final platform in platformsToUpdate) { - await _updatePlatform(platform); - } - _updateDocumentation(); - } else { - print('API update is not enabled in the configuration.'); - } - } - - Future _updatePlatform(String platform) async { - print('Updating $platform platform...'); - final destinationFolder = _getPlatformDestinationFolder(platform); - final isOutdated = await _checkIfOutdated(platform, destinationFolder); - - if (forceUpdate || isOutdated) { - final zipFileUrl = await _findZipFileUrl(platform); - await _downloadAndExtract(zipFileUrl, destinationFolder, platform); - _updateLastUpdatedFile(platform, destinationFolder); - print('$platform platform update completed.'); - } else { - print('$platform platform is up to date.'); - } - } - - Future _checkIfOutdated( - String platform, String destinationFolder) async { - final lastUpdatedFilePath = - path.join(destinationFolder, '.api_last_updated'); - final lastUpdatedFile = File(lastUpdatedFilePath); - - if (!lastUpdatedFile.existsSync()) { - return true; - } - - try { - final lastUpdatedData = json.decode(lastUpdatedFile.readAsStringSync()); - if (lastUpdatedData['version'] == apiVersion) { - print("version: $apiVersion"); - return false; - } - } catch (e) { - print('Error reading or parsing .api_last_updated: $e'); - } - - return true; - } - - Future _updateWebPlatform() async { - print('Updating Web platform...'); - final installResult = - await Process.run('npm', ['install'], workingDirectory: projectRoot); - if (installResult.exitCode != 0) { - throw Exception('npm install failed: ${installResult.stderr}'); - } - - final buildResult = await Process.run('npm', ['run', 'build'], - workingDirectory: projectRoot); - if (buildResult.exitCode != 0) { - throw Exception('npm run build failed: ${buildResult.stderr}'); - } - - print('Web platform updated successfully.'); - } - - Future _updateLinuxPlatform(String destinationFolder) async { - print('Updating Linux platform...'); - final mm2FilePath = path.join(destinationFolder, 'mm2'); - await Process.run('chmod', ['+x', mm2FilePath]); - print('Linux platform updated successfully.'); - } - - String _getPlatformDestinationFolder(String platform) { - if (platformsConfig.containsKey(platform)) { - return path.join(projectRoot, platformsConfig[platform]['path']); - } else { - throw ArgumentError('Invalid platform: $platform'); - } - } - - Future _findZipFileUrl(String platform) async { - final url = '$baseUrl/$apiBranch/'; - final response = await http.get(Uri.parse(url)); - _checkResponseSuccess(response); - - final document = parser.parse(response.body); - final searchParameters = platformsConfig[platform]; - final keywords = searchParameters['keywords']; - final extensions = ['.zip']; - - for (final element in document.querySelectorAll('a')) { - final href = element.attributes['href']; - if (href != null && - keywords.any((keyword) => href.contains(keyword)) && - extensions.any((extension) => href.endsWith(extension)) && - href.contains(apiVersion)) { - return '$baseUrl/$apiBranch/$href'; - } - } - - throw Exception('Zip file not found for platform $platform'); - } - - void _checkResponseSuccess(http.Response response) { - if (response.statusCode != 200) { - throw HttpException( - 'Failed to fetch data: ${response.statusCode} ${response.reasonPhrase}'); - } - } - - Future _downloadAndExtract( - String url, String destinationFolder, String platform) async { - print('Downloading $url...'); - final response = await http.get(Uri.parse(url)); - _checkResponseSuccess(response); - - final zipFileName = path.basename(url); - final zipFilePath = path.join(destinationFolder, zipFileName); - - // Ensure the destination folder exists - final directory = Directory(destinationFolder); - if (!await directory.exists()) { - await directory.create(recursive: true); - } - - final zipFile = File(zipFilePath); - try { - await zipFile.writeAsBytes(response.bodyBytes); - } catch (e) { - print('Error writing file: $e'); - rethrow; - } - - print('Downloaded $zipFileName'); - - await _extractZipFile(zipFilePath, destinationFolder); - zipFile.deleteSync(); - - if (platform == 'web') { - await _updateWebPlatform(); - } else if (platform == 'linux') { - await _updateLinuxPlatform(destinationFolder); - } - } - - Future _extractZipFile( - String zipFilePath, String destinationFolder) async { - final bytes = File(zipFilePath).readAsBytesSync(); - final archive = ZipDecoder().decodeBytes(bytes); - - for (final file in archive) { - final filename = file.name; - if (file.isFile) { - final data = file.content as List; - File(path.join(destinationFolder, filename)) - ..createSync(recursive: true) - ..writeAsBytesSync(data); - } else { - Directory(path.join(destinationFolder, filename)) - .create(recursive: true); - } - } - print('Extraction completed.'); - } - - void _updateLastUpdatedFile(String platform, String destinationFolder) { - final lastUpdatedFile = - File(path.join(destinationFolder, '.api_last_updated')); - final currentTimestamp = DateTime.now().toIso8601String(); - lastUpdatedFile.writeAsStringSync( - json.encode({'version': apiVersion, 'timestamp': currentTimestamp})); - print('Updated last updated file for $platform.'); - } - - void _updateDocumentation() { - final documentationFile = File('$projectRoot/docs/UPDATE_API_MODULE.md'); - final content = documentationFile.readAsStringSync().replaceAllMapped( - RegExp(r'(Current api module version is) `([^`]+)`'), - (match) => '${match[1]} `$apiVersion`', - ); - documentationFile.writeAsStringSync(content); - print('Updated API version in documentation.'); - } -} diff --git a/.docker/update_api.py b/.docker/update_api.py new file mode 100644 index 000000000..dd160b489 --- /dev/null +++ b/.docker/update_api.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python3 +import os +import re +import sys +import json +import shutil +import zipfile +import requests +import argparse +import subprocess +from pathlib import Path +from datetime import datetime +from bs4 import BeautifulSoup + + +class UpdateAPI(): + '''Updates the API module version for all or a specified platform.''' + def __init__(self, version=None, platform=None, force=False): + self.version = version + self.platform = platform + self.force = force + + # Get the absolute path of the project root directory + self.project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + self.config_file = os.path.join(self.project_root, ".docker/build_config.json") + + # Load the build_config.json + with open(self.config_file, "r") as f: + self.config = json.load(f) + + # Use version from build_config.json if version is not specified + if not self.version: + self.version = self.config["api"]["version"] + + # Get the platforms config + self.platforms_config = self.config["api"]["platforms"] + + # Get the base URL and branch for the API module + self.base_url = self.config["api"]["base_url"] + self.api_branch = self.config["api"]["default_branch"] + + + def get_platform_destination_folder(self, platform): + '''Returns the destination folder for the specified platform.''' + if platform in self.platforms_config: + return os.path.join(self.project_root, self.platforms_config[platform]["path"]) + else: + raise ValueError(f"Invalid platform: {platform}. Please select a valid platform from the following list: {', '.join(self.platforms_config.keys())}") + + def get_zip_file_url(self, platform, branch): + '''Returns the URL of the zip file for the requested version / branch / platform.''' + response = requests.get(f"{self.base_url}/{branch}/") + response.raise_for_status() + + # Configure the HTML parser + soup = BeautifulSoup(response.text, "html.parser") + search_parameters = self.platforms_config[platform] + keywords = search_parameters["keywords"] + extensions = [".zip"] # Assuming that the extensions are the same for all platforms + + # Parse the HTML and search for the zip file + for link in soup.find_all("a"): + file_name = link.get("href") + if all(keyword in file_name for keyword in keywords) \ + and any(file_name.endswith(ext) for ext in extensions) \ + and self.version in file_name: + return f"{self.base_url}/{branch}/{file_name}" + return None + + def download_api_file(self, platform): + '''Downloads the API version zip file for a specific platform.''' + # Get the URL of the zip file in the main directory + zip_file_url = self.get_zip_file_url(platform, self.api_branch) + + # If the zip file is not found in the main directory, search in all directories + if not zip_file_url: + response = requests.get(self.base_url) + response.raise_for_status() + soup = BeautifulSoup(response.text, "html.parser") + + for link in soup.find_all("a"): + branch = link.get("href") + zip_file_url = self.get_zip_file_url(platform, branch) + + if zip_file_url: + print(f"'{platform}': Found zip file in '{branch}' folder.") + break + + if not zip_file_url: + raise ValueError(f"Could not find zip file for version '{self.version}' on '{platform}' platform!") + + # Download the zip file + print(f"Downloading '{self.version}' API module for [{platform}]...") + response = requests.get(zip_file_url, stream=True) + response.raise_for_status() + + destination_folder = self.get_platform_destination_folder(platform) + zip_file_name = os.path.basename(zip_file_url) + destination_path = os.path.join(destination_folder, zip_file_name) + + # Save the zip file to the specified folder + with open(destination_path, "wb") as file: + response.raw.decode_content = True + shutil.copyfileobj(response.raw, file) + + print(f"Saved to '{destination_path}'") + return destination_path + + def update_documentation(self): + '''Updates the API version in the documentation.''' + documentation_file = f"{self.project_root}/docs/UPDATE_API_MODULE.md" + + # Read the existing documentation file + with open(documentation_file, "r") as f: + content = f.read() + + # Update the version information in the documentation + updated_content = re.sub( + r"(Current api module version is) `([^`]+)`", + f"\\1 `{self.version}`", + content + ) + + # Write the updated content back to the documentation file + with open(documentation_file, "w") as f: + f.write(updated_content) + + print(f"API version in documentation updated to {self.version}") + + def update_api(self): + '''Updates the API module.''' + if self.config["api"]["should_update"]: + version = self.config["api"]["version"][:7] + platforms = self.config["api"]["platforms"] + + # If a platform is specified, only update that platform + if self.platform: + platforms = {self.platform: platforms[self.platform]} + + for platform, platform_info in platforms.items(): + # Set the api module destination folder + destination_folder = self.get_platform_destination_folder(platform) + + # Check if .api_last_updated file exists + last_api_update_file = os.path.join(destination_folder, ".api_last_updated") + + is_outdated = True + + if not self.force and os.path.exists(last_api_update_file): + with open(last_api_update_file, "r") as f: + last_api_update = json.load(f) + if last_api_update.get("version") == version: + print(f"{platform} API module is up to date ({version}).") + is_outdated = False + + if is_outdated: + # Download the API file for the platform + zip_file_path = self.download_api_file(platform) + + # Unzip the downloaded file + print(f"Extracting...") + with zipfile.ZipFile(zip_file_path, 'r') as zip_ref: + zip_ref.extractall(destination_folder) + + # Update wasm module + if platform == 'web': + print(f"Updating WASM module...") + npm_exec = "npm.cmd" if sys.platform == "win32" else "npm" + # If we dont do this first, we might get stuck at the `npm run build` step as there + # appears to be no "non-interactive" flag to accept installing deps with `npm run build` + result = subprocess.run([npm_exec, "install"], capture_output=True, text=True) + if result.returncode == 0: + print("npm install completed.") + else: + print("npm install failed. Please make sure you are using nodejs 18, e.g. `nvm use 18`.)") + print(result.stderr) + sys.exit(1) + + result = subprocess.run([npm_exec, "run", "build"], capture_output=True, text=True) + if result.returncode == 0: + print("Done.") + else: + print("npm run build failed. Please make sure you are using nodejs 18, e.g. `nvm use 18`.)") + print(result.stderr) + sys.exit(1) + + # Make mm2 file executable for Linux + if platform == 'linux': + print("Make mm2 file executable for Linux") + os.chmod(os.path.join(destination_folder, "mm2"), 0o755) + + # Delete the zip file after extraction + os.remove(zip_file_path) + + # Update .api_last_updated file + with open(last_api_update_file, "w") as f: + current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + json.dump({"version": version, "timestamp": current_timestamp}, f) + + # Update the API version in documentation + # self.update_documentation() + + def update_build_config_version(self): + '''Updates the API version in build_config.json.''' + self.config["api"]["version"] = self.version + + with open(self.config_file, "w") as f: + json.dump(self.config, f, indent=4) + + print(f"Version in build_config.json updated to {self.version}.") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Download API module file for specified version and platform.") + # Optional arguments + parser.add_argument("-a", "--api", help="version of the API module to download.", default=None) + parser.add_argument("-p", "--platform", help="platform for which the API module should be downloaded.", default=None) + parser.add_argument("--force", action="store_true", help="force update, ignoring .api_last_updated.", default=False) + args = parser.parse_args() + + try: + updateAPI = UpdateAPI(args.api, args.platform, args.force) + # Update the API version in build_config.json if the API version is specified + if args.api: + updateAPI.update_build_config_version() + updateAPI.update_api() + + except Exception as e: + print(f"Error: {e}") \ No newline at end of file From a6f0fc32f226b6145e279d16121cf4034e6f93b7 Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 21 May 2024 12:15:22 +0200 Subject: [PATCH 07/28] Change from clone to COPY and fix permission issue --- .docker/android-apk-build.dockerfile | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index 1b3f7f76e..bee079d5f 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -1,18 +1,19 @@ FROM ubuntu:latest as build -RUN apt update && apt upgrade -y && apt install -y python3 python3-pip git curl && \ - mkdir -p /home/mobiledevops && \ - git clone https://github.com/KomodoPlatform/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile && \ - cd /home/mobiledevops/komodo-wallet-mobile && \ - git checkout origin/$BRANCH &&\ - curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins && \ +RUN apt update && apt upgrade -y && apt install -y python3 python3-pip git curl nodejs python3-venv && \ + mkdir -p /home/mobiledevops/komodo-wallet-mobile + +WORKDIR /home/mobiledevops/komodo-wallet-mobile + +COPY . . + +RUN curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins && \ curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json && \ mkdir -p android/app/src/main/cpp/libs/armeabi-v7a && \ mkdir -p android/app/src/main/cpp/libs/arm64-v8a && \ - python3 -m pip install -r .docker/requirements.txt && \ - python3 .docker/update_api.py --force - -ADD .docker docker + python3 -m venv .venv && \ + .venv/bin/pip install -r .docker/requirements.txt && \ + .venv/bin/python .docker/update_api.py --force FROM mobiledevops/android-sdk-image:34.0.0-jdk17 as final @@ -36,14 +37,14 @@ RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} -- sdkmanager --install "cmdline-tools;latest" --sdk_root=${ANDROID_SDK_ROOT} && \ sdkmanager --install "platform-tools" --sdk_root=${ANDROID_SDK_ROOT} -COPY --from=build /home/mobiledevops/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile - -WORKDIR /home/$USER/komodo-wallet-mobile - RUN flutter config --no-analytics --android-sdk=$ANDROID_HOME \ && flutter precache \ && yes "y" | flutter doctor --android-licenses \ && flutter doctor \ && flutter update-packages +COPY --from=build --chown=$USER:$USER /home/mobiledevops/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile + +WORKDIR /home/$USER/komodo-wallet-mobile + CMD [ "flutter", "build", "apk", "--release" ] From 93dfbaaebe677d2bdd698a38615ebd926cf0c853 Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 21 May 2024 16:08:34 +0200 Subject: [PATCH 08/28] Add documentation and fix build directory permission issues --- .docker/android-apk-build.dockerfile | 35 +++++++++++++--------------- README.md | 8 +++++++ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index bee079d5f..a49a4728a 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -1,12 +1,16 @@ -FROM ubuntu:latest as build +FROM --platform=linux/amd64 ubuntu:latest as build -RUN apt update && apt upgrade -y && apt install -y python3 python3-pip git curl nodejs python3-venv && \ - mkdir -p /home/mobiledevops/komodo-wallet-mobile +RUN apt update && \ + apt upgrade -y && \ + apt install -y python3 python3-pip git curl nodejs python3-venv && \ + mkdir -p /app -WORKDIR /home/mobiledevops/komodo-wallet-mobile +WORKDIR /app +# TODO: add .dockerignore COPY . . +# TODO: add .gitkeep files for the missing directories RUN curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins && \ curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json && \ mkdir -p android/app/src/main/cpp/libs/armeabi-v7a && \ @@ -15,36 +19,29 @@ RUN curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/c .venv/bin/pip install -r .docker/requirements.txt && \ .venv/bin/python .docker/update_api.py --force -FROM mobiledevops/android-sdk-image:34.0.0-jdk17 as final +FROM --platform=linux/amd64 ghcr.io/cirruslabs/android-sdk:34 as final ENV FLUTTER_VERSION="2.8.1" -ENV FLUTTER_HOME "/home/mobiledevops/.flutter-sdk" -ENV USER="mobiledevops" +ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" +ENV USER="komodo" ENV PATH $PATH:$FLUTTER_HOME/bin # Download and extract Flutter SDK -RUN mkdir $FLUTTER_HOME \ +RUN mkdir -p $FLUTTER_HOME \ + && git config --global --add safe.directory /home/komodo/.flutter-sdk \ && cd $FLUTTER_HOME \ && curl --fail --remote-time --silent --location -O https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ && tar xf flutter_linux_${FLUTTER_VERSION}-stable.tar.xz --strip-components=1 \ && rm flutter_linux_${FLUTTER_VERSION}-stable.tar.xz -ENV ANDROID_HOME "/opt/android-sdk-linux" -ENV ANDROID_SDK_ROOT $ANDROID_HOME -ENV PATH $PATH:$ANDROID_HOME/cmdline-tools:$ANDROID_HOME/cmdline-tools/bin:$ANDROID_HOME/platform-tools - -RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --update && \ - sdkmanager --install "cmdline-tools;latest" --sdk_root=${ANDROID_SDK_ROOT} && \ - sdkmanager --install "platform-tools" --sdk_root=${ANDROID_SDK_ROOT} - -RUN flutter config --no-analytics --android-sdk=$ANDROID_HOME \ +RUN flutter config --no-analytics \ && flutter precache \ && yes "y" | flutter doctor --android-licenses \ && flutter doctor \ && flutter update-packages -COPY --from=build --chown=$USER:$USER /home/mobiledevops/komodo-wallet-mobile /home/mobiledevops/komodo-wallet-mobile +COPY --from=build /app /app -WORKDIR /home/$USER/komodo-wallet-mobile +WORKDIR /app CMD [ "flutter", "build", "apk", "--release" ] diff --git a/README.md b/README.md index 3a394f0c7..1402ecb7c 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,14 @@ Windows: `choco install jq`, [Choco software](https://chocolatey.org/) https://github.com/KomodoPlatform/AtomicDEX-mobile/wiki/Project-Setup#build-and-run +### Build with docker + +To build from a container without installing Flutter on an x86_64 machine (Linux or Windows) with Docker or Podman installed, you can use the provided Dockerfile. + +```bash +docker build -f .docker/android-apk-build.dockerfile . -t mobile_apk_build +docker run --rm -u 1001:1001 -v ./build:/app/build mobile_apk_build:latest +``` ## Run/Build with screenshot and video recording ON From 1e351d0ccfe0e4f9b26a7004464f9fa87f2cfd1b Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 21 May 2024 17:30:29 +0200 Subject: [PATCH 09/28] Update devcontainer image and fix permission issues --- .devcontainer/devcontainer.json | 10 ++++----- .docker/android-apk-build.dockerfile | 1 - .docker/android-dev.dockerfile | 32 +++++++++++++++------------- .docker/dev-setup.sh | 5 +++++ README.md | 2 ++ 5 files changed, 28 insertions(+), 22 deletions(-) create mode 100644 .docker/dev-setup.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f76a922fb..a5ededa25 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,13 +2,11 @@ "name": "flutter_docker", "context": "..", "dockerFile": "../.docker/android-dev.dockerfile", - "remoteUser": "mobiledevops", - "settings": { - "terminal.integrated.shell.linux": null - }, + "remoteUser": "komodo", + "postAttachCommand": "sh .docker/dev-setup.sh", "runArgs": [ "--privileged" ], - "workspaceMount": "source=${localWorkspaceFolder},target=/home/mobiledevops/workspace,type=bind,consistency=delegated", - "workspaceFolder": "/home/mobiledevops/workspace" + "workspaceMount": "source=${localWorkspaceFolder},target=/home/komodo/workspace,type=bind,consistency=delegated", + "workspaceFolder": "/home/komodo/workspace" } \ No newline at end of file diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index a49a4728a..abed40464 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -7,7 +7,6 @@ RUN apt update && \ WORKDIR /app -# TODO: add .dockerignore COPY . . # TODO: add .gitkeep files for the missing directories diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile index 4c2d327b1..9cc146d86 100644 --- a/.docker/android-dev.dockerfile +++ b/.docker/android-dev.dockerfile @@ -1,26 +1,28 @@ -FROM mobiledevops/android-sdk-image:34.0.0-jdk17 as final +FROM --platform=linux/amd64 ghcr.io/cirruslabs/android-sdk:34 as final ENV FLUTTER_VERSION="2.8.1" -ENV FLUTTER_HOME "/home/mobiledevops/.flutter-sdk" -ENV USER="mobiledevops" +ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" +ENV USER="komodo" ENV PATH $PATH:$FLUTTER_HOME/bin +RUN apt update && apt install -y python3 python3-pip python3-venv && \ + python3 -m venv /home/komodo/.venv && \ + useradd -u 1001 -m $USER && \ + usermod -aG sudo $USER && \ + echo "$USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ + chown -R $USER:$USER /home/$USER + +USER $USER + # Download and extract Flutter SDK -RUN mkdir $FLUTTER_HOME \ +RUN mkdir -p /home/komodo/workspace \ + && chown -R $USER:$USER /home/komodo/workspace \ + && mkdir -p $FLUTTER_HOME \ && cd $FLUTTER_HOME \ && curl --fail --remote-time --silent --location -O https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ && tar xf flutter_linux_${FLUTTER_VERSION}-stable.tar.xz --strip-components=1 \ - && rm flutter_linux_${FLUTTER_VERSION}-stable.tar.xz - -ENV ANDROID_HOME "/opt/android-sdk-linux" -ENV ANDROID_SDK_ROOT $ANDROID_HOME -ENV PATH $PATH:$ANDROID_HOME/cmdline-tools:$ANDROID_HOME/cmdline-tools/bin:$ANDROID_HOME/platform-tools - -RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --update && \ - sdkmanager --install "cmdline-tools;latest" --sdk_root=${ANDROID_SDK_ROOT} && \ - sdkmanager --install "platform-tools" --sdk_root=${ANDROID_SDK_ROOT} - -RUN flutter config --no-analytics --android-sdk=$ANDROID_HOME \ + && rm flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ + && flutter config --no-analytics \ && flutter precache \ && yes "y" | flutter doctor --android-licenses \ && flutter doctor \ diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh new file mode 100644 index 000000000..144bf843b --- /dev/null +++ b/.docker/dev-setup.sh @@ -0,0 +1,5 @@ +chmod u+rw,g+r komodo:komodo /home/komodo/workspace +mkdir -p android/app/src/main/cpp/libs/armeabi-v7a +mkdir -p android/app/src/main/cpp/libs/arm64-v8a +/home/komodo/.venv/bin/pip install -r .docker/requirements.txt +/home/komodo/.venv/bin/python .docker/update_api.py \ No newline at end of file diff --git a/README.md b/README.md index 1402ecb7c..bb805fff5 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,8 @@ docker build -f .docker/android-apk-build.dockerfile . -t mobile_apk_build docker run --rm -u 1001:1001 -v ./build:/app/build mobile_apk_build:latest ``` +The build output should be in the following directory: `build/app/outputs/flutter-apk/app-release.apk` + ## Run/Build with screenshot and video recording ON ``` From 566ba0b045518dbc57dc06270b56eba3a9d2115d Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 21 May 2024 22:19:03 +0200 Subject: [PATCH 10/28] Fix devcontainer ndk install error Write permission denied to `/opt/android-sdk-linux` --- .docker/dev-setup.sh | 1 + README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh index 144bf843b..9af06790e 100644 --- a/.docker/dev-setup.sh +++ b/.docker/dev-setup.sh @@ -1,4 +1,5 @@ chmod u+rw,g+r komodo:komodo /home/komodo/workspace +chown -R komodo:komodo /opt/android-sdk-linux mkdir -p android/app/src/main/cpp/libs/armeabi-v7a mkdir -p android/app/src/main/cpp/libs/arm64-v8a /home/komodo/.venv/bin/pip install -r .docker/requirements.txt diff --git a/README.md b/README.md index bb805fff5..137e9facd 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ To build from a container without installing Flutter on an x86_64 machine (Linux ```bash docker build -f .docker/android-apk-build.dockerfile . -t mobile_apk_build -docker run --rm -u 1001:1001 -v ./build:/app/build mobile_apk_build:latest +docker run --rm -v ./build:/app/build mobile_apk_build:latest ``` The build output should be in the following directory: `build/app/outputs/flutter-apk/app-release.apk` From 2f258ca8ecf6e88f6cedafad41fb5bfb3c372dd5 Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 21 May 2024 22:50:22 +0200 Subject: [PATCH 11/28] Move changing ownership of android sdk folder to dockerfile --- .docker/android-dev.dockerfile | 4 +++- .docker/dev-setup.sh | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile index 9cc146d86..50330b1e3 100644 --- a/.docker/android-dev.dockerfile +++ b/.docker/android-dev.dockerfile @@ -10,7 +10,9 @@ RUN apt update && apt install -y python3 python3-pip python3-venv && \ useradd -u 1001 -m $USER && \ usermod -aG sudo $USER && \ echo "$USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ - chown -R $USER:$USER /home/$USER + chown -R $USER:$USER /home/$USER && \ + chown -R $USER:$USER /opt/android-sdk-linux && \ + chmod -R u+rw,g+rw /opt/android-sdk-linux USER $USER diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh index 9af06790e..144bf843b 100644 --- a/.docker/dev-setup.sh +++ b/.docker/dev-setup.sh @@ -1,5 +1,4 @@ chmod u+rw,g+r komodo:komodo /home/komodo/workspace -chown -R komodo:komodo /opt/android-sdk-linux mkdir -p android/app/src/main/cpp/libs/armeabi-v7a mkdir -p android/app/src/main/cpp/libs/arm64-v8a /home/komodo/.venv/bin/pip install -r .docker/requirements.txt From 6160a98cd8b2893054607ad685c72ae12ea8f4a5 Mon Sep 17 00:00:00 2001 From: Francois Date: Wed, 22 May 2024 11:38:53 +0200 Subject: [PATCH 12/28] Replace Flutter archive download with git clone of Flutter repo Use a build matching the current architecture rather than downloading a prebuilt archive --- .docker/android-apk-build.dockerfile | 20 ++++++++++---------- .docker/android-dev.dockerfile | 9 ++++----- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index abed40464..365490f66 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -1,4 +1,6 @@ -FROM --platform=linux/amd64 ubuntu:latest as build +FROM ubuntu:latest as build + +ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" RUN apt update && \ apt upgrade -y && \ @@ -16,22 +18,20 @@ RUN curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/c mkdir -p android/app/src/main/cpp/libs/arm64-v8a && \ python3 -m venv .venv && \ .venv/bin/pip install -r .docker/requirements.txt && \ - .venv/bin/python .docker/update_api.py --force + .venv/bin/python .docker/update_api.py --force && \ + git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} && \ + cd ${FLUTTER_HOME} && \ + git fetch && \ + git checkout tags/2.8.1 -FROM --platform=linux/amd64 ghcr.io/cirruslabs/android-sdk:34 as final +FROM ghcr.io/cirruslabs/android-sdk:34 as final ENV FLUTTER_VERSION="2.8.1" ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" ENV USER="komodo" ENV PATH $PATH:$FLUTTER_HOME/bin -# Download and extract Flutter SDK -RUN mkdir -p $FLUTTER_HOME \ - && git config --global --add safe.directory /home/komodo/.flutter-sdk \ - && cd $FLUTTER_HOME \ - && curl --fail --remote-time --silent --location -O https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ - && tar xf flutter_linux_${FLUTTER_VERSION}-stable.tar.xz --strip-components=1 \ - && rm flutter_linux_${FLUTTER_VERSION}-stable.tar.xz +COPY --from=build --chown=$USER:$USER ${FLUTTER_HOME} ${FLUTTER_HOME} RUN flutter config --no-analytics \ && flutter precache \ diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile index 50330b1e3..66f2f2822 100644 --- a/.docker/android-dev.dockerfile +++ b/.docker/android-dev.dockerfile @@ -19,11 +19,10 @@ USER $USER # Download and extract Flutter SDK RUN mkdir -p /home/komodo/workspace \ && chown -R $USER:$USER /home/komodo/workspace \ - && mkdir -p $FLUTTER_HOME \ - && cd $FLUTTER_HOME \ - && curl --fail --remote-time --silent --location -O https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ - && tar xf flutter_linux_${FLUTTER_VERSION}-stable.tar.xz --strip-components=1 \ - && rm flutter_linux_${FLUTTER_VERSION}-stable.tar.xz \ + && git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} \ + && cd ${FLUTTER_HOME} \ + && git fetch \ + && git checkout tags/2.8.1 \ && flutter config --no-analytics \ && flutter precache \ && yes "y" | flutter doctor --android-licenses \ From 505279d1f773f2730893c26e19970bd63b4d226c Mon Sep 17 00:00:00 2001 From: "Charl (Nitride)" <77973576+CharlVS@users.noreply.github.com> Date: Wed, 22 May 2024 14:24:15 +0200 Subject: [PATCH 13/28] Refactor to fetch Defi binaries only from GH releases (#148) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor to fetch Defi binaries from GH releases Refactor to fetch Defi binaries from GH releases since they are built in a secure environment instead of the automated CI builds. * Fix script to use version tag Fix the script to use a version tag instead of a hash, as GH’s API does not support fetching a release tied to a specific commit. In the future, we can investigate if there’s an alternate way to verify/validate that the release build is indeed built from a given hash so we can change from a tag ref to a hash ref. * Fix bug in API fetch script Fix the API binary fetch script Ravioli ravioli --- .docker/build_config.json | 7 +- .docker/update_api.py | 235 ++++++++++++++------------------------ .gitignore | 1 + 3 files changed, 90 insertions(+), 153 deletions(-) diff --git a/.docker/build_config.json b/.docker/build_config.json index d0cb91a42..cf8795739 100644 --- a/.docker/build_config.json +++ b/.docker/build_config.json @@ -1,9 +1,8 @@ { "api": { - "version": "b0fd99e", - "should_update": true, - "base_url": "https://sdk.devbuilds.komodo.earth", - "default_branch": "main", + "release_tag": "v2.0.0-beta", + "use_latest_release": false, + "github_repository": "https://github.com/KomodoPlatform/komodo-defi-framework", "platforms": { "ios": { "keywords": [ diff --git a/.docker/update_api.py b/.docker/update_api.py index dd160b489..581648c7f 100644 --- a/.docker/update_api.py +++ b/.docker/update_api.py @@ -1,22 +1,18 @@ #!/usr/bin/env python3 import os -import re import sys import json import shutil import zipfile import requests import argparse -import subprocess from pathlib import Path from datetime import datetime -from bs4 import BeautifulSoup - -class UpdateAPI(): +class UpdateAPI: '''Updates the API module version for all or a specified platform.''' - def __init__(self, version=None, platform=None, force=False): - self.version = version + def __init__(self, tag=None, platform=None, force=False): + self.tag = tag self.platform = platform self.force = force @@ -28,17 +24,18 @@ def __init__(self, version=None, platform=None, force=False): with open(self.config_file, "r") as f: self.config = json.load(f) - # Use version from build_config.json if version is not specified - if not self.version: - self.version = self.config["api"]["version"] + # Use tag from build_config.json if tag is not specified + if not self.tag: + self.tag = self.config["api"]["release_tag"] # Get the platforms config self.platforms_config = self.config["api"]["platforms"] - # Get the base URL and branch for the API module - self.base_url = self.config["api"]["base_url"] - self.api_branch = self.config["api"]["default_branch"] + # Get the GitHub repository URL + self.github_repo = self.config["api"]["github_repository"].replace("https://github.com/", "https://api.github.com/repos/") + # Check if should use the latest release + self.use_latest_release = self.config["api"].get("use_latest_release", False) def get_platform_destination_folder(self, platform): '''Returns the destination folder for the specified platform.''' @@ -47,50 +44,37 @@ def get_platform_destination_folder(self, platform): else: raise ValueError(f"Invalid platform: {platform}. Please select a valid platform from the following list: {', '.join(self.platforms_config.keys())}") - def get_zip_file_url(self, platform, branch): - '''Returns the URL of the zip file for the requested version / branch / platform.''' - response = requests.get(f"{self.base_url}/{branch}/") + def get_release_assets(self): + '''Fetches the assets of the specified or latest release from the GitHub repository.''' + if self.use_latest_release: + api_url = f"{self.github_repo}/releases/latest" + else: + api_url = f"{self.github_repo}/releases/tags/{self.tag}" + + response = requests.get(api_url) response.raise_for_status() + release = response.json() + + return release["assets"] - # Configure the HTML parser - soup = BeautifulSoup(response.text, "html.parser") + def get_zip_file_url(self, platform): + '''Returns the URL of the zip file for the requested version / platform.''' + assets = self.get_release_assets() search_parameters = self.platforms_config[platform] keywords = search_parameters["keywords"] - extensions = [".zip"] # Assuming that the extensions are the same for all platforms - - # Parse the HTML and search for the zip file - for link in soup.find_all("a"): - file_name = link.get("href") - if all(keyword in file_name for keyword in keywords) \ - and any(file_name.endswith(ext) for ext in extensions) \ - and self.version in file_name: - return f"{self.base_url}/{branch}/{file_name}" - return None + for asset in assets: + file_name = asset["name"] + if all(keyword in file_name for keyword in keywords): + return asset["browser_download_url"] + raise ValueError(f"Could not find release zip file for tag '{self.tag}' on '{platform}' platform!") def download_api_file(self, platform): '''Downloads the API version zip file for a specific platform.''' - # Get the URL of the zip file in the main directory - zip_file_url = self.get_zip_file_url(platform, self.api_branch) - - # If the zip file is not found in the main directory, search in all directories - if not zip_file_url: - response = requests.get(self.base_url) - response.raise_for_status() - soup = BeautifulSoup(response.text, "html.parser") - - for link in soup.find_all("a"): - branch = link.get("href") - zip_file_url = self.get_zip_file_url(platform, branch) - - if zip_file_url: - print(f"'{platform}': Found zip file in '{branch}' folder.") - break - - if not zip_file_url: - raise ValueError(f"Could not find zip file for version '{self.version}' on '{platform}' platform!") + # Get the URL of the zip file + zip_file_url = self.get_zip_file_url(platform) # Download the zip file - print(f"Downloading '{self.version}' API module for [{platform}]...") + print(f"Downloading '{self.tag}' API module for [{platform}]...") response = requests.get(zip_file_url, stream=True) response.raise_for_status() @@ -106,124 +90,77 @@ def download_api_file(self, platform): print(f"Saved to '{destination_path}'") return destination_path - def update_documentation(self): - '''Updates the API version in the documentation.''' - documentation_file = f"{self.project_root}/docs/UPDATE_API_MODULE.md" - - # Read the existing documentation file - with open(documentation_file, "r") as f: - content = f.read() - - # Update the version information in the documentation - updated_content = re.sub( - r"(Current api module version is) `([^`]+)`", - f"\\1 `{self.version}`", - content - ) - - # Write the updated content back to the documentation file - with open(documentation_file, "w") as f: - f.write(updated_content) - - print(f"API version in documentation updated to {self.version}") - def update_api(self): '''Updates the API module.''' - if self.config["api"]["should_update"]: - version = self.config["api"]["version"][:7] - platforms = self.config["api"]["platforms"] - - # If a platform is specified, only update that platform - if self.platform: - platforms = {self.platform: platforms[self.platform]} - - for platform, platform_info in platforms.items(): - # Set the api module destination folder - destination_folder = self.get_platform_destination_folder(platform) - - # Check if .api_last_updated file exists - last_api_update_file = os.path.join(destination_folder, ".api_last_updated") - - is_outdated = True - - if not self.force and os.path.exists(last_api_update_file): - with open(last_api_update_file, "r") as f: - last_api_update = json.load(f) - if last_api_update.get("version") == version: - print(f"{platform} API module is up to date ({version}).") - is_outdated = False - - if is_outdated: - # Download the API file for the platform - zip_file_path = self.download_api_file(platform) - - # Unzip the downloaded file - print(f"Extracting...") - with zipfile.ZipFile(zip_file_path, 'r') as zip_ref: - zip_ref.extractall(destination_folder) - - # Update wasm module - if platform == 'web': - print(f"Updating WASM module...") - npm_exec = "npm.cmd" if sys.platform == "win32" else "npm" - # If we dont do this first, we might get stuck at the `npm run build` step as there - # appears to be no "non-interactive" flag to accept installing deps with `npm run build` - result = subprocess.run([npm_exec, "install"], capture_output=True, text=True) - if result.returncode == 0: - print("npm install completed.") - else: - print("npm install failed. Please make sure you are using nodejs 18, e.g. `nvm use 18`.)") - print(result.stderr) - sys.exit(1) - - result = subprocess.run([npm_exec, "run", "build"], capture_output=True, text=True) - if result.returncode == 0: - print("Done.") - else: - print("npm run build failed. Please make sure you are using nodejs 18, e.g. `nvm use 18`.)") - print(result.stderr) - sys.exit(1) - - # Make mm2 file executable for Linux - if platform == 'linux': - print("Make mm2 file executable for Linux") - os.chmod(os.path.join(destination_folder, "mm2"), 0o755) - - # Delete the zip file after extraction - os.remove(zip_file_path) - - # Update .api_last_updated file - with open(last_api_update_file, "w") as f: - current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - json.dump({"version": version, "timestamp": current_timestamp}, f) - - # Update the API version in documentation - # self.update_documentation() - - def update_build_config_version(self): - '''Updates the API version in build_config.json.''' - self.config["api"]["version"] = self.version + tag = self.config["api"]["release_tag"] + platforms = self.config["api"]["platforms"] + + # If a platform is specified, only update that platform + if self.platform: + platforms = {self.platform: platforms[self.platform]} + + for platform in platforms: + # Set the api module destination folder + destination_folder = self.get_platform_destination_folder(platform) + + # Check if .api_last_updated file exists + last_api_update_file = os.path.join(destination_folder, ".api_last_updated") + + is_outdated = True + + if not self.force and os.path.exists(last_api_update_file): + with open(last_api_update_file, "r") as f: + last_api_update = json.load(f) + if last_api_update.get("tag") == tag: + print(f"{platform} API module is up to date ({tag}).") + is_outdated = False + + if is_outdated: + # Download the API file for the platform + zip_file_path = self.download_api_file(platform) + + # Unzip the downloaded file + print(f"Extracting...") + with zipfile.ZipFile(zip_file_path, 'r') as zip_ref: + zip_ref.extractall(destination_folder) + + # Make mm2 file executable for Linux + if platform == 'linux': + print("Make mm2 file executable for Linux") + os.chmod(os.path.join(destination_folder, "mm2"), 0o755) + + # Delete the zip file after extraction + os.remove(zip_file_path) + + # Update .api_last_updated file + with open(last_api_update_file, "w") as f: + current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + json.dump({"tag": tag, "timestamp": current_timestamp}, f) + + def update_build_config_tag(self): + '''Updates the API tag in build_config.json.''' + self.config["api"]["release_tag"] = self.tag with open(self.config_file, "w") as f: json.dump(self.config, f, indent=4) - print(f"Version in build_config.json updated to {self.version}.") + print(f"Tag in build_config.json updated to {self.tag}.") if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Download API module file for specified version and platform.") + parser = argparse.ArgumentParser(description="Download API module file for specified tag and platform.") # Optional arguments - parser.add_argument("-a", "--api", help="version of the API module to download.", default=None) + parser.add_argument("-a", "--api", help="tag of the API module to download.", default=None) parser.add_argument("-p", "--platform", help="platform for which the API module should be downloaded.", default=None) parser.add_argument("--force", action="store_true", help="force update, ignoring .api_last_updated.", default=False) args = parser.parse_args() try: updateAPI = UpdateAPI(args.api, args.platform, args.force) - # Update the API version in build_config.json if the API version is specified + # Update the API tag in build_config.json if the API tag is specified if args.api: - updateAPI.update_build_config_version() + updateAPI.update_build_config_tag() updateAPI.update_api() except Exception as e: - print(f"Error: {e}") \ No newline at end of file + print(f"Error: {e}") diff --git a/.gitignore b/.gitignore index 6739ab05f..d8e0ec18e 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ .buildlog/ .history .svn/ +**/.api_last_updated # coins file extras # /assets/coins.json From 6d2d37968e5a3d8b2226ecad0495fbc6596def28 Mon Sep 17 00:00:00 2001 From: Francois Date: Wed, 22 May 2024 15:24:26 +0200 Subject: [PATCH 14/28] Remove the hardcoded platform from the devcontainer image --- .docker/android-dev.dockerfile | 2 +- .docker/dev-setup.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile index 66f2f2822..4917b6858 100644 --- a/.docker/android-dev.dockerfile +++ b/.docker/android-dev.dockerfile @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 ghcr.io/cirruslabs/android-sdk:34 as final +FROM ghcr.io/cirruslabs/android-sdk:34 as final ENV FLUTTER_VERSION="2.8.1" ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh index 144bf843b..b4fe77c7b 100644 --- a/.docker/dev-setup.sh +++ b/.docker/dev-setup.sh @@ -1,4 +1,4 @@ -chmod u+rw,g+r komodo:komodo /home/komodo/workspace +chmod u+rw,g+r /home/komodo/workspace mkdir -p android/app/src/main/cpp/libs/armeabi-v7a mkdir -p android/app/src/main/cpp/libs/arm64-v8a /home/komodo/.venv/bin/pip install -r .docker/requirements.txt From d5943df1c74f0c5cbc515e228369fa7680e5ea05 Mon Sep 17 00:00:00 2001 From: Francois Date: Wed, 22 May 2024 15:40:10 +0200 Subject: [PATCH 15/28] Copy over android sdk dockerfile from Cirrus CI Remove references to 3rd party dockerfiles, allow for local image tagging and simplify code review. Credit to https://github.com/cirruslabs/docker-images-android/tree/master --- .docker/android-apk-build.dockerfile | 5 ++- .docker/android-sdk.dockerfile | 57 ++++++++++++++++++++++++++++ .docker/dev-setup.sh | 3 +- README.md | 16 +++++++- 4 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 .docker/android-sdk.dockerfile diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index 365490f66..16fe325d8 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:latest as build +FROM ubuntu:24.04 as build ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" @@ -24,7 +24,8 @@ RUN curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/c git fetch && \ git checkout tags/2.8.1 -FROM ghcr.io/cirruslabs/android-sdk:34 as final +# Locally tagged image for now +FROM komodo/android-sdk:34 as final ENV FLUTTER_VERSION="2.8.1" ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" diff --git a/.docker/android-sdk.dockerfile b/.docker/android-sdk.dockerfile new file mode 100644 index 000000000..c374fa9a4 --- /dev/null +++ b/.docker/android-sdk.dockerfile @@ -0,0 +1,57 @@ +FROM ubuntu:24.04 + +# Credit to Cirrus Labs for the original Dockerfile +# LABEL org.opencontainers.image.source=https://github.com/cirruslabs/docker-images-android + +USER root + +ENV ANDROID_HOME=/opt/android-sdk-linux \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + LANGUAGE=en_US:en + +ENV ANDROID_SDK_ROOT=$ANDROID_HOME \ + PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/emulator + +# comes from https://developer.android.com/studio/#command-tools +ENV ANDROID_SDK_TOOLS_VERSION 10406996 + +# https://developer.android.com/studio/releases/build-tools +ENV ANDROID_PLATFORM_VERSION 34 +ENV ANDROID_BUILD_TOOLS_VERSION 34.0.0 + +# https://developer.android.com/ndk/downloads +ENV ANDROID_NDK_VERSION 26.2.11394342 + +RUN set -o xtrace \ + && cd /opt \ + && apt-get update \ + && apt-get install -y jq \ + && apt-get install -y openjdk-17-jdk \ + && apt-get install -y sudo wget zip unzip git openssh-client curl bc software-properties-common build-essential ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov libsqlite3-dev --no-install-recommends \ + # for x86 emulators + && apt-get install -y libxtst6 libnss3-dev libnspr4 libxss1 libasound2t64 libatk-bridge2.0-0 libgtk-3-0 libgdk-pixbuf2.0-0 \ + && rm -rf /var/lib/apt/lists/* \ + && sh -c 'echo "en_US.UTF-8 UTF-8" > /etc/locale.gen' \ + && locale-gen \ + && update-locale LANG=en_US.UTF-8 \ + && wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip -O android-sdk-tools.zip \ + && mkdir -p ${ANDROID_HOME}/cmdline-tools/ \ + && unzip -q android-sdk-tools.zip -d ${ANDROID_HOME}/cmdline-tools/ \ + && mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest \ + && chown -R root:root $ANDROID_HOME \ + && rm android-sdk-tools.zip \ + && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \ + && yes | sdkmanager --licenses \ + && wget -O /usr/bin/android-wait-for-emulator https://raw.githubusercontent.com/travis-ci/travis-cookbooks/master/community-cookbooks/android-sdk/files/default/android-wait-for-emulator \ + && chmod +x /usr/bin/android-wait-for-emulator \ + && touch /root/.android/repositories.cfg \ + && sdkmanager platform-tools \ + && mkdir -p /root/.android \ + && touch /root/.android/repositories.cfg \ + && git config --global user.email "hello@komodoplatform.com" \ + && git config --global user.name "Komodo Platform" \ + && yes | sdkmanager \ + "platforms;android-$ANDROID_PLATFORM_VERSION" \ + "build-tools;$ANDROID_BUILD_TOOLS_VERSION" \ + && yes | sdkmanager "ndk;$ANDROID_NDK_VERSION" \ No newline at end of file diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh index b4fe77c7b..4347daf1c 100644 --- a/.docker/dev-setup.sh +++ b/.docker/dev-setup.sh @@ -2,4 +2,5 @@ chmod u+rw,g+r /home/komodo/workspace mkdir -p android/app/src/main/cpp/libs/armeabi-v7a mkdir -p android/app/src/main/cpp/libs/arm64-v8a /home/komodo/.venv/bin/pip install -r .docker/requirements.txt -/home/komodo/.venv/bin/python .docker/update_api.py \ No newline at end of file +/home/komodo/.venv/bin/python .docker/update_api.py +flutter pub get \ No newline at end of file diff --git a/README.md b/README.md index 137e9facd..2a95976c1 100644 --- a/README.md +++ b/README.md @@ -72,9 +72,21 @@ https://github.com/KomodoPlatform/AtomicDEX-mobile/wiki/Project-Setup#build-and- To build from a container without installing Flutter on an x86_64 machine (Linux or Windows) with Docker or Podman installed, you can use the provided Dockerfile. +On x86 systems you can build using the following commands: + +```bash +flutter clean +docker build -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 +docker build -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile +docker run --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest +``` +On ARM systems (M1 Mac, Raspberry Pi, etc.) you can build using the following commands: + ```bash -docker build -f .docker/android-apk-build.dockerfile . -t mobile_apk_build -docker run --rm -v ./build:/app/build mobile_apk_build:latest +flutter clean +docker build --platform=linux/arm64 -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 +docker build --platform=linux/arm64 -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile +docker run --platform=linux/arm64 --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest ``` The build output should be in the following directory: `build/app/outputs/flutter-apk/app-release.apk` From 2622fd40d149d43e59fb9037c09b67f025b3e8b0 Mon Sep 17 00:00:00 2001 From: CharlVS <77973576+CharlVS@users.noreply.github.com> Date: Wed, 22 May 2024 21:43:19 +0200 Subject: [PATCH 16/28] Fix bug in API fetch script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix bug in API fetch script where fetching would fail if the android lib folders didn’t already exist. --- .docker/update_api.py | 3 +++ README.md | 2 ++ 2 files changed, 5 insertions(+) diff --git a/.docker/update_api.py b/.docker/update_api.py index 581648c7f..e27d6069f 100644 --- a/.docker/update_api.py +++ b/.docker/update_api.py @@ -82,6 +82,9 @@ def download_api_file(self, platform): zip_file_name = os.path.basename(zip_file_url) destination_path = os.path.join(destination_folder, zip_file_name) + # Ensure the destination directory exists + os.makedirs(destination_folder, exist_ok=True) + # Save the zip file to the specified folder with open(destination_path, "wb") as file: response.raw.decode_content = True diff --git a/README.md b/README.md index 2a95976c1..196bc49ad 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # Komodo Wallet - Open Source GitHub Repository 🚀 +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/KomodoPlatform/komodo-wallet-mobile?quickstart=1) + ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/komodoplatform/atomicdex-mobile/build.yml) ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/komodoplatform/atomicdex-mobile) ![GitHub contributors](https://img.shields.io/github/contributors-anon/komodoplatform/atomicdex-mobile) From 7022813b86e580fba94c91ea1955ce68b1a9a502 Mon Sep 17 00:00:00 2001 From: Francois Date: Wed, 22 May 2024 21:48:53 +0200 Subject: [PATCH 17/28] Add script to abstract apk release build --- .docker/android-sdk.dockerfile | 4 ++-- .docker/build_apk_release.sh | 3 +++ README.md | 11 +++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 .docker/build_apk_release.sh diff --git a/.docker/android-sdk.dockerfile b/.docker/android-sdk.dockerfile index c374fa9a4..b99e0ed63 100644 --- a/.docker/android-sdk.dockerfile +++ b/.docker/android-sdk.dockerfile @@ -14,14 +14,14 @@ ENV ANDROID_SDK_ROOT=$ANDROID_HOME \ PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/emulator # comes from https://developer.android.com/studio/#command-tools -ENV ANDROID_SDK_TOOLS_VERSION 10406996 +ENV ANDROID_SDK_TOOLS_VERSION 11076708 # https://developer.android.com/studio/releases/build-tools ENV ANDROID_PLATFORM_VERSION 34 ENV ANDROID_BUILD_TOOLS_VERSION 34.0.0 # https://developer.android.com/ndk/downloads -ENV ANDROID_NDK_VERSION 26.2.11394342 +ENV ANDROID_NDK_VERSION 26.3.11579264 RUN set -o xtrace \ && cd /opt \ diff --git a/.docker/build_apk_release.sh b/.docker/build_apk_release.sh new file mode 100644 index 000000000..f129185e2 --- /dev/null +++ b/.docker/build_apk_release.sh @@ -0,0 +1,3 @@ +docker build -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 +docker build -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile +docker run --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest \ No newline at end of file diff --git a/README.md b/README.md index 196bc49ad..f04454ee7 100644 --- a/README.md +++ b/README.md @@ -74,18 +74,21 @@ https://github.com/KomodoPlatform/AtomicDEX-mobile/wiki/Project-Setup#build-and- To build from a container without installing Flutter on an x86_64 machine (Linux or Windows) with Docker or Podman installed, you can use the provided Dockerfile. -On x86 systems you can build using the following commands: +```bash +sh .docker/build_apk_release.sh +``` + +You can build using docker with the following commands: ```bash -flutter clean docker build -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 docker build -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile docker run --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest ``` -On ARM systems (M1 Mac, Raspberry Pi, etc.) you can build using the following commands: + +On ARM systems (M1 Mac, Raspberry Pi, etc.) you might have to specify the platform for the build steps as shown below: ```bash -flutter clean docker build --platform=linux/arm64 -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 docker build --platform=linux/arm64 -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile docker run --platform=linux/arm64 --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest From 95ce8bf9939e01c0beff99ae3dd07121e8141e9c Mon Sep 17 00:00:00 2001 From: Francois Date: Thu, 23 May 2024 12:30:05 +0200 Subject: [PATCH 18/28] Change devcontainer to docker-compose format Use local tagged image instead of the 3rd party image --- .devcontainer/devcontainer.json | 8 ++------ .docker/android-dev.dockerfile | 2 +- .docker/docker-compose.yml | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 .docker/docker-compose.yml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a5ededa25..2e95e86d1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,12 +1,8 @@ { "name": "flutter_docker", - "context": "..", - "dockerFile": "../.docker/android-dev.dockerfile", + "dockerComposeFile": "../.docker/docker-compose.yml", + "service": "komodo-wallet-mobile", "remoteUser": "komodo", "postAttachCommand": "sh .docker/dev-setup.sh", - "runArgs": [ - "--privileged" - ], - "workspaceMount": "source=${localWorkspaceFolder},target=/home/komodo/workspace,type=bind,consistency=delegated", "workspaceFolder": "/home/komodo/workspace" } \ No newline at end of file diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile index 4917b6858..83dca76f0 100644 --- a/.docker/android-dev.dockerfile +++ b/.docker/android-dev.dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/cirruslabs/android-sdk:34 as final +FROM komodo/android-sdk:34 as final ENV FLUTTER_VERSION="2.8.1" ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml new file mode 100644 index 000000000..6ab311765 --- /dev/null +++ b/.docker/docker-compose.yml @@ -0,0 +1,17 @@ +services: + android-sdk: + build: + context: .. + dockerfile: .docker/android-sdk.dockerfile + image: komodo/android-sdk:34 + + komodo-wallet-mobile: + build: + context: .. + dockerfile: .docker/android-dev.dockerfile + image: komodo/komodo-wallet-mobile + volumes: + - ../:/home/komodo/workspace + depends_on: + - android-sdk + command: "/bin/sh -c 'while true; do sleep 1000; done'" From 08baacc76e860785601ffd0f3de6e2c85e5453be Mon Sep 17 00:00:00 2001 From: Francois Date: Thu, 23 May 2024 13:13:03 +0200 Subject: [PATCH 19/28] Revert "Change devcontainer to docker-compose format" This reverts commit 95ce8bf9939e01c0beff99ae3dd07121e8141e9c. --- .devcontainer/devcontainer.json | 8 ++++++-- .docker/android-dev.dockerfile | 2 +- .docker/docker-compose.yml | 17 ----------------- 3 files changed, 7 insertions(+), 20 deletions(-) delete mode 100644 .docker/docker-compose.yml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2e95e86d1..a5ededa25 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,8 +1,12 @@ { "name": "flutter_docker", - "dockerComposeFile": "../.docker/docker-compose.yml", - "service": "komodo-wallet-mobile", + "context": "..", + "dockerFile": "../.docker/android-dev.dockerfile", "remoteUser": "komodo", "postAttachCommand": "sh .docker/dev-setup.sh", + "runArgs": [ + "--privileged" + ], + "workspaceMount": "source=${localWorkspaceFolder},target=/home/komodo/workspace,type=bind,consistency=delegated", "workspaceFolder": "/home/komodo/workspace" } \ No newline at end of file diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile index 83dca76f0..4917b6858 100644 --- a/.docker/android-dev.dockerfile +++ b/.docker/android-dev.dockerfile @@ -1,4 +1,4 @@ -FROM komodo/android-sdk:34 as final +FROM ghcr.io/cirruslabs/android-sdk:34 as final ENV FLUTTER_VERSION="2.8.1" ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml deleted file mode 100644 index 6ab311765..000000000 --- a/.docker/docker-compose.yml +++ /dev/null @@ -1,17 +0,0 @@ -services: - android-sdk: - build: - context: .. - dockerfile: .docker/android-sdk.dockerfile - image: komodo/android-sdk:34 - - komodo-wallet-mobile: - build: - context: .. - dockerfile: .docker/android-dev.dockerfile - image: komodo/komodo-wallet-mobile - volumes: - - ../:/home/komodo/workspace - depends_on: - - android-sdk - command: "/bin/sh -c 'while true; do sleep 1000; done'" From 78a51a09777b84af0b393cd61ccecead2d2cde40 Mon Sep 17 00:00:00 2001 From: Francois Date: Thu, 23 May 2024 13:44:17 +0200 Subject: [PATCH 20/28] Add note regarding build limitations and the Python script --- README.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f04454ee7..96dc35c7f 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ To build from a container without installing Flutter on an x86_64 machine (Linux sh .docker/build_apk_release.sh ``` -You can build using docker with the following commands: +You can also manually build using docker with the following commands: ```bash docker build -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 @@ -86,16 +86,12 @@ docker build -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-m docker run --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest ``` -On ARM systems (M1 Mac, Raspberry Pi, etc.) you might have to specify the platform for the build steps as shown below: - -```bash -docker build --platform=linux/arm64 -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 -docker build --platform=linux/arm64 -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile -docker run --platform=linux/arm64 --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest -``` - The build output should be in the following directory: `build/app/outputs/flutter-apk/app-release.apk` +NOTE: There are known issues with building this repository using docker on ARM-based systems (e.g. M-series Macs, Raspberry Pi): + - linux/amd64: [Dart VM emulation on M1 Mac fails](https://github.com/dart-lang/sdk/issues/48420) + - linux/arm64: fails due to dependencies limiting the versions of the dart sdk, android gradle plugin, and gradle build tools. See the [Gradle Compatibility Matrix](https://docs.gradle.org/current/userguide/compatibility.html) + ## Run/Build with screenshot and video recording ON ``` @@ -123,6 +119,17 @@ Ensure you run the most recent Komodo DeFi Framework [stable release](https://gi See [our wiki](https://github.com/KomodoPlatform/atomicdex-mobile/wiki/Project-Setup#android-builds-from-scratch) here for more thorough project setup steps. Besides installing the API binary, Komodo Wallet is set up similarly to any other cloned Flutter project. +### Setup with Python script + +You can use the provided Python script to download and extract the API binary for you. This script will download the latest release of the API binary from GitHub and extract it to the correct location. + +```bash +python3 -m venv .venv +source .venv/bin/activate +pip install -r .docker/requirements.txt +python .docker/update_api.py --force +``` + ## Accessing the database adb exec-out run-as com.komodoplatform.atomicdex cat /data/data/com.komodoplatform.atomicdex/app_flutter/AtomicDEX.db > AtomicDEX.db From d86be741de164745fd493884f8ef898e313f30e8 Mon Sep 17 00:00:00 2001 From: Francois Date: Thu, 23 May 2024 13:48:59 +0200 Subject: [PATCH 21/28] Update fetch coins scripts --- fetch_coins.ps1 | 4 +++- fetch_coins.sh | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/fetch_coins.ps1 b/fetch_coins.ps1 index aa30463b7..b90fbad8d 100644 --- a/fetch_coins.ps1 +++ b/fetch_coins.ps1 @@ -1,4 +1,5 @@ $config_init_mm2 = "assets\coins.json" +$config_mm2 = "assets\coins_config_tcp.json" # back compatibility if ( ( Test-Path -Path $config_init_mm2 -PathType Leaf ) -and -not ( Test-Path -Path "coins_ci.json" -PathType Leaf ) ) { @@ -8,13 +9,14 @@ if ( ( Test-Path -Path $config_init_mm2 -PathType Leaf ) -and -not ( Test-Path - # get coins file $coins_repo_commit = $( jq.exe -r '.coins_repo_commit' .\coins_ci.json) curl.exe -l "https://raw.githubusercontent.com/KomodoPlatform/coins/${coins_repo_commit}/coins" --output $config_init_mm2 +curl.exe -l "https://raw.githubusercontent.com/KomodoPlatform/coins/${coins_repo_commit}/utils/coins_config_tcp.json" --output $config_mm2 # clean checks from previous run rm .\app_assets rm .\coins_assets # get assets lists -jq.exe -r 'keys | .[]' "assets/coins_config.json" > app_assets +jq.exe -r 'keys | .[]' $config_mm2 > app_assets jq.exe -r '.[].coin' $config_init_mm2 > coins_assets # check if all assets from coins_config are present in coins.json diff --git a/fetch_coins.sh b/fetch_coins.sh index 0061015f3..b250268c7 100755 --- a/fetch_coins.sh +++ b/fetch_coins.sh @@ -10,9 +10,10 @@ fi # get coins file coins_repo_commit="$( jq -r '.coins_repo_commit' coins_ci.json )" curl -l "https://raw.githubusercontent.com/KomodoPlatform/coins/${coins_repo_commit}/coins" --output "assets/coins.json" +curl -l "https://raw.githubusercontent.com/KomodoPlatform/coins/${coins_repo_commit}/utils/coins_config_tcp.json" --output "assets/coins_config_tcp.json" # get assets lists -jq -r 'keys | .[]' assets/coins_config.json > app_assets +jq -r 'keys | .[]' assets/coins_config_tcp.json > app_assets jq -r '.[].coin' assets/coins.json > coins_assets # check if all assets from 0.5.6-coins are present in coins.json From 77a9b697fe549b8b48770630b3e4b563a4341977 Mon Sep 17 00:00:00 2001 From: Francois Date: Mon, 27 May 2024 11:01:33 +0200 Subject: [PATCH 22/28] Add komodo-defi-framework build step to apk build image Also standardise base images to ubuntu:22.04 --- .docker/android-apk-build.dockerfile | 47 +++++++------- .docker/android-sdk.dockerfile | 8 +-- .docker/build_apk_release.sh | 5 +- .docker/kdf-android-build.dockerfile | 96 ++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 28 deletions(-) create mode 100644 .docker/kdf-android-build.dockerfile diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index 16fe325d8..f3433426d 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -1,38 +1,43 @@ -FROM ubuntu:24.04 as build +FROM komodo/kdf-android:latest as build ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" -RUN apt update && \ - apt upgrade -y && \ - apt install -y python3 python3-pip git curl nodejs python3-venv && \ - mkdir -p /app +RUN cd /app && \ + rustup default nightly-2022-10-29 && \ + rustup target add aarch64-linux-android && \ + rustup target add armv7-linux-androideabi && \ + export PATH=$PATH:/android-ndk/bin && \ + CC_aarch64_linux_android=aarch64-linux-android21-clang CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang cargo rustc --target=aarch64-linux-android --lib --release --crate-type=staticlib --package mm2_bin_lib && \ + mv target/aarch64-linux-android/release/libmm2lib.a target/aarch64-linux-android/release/libmm2.a &&\ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang cargo rustc --target=armv7-linux-androideabi --lib --release --crate-type=staticlib --package mm2_bin_lib && \ + mv target/armv7-linux-androideabi/release/libmm2lib.a target/armv7-linux-androideabi/release/libmm2.a -WORKDIR /app +# Locally tagged image for now +FROM komodo/android-sdk:34 as final + +ENV FLUTTER_VERSION="2.8.1" +ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" +ENV USER="komodo" +ENV PATH $PATH:$FLUTTER_HOME/bin +ENV ANDROID_AARCH64_LIB=android/app/src/main/cpp/libs/arm64-v8a +ENV ANDROID_AARCH64_LIB_SRC=/app/target/aarch64-linux-android/release/libmm2.a +ENV ANDROID_ARMV7_LIB=android/app/src/main/cpp/libs/armeabi-v7a +ENV ANDROID_ARMV7_LIB_SRC=/app/target/armv7-linux-androideabi/release/libmm2.a +WORKDIR /app COPY . . -# TODO: add .gitkeep files for the missing directories RUN curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins && \ curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json && \ mkdir -p android/app/src/main/cpp/libs/armeabi-v7a && \ mkdir -p android/app/src/main/cpp/libs/arm64-v8a && \ - python3 -m venv .venv && \ - .venv/bin/pip install -r .docker/requirements.txt && \ - .venv/bin/python .docker/update_api.py --force && \ git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} && \ cd ${FLUTTER_HOME} && \ git fetch && \ git checkout tags/2.8.1 -# Locally tagged image for now -FROM komodo/android-sdk:34 as final - -ENV FLUTTER_VERSION="2.8.1" -ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" -ENV USER="komodo" -ENV PATH $PATH:$FLUTTER_HOME/bin - -COPY --from=build --chown=$USER:$USER ${FLUTTER_HOME} ${FLUTTER_HOME} +COPY --from=build --chown=$USER:$USER ${ANDROID_AARCH64_LIB_SRC} ${ANDROID_AARCH64_LIB} +COPY --from=build --chown=$USER:$USER ${ANDROID_ARMV7_LIB_SRC} ${ANDROID_ARMV7_LIB} RUN flutter config --no-analytics \ && flutter precache \ @@ -41,7 +46,3 @@ RUN flutter config --no-analytics \ && flutter update-packages COPY --from=build /app /app - -WORKDIR /app - -CMD [ "flutter", "build", "apk", "--release" ] diff --git a/.docker/android-sdk.dockerfile b/.docker/android-sdk.dockerfile index b99e0ed63..8c558fc36 100644 --- a/.docker/android-sdk.dockerfile +++ b/.docker/android-sdk.dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:24.04 +FROM docker.io/ubuntu:22.04 # Credit to Cirrus Labs for the original Dockerfile # LABEL org.opencontainers.image.source=https://github.com/cirruslabs/docker-images-android @@ -27,10 +27,10 @@ RUN set -o xtrace \ && cd /opt \ && apt-get update \ && apt-get install -y jq \ - && apt-get install -y openjdk-17-jdk \ - && apt-get install -y sudo wget zip unzip git openssh-client curl bc software-properties-common build-essential ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov libsqlite3-dev --no-install-recommends \ + openjdk-17-jdk \ + sudo wget zip unzip git openssh-client curl bc software-properties-common build-essential ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov libsqlite3-dev --no-install-recommends \ # for x86 emulators - && apt-get install -y libxtst6 libnss3-dev libnspr4 libxss1 libasound2t64 libatk-bridge2.0-0 libgtk-3-0 libgdk-pixbuf2.0-0 \ + libxtst6 libnss3-dev libnspr4 libxss1 libatk-bridge2.0-0 libgtk-3-0 libgdk-pixbuf2.0-0 \ && rm -rf /var/lib/apt/lists/* \ && sh -c 'echo "en_US.UTF-8 UTF-8" > /etc/locale.gen' \ && locale-gen \ diff --git a/.docker/build_apk_release.sh b/.docker/build_apk_release.sh index f129185e2..2a728b7f3 100644 --- a/.docker/build_apk_release.sh +++ b/.docker/build_apk_release.sh @@ -1,3 +1,6 @@ +set -e + +docker build -f .docker/kdf-android-build.dockerfile . -t komodo/kdf-android docker build -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 docker build -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile -docker run --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest \ No newline at end of file +docker run --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest flutter build apk --release \ No newline at end of file diff --git a/.docker/kdf-android-build.dockerfile b/.docker/kdf-android-build.dockerfile new file mode 100644 index 000000000..db0f65742 --- /dev/null +++ b/.docker/kdf-android-build.dockerfile @@ -0,0 +1,96 @@ +FROM docker.io/ubuntu:22.04 + +LABEL Author "Onur Özkan " + +RUN apt-get update -y && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + build-essential \ + libssl-dev \ + cmake \ + llvm-dev \ + libclang-dev \ + lld \ + gcc \ + libc6-dev \ + jq \ + make \ + pkg-config \ + git \ + automake \ + libtool \ + m4 \ + autoconf \ + make \ + file \ + curl \ + wget \ + gnupg \ + software-properties-common \ + lsb-release \ + libudev-dev \ + zip unzip \ + binutils && \ + apt-get clean + +RUN ln -s /usr/bin/python3 /bin/python &&\ + curl --output llvm.sh https://apt.llvm.org/llvm.sh && \ + chmod +x llvm.sh && \ + ./llvm.sh 16 && \ + rm ./llvm.sh && \ + ln -s /usr/bin/clang-16 /usr/bin/clang && \ + PROTOC_ZIP=protoc-25.3-linux-x86_64.zip && \ + curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v25.3/$PROTOC_ZIP && \ + unzip -o $PROTOC_ZIP -d /usr/local bin/protoc && \ + unzip -o $PROTOC_ZIP -d /usr/local 'include/*' && \ + rm -f $PROTOC_ZIP + +ENV AR=/usr/bin/llvm-ar-16 +ENV CC=/usr/bin/clang-16 + +RUN mkdir -m 0755 -p /etc/apt/keyrings + +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \ + export PATH="/root/.cargo/bin:$PATH" && \ + rustup toolchain install nightly-2022-10-29 --no-self-update --profile=minimal &&\ + rustup default nightly-2022-10-29 && \ + rustup target add aarch64-linux-android && \ + rustup target add armv7-linux-androideabi && \ + apt install -y python3 python3-pip git curl nodejs python3-venv sudo && \ + git clone https://github.com/KomodoPlatform/komodo-defi-framework.git /app && \ + cd /app && \ + if [ "$(uname -m)" = "x86_64" ]; then \ + bash ./scripts/ci/android-ndk.sh x86 23; \ + elif [ "$(uname -m)" = "aarch64" ]; then \ + bash ./scripts/ci/android-ndk.sh arm64 23; \ + else \ + echo "Unsupported architecture"; \ + exit 1; \ + fi + +ENV PATH="/root/.cargo/bin:$PATH" + +ENV PATH=$PATH:/android-ndk/bin +ARG KDF_BRANCH=main + +# Libz is distributed in the android ndk, but for some unknown reason it is not +# found in the build process of some crates, so we explicit set the DEP_Z_ROOT +ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-clang \ + CARGO_TARGET_X86_64_LINUX_ANDROID_RUNNER="qemu-x86_64 -cpu qemu64,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt" \ + CC_x86_64_linux_android=x86_64-linux-android-clang \ + CXX_x86_64_linux_android=x86_64-linux-android-clang++ \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_RUNNER=qemu-arm \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CXX_armv7_linux_androideabi=armv7a-linux-androideabi21-clang++ \ + DEP_Z_INCLUDE=/android-ndk/sysroot/usr/include/ \ + OPENSSL_STATIC=1 \ + OPENSSL_DIR=/openssl \ + OPENSSL_INCLUDE_DIR=/openssl/include \ + OPENSSL_LIB_DIR=/openssl/lib \ + RUST_TEST_THREADS=1 \ + HOME=/tmp/ \ + TMPDIR=/tmp/ \ + ANDROID_DATA=/ \ + ANDROID_DNS_MODE=local \ + ANDROID_ROOT=/system From b4abb970636e1d6c3d06039f03056be07c1b7677 Mon Sep 17 00:00:00 2001 From: Francois Date: Mon, 27 May 2024 12:16:29 +0200 Subject: [PATCH 23/28] Fix kdf branch build argument --- .docker/android-apk-build.dockerfile | 2 +- .docker/build_apk_release.sh | 2 +- .docker/kdf-android-build.dockerfile | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index f3433426d..105d419e5 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -8,8 +8,8 @@ RUN cd /app && \ rustup target add armv7-linux-androideabi && \ export PATH=$PATH:/android-ndk/bin && \ CC_aarch64_linux_android=aarch64-linux-android21-clang CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang cargo rustc --target=aarch64-linux-android --lib --release --crate-type=staticlib --package mm2_bin_lib && \ - mv target/aarch64-linux-android/release/libmm2lib.a target/aarch64-linux-android/release/libmm2.a &&\ CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang cargo rustc --target=armv7-linux-androideabi --lib --release --crate-type=staticlib --package mm2_bin_lib && \ + mv target/aarch64-linux-android/release/libmm2lib.a target/aarch64-linux-android/release/libmm2.a &&\ mv target/armv7-linux-androideabi/release/libmm2lib.a target/armv7-linux-androideabi/release/libmm2.a # Locally tagged image for now diff --git a/.docker/build_apk_release.sh b/.docker/build_apk_release.sh index 2a728b7f3..0936bd738 100644 --- a/.docker/build_apk_release.sh +++ b/.docker/build_apk_release.sh @@ -1,6 +1,6 @@ set -e -docker build -f .docker/kdf-android-build.dockerfile . -t komodo/kdf-android +docker build -f .docker/kdf-android-build.dockerfile . -t komodo/kdf-android --build-arg KDF_BRANCH=main docker build -f .docker/android-sdk.dockerfile . -t komodo/android-sdk:34 docker build -f .docker/android-apk-build.dockerfile . -t komodo/komodo-wallet-mobile docker run --rm -v ./build:/app/build komodo/komodo-wallet-mobile:latest flutter build apk --release \ No newline at end of file diff --git a/.docker/kdf-android-build.dockerfile b/.docker/kdf-android-build.dockerfile index db0f65742..dc687b0fa 100644 --- a/.docker/kdf-android-build.dockerfile +++ b/.docker/kdf-android-build.dockerfile @@ -1,6 +1,7 @@ FROM docker.io/ubuntu:22.04 LABEL Author "Onur Özkan " +ARG KDF_BRANCH=main RUN apt-get update -y && \ apt-get install -y --no-install-recommends \ @@ -59,6 +60,8 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \ apt install -y python3 python3-pip git curl nodejs python3-venv sudo && \ git clone https://github.com/KomodoPlatform/komodo-defi-framework.git /app && \ cd /app && \ + git fetch --all && \ + git checkout origin/$KDF_BRANCH && \ if [ "$(uname -m)" = "x86_64" ]; then \ bash ./scripts/ci/android-ndk.sh x86 23; \ elif [ "$(uname -m)" = "aarch64" ]; then \ @@ -71,7 +74,6 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \ ENV PATH="/root/.cargo/bin:$PATH" ENV PATH=$PATH:/android-ndk/bin -ARG KDF_BRANCH=main # Libz is distributed in the android ndk, but for some unknown reason it is not # found in the build process of some crates, so we explicit set the DEP_Z_ROOT @@ -83,6 +85,10 @@ ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-clang \ CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_RUNNER=qemu-arm \ CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ CXX_armv7_linux_androideabi=armv7a-linux-androideabi21-clang++ \ + CC_aarch64_linux_android=aarch64-linux-android21-clang \ + CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ DEP_Z_INCLUDE=/android-ndk/sysroot/usr/include/ \ OPENSSL_STATIC=1 \ OPENSSL_DIR=/openssl \ From 7cdbc989a386cddf864f06836f38400113e81c12 Mon Sep 17 00:00:00 2001 From: Francois Date: Mon, 27 May 2024 13:25:29 +0200 Subject: [PATCH 24/28] Remove unnecessary copy Leftover artefact from previous build stage setup --- .docker/android-apk-build.dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index 105d419e5..5c0c362ae 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -12,7 +12,6 @@ RUN cd /app && \ mv target/aarch64-linux-android/release/libmm2lib.a target/aarch64-linux-android/release/libmm2.a &&\ mv target/armv7-linux-androideabi/release/libmm2lib.a target/armv7-linux-androideabi/release/libmm2.a -# Locally tagged image for now FROM komodo/android-sdk:34 as final ENV FLUTTER_VERSION="2.8.1" @@ -44,5 +43,3 @@ RUN flutter config --no-analytics \ && yes "y" | flutter doctor --android-licenses \ && flutter doctor \ && flutter update-packages - -COPY --from=build /app /app From 1753e65fb050f5a8382c65bb9305cef6f2d3406b Mon Sep 17 00:00:00 2001 From: Francois Date: Fri, 31 May 2024 20:45:54 +0200 Subject: [PATCH 25/28] Combine dockerfiles into `android-dev` for Github codespaces --- .docker/android-apk-build.dockerfile | 2 - .docker/android-dev.dockerfile | 175 ++++++++++++++++++++++++--- .docker/android-sdk.dockerfile | 1 - .docker/dev-setup.sh | 17 ++- 4 files changed, 172 insertions(+), 23 deletions(-) diff --git a/.docker/android-apk-build.dockerfile b/.docker/android-apk-build.dockerfile index 5c0c362ae..1856ba57d 100644 --- a/.docker/android-apk-build.dockerfile +++ b/.docker/android-apk-build.dockerfile @@ -1,7 +1,5 @@ FROM komodo/kdf-android:latest as build -ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" - RUN cd /app && \ rustup default nightly-2022-10-29 && \ rustup target add aarch64-linux-android && \ diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile index 4917b6858..5b3390e2f 100644 --- a/.docker/android-dev.dockerfile +++ b/.docker/android-dev.dockerfile @@ -1,26 +1,173 @@ -FROM ghcr.io/cirruslabs/android-sdk:34 as final +FROM docker.io/ubuntu:22.04 + +LABEL Author "Onur Özkan " +ARG KDF_BRANCH=main +ENV KDF_DIR=/kdf ENV FLUTTER_VERSION="2.8.1" ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" ENV USER="komodo" +ENV USER_ID=1000 ENV PATH $PATH:$FLUTTER_HOME/bin +ENV AR=/usr/bin/llvm-ar-16 +ENV CC=/usr/bin/clang-16 +ENV PATH="$HOME/.cargo/bin:$PATH" +ENV PATH=$PATH:/android-ndk/bin +ENV ANDROID_HOME=/opt/android-sdk-linux \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + LANGUAGE=en_US:en + +ENV ANDROID_SDK_ROOT=$ANDROID_HOME \ + PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/emulator + +# comes from https://developer.android.com/studio/#command-tools +ENV ANDROID_SDK_TOOLS_VERSION 11076708 + +# https://developer.android.com/studio/releases/build-tools +ENV ANDROID_PLATFORM_VERSION 34 +ENV ANDROID_BUILD_TOOLS_VERSION 34.0.0 + +# https://developer.android.com/ndk/downloads +ENV ANDROID_NDK_VERSION 26.3.11579264 +# Libz is distributed in the android ndk, but for some unknown reason it is not +# found in the build process of some crates, so we explicit set the DEP_Z_ROOT +ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-clang \ + CARGO_TARGET_X86_64_LINUX_ANDROID_RUNNER="qemu-x86_64 -cpu qemu64,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt" \ + CC_x86_64_linux_android=x86_64-linux-android-clang \ + CXX_x86_64_linux_android=x86_64-linux-android-clang++ \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_RUNNER=qemu-arm \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CXX_armv7_linux_androideabi=armv7a-linux-androideabi21-clang++ \ + CC_aarch64_linux_android=aarch64-linux-android21-clang \ + CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ + DEP_Z_INCLUDE=/android-ndk/sysroot/usr/include/ \ + OPENSSL_STATIC=1 \ + OPENSSL_DIR=/openssl \ + OPENSSL_INCLUDE_DIR=/openssl/include \ + OPENSSL_LIB_DIR=/openssl/lib \ + RUST_TEST_THREADS=1 \ + HOME=/tmp/ \ + TMPDIR=/tmp/ \ + ANDROID_DATA=/ \ + ANDROID_DNS_MODE=local \ + ANDROID_ROOT=/system -RUN apt update && apt install -y python3 python3-pip python3-venv && \ - python3 -m venv /home/komodo/.venv && \ - useradd -u 1001 -m $USER && \ - usermod -aG sudo $USER && \ - echo "$USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ - chown -R $USER:$USER /home/$USER && \ - chown -R $USER:$USER /opt/android-sdk-linux && \ - chmod -R u+rw,g+rw /opt/android-sdk-linux +RUN apt update && apt install -y sudo && \ + useradd -u $USER_ID -m $USER && \ + usermod -aG sudo $USER && \ + echo "$USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers USER $USER -# Download and extract Flutter SDK -RUN mkdir -p /home/komodo/workspace \ - && chown -R $USER:$USER /home/komodo/workspace \ - && git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} \ - && cd ${FLUTTER_HOME} \ +RUN sudo apt-get update -y && \ + sudo apt-get install -y --no-install-recommends \ + ca-certificates \ + build-essential \ + libssl-dev \ + cmake \ + llvm-dev \ + libclang-dev \ + lld \ + gcc \ + libc6-dev \ + jq \ + make \ + pkg-config \ + git \ + automake \ + libtool \ + m4 \ + autoconf \ + make \ + file \ + curl \ + wget \ + gnupg \ + software-properties-common \ + lsb-release \ + libudev-dev \ + zip unzip \ + binutils && \ + sudo apt-get clean + +RUN sudo ln -s /usr/bin/python3 /bin/python &&\ + sudo curl --output llvm.sh https://apt.llvm.org/llvm.sh && \ + sudo chmod +x llvm.sh && \ + sudo ./llvm.sh 16 && \ + sudo rm ./llvm.sh && \ + sudo ln -s /usr/bin/clang-16 /usr/bin/clang && \ + PROTOC_ZIP=protoc-25.3-linux-x86_64.zip && \ + sudo curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v25.3/$PROTOC_ZIP && \ + sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc && \ + sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*' && \ + sudo rm -f $PROTOC_ZIP && \ + sudo mkdir $KDF_DIR && \ + sudo chown -R $USER:$USER $KDF_DIR + +RUN PATH="$HOME/.cargo/bin:$PATH" && \ + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \ + export PATH="$HOME/.cargo/bin:$PATH" && \ + sudo chown -R $USER:$USER $HOME/.cargo && \ + rustup toolchain install nightly-2022-10-29 --no-self-update --profile=minimal &&\ + rustup default nightly-2022-10-29 && \ + rustup target add aarch64-linux-android && \ + rustup target add armv7-linux-androideabi && \ + sudo apt install -y python3 python3-pip git curl nodejs python3-venv sudo && \ + git clone https://github.com/KomodoPlatform/komodo-defi-framework.git $KDF_DIR && \ + cd $KDF_DIR && \ + git fetch --all && \ + git checkout origin/$KDF_BRANCH && \ + if [ "$(uname -m)" = "x86_64" ]; then \ + bash ./scripts/ci/android-ndk.sh x86 23; \ + elif [ "$(uname -m)" = "aarch64" ]; then \ + bash ./scripts/ci/android-ndk.sh arm64 23; \ + else \ + echo "Unsupported architecture"; \ + exit 1; \ + fi && \ + cd $KDF_DIR && \ + export PATH="$HOME/.cargo/bin:$PATH" && \ + export PATH=$PATH:/android-ndk/bin && \ + CC_aarch64_linux_android=aarch64-linux-android21-clang CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang cargo rustc --target=aarch64-linux-android --lib --release --crate-type=staticlib --package mm2_bin_lib && \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang cargo rustc --target=armv7-linux-androideabi --lib --release --crate-type=staticlib --package mm2_bin_lib && \ + mv target/aarch64-linux-android/release/libmm2lib.a target/aarch64-linux-android/release/libmm2.a &&\ + mv target/armv7-linux-androideabi/release/libmm2lib.a target/armv7-linux-androideabi/release/libmm2.a + +RUN set -e -o xtrace \ + && cd /opt \ + && sudo chown -R $USER:$USER /opt \ + && sudo apt-get update \ + && sudo apt-get install -y jq \ + openjdk-17-jdk \ + wget zip unzip git openssh-client curl bc software-properties-common build-essential ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov libsqlite3-dev --no-install-recommends \ + # for x86 emulators + libxtst6 libnss3-dev libnspr4 libxss1 libatk-bridge2.0-0 libgtk-3-0 libgdk-pixbuf2.0-0 \ + && sudo rm -rf /var/lib/apt/lists/* \ + && sudo sh -c 'echo "en_US.UTF-8 UTF-8" > /etc/locale.gen' \ + && sudo locale-gen \ + && sudo update-locale LANG=en_US.UTF-8 \ + && wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip -O android-sdk-tools.zip \ + && mkdir -p ${ANDROID_HOME}/cmdline-tools/ \ + && unzip -q android-sdk-tools.zip -d ${ANDROID_HOME}/cmdline-tools/ \ + && mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest \ + && sudo chown -R $USER:$USER $ANDROID_HOME \ + && rm android-sdk-tools.zip \ + && yes | sdkmanager --licenses \ + && sdkmanager platform-tools \ + && git config --global user.email "hello@komodoplatform.com" \ + && git config --global user.name "Komodo Platform" \ + && yes | sdkmanager \ + "platforms;android-$ANDROID_PLATFORM_VERSION" \ + "build-tools;$ANDROID_BUILD_TOOLS_VERSION" \ + && yes | sdkmanager "ndk;$ANDROID_NDK_VERSION" + + +RUN git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} \ + && cd ${FLUTTER_HOME} \ && git fetch \ && git checkout tags/2.8.1 \ && flutter config --no-analytics \ diff --git a/.docker/android-sdk.dockerfile b/.docker/android-sdk.dockerfile index 8c558fc36..7f176434e 100644 --- a/.docker/android-sdk.dockerfile +++ b/.docker/android-sdk.dockerfile @@ -45,7 +45,6 @@ RUN set -o xtrace \ && yes | sdkmanager --licenses \ && wget -O /usr/bin/android-wait-for-emulator https://raw.githubusercontent.com/travis-ci/travis-cookbooks/master/community-cookbooks/android-sdk/files/default/android-wait-for-emulator \ && chmod +x /usr/bin/android-wait-for-emulator \ - && touch /root/.android/repositories.cfg \ && sdkmanager platform-tools \ && mkdir -p /root/.android \ && touch /root/.android/repositories.cfg \ diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh index 4347daf1c..e18aeb5a3 100644 --- a/.docker/dev-setup.sh +++ b/.docker/dev-setup.sh @@ -1,6 +1,11 @@ -chmod u+rw,g+r /home/komodo/workspace -mkdir -p android/app/src/main/cpp/libs/armeabi-v7a -mkdir -p android/app/src/main/cpp/libs/arm64-v8a -/home/komodo/.venv/bin/pip install -r .docker/requirements.txt -/home/komodo/.venv/bin/python .docker/update_api.py -flutter pub get \ No newline at end of file +sudo chmod -R u+rwx,g+rwx /home/komodo/workspace +sudo chown -R /home/komodo/workspace +flutter pub get + +curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins +curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json +mkdir -p android/app/src/main/cpp/libs/armeabi-v7a +mkdir -p android/app/src/main/cpp/libs/arm64-v8a + +cp /kdf/target/aarch64-linux-android/release/libmm2.a android/app/src/main/cpp/libs/arm64-v8a +cp /kdf/target/armv7-linux-androideabi/release/libmm2.a android/app/src/main/cpp/libs/armeabi-v7a \ No newline at end of file From 2aa8459c26902a14f0925098cfbd34c624779799 Mon Sep 17 00:00:00 2001 From: Francois Date: Sat, 1 Jun 2024 20:22:03 +0200 Subject: [PATCH 26/28] Move API build to postAttach event of devcontainer API was built in image to reduce Codespaces startup time, but ended up increasing the already large image size --- .docker/android-dev.dockerfile | 18 +++++------------- .docker/dev-setup.sh | 14 +++++++++++--- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile index 5b3390e2f..3a8d066a8 100644 --- a/.docker/android-dev.dockerfile +++ b/.docker/android-dev.dockerfile @@ -1,6 +1,5 @@ FROM docker.io/ubuntu:22.04 -LABEL Author "Onur Özkan " ARG KDF_BRANCH=main ENV KDF_DIR=/kdf @@ -128,14 +127,7 @@ RUN PATH="$HOME/.cargo/bin:$PATH" && \ else \ echo "Unsupported architecture"; \ exit 1; \ - fi && \ - cd $KDF_DIR && \ - export PATH="$HOME/.cargo/bin:$PATH" && \ - export PATH=$PATH:/android-ndk/bin && \ - CC_aarch64_linux_android=aarch64-linux-android21-clang CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang cargo rustc --target=aarch64-linux-android --lib --release --crate-type=staticlib --package mm2_bin_lib && \ - CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang cargo rustc --target=armv7-linux-androideabi --lib --release --crate-type=staticlib --package mm2_bin_lib && \ - mv target/aarch64-linux-android/release/libmm2lib.a target/aarch64-linux-android/release/libmm2.a &&\ - mv target/armv7-linux-androideabi/release/libmm2lib.a target/armv7-linux-androideabi/release/libmm2.a + fi RUN set -e -o xtrace \ && cd /opt \ @@ -143,7 +135,9 @@ RUN set -e -o xtrace \ && sudo apt-get update \ && sudo apt-get install -y jq \ openjdk-17-jdk \ - wget zip unzip git openssh-client curl bc software-properties-common build-essential ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov libsqlite3-dev --no-install-recommends \ + wget zip unzip git openssh-client curl bc software-properties-common build-essential \ + ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov \ + libsqlite3-dev --no-install-recommends \ # for x86 emulators libxtst6 libnss3-dev libnspr4 libxss1 libatk-bridge2.0-0 libgtk-3-0 libgdk-pixbuf2.0-0 \ && sudo rm -rf /var/lib/apt/lists/* \ @@ -162,9 +156,7 @@ RUN set -e -o xtrace \ && git config --global user.name "Komodo Platform" \ && yes | sdkmanager \ "platforms;android-$ANDROID_PLATFORM_VERSION" \ - "build-tools;$ANDROID_BUILD_TOOLS_VERSION" \ - && yes | sdkmanager "ndk;$ANDROID_NDK_VERSION" - + "build-tools;$ANDROID_BUILD_TOOLS_VERSION" RUN git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} \ && cd ${FLUTTER_HOME} \ diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh index e18aeb5a3..dd8781696 100644 --- a/.docker/dev-setup.sh +++ b/.docker/dev-setup.sh @@ -1,5 +1,5 @@ sudo chmod -R u+rwx,g+rwx /home/komodo/workspace -sudo chown -R /home/komodo/workspace +sudo chown -R komodo:komodo /home/komodo/workspace flutter pub get curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins @@ -7,5 +7,13 @@ curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatfor mkdir -p android/app/src/main/cpp/libs/armeabi-v7a mkdir -p android/app/src/main/cpp/libs/arm64-v8a -cp /kdf/target/aarch64-linux-android/release/libmm2.a android/app/src/main/cpp/libs/arm64-v8a -cp /kdf/target/armv7-linux-androideabi/release/libmm2.a android/app/src/main/cpp/libs/armeabi-v7a \ No newline at end of file +cd /kdf +export PATH="$HOME/.cargo/bin:$PATH" +export PATH=$PATH:/android-ndk/bin +CC_aarch64_linux_android=aarch64-linux-android21-clang CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang cargo rustc --target=aarch64-linux-android --lib --release --crate-type=staticlib --package mm2_bin_lib +CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang cargo rustc --target=armv7-linux-androideabi --lib --release --crate-type=staticlib --package mm2_bin_lib +mv target/aarch64-linux-android/release/libmm2lib.a target/aarch64-linux-android/release/libmm2.a +mv target/armv7-linux-androideabi/release/libmm2lib.a target/armv7-linux-androideabi/release/libmm2.a + +mv /kdf/target/aarch64-linux-android/release/libmm2.a /home/komodo/workspace/android/app/src/main/cpp/libs/arm64-v8a/libmm2.a +mv /kdf/target/armv7-linux-androideabi/release/libmm2.a /home/komodo/workspace/android/app/src/main/cpp/libs/armeabi-v7a/libmm2.a \ No newline at end of file From 7212f5387105d23cff75c462b9d4958460cb4aee Mon Sep 17 00:00:00 2001 From: Francois Date: Mon, 3 Jun 2024 21:31:21 +0200 Subject: [PATCH 27/28] Fix cargo install in devcontainer/Codespaces --- .docker/android-dev.dockerfile | 51 +++++++++++++++++----------------- .docker/dev-setup.sh | 11 ++++++-- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/.docker/android-dev.dockerfile b/.docker/android-dev.dockerfile index 3a8d066a8..375b59e78 100644 --- a/.docker/android-dev.dockerfile +++ b/.docker/android-dev.dockerfile @@ -3,6 +3,32 @@ FROM docker.io/ubuntu:22.04 ARG KDF_BRANCH=main ENV KDF_DIR=/kdf +# Libz is distributed in the android ndk, but for some unknown reason it is not +# found in the build process of some crates, so we explicit set the DEP_Z_ROOT +ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-clang \ + CARGO_TARGET_X86_64_LINUX_ANDROID_RUNNER="qemu-x86_64 -cpu qemu64,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt" \ + CC_x86_64_linux_android=x86_64-linux-android-clang \ + CXX_x86_64_linux_android=x86_64-linux-android-clang++ \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_RUNNER=qemu-arm \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CXX_armv7_linux_androideabi=armv7a-linux-androideabi21-clang++ \ + CC_aarch64_linux_android=aarch64-linux-android21-clang \ + CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang \ + CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ + DEP_Z_INCLUDE=/android-ndk/sysroot/usr/include/ \ + OPENSSL_STATIC=1 \ + OPENSSL_DIR=/openssl \ + OPENSSL_INCLUDE_DIR=/openssl/include \ + OPENSSL_LIB_DIR=/openssl/lib \ + RUST_TEST_THREADS=1 \ + HOME=/home/komodo/ \ + TMPDIR=/tmp/ \ + ANDROID_DATA=/ \ + ANDROID_DNS_MODE=local \ + ANDROID_ROOT=/system + ENV FLUTTER_VERSION="2.8.1" ENV FLUTTER_HOME "/home/komodo/.flutter-sdk" ENV USER="komodo" @@ -29,31 +55,6 @@ ENV ANDROID_BUILD_TOOLS_VERSION 34.0.0 # https://developer.android.com/ndk/downloads ENV ANDROID_NDK_VERSION 26.3.11579264 -# Libz is distributed in the android ndk, but for some unknown reason it is not -# found in the build process of some crates, so we explicit set the DEP_Z_ROOT -ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-clang \ - CARGO_TARGET_X86_64_LINUX_ANDROID_RUNNER="qemu-x86_64 -cpu qemu64,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt" \ - CC_x86_64_linux_android=x86_64-linux-android-clang \ - CXX_x86_64_linux_android=x86_64-linux-android-clang++ \ - CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ - CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_RUNNER=qemu-arm \ - CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ - CXX_armv7_linux_androideabi=armv7a-linux-androideabi21-clang++ \ - CC_aarch64_linux_android=aarch64-linux-android21-clang \ - CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clang \ - CC_armv7_linux_androideabi=armv7a-linux-androideabi21-clang \ - CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=armv7a-linux-androideabi21-clang \ - DEP_Z_INCLUDE=/android-ndk/sysroot/usr/include/ \ - OPENSSL_STATIC=1 \ - OPENSSL_DIR=/openssl \ - OPENSSL_INCLUDE_DIR=/openssl/include \ - OPENSSL_LIB_DIR=/openssl/lib \ - RUST_TEST_THREADS=1 \ - HOME=/tmp/ \ - TMPDIR=/tmp/ \ - ANDROID_DATA=/ \ - ANDROID_DNS_MODE=local \ - ANDROID_ROOT=/system RUN apt update && apt install -y sudo && \ useradd -u $USER_ID -m $USER && \ diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh index dd8781696..0e1ce4bfe 100644 --- a/.docker/dev-setup.sh +++ b/.docker/dev-setup.sh @@ -1,9 +1,14 @@ -sudo chmod -R u+rwx,g+rwx /home/komodo/workspace -sudo chown -R komodo:komodo /home/komodo/workspace +#!/bin/bash + +set -e + +sudo git config core.fileMode false +sudo chmod -R u+rwx /home/komodo +sudo chown -R komodo:komodo /home/komodo flutter pub get curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins -curl -o assets/coins_config.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config.json +curl -o assets/coins_config_tcp.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/utils/coins_config_tcp.json mkdir -p android/app/src/main/cpp/libs/armeabi-v7a mkdir -p android/app/src/main/cpp/libs/arm64-v8a From 99efab097eea708b4ac0afe0b6d8cff085a5fcfd Mon Sep 17 00:00:00 2001 From: Francois Date: Tue, 4 Jun 2024 10:31:08 +0200 Subject: [PATCH 28/28] Set the minimum host requirements for Codespaces 4 cores, 16GB RAM and 32GB storage is the minimum requirements for the API to build successfully from source. --- .devcontainer/devcontainer.json | 7 ++++++- .docker/dev-setup.sh | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a5ededa25..83a48756a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,5 +8,10 @@ "--privileged" ], "workspaceMount": "source=${localWorkspaceFolder},target=/home/komodo/workspace,type=bind,consistency=delegated", - "workspaceFolder": "/home/komodo/workspace" + "workspaceFolder": "/home/komodo/workspace", + "hostRequirements": { + "cpus": 4, + "memory": "16gb", + "storage": "32gb" + } } \ No newline at end of file diff --git a/.docker/dev-setup.sh b/.docker/dev-setup.sh index 0e1ce4bfe..0b0f225c9 100644 --- a/.docker/dev-setup.sh +++ b/.docker/dev-setup.sh @@ -3,8 +3,8 @@ set -e sudo git config core.fileMode false -sudo chmod -R u+rwx /home/komodo -sudo chown -R komodo:komodo /home/komodo +sudo chmod -R u+rwx /home/komodo/workspace +sudo chown -R komodo:komodo /home/komodo/workspace flutter pub get curl -o assets/coins.json https://raw.githubusercontent.com/KomodoPlatform/coins/master/coins