Automatically Build AOSP Before Merging to Integration Branch Using Jenkins and Gerrit

In large-scale Android development, it’s essential to verify each proposed change before it’s merged into the integration branch. This guide shows how to integrate Jenkins with Gerrit Trigger Plugin to automatically build AOSP whenever a developer pushes a patchset to integration branch.

Only changes that pass the build are allowed to merge, ensuring the integrity of the integration branch.


Workflow Summary

  • Developers push code to: refs/for/prj-0001-15-vanilla
  • Jenkins automatically builds each patchset
  • Jenkins votes Verified +1 if the build succeeds
  • Only Verified +1 changes are allowed to be merged

Plan for Build Load at Scale

Important Note: Building AOSP is resource-intensive, it consumes a lot of CPU, memory, and disk.

While a single AOSP build is already heavy, the real challenge comes when:

  • Multiple developers submit patchsets simultaneously
  • Jenkins triggers many AOSP builds in parallel

If your CI system isn’t properly scaled, builds will queue up or fail due to insufficient resources.


Prerequisites

Before continuing, make sure:

  • You already have Jenkins set up with an agent capable of building AOSP
  • The AOSP build environment (e.g. Docker + SSH-connected agents) is already configured

If not done yet, check out this first:
Build Android 15 AOSP with Jenkins and Docker on an SSH-Connected Agent


  1. Set Up Jenkins with Gerrit Trigger Plugin
  • Go to Manage Jenkins β†’ Plugins β†’ Available
  • Install:
    • Gerrit Trigger Plugin
      This will also install required dependencies like Git and SCM API plugins.
  • After installation, go to Manage Jenkins β†’ Gerrit Trigger
    • Click New Server and configure:
      • Add New Server: Gerrit
      • Type: Gerrit Server with Default Configurations
    • Click Create
  • Configure

Gerrit Connection Setting

FieldValue
Namegerrit
No Connection On Startup(optional)
Hostnamegerrit.maksonlee.com
Frontend URLhttps://gerrit.maksonlee.com/
SSH Port29418
Proxy(leave blank if unused)
Usernamejenkins
E-mail(optional)
SSH Keyfile/var/lib/jenkins/.ssh/id_ed25519
SSH Keyfile PasswordπŸ” Concealed
Build Current Patches Onlyβœ… (recommended)
Vote patch sets with same topicβœ… (optional)

REST API

FieldValue
Use REST APIβœ… Enabled
Gerrit HTTP Usernamejenkins
Gerrit HTTP PasswordπŸ” Concealed
Enable Code-Review(Optional) βœ…
Enable Verifiedβœ… Enabled

  1. Gerrit Permissions

The Gerrit user (jenkins) used in the Jenkins plugin must have both SSH and REST API access with proper permissions on the project and branch scope.

RefPermission
refs/heads/*Read
refs/for/*Read
refs/changes/*Read
RefPermissionRange
refs/for/prj-0001-15-vanillaLabel Verified-1..+1
RefPermissionRange
refs/for/prj-0001-15-vanillaLabel Code-Review0..+1

  1. Create Jenkins Pipeline Job
pipeline {
    agent {
        label 'ssh-agent-with-docker'
    }
    
    environment {
        CCACHE_PATH = "/home/administrator/.cache/ccache"
        MIRROR_PATH = "/home/administrator/mirror"
    }
    
    triggers {
        gerrit(
            serverName: 'gerrit',
            gerritProjects: [[
                compareType: 'ANT', pattern: '**',
                branches: [[compareType: 'PLAIN', pattern: 'prj-0001-15-vanilla']]
            ]],
            triggerOnEvents: [
                patchsetCreated(excludeNoCodeChange: true, excludeWipState: true, excludeDrafts: true),
                wipStateChanged()
            ]
        )
    }

    stages {
        stage('Clean Workspace') {
            steps {
                deleteDir()
            }
        }
        
        stage('Build AOSP') {
            steps {
                script {
                    docker.image('harbor.maksonlee.com/library/aosp-builder').inside("-v ${CCACHE_PATH}:/ccache -v ${MIRROR_PATH}:/mirror") {
                        sshagent(['ssh-agent-jenkins']) {
                            sh '''#!/bin/bash
                            mkdir -p ~/.ssh
                            chmod 700 ~/.ssh
                            ssh-keyscan -p 29418 -H gerrit.maksonlee.com >> ~/.ssh/known_hosts
                          
                            repo init -u ssh://jenkins@gerrit.maksonlee.com:29418/platform/manifest -b prj-0001-15-vanilla --reference=/mirror
                            repo sync -c -j1
                            
                            p=$(repo list $GERRIT_PROJECT -p)
                            cd $p
                            git config --global user.email "jenkins@maksonlee.com"
                            git config --global user.name "jenkins"
                            git fetch ssh://jenkins@$GERRIT_HOST:29418/$GERRIT_PROJECT $GERRIT_REFSPEC
                            git cherry-pick --allow-empty --no-edit --strategy=recursive --strategy-option=theirs FETCH_HEAD
                          
                            source build/envsetup.sh
                            lunch aosp_arm64-trunk_staging-userdebug
                            '''
                        }
                    }
                }
            }
        }
    }
}

You must run the job manually once after creating it, this initializes the job in the Gerrit Trigger plugin so it can start listening for events.

Until the first manual run, Gerrit will not trigger the job, even if patchsets are uploaded.


Example: Gerrit Change Log After Successful Trigger

After the first successful build is triggered, your Gerrit change log should look like this:

This confirms that Jenkins is correctly integrated with Gerrit, listens for patchset events, starts the build, and applies the Verified +1 vote if the build passes.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top