[Step] AOSP Build
Overview
HexDroid provides a dedicated aosp
step that simplifies the process of building AOSP/Android based projects.
The aosp
step can handle the following tasks:
- Syncing AOSP manifest
- Setting up the build environment and lunch configuration(s)
- Running build commands
- Integrating with HexDroid Update Management (OTA) to define and distribute OTA (over-the-air) updates as part of your CI/CD pipeline.
A primary advantage of the aosp
step is that it requires no scripting or custom logic.
All configurations are declarative.
This improves clarity, reduces maintenance overhead, and ensures reproducibility.
For example, when multiple build_variant
values are defined under a single product_name
, HexDroid automatically
expands these into
individual build executions. This expansion is handled internally and does not require additional pipeline logic.
Top Level elements
aosp
command has several top level elements:
Key | Description | Optional |
---|---|---|
manifest | Performs checkout of aosp tree (repo init/repo sync). | Yes |
lunch | Defines product configurations to build (eng vs userdebug, etc) | Yes |
build | Commands that will be executed for each product configuration | Yes |
release | Creates release, uploads OTA files to HexDroid Update Management | Yes |
artifact | Attaches CI Artifacts (eg. target-files.zip, build logs, etc) | Yes |
steps:
- aosp:
# All elements here are incomplete, shown as example what all top level elements available
manifest:
lunch:
build:
release:
artifact:
Simplified Example
Example of a simple aosp
step configuration:
steps:
- aosp:
manifest:
url: https://android.googlesource.com/platform/manifest
revision: main
name: default.xml
lunch:
product_name: aosp_cf_x86_64_phone
build_variant:
- userdebug
- eng
- user
build:
commands:
- m installclean
- m dist
This will be translated into the following steps:
repo init --manifest-url=https://android.googlesource.com/platform/manifest --manifest-branch=main --manifest-name=default.xml
repo sync --verbose
repo manifest --revision-as-HEAD --output-file=aosp_build_manifest_pinned.xml
bash -c set -e
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-userdebug
m installclean
m dist
bash -c set -e
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-eng
m installclean
m dist
bash -c set -e
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-user
m installclean
m dist
manifest
The aosp
step provides fine-grained control over the manifest initialization process through three optional phases:
init, sync, and pin.
By default, all three are enabled, ensuring a complete and repeatable setup of the AOSP source tree. However, each can be individually customized or disabled based on the needs of your project.
This allows for more flexible workflows, such as applying specific flags during sync operations.
Element | Description | Required | Type |
---|---|---|---|
url | Manifest URL to checkout. Correspond to --manifest-url= in repo init | Required | String |
revision | Manifest revision to checkout. Correspond to --manifest-branch= in repo init | Required | String Or Dynamic Lookup |
name | Manifest file to use. Correspond to --manifest-name= in repo init | Optional | String |
init | Additional control over repo init command. | Optional | Object |
sync | Additional control over repo sync command. | Optional | Object |
pin | Additional control over repo manifest command. | Optional | Object |
manifest.revision (required)
manifest.revision
element can be either hardcoded such as:
steps:
- aosp:
manifest:
url: https://android.googlesource.com/platform/manifest
revision: main # points to a specific branch
or manifest.revision
can be derived at runtime based on the trigger:
steps:
- aosp:
manifest:
url: https://android.googlesource.com/platform/manifest
revision:
# revision will be derived based on the trigger (e.g. `pull_request` trigger)
# For example, if `pull_request` trigger is set up, and the developer opens the pull request,
# The source branch of `pull_request` will be available here.
from: source_branch
manifest.init (optional)
By default init
element will be expanded into: repo init --manifest-url={url} --manifest-branch={revision} --manifest-name={name}
However, by defining init
element you can have extra control such as turn it off, or adding specific flags.
init:
enabled: true # false to disable 'repo init ...', default is true
# List of additional flags to pass to 'repo init'
# Default empty
flags:
- "--depth=1"
manifest.sync (optional)
By default sync
element will be expanded into: repo sync
However, by defining sync
element you can have extra control such as turn it off, or adding specific flags.
sync:
enabled: true # false to disable 'repo sync', default is true
# List of additional flags to pass to 'repo sync ...'
# Default empty
flags:
- "--current-branch"
manifest.pin (optional)
By default pin
element will be expanded into: repo manifest --revision-as-HEAD --output-file=aosp_build_manifest_pinned.xml
However, by defining pin
element you can have extra control such as turn it off, or adding specific flags.
pin:
enabled: true # false to disable 'repo manifest ...', default is true
# List of additional flags to pass to 'repo manifest ...'
# Default empty
flags:
- "--verbose"
Example
steps:
- aosp:
manifest:
url: https://android.googlesource.com/platform/manifest
revision: main
name: default.xml
+ init:
+ enabled: true
+ flags:
+ - "--depth=1"
+ sync:
+ enabled: true
+ flags:
+ - "--current-branch"
+ - "--verbose"
+ pin:
+ enabled: true
+ flags:
+ - "--verbose"
lunch
Element | Required | Type |
---|---|---|
product_name | Required | String |
release_config | Optional | List of Nullable Strings |
build_variant | Optional | List of Not Null Strings |
The lunch
configuration in the aosp
step defines the Android build environment, specifying the target product and
the build variants.
lunch:
product_name: aosp_cf_x86_64_phone
build_variant:
- user
- userdebug
- eng
In this case, the build step will be repeated 3 times with the following lunch targets:
aosp_cf_x86_64_phone-user
, then aosp_cf_x86_64_phone-userdebug
, then aosp_cf_x86_64_phone-eng
.
In addition to the basic product_name
and build_variant
parameters, the release_config
option provides
additional flexibility by allowing you to control build-time flags.
release_config
identifies certain features and code that are behind feature launch flags and are either enabled or
disabled for a build.
For more on release configurations,
see Set feature flag launch values.
This allows you to verify, for example, in a pull request build job, that you can build all flag variations.
lunch:
product_name: aosp_cf_x86_64_phone
+ release_config:
+ # development release configuration called trunk_staging
+ - trunk_staging
build_variant:
- user
- userdebug
- eng
In this case, the build step will be repeated 3 times with the following lunch targets:
aosp_cf_x86_64_phone-trunk_staging-user
, then aosp_cf_x86_64_phone-trunk_staging-userdebug
, then
aosp_cf_x86_64_phone-trunk_staging-eng
.
To build 'without' feature flag, you can specify an 'empty (aka null)' entry as such:
lunch:
product_name: aosp_cf_x86_64_phone
release_config:
# development release configuration called trunk_staging
- trunk_staging
+ # this will build without feature flags
+ -
build_variant:
- user
- userdebug
- eng
In this case, the build step will be repeated 6 times with the following lunch targets:
aosp_cf_x86_64_phone-trunk_staging-user
aosp_cf_x86_64_phone-trunk_staging-userdebug
aosp_cf_x86_64_phone-trunk_staging-eng
aosp_cf_x86_64_phone-user
aosp_cf_x86_64_phone-userdebug
aosp_cf_x86_64_phone-eng
build
Element | Required | Type |
---|---|---|
commands | Optional (Default is empty) | List of Strings |
aosp_build_env_setup | Optional (Default is true ) | Boolean |
The build
section lets you specify the AOSP build commands to execute after the environment is set up (source build/envsetup.sh
and lunch
).
Default Behavior
By default, the aosp
step handles the environment setup.
You only need to list the make
commands (or other shell commands) you want to run within that environment.
build:
commands:
- m installclean
- m dist
Assuming the target is aosp_cf_x86_64_phone-userdebug
(defined in the aosp.lunch
step), the execution would resemble
this:
bash -c set -e
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-userdebug
# Commands from your build.commands list
m installclean
m dist
Using a Custom Build Script
If you have a custom script that handles both the AOSP environment setup and the build process, you can disable the
step's automatic setup using aosp_build_env_setup: false
.
build:
# Disable automatic 'source' and 'lunch'
aosp_build_env_setup: false
commands:
# Your custom script now handles setup and build
- ./my-aosp-build-script.sh
When aosp_build_env_setup
is false
:
- The
source build/envsetup.sh
andlunch <target>
commands are not executed automatically by the step. - The intended target (e.g.,
aosp_cf_x86_64_phone-userdebug
) is passed to your script(s) via the environment variableHEXDROID_CI_AOSP_LUNCH_TARGET
. - Your script(s) listed under
commands
are executed sequentially.
The resulting execution for the example above would be:
bash -c set -e
export HEXDROID_CI_AOSP_LUNCH_TARGET=aosp_cf_x86_64_phone-userdebug
./my-aosp-build-script.sh
If you list multiple commands with aosp_build_env_setup: false
:
build:
+ aosp_build_env_setup: false
commands:
+ - ./my-aosp-build-script.sh
+ - ./my-aosp-test-script.sh
They will run one after the other, with the environment variable available to both:
bash -c set -e
export HEXDROID_CI_AOSP_LUNCH_TARGET=aosp_cf_x86_64_phone-userdebug
./my-aosp-build-script.sh
./my-aosp-test-script.sh
artifact
The artifact
step defined within the aosp
step is inlined way to add CI artifacts for each configuration with in
aosp
step.
When placed inside the aosp
step, the artifact command will automatically execute for each build
variant (e.g., user, userdebug, eng) and configuration you defined.
This provides a convenient shortcut compared to defining multiple top-level artifact steps manually. The functionality remains the same as the standalone artifact step - refer to its documentation for the complete syntax and options.
Artifacts are files or sets of files generated during a pipeline execution that you can save after a job finishes. They allow you to preserve data like build outputs or test results beyond the job's lifespan.
Example:
steps:
- aosp:
manifest:
url: https://android.googlesource.com/platform/manifest
revision: main
name: default.xml
lunch:
product_name: aosp_cf_x86_64_phone
build_variant:
- userdebug
- eng
- user
build:
commands:
- m installclean
- m dist
+ artifact:
+ paths:
+ - out/dist/otatools.zip
+ - out/dist/*-target_files-root.zip
+ - out/dist/*-ota-root.zip
release (OTA)
The release
step defined within the aosp
step is a simplified way to publish OTA updates for each Android build
configuration.
When placed inside the aosp
step, the release process will automatically execute for each build
variant (e.g., user, userdebug, eng) and configuration you defined.
This provides a convenient shortcut compared to defining multiple top-level release steps manually. The functionality remains the same as the standalone release step - refer to its documentation for the complete syntax and options.
The aosp
step supports defining and publishing OTA releases through HexDroid Update Management.
You can learn more about HexDroid Release (OTA) management here.
Release step allows you to attach build artifacts, control distribution settings, and define staged rollouts.
Below is a starting template for an AOSP-based project, which will infer the target, resolve version_name and version_code based on AOSP build output artifacts.
steps:
- aosp:
manifest:
url: https://android.googlesource.com/platform/manifest
revision: main
name: default.xml
lunch:
product_name: aosp_cf_x86_64_phone
build_variant:
- userdebug
- eng
- user
build:
commands:
- m installclean
- m dist
+ release:
+ meta:
+ target:
+ type: execs
+ separator: /
+ # Example: generic/vsoc_x86_64/aosp_cf_x86_64_phone/userdebug/test-keys
+ command:
+ - get_build_var PRODUCT_BRAND
+ - get_build_var TARGET_DEVICE
+ - get_build_var TARGET_PRODUCT
+ - get_build_var TARGET_BUILD_VARIANT
+ - get_build_var BUILD_VERSION_TAGS
+ version_code:
+ type: file
+ # Example: 1743844748
+ path: out/build_date.txt
+ version_name:
+ type: file
+ path: out/dist/build.prop
+ # Example: BP1A.250405.007.D1
+ regex: "ro\\.system\\.build\\.id=(.+)"
+ payloads:
+ - file:
+ path: out/target/product/vsoc_x86_64/boot.img
+ type: ota
+ distributed: true
+ rollouts:
+ - rollout:
+ cohort_slug: development
+ action: activate
+ percentage: 100
+ - rollout:
+ cohort_slug: sqa
+ action: activate
+ percentage: 10
If aosp_build_env_setup
is set to false
in aosp.build
, each command (for exec/execs meta-fields) will have
environment variable HEXDROID_CI_AOSP_LUNCH_TARGET
set with the intended target (e.g.,
aosp_cf_x86_64_phone-userdebug
).