Initial commit: Android ROM building with Buildkite

- Added Buildkite pipeline configuration
- Added Docker setup for Android build environment
- Added build scripts for ROM compilation
- Added comprehensive documentation
- Added setup script for easy initialization
This commit is contained in:
Android ROM Builder
2025-06-29 23:43:32 +02:00
commit c5eb3171a7
8 changed files with 616 additions and 0 deletions

107
.buildkite/pipeline.yml Normal file
View File

@@ -0,0 +1,107 @@
steps:
- label: ":android: Setup Environment"
key: "setup"
command: |
echo "Setting up Android build environment..."
docker --version
docker-compose --version
echo "Environment ready!"
agents:
queue: "default"
- label: ":package: Build Docker Image"
key: "build-image"
depends_on: "setup"
command: |
echo "Building Android ROM builder Docker image..."
cd docker
docker build -t android-rom-builder:latest .
echo "Docker image built successfully!"
agents:
queue: "default"
- label: ":octocat: Initialize Android Source"
key: "init-source"
depends_on: "build-image"
command: |
echo "Initializing Android source repository..."
mkdir -p source
docker run --rm \
-v $$(pwd)/source:/home/buildbot/android/source \
-v $$(pwd)/scripts:/home/buildbot/scripts:ro \
android-rom-builder:latest \
/home/buildbot/scripts/init-source.sh
agents:
queue: "default"
timeout_in_minutes: 30
- label: ":arrows_counterclockwise: Sync Android Source"
key: "sync-source"
depends_on: "init-source"
command: |
echo "Syncing Android source code..."
docker run --rm \
-v $$(pwd)/source:/home/buildbot/android/source \
-v $$(pwd)/ccache:/home/buildbot/android/ccache \
-v $$(pwd)/scripts:/home/buildbot/scripts:ro \
android-rom-builder:latest \
/home/buildbot/scripts/sync-source.sh
agents:
queue: "default"
timeout_in_minutes: 120
- label: ":hammer_and_wrench: Build Android ROM"
key: "build-rom"
depends_on: "sync-source"
command: |
echo "Building Android ROM..."
docker run --rm \
-v $$(pwd)/source:/home/buildbot/android/source \
-v $$(pwd)/out:/home/buildbot/android/out \
-v $$(pwd)/ccache:/home/buildbot/android/ccache \
-v $$(pwd)/scripts:/home/buildbot/scripts:ro \
--shm-size=2g \
android-rom-builder:latest \
/home/buildbot/scripts/build-rom.sh
agents:
queue: "default"
timeout_in_minutes: 480
env:
USE_CCACHE: "1"
CCACHE_DIR: "/home/buildbot/android/ccache"
- label: ":package: Package ROM"
key: "package-rom"
depends_on: "build-rom"
command: |
echo "Packaging ROM artifacts..."
docker run --rm \
-v $$(pwd)/out:/home/buildbot/android/out \
-v $$(pwd)/artifacts:/home/buildbot/artifacts \
-v $$(pwd)/scripts:/home/buildbot/scripts:ro \
android-rom-builder:latest \
/home/buildbot/scripts/package-rom.sh
agents:
queue: "default"
timeout_in_minutes: 30
- label: ":arrow_up: Upload Artifacts"
key: "upload-artifacts"
depends_on: "package-rom"
command: |
echo "Uploading ROM artifacts..."
buildkite-agent artifact upload "artifacts/*.zip"
buildkite-agent artifact upload "artifacts/*.img"
buildkite-agent artifact upload "artifacts/*.json"
agents:
queue: "default"
- label: ":white_check_mark: Build Complete"
depends_on: "upload-artifacts"
command: |
echo ":tada: Android ROM build completed successfully!"
echo "Build Number: $BUILDKITE_BUILD_NUMBER"
echo "Commit: $BUILDKITE_COMMIT"
echo "Branch: $BUILDKITE_BRANCH"
agents:
queue: "default"

38
.gitignore vendored Normal file
View File

@@ -0,0 +1,38 @@
# Android ROM Build Artifacts
source/
out/
ccache/
artifacts/
# Environment files
.env
# Docker volumes
docker/source/
docker/out/
docker/ccache/
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# IDE files
.vscode/
.idea/
*.swp
*.swo
*~
# Log files
*.log
*.log.*
# Temporary files
*.tmp
*.temp
.cache/

179
README.md Normal file
View File

@@ -0,0 +1,179 @@
# Android ROM Building with Buildkite
This repository contains everything you need to build Android ROMs using Buildkite CI/CD with Docker containers.
## 🚀 Quick Setup
### 1. Buildkite Pipeline Setup
1. Go to your Buildkite dashboard
2. Click "New Pipeline"
3. Connect this GitHub repository
4. Set the pipeline configuration to use `.buildkite/pipeline.yml`
5. Add your agent queue (usually "default")
### 2. Agent Configuration
Make sure your Buildkite agent has:
- Docker installed and running
- Sufficient disk space (200GB+ recommended)
- Good internet connection for source sync
### 3. Environment Configuration
Copy `.env.example` to `.env` and configure:
```bash
cp .env.example .env
# Edit .env with your specific settings
```
## 📋 Pipeline Steps
The pipeline includes these automated steps:
1. **🔧 Setup Environment** - Verify Docker and dependencies
2. **📦 Build Docker Image** - Create Android build environment
3. **🐙 Initialize Source** - Set up Android source repository
4. **🔄 Sync Source** - Download Android source code (~100GB)
5. **🔨 Build ROM** - Compile the Android ROM (2-8 hours)
6. **📦 Package ROM** - Prepare artifacts for download
7. **⬆️ Upload Artifacts** - Upload ROM files to Buildkite
8. **✅ Complete** - Build finished notification
## 🎯 Device Configuration
To build for a specific device, modify these environment variables:
```yaml
env:
TARGET_DEVICE: "your_device_codename"
BUILD_VARIANT: "lineage" # or aosp, etc.
BUILD_TYPE: "userdebug" # or user, eng
```
## 🏗️ Supported ROM Types
- **LineageOS** (default configuration)
- **AOSP** (Android Open Source Project)
- **Custom ROMs** (modify manifest URL)
## 📱 Popular Device Examples
### OnePlus 9 Pro (lemonades)
```yaml
env:
TARGET_DEVICE: "lemonades"
MANIFEST_URL: "https://github.com/LineageOS/android.git"
MANIFEST_BRANCH: "lineage-21.0"
```
### Pixel 7 Pro (cheetah)
```yaml
env:
TARGET_DEVICE: "cheetah"
MANIFEST_URL: "https://github.com/PixelExperience/manifest.git"
MANIFEST_BRANCH: "thirteen"
```
## 🔧 Manual Build Commands
If you want to run builds manually:
```bash
# Build Docker image
cd docker && docker build -t android-rom-builder .
# Run full build process
docker-compose up
# Run individual steps
docker run --rm -v $(pwd)/source:/home/buildbot/android/source android-rom-builder /home/buildbot/scripts/init-source.sh
docker run --rm -v $(pwd)/source:/home/buildbot/android/source android-rom-builder /home/buildbot/scripts/sync-source.sh
docker run --rm -v $(pwd)/source:/home/buildbot/android/source -v $(pwd)/out:/home/buildbot/android/out android-rom-builder /home/buildbot/scripts/build-rom.sh
```
## 📊 Build Requirements
### System Requirements
- **CPU**: 8+ cores recommended
- **RAM**: 32GB+ recommended
- **Storage**: 200GB+ free space
- **Network**: Stable high-speed connection
### Build Times (approximate)
- **Source Sync**: 30-60 minutes
- **First Build**: 4-8 hours
- **Incremental**: 30-120 minutes
## 🗂️ Directory Structure
```
.
├── .buildkite/
│ └── pipeline.yml # Buildkite pipeline configuration
├── docker/
│ ├── Dockerfile # Android build environment
│ └── docker-compose.yml # Container orchestration
├── scripts/
│ ├── init-source.sh # Initialize Android source
│ ├── sync-source.sh # Sync source code
│ ├── build-rom.sh # Build ROM
│ └── package-rom.sh # Package artifacts
├── source/ # Android source code (auto-created)
├── out/ # Build outputs (auto-created)
├── ccache/ # Build cache (auto-created)
├── artifacts/ # Final ROM files (auto-created)
└── .env # Environment configuration
```
## 🎛️ Advanced Configuration
### Custom Manifest
To use a different ROM source:
```bash
# In .env file
MANIFEST_URL=https://github.com/YourROM/android.git
MANIFEST_BRANCH=your-branch-name
```
### Build Optimization
```bash
# Enable ccache for faster builds
USE_CCACHE=1
# Set build jobs (usually = CPU cores)
BUILD_JOBS=16
# Clean build (slower but ensures clean state)
CLEAN_BUILD=1
```
## 🔍 Troubleshooting
### Common Issues
1. **Out of disk space**: Ensure 200GB+ free space
2. **Build fails**: Check logs in Buildkite dashboard
3. **Sync errors**: Verify internet connection and manifest URL
4. **Docker issues**: Ensure Docker daemon is running
### Log Locations
- Buildkite logs: Available in web dashboard
- Docker logs: `docker logs android-rom-builder`
- Build logs: `out/verbose.log.gz`
## 📞 Support
- Check Buildkite documentation for CI/CD issues
- Android build issues: Check device-specific forums
- Docker problems: Verify container setup
## 🎉 Success!
Once your build completes, download artifacts from the Buildkite dashboard:
- `*.zip` - Flashable ROM package
- `*.img` - Individual partition images
- `build-info.json` - Build metadata
- `*.md5`/`*.sha256` - Checksums for verification

65
scripts/build-rom.sh Executable file
View File

@@ -0,0 +1,65 @@
#!/bin/bash
set -euo pipefail
echo "🔨 Starting Android ROM build..."
cd /home/buildbot/android/source
# Configuration - modify these for your target device
TARGET_DEVICE="${TARGET_DEVICE:-generic}"
BUILD_TYPE="${BUILD_TYPE:-userdebug}"
BUILD_VARIANT="${BUILD_VARIANT:-lineage}"
echo "🎯 Build configuration:"
echo " Device: $TARGET_DEVICE"
echo " Type: $BUILD_TYPE"
echo " Variant: $BUILD_VARIANT"
# Set up build environment
echo "⚙️ Setting up build environment..."
source build/envsetup.sh
# Setup ccache
if [ "${USE_CCACHE:-1}" = "1" ]; then
echo "🚀 Configuring ccache..."
export USE_CCACHE=1
export CCACHE_DIR=/home/buildbot/android/ccache
ccache -M 50G
ccache -s
fi
# Clean previous builds if requested
if [ "${CLEAN_BUILD:-0}" = "1" ]; then
echo "🧹 Cleaning previous build..."
make clean
fi
# Select build target
echo "🎯 Selecting build target..."
lunch "${BUILD_VARIANT}_${TARGET_DEVICE}-${BUILD_TYPE}"
# Start build
echo "🔨 Starting compilation..."
START_TIME=$(date +%s)
# Build with appropriate number of parallel jobs
JOBS=${BUILD_JOBS:-$(nproc)}
echo "🚀 Building with $JOBS parallel jobs..."
if [ "$BUILD_VARIANT" = "lineage" ]; then
# LineageOS specific build command
brunch "$TARGET_DEVICE"
else
# Generic AOSP build
make -j"$JOBS" otapackage
fi
END_TIME=$(date +%s)
BUILD_TIME=$((END_TIME - START_TIME))
echo "✅ Build completed successfully!"
echo "⏱️ Build time: $(date -u -d @$BUILD_TIME +%H:%M:%S)"
# Display build artifacts
echo "📦 Build artifacts:"
find /home/buildbot/android/out/target/product/"$TARGET_DEVICE"/ -name "*.zip" -o -name "*.img" | head -10

32
scripts/init-source.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/bin/bash
set -euo pipefail
echo "🚀 Initializing Android source repository..."
cd /home/buildbot/android/source
# Configuration - you can modify these
MANIFEST_URL="https://github.com/LineageOS/android.git"
MANIFEST_BRANCH="lineage-21.0"
MANIFEST_NAME="default.xml"
# Check if source is already initialized
if [ ! -d ".repo" ]; then
echo "📁 Initializing repo with manifest: $MANIFEST_URL"
echo "📋 Branch: $MANIFEST_BRANCH"
repo init \
-u "$MANIFEST_URL" \
-b "$MANIFEST_BRANCH" \
-m "$MANIFEST_NAME" \
--depth=1 \
--no-clone-bundle
echo "✅ Repository initialized successfully!"
else
echo "📁 Repository already initialized, skipping..."
fi
# Display repo info
echo "📊 Repository information:"
repo info | head -10

68
scripts/package-rom.sh Executable file
View File

@@ -0,0 +1,68 @@
#!/bin/bash
set -euo pipefail
echo "📦 Packaging ROM artifacts..."
TARGET_DEVICE="${TARGET_DEVICE:-generic}"
OUT_DIR="/home/buildbot/android/out/target/product/$TARGET_DEVICE"
ARTIFACTS_DIR="/home/buildbot/artifacts"
# Create artifacts directory
mkdir -p "$ARTIFACTS_DIR"
echo "📁 Copying build artifacts..."
# Copy main ROM files
if [ -f "$OUT_DIR"/*.zip ]; then
echo "📱 Copying ROM zip files..."
cp "$OUT_DIR"/*.zip "$ARTIFACTS_DIR/" || true
fi
# Copy recovery image
if [ -f "$OUT_DIR/recovery.img" ]; then
echo "🔧 Copying recovery image..."
cp "$OUT_DIR/recovery.img" "$ARTIFACTS_DIR/" || true
fi
# Copy boot image
if [ -f "$OUT_DIR/boot.img" ]; then
echo "🥾 Copying boot image..."
cp "$OUT_DIR/boot.img" "$ARTIFACTS_DIR/" || true
fi
# Copy system image
if [ -f "$OUT_DIR/system.img" ]; then
echo "💿 Copying system image..."
cp "$OUT_DIR/system.img" "$ARTIFACTS_DIR/" || true
fi
# Copy vendor image
if [ -f "$OUT_DIR/vendor.img" ]; then
echo "🏪 Copying vendor image..."
cp "$OUT_DIR/vendor.img" "$ARTIFACTS_DIR/" || true
fi
# Create build info JSON
echo "📋 Creating build information..."
cat > "$ARTIFACTS_DIR/build-info.json" << EOF
{
"build_number": "${BUILDKITE_BUILD_NUMBER:-unknown}",
"commit": "${BUILDKITE_COMMIT:-unknown}",
"branch": "${BUILDKITE_BRANCH:-unknown}",
"device": "$TARGET_DEVICE",
"build_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"build_type": "${BUILD_TYPE:-userdebug}",
"variant": "${BUILD_VARIANT:-lineage}"
}
EOF
# Create checksums
echo "🔐 Generating checksums..."
cd "$ARTIFACTS_DIR"
find . -name "*.zip" -o -name "*.img" | xargs -I {} sh -c 'md5sum "{}" > "{}.md5"'
find . -name "*.zip" -o -name "*.img" | xargs -I {} sh -c 'sha256sum "{}" > "{}.sha256"'
echo "📊 Artifact summary:"
ls -lh "$ARTIFACTS_DIR"
echo "✅ Packaging completed successfully!"

39
scripts/sync-source.sh Executable file
View File

@@ -0,0 +1,39 @@
#!/bin/bash
set -euo pipefail
echo "🔄 Syncing Android source code..."
cd /home/buildbot/android/source
# Check if repo is initialized
if [ ! -d ".repo" ]; then
echo "❌ Repository not initialized! Run init-source.sh first."
exit 1
fi
# Sync with multiple jobs for faster download
echo "⬇️ Starting source sync..."
repo sync \
-c \
-j$(nproc) \
--force-sync \
--no-clone-bundle \
--no-tags \
--optimized-fetch \
--prune
echo "✅ Source sync completed successfully!"
# Display sync statistics
echo "📊 Sync statistics:"
echo "Total repositories: $(find .repo/projects -name "*.git" | wc -l)"
echo "Disk usage: $(du -sh . | cut -f1)"
# Check for any missing projects
echo "🔍 Checking for missing projects..."
if repo status | grep -q "project.*dirty\|project.*not up-to-date"; then
echo "⚠️ Some projects may need attention:"
repo status | grep -E "project.*dirty|project.*not up-to-date" || true
else
echo "✅ All projects are clean and up-to-date"
fi

88
setup.sh Executable file
View File

@@ -0,0 +1,88 @@
#!/bin/bash
set -euo pipefail
echo "🚀 Setting up Android ROM building environment..."
# Create necessary directories
echo "📁 Creating directory structure..."
mkdir -p source out ccache artifacts
# Create environment file if it doesn't exist
if [ ! -f ".env" ]; then
echo "⚙️ Creating environment configuration..."
cat > .env << 'EOF'
# Buildkite Agent Configuration
BUILDKITE_AGENT_TOKEN=your_buildkite_agent_token_here
# Android Build Configuration
TARGET_DEVICE=generic
BUILD_TYPE=userdebug
BUILD_VARIANT=lineage
BUILD_JOBS=8
# Build Options
USE_CCACHE=1
CLEAN_BUILD=0
# Manifest Configuration
MANIFEST_URL=https://github.com/LineageOS/android.git
MANIFEST_BRANCH=lineage-21.0
MANIFEST_NAME=default.xml
# Storage Paths (adjust these for your system)
SOURCE_DIR=./source
OUT_DIR=./out
CCACHE_DIR=./ccache
ARTIFACTS_DIR=./artifacts
EOF
echo "✅ Created .env file - please edit it with your configuration!"
else
echo "⚠️ .env file already exists, skipping..."
fi
# Check Docker installation
echo "🐳 Checking Docker installation..."
if command -v docker &> /dev/null; then
echo "✅ Docker is installed"
docker --version
else
echo "❌ Docker is not installed! Please install Docker first."
exit 1
fi
# Check Docker Compose
if command -v docker-compose &> /dev/null; then
echo "✅ Docker Compose is installed"
docker-compose --version
else
echo "❌ Docker Compose is not installed! Please install Docker Compose first."
exit 1
fi
# Check available disk space
echo "💾 Checking available disk space..."
AVAILABLE_SPACE=$(df -BG . | tail -1 | awk '{print $4}' | sed 's/G//')
if [ "$AVAILABLE_SPACE" -lt 200 ]; then
echo "⚠️ Warning: Only ${AVAILABLE_SPACE}GB available. Android builds need 200GB+!"
else
echo "${AVAILABLE_SPACE}GB available - sufficient for ROM building"
fi
# Build Docker image
echo "🔨 Building Docker image (this may take a while)..."
cd docker
docker build -t android-rom-builder:latest .
cd ..
echo ""
echo "🎉 Setup completed successfully!"
echo ""
echo "Next steps:"
echo "1. Edit .env file with your device and ROM configuration"
echo "2. Set up your Buildkite pipeline using .buildkite/pipeline.yml"
echo "3. Push this repository to GitHub/GitLab"
echo "4. Connect the repository to Buildkite"
echo "5. Trigger your first build!"
echo ""
echo "For manual builds, run: docker-compose up"
echo ""