commit c5eb3171a7643055b6ca0aff8d34be0c8c0ae7dd Author: Android ROM Builder Date: Sun Jun 29 23:43:32 2025 +0200 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 diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml new file mode 100644 index 0000000..651537b --- /dev/null +++ b/.buildkite/pipeline.yml @@ -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" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0203ea6 --- /dev/null +++ b/.gitignore @@ -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/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..31b6070 --- /dev/null +++ b/README.md @@ -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 \ No newline at end of file diff --git a/scripts/build-rom.sh b/scripts/build-rom.sh new file mode 100755 index 0000000..c3cbb98 --- /dev/null +++ b/scripts/build-rom.sh @@ -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 \ No newline at end of file diff --git a/scripts/init-source.sh b/scripts/init-source.sh new file mode 100755 index 0000000..23d2ad5 --- /dev/null +++ b/scripts/init-source.sh @@ -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 \ No newline at end of file diff --git a/scripts/package-rom.sh b/scripts/package-rom.sh new file mode 100755 index 0000000..efbd3ac --- /dev/null +++ b/scripts/package-rom.sh @@ -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!" \ No newline at end of file diff --git a/scripts/sync-source.sh b/scripts/sync-source.sh new file mode 100755 index 0000000..eb10317 --- /dev/null +++ b/scripts/sync-source.sh @@ -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 \ No newline at end of file diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..d4385be --- /dev/null +++ b/setup.sh @@ -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 "" \ No newline at end of file