How to Store AOSP Build Artifacts in Artifactory

This guide explains how to automate AOSP (Android Open Source Project) artifact uploads to Artifactory using a Maven-style layout via a Jenkins pipeline.


Prerequisites

You should have:

  • A Jenkins server with Artifactory plugin installed
  • An Artifactory instance with a Maven snapshot repository

  1. Create a Local Maven Repository in Artifactory
  • Log into Artifactory.
  • Go to Administration → Repositories
  • Click Create a Respository
  • Select Package Type: Maven
  • Fill in the settings:
FieldValue
Repository Keyproduct-snapshots
Handle SnapshotsChecked
Handle ReleasesUnchecked
Layoutmaven-2-default
  • Click Save

  1. Jenkins Pipeline

This pipeline builds AOSP and uploads system.img, vbmeta.img, and ramdisk.img to Artifactory.

pipeline {
    agent { label 'ssh-agent-with-docker' }

    environment {
        CCACHE_PATH = "/home/administrator/.cache/ccache"
    }

    stages {
        stage('Build AOSP') {
            steps {
                script {
                    docker.image('aosp-builder').inside("-v ${CCACHE_PATH}:/ccache") {
                        sshagent(['gerrit-ssh-maksonlee']) {
                            sh '''#!/bin/bash
                                mkdir -p ~/.ssh
                                chmod 700 ~/.ssh
                                ssh-keyscan -p 29418 -H gerrit.maksonlee.com >> ~/.ssh/known_hosts
                                
                                repo init -u ssh://maksonlee@gerrit.maksonlee.com:29418/platform/manifest -b android-15.0.0_r30
                                repo sync -c -j1
                                
                                source build/envsetup.sh
                                lunch aosp_arm64-trunk_staging-userdebug
                                m
                            '''
                        }
                    }
                }
            }
        }

        stage('Deploy to Artifactory') {
            steps {
                script {
                    def timestamp = new Date().format("yyyyMMdd.HHmmss", TimeZone.getTimeZone('UTC'))
                    def buildNum = env.BUILD_NUMBER
                    def fileItegRev = "${timestamp}-${buildNum}"
                    def orgPath = "com/maksonlee"
                    def module = "1234"
                    def baseRev = "003-vanilla-continuous"
                    def folderItegRev = "SNAPSHOT"
                    def repo = "product-snapshots"

                    def targetBasePath = "${repo}/${orgPath}/${module}/${baseRev}-${folderItegRev}"

                    def spec = """{
                        "files": [
                            {
                                "pattern": "out/target/product/generic_arm64/system.img",
                                "target": "${targetBasePath}/${module}-${baseRev}-${fileItegRev}-system.img"
                            },
                            {
                                "pattern": "out/target/product/generic_arm64/vbmeta.img",
                                "target": "${targetBasePath}/${module}-${baseRev}-${fileItegRev}-vbmeta.img"
                            },
                            {
                                "pattern": "out/target/product/generic_arm64/ramdisk.img",
                                "target": "${targetBasePath}/${module}-${baseRev}-${fileItegRev}-ramdisk.img"
                            }
                        ]
                    }"""

                    echo "Uploading artifacts to: ${targetBasePath}"

                    rtUpload(
                            serverId: "artifactory",
                            spec: spec,
                            failNoOp: true
                    )
                }
            }
        }
    }
}

Result in Artifactory

After the pipeline runs, Artifactory will contain:


Artifact Layout Explanation

The artifact path and filename follow this pattern:

[orgPath]/[module]/[baseRev](-[folderItegRev])/[module]-[baseRev](-[fileItegRev])(-[classifier]).[ext]

Directory Breakdown

SegmentMeaningExample
orgPathGroup ID (e.g., reversed domain)com/maksonlee
moduleArtifact ID (product or component)1234
baseRevBase version003-vanilla-continuous
folderItegRevSnapshot version folderSNAPSHOT

File Name Breakdown

SegmentMeaningExample
fileItegRevTimestamp + Jenkins build number20250515.153000-24
classifierArtifact type (e.g. system, vbmeta)system, vbmeta, ramdisk
extFile extensionimg

Conclusion

This Jenkins pipeline gives you a clean, automated way to upload AOSP build artifacts to Artifactory using a Maven-style structure. It ensures proper versioning, traceability, and CI/CD compatibility.

Leave a Comment

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

Scroll to Top