Build Methods¶
Select your compilation method: automate through GitHub in the cloud, compile locally via the CLI, or use the guided terminal UI. All methods produce identical flashable ZIP outputs.
GitHub Actions (Cloud)¶
Build LumiROM entirely in the cloud using GitHub's free runners - no local Linux environment required. The workflow handles everything automatically.
Fork the Repository
Give a ⭐ star to the official LumiROM repository on GitHub.
Fork the repository to your own GitHub account to execute custom build workflows.
Run the Workflow
Open your forked repository and click on the Actions tab.
Select LumiROM Tools from the left sidebar and click Run workflow.
Note: the All Devices workflow (Matrix) is only intended for the developer, as it builds LumiROM for every supported device at once in a single run. If you are building from a fork, always use LumiROM Tools.
Configure Device Parameters
Fill in STOCK_DEVICE with your phone's model
(it must exist in the /LumiROM/Devices folder of your repository -
check the Supported Devices page).
Fill in TARGET_DEVICE, TARGET_CSC and
TARGET_IMEI using your device's Base: the base model,
a region code and a valid 15-digit IMEI of that base device.
Set Kernel BPF Version (USE_UI_8_TETHERING_APEX): tick it only if
your kernel BPF version is lower than 5.10. You can check your kernel version under
Settings → About phone → Software information → Kernel version. All supported devices
already have compatible kernels, so leave it disabled.
Optionally, tick ZIP_IMG to receive the partition images (.img) inside
a ZIP instead of a flashable ROM.
Upload Destination
The DESTINATION option chooses where the ROM will be uploaded:
GoFile (the default - no account needed, it generates a download
link once the ROM is uploaded) or Hugging Face.
To use Hugging Face, set up two things on your fork before running the workflow:
1. Create a Hugging Face account.
2. Go to Settings → Access Tokens → Generate a write token.
3. In your GitHub repository: Settings → Secrets and variables → Actions.
4. Add the token as a repository secret named
HF_TOKEN.5. In the Variables tab, add a repository variable named
HF_USER with your Hugging Face username as the value.
Local Build¶
Compile LumiROM locally on your Linux machine (Ubuntu/Debian) or Windows via WSL. The script is fully automated and caches firmware to avoid re-downloading. Requirements: around 15 GB of free disk space for the firmware download and the build.
Clone the Repository
Open a Linux terminal and clone the source code:
Choose Your Options
Only the stock model, region and IMEI are required - everything else has a default. If you omit a required option, the script asks for it interactively:
Execute the Script
Run the script to download dependencies, apply modifications, and package
the flashable ZIP into the ROM/ directory:
bash build_local.sh -s SM-A325F -c DBT -i 353117555323497Before building, the script validates all your inputs (models, CSC, IMEI) and detects the One UI version automatically. Builds made locally are tagged as Unofficial.
Manage Firmware Cache
The build tool features a smart cache manager to avoid downloading clean firmwares multiple times. Test it interactively:
Terminal UI (TUI)¶
If you prefer a guided interface, LumiROM Builder is a terminal UI
that wraps build_local.sh. Fill a form on the right, watch the build run in a
real embedded terminal on the left, and get the resulting ZIP listed when it finishes.
It requires the same resources as the CLI build.
Clone the Repository
Open a Linux terminal and clone the source code:
Install the TUI Dependencies
Python 3.10 or newer is required. Install the TUI dependencies:
python3 -m pip install --break-system-packages -r scripts/tui/requirements.txtLaunch the TUI
Start LumiROM Builder from the repository root:
python3 -m scripts.tuiFill the Form and Build
In the right panel, choose your Stock device, type the CSC/region (3 letters, always uppercased automatically) and the IMEI of the base device, then set your Maintainer name. You can also toggle mods, Galaxy AI, the BPF-legacy option, image-only ZIP delivery and an incremental build. The exact command is always previewed on the left.
Press Start Build to run it. The build executes in the terminal
panel on the left - because it is a real terminal, colors, progress bars and
sudo prompts work as usual, so type your password there when asked.
Start Build - validate the form and start the build.Cancel Build or Ctrl+X - stop a running build.Ctrl+S - save the current form · Ctrl+Q - quit.The form is remembered in
scripts/tui/.tui_state.json.
The TUI runs the exact same steps as the CLI method, so the
firmware cache and the output
in the ROM/ folder work identically.
OTA Signing¶
Every flashable package - both the full ROM and the incremental OTA - is signed with
signapk -w. The signature is stored as a ZIP comment (the footer) that
Cloudy and Android's RecoverySystem read before installing. Without it the device
rejects the package with:
no signature in file (no footer)
Signing is fully automatic: the workflows (OneUi8-5.yml and
OneUi8-5-Matrix.yml) and build_local.sh sign the full ROM and then sign
the incremental OTA after its post-processing (the SamsungCamera cleanup re-zips
the package, which would otherwise strip an earlier signature). The OTA key comes from the
OTA_PK8/OTA_CERT secrets, or from ~/.lumi/keys/ota.*
locally. If the key is missing the build fails on purpose, so a broken OTA is never
published.
Re-signing already published OTAs
OTAs published before the incremental signing step existed lack the footer and must be re-signed and re-uploaded:
By default it processes a32 a22 m32 f22. For each device it downloads the
incremental from its OTA manifest, re-signs it, regenerates the manifest under
OTA_MANIFESTS/{device}_ota.json, and re-uploads it to the
<HF_USER>/OTAs bucket. Add --dry-run to only sign locally.
Remember to commit the regenerated manifests to the
cloudy
repository (updater/ota/{device}.json).