Skip to content

Commit b0c7fb6

Browse files
Copilotthenot-lab
andcommitted
Add BUILD_AND_RELEASE.md and GitHub Actions workflow for mobile-ide
Co-authored-by: thenot-lab <246272765+thenot-lab@users.noreply.github.com>
1 parent b5ae351 commit b0c7fb6

File tree

3 files changed

+295
-0
lines changed

3 files changed

+295
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
name: Scaffold, Build & Release APK
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches: [ main ]
7+
8+
jobs:
9+
scaffold-build-release:
10+
runs-on: ubuntu-latest
11+
env:
12+
PYVER: '3.9'
13+
ANDROID_SDK_ROOT: ${{ runner.temp }}/android-sdk
14+
APK_NAME: mobileidepro-debug.apk
15+
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
22+
- name: Scaffold minimal app if missing
23+
id: scaffold
24+
run: |
25+
set -e
26+
if [ ! -f main.py ] || [ ! -f buildozer.spec ]; then
27+
echo "Scaffolding minimal mobile-ide app..."
28+
cat > main.py <<'PY'
29+
#!/usr/bin/env python3
30+
from kivy.app import App
31+
from kivy.uix.boxlayout import BoxLayout
32+
from kivy.uix.label import Label
33+
from kivy.uix.button import Button
34+
from kivy.core.window import Window
35+
36+
class MobileIDERoot(BoxLayout):
37+
def __init__(self, **kwargs):
38+
super().__init__(**kwargs)
39+
self.orientation = 'vertical'
40+
top = BoxLayout(size_hint_y=0.15)
41+
top.add_widget(Button(text='Login (GitHub)', on_press=lambda x: None))
42+
self.add_widget(top)
43+
editor = Label(text='Code editor placeholder\nStart typing here...', halign='left')
44+
self.add_widget(editor)
45+
bottom = BoxLayout(size_hint_y=0.15)
46+
bottom.add_widget(Button(text='Run', on_press=lambda x: None))
47+
bottom.add_widget(Button(text='Cloud Sync', on_press=lambda x: None))
48+
self.add_widget(bottom)
49+
50+
class MobileIDEApp(App):
51+
def build(self):
52+
Window.clearcolor = (0.12,0.12,0.13,1)
53+
return MobileIDERoot()
54+
55+
if __name__ == '__main__':
56+
MobileIDEApp().run()
57+
PY
58+
cat > buildozer.spec <<'INI'
59+
[app]
60+
title = Mobile IDE
61+
package.name = mobileidepro
62+
package.domain = com.thenotlab
63+
source.dir = .
64+
source.include_exts = py,png,jpg,kv,atlas,json,ttf
65+
version = 1.0.0
66+
requirements = python3,kivy,pygments,aiohttp,requests,Pillow
67+
orientation = portrait
68+
android.permissions = INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE,ACCESS_NETWORK_STATE
69+
android.minapi = 27
70+
android.api = 33
71+
android.ndk = 25b
72+
icon.filename = assets/icon.png
73+
INI
74+
cat > requirements.txt <<'REQ'
75+
kivy>=2.2.0
76+
pygments>=2.15.0
77+
aiohttp>=3.8.0
78+
requests>=2.31.0
79+
Pillow>=10.0.0
80+
REQ
81+
mkdir -p assets/fonts assets/themes src/ui src/copilot src/auth src/filesystem src/executor
82+
echo "Replace with real PNG" > assets/placeholder_icon.txt
83+
git config user.name "github-actions[bot]"
84+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
85+
git add main.py buildozer.spec requirements.txt assets || true
86+
git commit -m "scaffold: add minimal Kivy app and buildozer.spec" || true
87+
echo "Scaffolded=1" >> $GITHUB_OUTPUT
88+
else
89+
echo "Scaffolded=0" >> $GITHUB_OUTPUT
90+
fi
91+
92+
- name: Install OS packages
93+
run: |
94+
sudo apt-get update -y
95+
sudo apt-get install -y openjdk-11-jdk unzip wget libc6-i386 lib32stdc++6 lib32gcc1
96+
97+
- name: Install Android tools & SDK packages
98+
run: |
99+
set -e
100+
mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools"
101+
cd $RUNNER_TEMP
102+
wget -q https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -O cmdline-tools.zip
103+
unzip -q cmdline-tools.zip -d "$ANDROID_SDK_ROOT/cmdline-tools"
104+
mv "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools" "$ANDROID_SDK_ROOT/cmdline-tools/latest" || true
105+
export PATH="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$PATH"
106+
yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" "platform-tools" "platforms;android-33" "build-tools;33.0.2" || true
107+
echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT" >> $GITHUB_ENV
108+
echo "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin" >> $GITHUB_PATH
109+
110+
- name: Accept Android SDK licenses
111+
run: |
112+
yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses || true
113+
114+
- name: Setup Python
115+
uses: actions/setup-python@v4
116+
with:
117+
python-version: '3.9'
118+
119+
- name: Install Buildozer, Cython and requirements
120+
run: |
121+
python -m pip install --upgrade pip wheel setuptools
122+
pip install buildozer==1.4.2 cython==0.29.36
123+
pip install -r requirements.txt || true
124+
125+
- name: Build APK with Buildozer
126+
run: |
127+
set -e
128+
buildozer android clean || true
129+
buildozer -v android debug
130+
ls -la bin || true
131+
132+
- name: Upload APK artifact
133+
uses: actions/upload-artifact@v3
134+
with:
135+
name: mobileide-apk
136+
path: bin/*.apk
137+
138+
- name: Create Release and upload APK
139+
uses: softprops/action-gh-release@v1
140+
with:
141+
files: bin/*.apk
142+
tag_name: v${{ github.run_number }}
143+
name: "mobile-ide Release v${{ github.run_number }}"
144+
env:
145+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
146+
147+
- name: Output install link
148+
run: |
149+
APK_FILE=$(basename bin/*.apk)
150+
INSTALL_URL="https://github.com/${GITHUB_REPOSITORY}/releases/latest/download/${APK_FILE}"
151+
echo "InstallURL=${INSTALL_URL}" >> $GITHUB_OUTPUT
152+
echo "Download/Install: ${INSTALL_URL}"

.gitignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
venv/
8+
env/
9+
ENV/
10+
*.egg-info/
11+
dist/
12+
build/
13+
14+
# Buildozer
15+
.buildozer/
16+
bin/
17+
*.apk
18+
*.aab
19+
20+
# Android
21+
local.properties
22+
*.iml
23+
.gradle/
24+
.idea/
25+
26+
# Temporary files
27+
*.log
28+
*.tmp
29+
/tmp/

BUILD_AND_RELEASE.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Build & Release — mobile-ide
2+
3+
Save as BUILD_AND_RELEASE.md in the repo root (or paste into an agent). This single file includes: repo setup, local build steps, GitHub Actions workflow to scaffold/build/release an APK, keystore/signing notes, OAuth setup, runtime permissions, install instructions, and troubleshooting. Follow each numbered step.
4+
5+
## 1) Create repository
6+
- Create a new repo on GitHub:
7+
- Owner: thenot-lab
8+
- Name: mobile-ide
9+
- Branch: main
10+
- Initialize with README (optional)
11+
12+
## 2) Add this file and the workflow
13+
- Create these files in the repository (paths shown). You can paste them manually or use the unifile approach.
14+
- BUILD_AND_RELEASE.md (this file)
15+
- .github/workflows/scaffold-build-release.yml (workflow below)
16+
- Optionally: main.py, buildozer.spec, requirements.txt, assets/, src/ if you already have code.
17+
18+
## 3) Minimal/Scaffold GitHub Actions workflow
19+
- Create .github/workflows/scaffold-build-release.yml with the exact contents below. This workflow will:
20+
- Scaffold a minimal Kivy app if main.py/buildozer.spec missing
21+
- Install Android SDK tools, Buildozer, build the APK
22+
- Create a GitHub Release and upload the APK
23+
- Emit a direct download URL for the APK
24+
25+
See `.github/workflows/scaffold-build-release.yml` for the complete workflow.
26+
27+
## 4) Trigger the build
28+
- Push to main:
29+
```bash
30+
git add . && git commit -m "Add workflow" && git push origin main
31+
```
32+
- Or run Actions → Scaffold, Build & Release APK → Run workflow (workflow_dispatch).
33+
34+
## 5) After the workflow completes
35+
- Open the workflow run; view step "Output install link" or check the job summary for:
36+
```
37+
https://github.com/thenot-lab/mobile-ide/releases/latest/download/<apk-file>.apk
38+
```
39+
- Open that URL on your Android device to download the APK. Enable "Install unknown apps" for your browser/file manager if required. Tap to install.
40+
41+
## 6) Keystore & signed releases (recommended for distribution)
42+
- Create keystore locally:
43+
```bash
44+
keytool -genkeypair -v -keystore my-release.keystore -alias mobileide -keyalg RSA -keysize 2048 -validity 10000
45+
```
46+
- To sign in CI:
47+
- Base64-encode keystore and store secrets in repo Settings → Secrets:
48+
- ANDROID_KEYSTORE_BASE64
49+
- KEYSTORE_PASSWORD
50+
- KEY_ALIAS
51+
- KEY_PASSWORD
52+
- Add steps to the workflow to decode keystore, place at ~/.buildozer/android/platform/android-*/ and set buildozer.spec signing config:
53+
```ini
54+
android.release_keyalias = <alias>
55+
android.release_keystore = <path>
56+
android.release_storepass = <pass>
57+
android.release_keypass = <keypass>
58+
```
59+
- I can provide the workflow signing snippet on request.
60+
61+
## 7) GitHub OAuth (GitHub login & Copilot)
62+
- Create an OAuth App: https://github.com/settings/developers → New OAuth App
63+
- Name: Mobile IDE
64+
- Homepage: https://github.com/thenot-lab/mobile-ide
65+
- Authorization callback URL: mobile-ide://auth/callback
66+
- Copy Client ID and Client Secret; do NOT commit them.
67+
- Store secrets in repo or in-app config. Implement OAuth flow inside the app via a WebView or external browser + redirect handling.
68+
- Copilot: user must have Copilot subscription. Copilot token exchange is not public—use GitHub APIs/copilot proxy per current available docs and ensure compliance with GitHub terms.
69+
70+
## 8) Runtime storage permissions & file access
71+
- buildozer.spec includes READ/WRITE external storage. On Android 8.1 (API 27) this is enough for /sdcard access.
72+
- For Android 11+ (API 30+), scoped storage applies. Options:
73+
- Request MANAGE_EXTERNAL_STORAGE (special permission) in manifest (play store restrictions apply) and handle runtime request via Intent ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION.
74+
- Better: use Storage Access Framework (SAF) and DocumentFile APIs for file picking and read/write.
75+
- In-app: request runtime permissions using Android API or python-for-android Android modules. Prompt user on first use.
76+
77+
## 9) Inter-app communication (Copilot/Claude)
78+
- Use Intent filters and FileProvider to share files securely. Declare intent-filters in AndroidManifest and configure provider in buildozer.spec (android.manifest_additions) if needed.
79+
- Prefer content:// URIs returned by FileProvider rather than raw filesystem paths.
80+
81+
## 10) Local development & desktop testing
82+
- To run locally (desktop), install Python dependencies and run:
83+
```bash
84+
python3 -m venv venv && source venv/bin/activate
85+
pip install -r requirements.txt
86+
python main.py
87+
```
88+
89+
## 11) Troubleshooting (quick)
90+
- Build fails → check build logs (Actions run), search for missing system libs or dependency version conflicts.
91+
- "Timeout / disk space" errors → re-run; consider self-hosted runner for heavy builds.
92+
- App permission denied → ensure runtime permission request implemented and user granted.
93+
94+
## 12) OAuth customization (pick one)
95+
- Add full UI, file manager, Copilot client, OAuth code: I can provide code snippets or a PR if you permit.
96+
- Add APK signing snippet to CI: provide keystore and I will show workflow changes.
97+
- Add GitHub Pages install page to present "Install" button linking to release asset.
98+
99+
## 13) Best practices (brief)
100+
- Never commit secrets (Client Secret, keystore passwords). Use GitHub Secrets.
101+
- Use HTTPS for all network calls.
102+
- Validate and sandbox any executed code; running arbitrary code on device is risky—warn users and implement runtime limits.
103+
104+
## 14) Contact / reproduction notes
105+
- This file targets thenot-lab/mobile-ide on branch main and the GitHub Actions runner environment ubuntu-latest (2026-01-17). Adjust PYVER, android.api, ndk and buildozer versions if you have constraints.
106+
107+
## Next Steps
108+
109+
If you want, I will:
110+
- (A) produce the exact keystore signing workflow snippet,
111+
- (B) generate a richer scaffold (editor+file browser+terminal) and open a PR (I will need permission to create PRs),
112+
- (C) produce a GitHub Pages install page job.
113+
114+
Tell me which option to do next.

0 commit comments

Comments
 (0)