Skip to main content

[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:

KeyDescriptionOptional
manifestPerforms checkout of aosp tree (repo init/repo sync).Yes
lunchDefines product configurations to build (eng vs userdebug, etc)Yes
buildCommands that will be executed for each product configurationYes
releaseCreates release, uploads OTA files to HexDroid Update ManagementYes
artifactAttaches 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:

Step 1: Init the source
repo init --manifest-url=https://android.googlesource.com/platform/manifest --manifest-branch=main --manifest-name=default.xml
Step 2: Sync the source
repo sync --verbose
Step 3: Pin the source
repo manifest --revision-as-HEAD --output-file=aosp_build_manifest_pinned.xml
Step 4: Build[aosp_cf_x86_64_phone-userdebug]
bash -c set -e
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-userdebug
m installclean
m dist
Step 5: Build[aosp_cf_x86_64_phone-eng]
bash -c set -e
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-eng
m installclean
m dist
Step 6: Build[aosp_cf_x86_64_phone-user]
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.

ElementDescriptionRequiredType
urlManifest URL to checkout. Correspond to --manifest-url= in repo initRequiredString
revisionManifest revision to checkout. Correspond to --manifest-branch= in repo initRequiredString Or Dynamic Lookup
nameManifest file to use. Correspond to --manifest-name= in repo initOptionalString
initAdditional control over repo init command.OptionalObject
syncAdditional control over repo sync command.OptionalObject
pinAdditional control over repo manifest command.OptionalObject

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

ElementRequiredType
product_nameRequiredString
release_configOptionalList of Nullable Strings
build_variantOptionalList 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

ElementRequiredType
commandsOptional (Default is empty)List of Strings
aosp_build_env_setupOptional (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:

  1. The source build/envsetup.sh and lunch <target> commands are not executed automatically by the step.
  2. The intended target (e.g., aosp_cf_x86_64_phone-userdebug) is passed to your script(s) via the environment variable HEXDROID_CI_AOSP_LUNCH_TARGET.
  3. 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

note

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)

note

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
note

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