# build_manifests Device manifests for the A-Team Jenkins build pipelines. Each base branch has one Jenkins job (named after the branch) running the shared `Jenkinsfile` from `main`. It rolls the base's warm source tree back to `@warm`, drops one device XML into `.repo/local_manifests/`, syncs only the projects listed in it, reads the device info from its annotations and the base settings from the branch's `build.toml`. ## Layout **One branch per build base, one file per device.** ``` ofrp-12.1/ genevn.xml milanf.xml rtwo.xml ... twrp-12.1/ genevn.xml ... aera-16.0/ genevn.xml milanf.xml ... ``` A job points at a branch + file, e.g. `ofrp-12.1` / `genevn.xml`. ## Device XML A standard repo local manifest, plus `ateam.*` annotations on the device tree project. ```xml ``` ### Annotations All four are required; the build stops if one is missing. | Annotation | Used for | Example | |---|---|---| | `ateam.model` | Release file name, portal device name | `XT2315` | | `ateam.device_name` | Portal device name | `Moto G Stylus 5G 2023` | | `ateam.manufacturer` | Portal | `Motorola` | | `ateam.partition` | Build target and flash target | `recovery` | `ateam.partition` must be one of: | Value | Builds | |---|---| | `recovery` | `recoveryimage` | | `boot` | `bootimage` | | `vendor_boot` | `vendorbootimage` | The portal shows the device as ` ()`. ### Projects - List the device tree plus anything else the device needs (kernel, vendor, common trees). - Every project listed gets synced; nothing else in the base tree is touched. - Any git source works. Add another `` for GitHub or elsewhere; the device tree doesn't have to live on A-Team Forgejo. - Pin `revision` to the branch for that base (e.g. `ofrp-12.1`). - Don't add projects that override the base's own repos. Device-specific fixes go in the device trees. ## Release naming Builds come out as: ``` -_A-Team__-. ``` plus a `.sha256` for each, e.g. `OFRP-12.1_A-Team_genevn_XT2315-261009.zip`. ## Adding a device 1. Clone and switch to the base branch: ``` git clone ssh://git@ateam.gotadell.com/A-Team_Digital_Solutions/build_manifests.git cd build_manifests git checkout ofrp-12.1 ``` 2. Copy an existing XML to `.xml` and edit the projects and annotations. 3. Commit and push. 4. That's it: the branch's Jenkins job (named after the branch, e.g. `ofrp-12.1`) lists the new XML in its `DEVICE` dropdown, and the portal picks it up on its next device sync. ## Adding a base 1. Create a new branch named `-` (e.g. `shrp-12.1`) and add a device XML for each device built on it. Each base has its own copy of a device's XML, so update model or name changes on every branch that has that device. 2. Add a `build.toml` (see the README on `main`) describing the base: portal project, release naming, ZFS dataset, lunch target and release files. 3. Prepare the warm source tree on buildBox and snapshot it as `@warm`. 4. Create a Jenkins job named exactly like the branch, using *Pipeline script from SCM* on `build_manifests` branch `main`, script path `Jenkinsfile`. 5. Map the portal project to the job in the portal admin. ## Build pipeline `Jenkinsfile` on `main` is the build pipeline for every base. Each base branch has one Jenkins job named exactly like the branch (`ofrp-12.1`, `twrp-12.1`, ...), set to *Pipeline script from SCM* on this repo, branch `main`, script path `Jenkinsfile`. A job named `cms-` builds the same base for the cms test portal (test bucket, test credentials, `ateam-cms.gotadell.com`). Per run the job: 1. checks the device codename, resolves `build.toml` for that device (`pipeline/build_config.py`) and checks the warm snapshot and its mountpoint; 2. rolls the base back to `@warm` and checks the warm base is clean (no device tree for the device, empty `out/target/product`, empty `.repo/local_manifests`); 3. copies `.xml` into `.repo/local_manifests/`, fixes branch-name case, reads the `ateam.*` annotations and syncs only the listed projects; 4. runs `lunch`, `m installclean` and `mka `; 5. picks the release files from `out/target/product//`, verifies their native checksums, renames them to the A-Team scheme with a `.sha256` each, uploads them to Garage and registers the build with the portal as testing (including the portal request id when the portal started it); 6. rolls the base back to `@warm` again (on failure the tree is left for diagnosis; the next run rolls it back). A base's live and `cms-` jobs share one ZFS dataset and hold the `warm-base:` lock (Lockable Resources plugin) for the whole run. Parameters: `DEVICE` (lists the branch's XMLs), `CHANGELOG`, `PORTAL_REQUEST_ID` and `PORTAL_USER` (set by the portal's *Start build*), and `MANIFEST_REF` (cms- test jobs only, to build from an unmerged branch). ## build.toml Every base branch has a `build.toml` next to the device XMLs. It is data only: unknown keys, wrong types or placeholders other than `{codename}` stop the build. ```toml [base] project = "orangefox" # portal project slug project_name = "OrangeFox" version = "R12.1" # version shown in the portal release_tag = "OFRP" # -_A-Team__- release_ver = "12.1" source_root = "/build/ofox-12.1" # mountpoint of zfs_dataset; out/ lives inside it zfs_dataset = "build/ofox-12.1" # rolled back to @warm before and after every build warm_check = ["vendor/recovery"] # must exist in the warm base lunch_target = "twrp_{codename}-eng" make_extra = ["adbd"] # built together with the ateam.partition target changelog = "Automated OrangeFox testing build." [base.env] # extra environment for lunch and the build FOX_BUILD_DEVICE = "{codename}" [outputs.img] # release files in out/target/product//, exactly one match each glob = "OrangeFox-*.img" checksum = "md5" # native sidecar to verify: md5 | sha256 | none [outputs.zip] glob = "OrangeFox-*.zip" checksum = "md5" test_zip = true [devices.sycamore_row_5G] # optional per-device overrides: lunch_target, make_extra, env, outputs lunch_target = "twrp_sycamore_row_5G-eng" ``` Each `[outputs.]` becomes `.` plus `..sha256`.