11#!/usr/bin/env python3
22"""
3- Build lab_c5 for Momentum and Unleashed SDK bundles found in sdk/.
4- - Picks the newest zip whose name contains mntm/momentum (Momentum) or unlsh/unleashed (Unleashed).
5- - Runs `ufbt update --hw f7 --url <file:///path/to/sdk.zip>` and `ufbt` to build.
6- - Renames dist/lab_c5.fap to lab_c5_v<version>_<variant>.fap, removing older files with that name.
3+ CI-friendly FAP builder for lab_c5.
4+
5+ Ported from upstream (development branch) with tweaks:
6+ - Skips interactive upload when running in CI or when --no-upload is passed.
7+ - Allows optional --sdk-dir override; defaults to FLIPPER/sdk.
8+ - Renames artifacts to lab_c5_v<version>_<variant>.fap.
9+
10+ Expected layout:
11+ FLIPPER/
12+ Lab_C5.c (contains LAB_C5_VERSION_TEXT)
13+ sdk/*.zip (Momentum / Unleashed SDK zips)
14+ dist/ (build outputs)
715"""
816
917from __future__ import annotations
1018
19+ import argparse
20+ import os
1121import re
1222import shutil
1323import subprocess
1626from typing import Iterable , Optional
1727
1828ROOT = Path (__file__ ).resolve ().parent
19- SDK_DIR = ROOT / "sdk"
2029DIST_DIR = ROOT / "dist"
2130DIST_FAP = DIST_DIR / "lab_c5.fap"
2231SOURCE_FILE = ROOT / "Lab_C5.c"
2736)
2837
2938
39+ def parse_args () -> argparse .Namespace :
40+ parser = argparse .ArgumentParser (description = "Build lab_c5 FAP variants" )
41+ parser .add_argument (
42+ "--sdk-dir" ,
43+ type = Path ,
44+ default = ROOT / "sdk" ,
45+ help = "Directory containing Momentum/Unleashed SDK zips (default: FLIPPER/sdk)" ,
46+ )
47+ parser .add_argument (
48+ "--no-upload" ,
49+ action = "store_true" ,
50+ help = "Do not prompt or attempt upload after build" ,
51+ )
52+ return parser .parse_args ()
53+
54+
3055def read_version () -> str :
3156 text = SOURCE_FILE .read_text (encoding = "utf-8" , errors = "ignore" )
3257 match = re .search (r'#define\s+LAB_C5_VERSION_TEXT\s+"([^"]+)"' , text )
@@ -35,10 +60,10 @@ def read_version() -> str:
3560 return match .group (1 )
3661
3762
38- def pick_sdk (patterns : Iterable [str ]) -> Optional [Path ]:
63+ def pick_sdk (sdk_dir : Path , patterns : Iterable [str ]) -> Optional [Path ]:
3964 candidates = [
4065 path
41- for path in SDK_DIR .glob ("*.zip" )
66+ for path in sdk_dir .glob ("*.zip" )
4267 if any (token in path .name .lower () for token in patterns )
4368 ]
4469 if not candidates :
@@ -127,6 +152,7 @@ def prompt_upload_choice(built: list[tuple[str, Path]]) -> Optional[tuple[str, P
127152
128153
129154def main () -> None :
155+ args = parse_args ()
130156 ensure_dependencies ()
131157 version = read_version ()
132158 print (f"Detected version: { version } " )
@@ -136,9 +162,9 @@ def main() -> None:
136162 built_variants : list [tuple [str , Path ]] = []
137163
138164 for variant , patterns in VARIANTS :
139- sdk = pick_sdk (patterns )
165+ sdk = pick_sdk (args . sdk_dir , patterns )
140166 if not sdk :
141- print (f"Skipping { variant } : no matching SDK zip in { SDK_DIR } " )
167+ print (f"Skipping { variant } : no matching SDK zip in { args . sdk_dir } " )
142168 continue
143169 print (f"\n === { variant .upper ()} ===" )
144170 print (f"Using SDK: { sdk .name } " )
@@ -147,13 +173,21 @@ def main() -> None:
147173 rename_artifact (version , variant )
148174 built_variants .append ((variant , sdk ))
149175
150- selected = prompt_upload_choice (built_variants )
151- if selected :
152- variant , sdk = selected
153- print (f"\n Uploading { variant } build using SDK { sdk .name } ..." )
154- update_sdk (sdk )
155- upload_app ()
156- print ("Upload finished. Ensure your Flipper is connected over USB and unlocked." )
176+ if not built_variants :
177+ print ("No variants built (missing SDK zips?)." )
178+ return
179+
180+ should_upload = not args .no_upload and not os .getenv ("CI" )
181+ if should_upload :
182+ selected = prompt_upload_choice (built_variants )
183+ if selected :
184+ variant , sdk = selected
185+ print (f"\n Uploading { variant } build using SDK { sdk .name } ..." )
186+ update_sdk (sdk )
187+ upload_app ()
188+ print ("Upload finished. Ensure your Flipper is connected over USB and unlocked." )
189+ else :
190+ print ("Upload skipped (CI or --no-upload)." )
157191
158192 print ("\n Done." )
159193
0 commit comments