Jenkinsfile generalizes the OFRP-12.1 job for every base branch: one job per branch named after it (cms-<branch> jobs target the cms test portal), base settings from the branch build.toml (validated by pipeline/build_config.py), the same preflight, warm rollback, manifest sync, build, rename, checksum, Garage upload and portal registration stages, plus portal_request_id for builds started from the portal and a warm-base lock shared by a base's live and test jobs. README documents the device XMLs, the pipeline and build.toml. Co-Authored-By: Claude Opus 5.5 <[email protected]>
164 lines
6.9 KiB
Markdown
164 lines
6.9 KiB
Markdown
# 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
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<manifest>
|
|
<remote name="ateam" fetch="ssh://[email protected]/" />
|
|
|
|
<project path="device/motorola/genevn"
|
|
name="A-Team_Digital_Solutions/recovery_device_motorola_genevn"
|
|
remote="ateam" revision="ofrp-12.1">
|
|
<annotation name="ateam.model" value="XT2315"/>
|
|
<annotation name="ateam.device_name" value="Moto G Stylus 5G 2023"/>
|
|
<annotation name="ateam.manufacturer" value="Motorola"/>
|
|
<annotation name="ateam.partition" value="recovery"/>
|
|
</project>
|
|
</manifest>
|
|
```
|
|
|
|
### 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 `<device_name> (<model>)`.
|
|
|
|
### 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 `<remote>` 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:
|
|
|
|
```
|
|
<RECOVERY>-<ver>_A-Team_<codename>_<model>-<YYMMDD>.<img|zip>
|
|
```
|
|
|
|
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://[email protected]/A-Team_Digital_Solutions/build_manifests.git
|
|
cd build_manifests
|
|
git checkout ofrp-12.1
|
|
```
|
|
2. Copy an existing XML to `<codename>.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 `<base>-<version>` (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 `<dataset>@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-<branch>` 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 `<zfs_dataset>@warm` and checks the warm base is clean (no device tree for the device,
|
|
empty `out/target/product`, empty `.repo/local_manifests`);
|
|
3. copies `<DEVICE>.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 <make_extra> <partition target>`;
|
|
5. picks the release files from `out/target/product/<codename>/`, 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:<branch>` 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" # <release_tag>-<release_ver>_A-Team_<codename>_<model>-<YYMMDD>
|
|
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/<codename>/, 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.<ext>]` becomes `<release name>.<ext>` plus `<release name>.<ext>.sha256`.
|