Skip to content

Commit 904d09a

Browse files
committed
Merge remote-tracking branch 'origin/stage' into feat/ADFA-3253-skip-llama-assets-ci
# Conflicts: # app/build.gradle.kts
2 parents 8fd63c7 + deafbbd commit 904d09a

219 files changed

Lines changed: 238 additions & 29991 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 29 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -582,60 +582,16 @@ jobs:
582582
583583
echo "FIREBASE_CONSOLE_URL=$FIREBASE_URL" >> $GITHUB_OUTPUT
584584
585-
- name: Set up SSH key
585+
- name: Install uv
586+
uses: astral-sh/setup-uv@v6
587+
588+
- name: Upload APK to Cloudflare R2
586589
env:
587-
GREENGEEKS_HOST: ${{ vars.GREENGEEKS_SSH_HOST }}
588-
GREENGEEKS_KEY: ${{ secrets.GREENGEEKS_SSH_PRIVATE_KEY }}
589-
GREENGEEKS_USER: ${{ vars.GREENGEEKS_SSH_USER }}
590+
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
591+
CLOUDFLARE_KEY_ID: ${{ vars.CLOUDFLARE_KEY_ID }}
592+
CLOUDFLARE_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_SECRET_ACCESS_KEY }}
590593
run: |
591-
mkdir -p ~/.ssh
592-
if [ -z "$GREENGEEKS_HOST" ]; then
593-
echo "Error: SSH_HOST variable is not set"
594-
exit 1
595-
fi
596-
# Write the SSH key, ensuring proper formatting
597-
echo "$GREENGEEKS_KEY" > ~/.ssh/id_rsa
598-
# Remove any trailing newlines and ensure proper key format
599-
sed -i '' -e '$ { /^$/ d; }' ~/.ssh/id_rsa 2>/dev/null || sed -i '$ { /^$/ d; }' ~/.ssh/id_rsa
600-
chmod 600 ~/.ssh/id_rsa
601-
# Verify key format
602-
if ! grep -q "BEGIN.*PRIVATE KEY" ~/.ssh/id_rsa; then
603-
echo "Error: SSH key does not appear to be in correct format"
604-
exit 1
605-
fi
606-
# Configure SSH to use only the key file and disable other auth methods
607-
cat > ~/.ssh/config <<EOF
608-
Host *
609-
IdentitiesOnly yes
610-
PreferredAuthentications publickey
611-
StrictHostKeyChecking no
612-
UserKnownHostsFile ~/.ssh/known_hosts
613-
PubkeyAuthentication yes
614-
PasswordAuthentication no
615-
ChallengeResponseAuthentication no
616-
GSSAPIAuthentication no
617-
GSSAPIKeyExchange no
618-
GSSAPIDelegateCredentials no
619-
Host $GREENGEEKS_HOST
620-
User $GREENGEEKS_USER
621-
IdentityFile ~/.ssh/id_rsa
622-
IdentitiesOnly yes
623-
PreferredAuthentications publickey
624-
PubkeyAuthentication yes
625-
PasswordAuthentication no
626-
ChallengeResponseAuthentication no
627-
GSSAPIAuthentication no
628-
GSSAPIKeyExchange no
629-
GSSAPIDelegateCredentials no
630-
NumberOfPasswordPrompts 0
631-
EOF
632-
chmod 600 ~/.ssh/config
633-
# Disable SSH agent completely
634-
unset SSH_AUTH_SOCK
635-
unset SSH_AGENT_PID
636-
# Remove any default SSH keys that might interfere
637-
rm -f ~/.ssh/id_ed25519 ~/.ssh/id_ecdsa ~/.ssh/id_dsa ~/.ssh/id_rsa.pub 2>/dev/null
638-
ssh-keyscan -H "$GREENGEEKS_HOST" >> ~/.ssh/known_hosts 2>/dev/null
594+
uv run --with boto3 scripts/cloudflare-r2-upload.py "${{ steps.find_apk.outputs.APK_PATH }}" "${{ matrix.variant }}"
639595
640596
- name: Clean up build folder after upload
641597
run: |
@@ -735,6 +691,27 @@ jobs:
735691
736692
rm -f payload.json
737693
694+
- name: Send Telegram message
695+
env:
696+
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
697+
TELEGRAM_EARLY_ACCESS_CHAT_ID: ${{ vars.TELEGRAM_EARLY_ACCESS_CHAT_ID }}
698+
APK_PATH: ${{ steps.find_apk.outputs.APK_PATH }}
699+
VARIANT: ${{ matrix.variant }}
700+
run: |
701+
GIT_LOG=$(git log --oneline --since "24 hours ago" || true)
702+
if [ -z "$GIT_LOG" ]; then
703+
GIT_LOG="(no commits in the last 24 hours)"
704+
fi
705+
APK_BASENAME=$(basename "$APK_PATH")
706+
APK_FILENAME="${APK_BASENAME%.*}-${VARIANT}.${APK_BASENAME##*.}"
707+
DOWNLOAD_URL="https://download.appdevforall.org/${APK_FILENAME}"
708+
MESSAGE="${GIT_LOG}"$'\n\n'"Download: ${DOWNLOAD_URL}"
709+
# Telegram message limit 4096; use first 4096 chars
710+
MESSAGE="${MESSAGE:0:4096}"
711+
curl -s -X POST -H "Content-Type: application/json" \
712+
-d "$(jq -n --arg chat_id "$TELEGRAM_EARLY_ACCESS_CHAT_ID" --arg text "$MESSAGE" '{chat_id: $chat_id, text: $text}')" \
713+
"https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage"
714+
738715
- name: Cleanup google-services.json
739716
if: always()
740717
run: |

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<h2 align="center"><b>Code On The Go</b></h2>
66
<p align="center">
7-
Code on the Go is an IDE that lets you build Android apps on Android phones, without needing a traditional computer or Internet access.</p>
7+
Code on the Go is an IDE that lets you build Android apps on Android phones, without needing a traditional computer or Internet access. Code on the Go is a project of App Dev for All, a nonprofit organization committed to making computer science education and professional programming resources universally available.</p>
88
<p><br>
99

1010
<p align="center">
@@ -104,3 +104,4 @@ along with Code On The Go. If not, see <https://www.gnu.org/licenses/>.
104104
Any violations to the license can be reported either by opening an issue or writing a mail to us
105105
directly.
106106

107+

app/build.gradle.kts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ dependencies {
302302
implementation(projects.idetooltips)
303303
implementation(projects.cvImageToXml)
304304
implementation(projects.composePreview)
305-
implementation(projects.gitCore)
305+
implementation(projects.gitCore)
306306

307307
// This is to build the tooling-api-impl project before the app is built
308308
// So we always copy the latest JAR file to assets
@@ -318,7 +318,7 @@ dependencies {
318318
androidTestImplementation(libs.tests.junit.kts)
319319
androidTestImplementation(libs.tests.androidx.test.runner)
320320
androidTestUtil(libs.tests.orchestrator)
321-
testImplementation(libs.tests.kotlinx.coroutines)
321+
testImplementation(libs.tests.kotlinx.coroutines)
322322

323323
// brotli4j
324324
implementation(libs.brotli4j)
@@ -503,6 +503,21 @@ fun createAssetsZip(arch: String) {
503503

504504
// 4. Set the full command line
505505
commandLine(d8Command)
506+
507+
// Prepend JAVA_HOME/bin to PATH, so that `java` can be resolved
508+
// on systems which don't already have `java` in PATH
509+
val javaHome = System.getProperty("java.home")
510+
if (javaHome.isNotBlank()) {
511+
val javaHomeBin = javaHome + File.separator + "bin"
512+
val currentPath = System.getenv("PATH") ?: ""
513+
var finalPath = javaHomeBin
514+
if (currentPath.isNotBlank()) {
515+
finalPath += File.pathSeparator
516+
finalPath += currentPath
517+
}
518+
519+
environment("PATH", finalPath)
520+
}
506521
}.assertNormalExitValue()
507522

508523
if (!dexOutputFile.exists()) {

scripts/cloudflare-r2-upload.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env python3
2+
"""Upload a file (e.g. APK) to Cloudflare R2. Credentials via env: CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_KEY_ID, CLOUDFLARE_SECRET_ACCESS_KEY."""
3+
import sys
4+
import os
5+
import boto3
6+
from botocore.config import Config
7+
8+
REQUIRED_ENV = (
9+
"CLOUDFLARE_ACCOUNT_ID",
10+
"CLOUDFLARE_KEY_ID",
11+
"CLOUDFLARE_SECRET_ACCESS_KEY",
12+
)
13+
14+
for name in REQUIRED_ENV:
15+
if not os.environ.get(name):
16+
print(f"ERROR: {name} environment variable is not set.", file=sys.stderr)
17+
sys.exit(1)
18+
19+
CLOUDFLARE_ACCOUNT_ID = os.environ["CLOUDFLARE_ACCOUNT_ID"]
20+
CLOUDFLARE_KEY_ID = os.environ["CLOUDFLARE_KEY_ID"]
21+
CLOUDFLARE_SECRET_ACCESS_KEY = os.environ["CLOUDFLARE_SECRET_ACCESS_KEY"]
22+
BUCKET_NAME = "apk-repo"
23+
24+
R2_ENDPOINT_URL = f"https://{CLOUDFLARE_ACCOUNT_ID}.r2.cloudflarestorage.com"
25+
26+
config = Config(
27+
read_timeout=300,
28+
connect_timeout=60,
29+
retries={"max_attempts": 10},
30+
)
31+
32+
s3 = boto3.client(
33+
service_name="s3",
34+
endpoint_url=R2_ENDPOINT_URL,
35+
aws_access_key_id=CLOUDFLARE_KEY_ID,
36+
aws_secret_access_key=CLOUDFLARE_SECRET_ACCESS_KEY,
37+
region_name="auto",
38+
config=config,
39+
)
40+
41+
if len(sys.argv) < 3:
42+
print("Usage: cloudflare-r2-upload.py <file_path> <variant>", file=sys.stderr)
43+
sys.exit(1)
44+
45+
file_path = sys.argv[1]
46+
variant = sys.argv[2]
47+
file_size = os.path.getsize(file_path)
48+
base_name = os.path.basename(file_path)
49+
# Inject variant into filename before .apk so v7 and v8 upload to distinct R2 keys
50+
name_root, ext = os.path.splitext(base_name)
51+
file_name = f"{name_root}-{variant}{ext}"
52+
53+
extra_args = {}
54+
if file_name.lower().endswith(".apk"):
55+
extra_args["ContentType"] = "application/vnd.android.package-archive"
56+
57+
# Progress callback: print new lines at 10% intervals for CI-friendly logs (bytes_amount is incremental per call)
58+
_seen_so_far = [0]
59+
_last_printed_pct = [-1]
60+
61+
def progress_callback(bytes_amount):
62+
_seen_so_far[0] += bytes_amount
63+
if file_size <= 0:
64+
return
65+
pct = int(100 * _seen_so_far[0] / file_size)
66+
if pct >= _last_printed_pct[0] + 10 or pct == 100:
67+
_last_printed_pct[0] = pct
68+
mb = _seen_so_far[0] / (1024 * 1024)
69+
total_mb = file_size / (1024 * 1024)
70+
print(f"Upload progress: {pct}% ({mb:.1f} MB / {total_mb:.1f} MB)", flush=True)
71+
72+
73+
upload_kwargs = {"Callback": progress_callback}
74+
if extra_args:
75+
upload_kwargs["ExtraArgs"] = extra_args
76+
77+
print(f"Uploading {file_name} ({file_size / (1024*1024):.1f} MB) to R2...", flush=True)
78+
s3.upload_file(file_path, BUCKET_NAME, file_name, **upload_kwargs)
79+
print("Upload complete.", flush=True)

subprojects/llama.cpp/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ llama-cli -hf ggml-org/gemma-3-1b-it-GGUF
5353
llama-server -hf ggml-org/gemma-3-1b-it-GGUF
5454
```
5555

56+
## Security note (local wasm test server)
57+
58+
`scripts/serve-static.js` now constrains request paths to the wasm output directory and adds safer HTML response headers.
59+
- This prevents path traversal and reduces XSS risk in directory listings and served HTML.
60+
- How? Normalize/resolve paths under `build-wasm/bin`, return `403` on escapes, escape listing labels, and apply CSP + `nosniff` to HTML.
61+
5662
## Description
5763

5864
The main goal of `llama.cpp` is to enable LLM inference with minimal setup and state-of-the-art performance on a wide

subprojects/llama.cpp/examples/CMakeLists.txt

Lines changed: 0 additions & 45 deletions
This file was deleted.

subprojects/llama.cpp/examples/batched.swift/.gitignore

Lines changed: 0 additions & 9 deletions
This file was deleted.

subprojects/llama.cpp/examples/batched.swift/Makefile

Lines changed: 0 additions & 6 deletions
This file was deleted.

subprojects/llama.cpp/examples/batched.swift/Package.swift

Lines changed: 0 additions & 22 deletions
This file was deleted.

subprojects/llama.cpp/examples/batched.swift/README.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)