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.

1

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.

github.com/LumiROM/LumiROM

2

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.

3

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.

4

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:

💡 Hugging Face Setup:
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.

1

Clone the Repository

Open a Linux terminal and clone the source code:

bash
git clone https://github.com/LumiROM/LumiROM.git cd LumiROM
2

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:

build_local.sh
OPTIONS: -s, --stock <SM-XXXXX> Your phone model (must be supported) -c, --csc <XXX> Region code of the base firmware (3 letters) -i, --imei <15 digits> Valid IMEI of the base device -t, --target <SM-XXXXX> Base device (auto-derived from stock if omitted) -m, --maintainer <name> Maintainer name (default: git username) --no-mods Exclude mods (Cloudy app, Vulkan fix, VoLTE fix...) --no-ai Exclude Galaxy AI features --bpf-legacy Enable if kernel BPF < 5.10 --img-zip Deliver .img files in a ZIP instead of a flashable ROM -h, --help Show all options and supported devices
3

Execute the Script

Run the script to download dependencies, apply modifications, and package the flashable ZIP into the ROM/ directory:

bash
bash build_local.sh -s SM-A325F -c DBT -i 353117555323497

Before building, the script validates all your inputs (models, CSC, IMEI) and detects the One UI version automatically. Builds made locally are tagged as Unofficial.

4

Manage Firmware Cache

The build tool features a smart cache manager to avoid downloading clean firmwares multiple times. Test it interactively:

Interactive Console
$ bash scripts/firmware/cache_manager.sh status [CACHE STATUS] Checking firmware cache directory... Cache status: ENABLED Total firmware versions cached: 3 Latest build cached: SM-A346B (One UI 8.5) Integrity check: PASS

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.

1

Clone the Repository

Open a Linux terminal and clone the source code:

bash
git clone https://github.com/LumiROM/LumiROM.git cd LumiROM
2

Install the TUI Dependencies

Python 3.10 or newer is required. Install the TUI dependencies:

bash
python3 -m pip install --break-system-packages -r scripts/tui/requirements.txt
3

Launch the TUI

Start LumiROM Builder from the repository root:

bash
python3 -m scripts.tui
4

Fill 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.

💡 Controls:
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:

⚠️ Package verification failed:
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:

bash
HF_USER=<hf-user> HF_TOKEN=<token> \ scripts/package/resign_published_ota.sh [--dry-run] [device ...]

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).