Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 84 additions & 111 deletions ci/init_repo.sh
Original file line number Diff line number Diff line change
@@ -1,131 +1,104 @@
#!/usr/bin/env bash
# Usage: ci/init_repo.sh <manifest_url> [desired_branch] [workdir] [jobs]
# Example: ci/init_repo.sh https://github.com/minimal-manifest-twrp/platform_manifest_twrp_aosp.git android-15.0 ~/twrp 8

set -euo pipefail
set -o errtrace

MANIFEST_URL="${1:-}"
DESIRED="${2:-}"
#!/bin/bash
#
# Copyright (C) 2025 The TWRP Open Source Project
# Copyright (C) 2025 DUptain
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This script intelligently initializes and syncs the TWRP manifest repository.

set -e

# --- Configuration & Arguments ---
MANIFEST_URL="$1"
DESIRED_BRANCH="$2"
WORKDIR="${3:-$HOME/twrp}"
JOBS="${4:-8}"
# Allow caller to provide REPO_BIN (full path) or default to $HOME/bin/repo
REPO_BIN="${REPO_BIN:-$HOME/bin/repo}"

if [[ -z "$MANIFEST_URL" ]]; then
echo "Usage: $0 <manifest_url> [desired_branch] [workdir] [jobs]"
exit 2
fi

# Expand tilde if present and ensure absolute path for WORKDIR
WORKDIR="${WORKDIR/#\~/$HOME}"
mkdir -p "$WORKDIR"
cd "$WORKDIR"
JOBS="${4:-4}"
REPO_BIN="$HOME/bin/repo"

echo "ci/init_repo.sh: starting in $(pwd)"
echo "ci/init_repo.sh: starting in $WORKDIR"
echo "Manifest: $MANIFEST_URL"
echo "Desired branch: ${DESIRED:-<auto>}"
echo "Desired branch: $DESIRED_BRANCH"
echo "Workdir: $WORKDIR"
echo "Jobs: $JOBS"
echo "REPO_BIN: $REPO_BIN"

# Ensure repo tool present: prefer a usable REPO_BIN if it's executable, otherwise try 'repo' in PATH
repo_cmd=""
if [[ -x "$REPO_BIN" ]]; then
repo_cmd="$REPO_BIN"
elif command -v repo >/dev/null 2>&1; then
repo_cmd="$(command -v repo)"
else
echo "repo tool not found; installing to $REPO_BIN"
mkdir -p "$(dirname "$REPO_BIN")"
curl -fsSL "https://storage.googleapis.com/git-repo-downloads/repo" -o "$REPO_BIN"
chmod +x "$REPO_BIN"
repo_cmd="$REPO_BIN"
fi

if [[ -z "$repo_cmd" ]]; then
echo "ERROR: could not determine repo command; aborting"
exit 4
# --- Install repo tool if needed ---
if [ ! -f "$REPO_BIN" ]; then
echo "repo tool not found; installing to $REPO_BIN"
mkdir -p "$(dirname "$REPO_BIN")"
curl -o "$REPO_BIN" https://storage.googleapis.com/git-repo-downloads/repo
chmod a+x "$REPO_BIN"
fi
echo "Using repo command at: $REPO_BIN"

echo "Using repo command at: $repo_cmd"

# Make sure git can reach the manifest
# --- Branch Selection Logic ---
echo "Querying available branches from manifest repo: $MANIFEST_URL"
mapfile -t branches < <(git ls-remote --heads --refs "$MANIFEST_URL" 2>/dev/null | awk '{print $2}' | sed 's#refs/heads/##' || true)

if [[ ${#branches[@]} -eq 0 ]]; then
echo "ERROR: Could not list branches from $MANIFEST_URL"
echo "Check network access, manifest URL and that the repository exists. Aborting."
exit 3
AVAILABLE_BRANCHES=$(git ls-remote --heads "$MANIFEST_URL" | cut -f2 | sed 's#refs/heads/##')
Comment thread
DUptain1993 marked this conversation as resolved.
if [ $? -ne 0 ] || [ -z "$AVAILABLE_BRANCHES" ]; then
echo "ERROR: Failed to query branches from manifest repo at $MANIFEST_URL" >&2
exit 1
fi

echo "Available branches from manifest:"
for b in "${branches[@]}"; do echo " $b"; done
echo "$AVAILABLE_BRANCHES"

pick_branch() {
requested="$1"
# If requested branch exists, use it
if [[ -n "$requested" ]]; then
for b in "${branches[@]}"; do
if [[ "$b" == "$requested" ]]; then
echo "$b"
return
fi
done
fi
FINAL_BRANCH=""

# Prefer exact android-* branches and choose the highest numeric version
android_branches=()
for b in "${branches[@]}"; do
if [[ "$b" =~ ^android-([0-9]+) ]]; then
android_branches+=("$b")
# 1. Check if the exact desired branch exists
if echo "$AVAILABLE_BRANCHES" | grep -q "^${DESIRED_BRANCH}$"; then
FINAL_BRANCH="$DESIRED_BRANCH"
echo "Desired branch '${DESIRED_BRANCH}' found."
# 2. If not, find the highest available twrp-* branch
else
echo "Desired branch '${DESIRED_BRANCH}' not found. Searching for the best fallback."
# Filter for twrp- branches, sort them by version, and get the latest one
BEST_FALLBACK=$(echo "$AVAILABLE_BRANCHES" | grep '^twrp-' || true | sort -V | tail -n 1)
if [ -n "$BEST_FALLBACK" ]; then
FINAL_BRANCH="$BEST_FALLBACK"
echo "Using best fallback branch: ${FINAL_BRANCH}"
else
# 3. As a last resort, try 'main' or 'master'
if echo "$AVAILABLE_BRANCHES" | grep -q "^main$"; then
FINAL_BRANCH="main"
elif echo "$AVAILABLE_BRANCHES" | grep -q "^master$"; then
FINAL_BRANCH="master"
else
echo "ERROR: No suitable branch found in the manifest repository." >&2
exit 1
fi
echo "Warning: No twrp-* branch found. Using last resort: ${FINAL_BRANCH}"
fi
done

if [[ ${#android_branches[@]} -gt 0 ]]; then
# sort by numeric portion descending and pick first
printf "%s\n" "${android_branches[@]}" | sort -Vr | head -n1
return
fi

# Fallback to main, then master, then first available
for candidate in main master; do
for b in "${branches[@]}"; do
if [[ "$b" == "$candidate" ]]; then
echo "$b"
return
fi
done
done

# Last resort: return the first available branch
echo "${branches[0]}"
}
fi

BRANCH="$(pick_branch "$DESIRED")"
echo "Using manifest branch: $BRANCH"
echo "Using manifest branch: ${FINAL_BRANCH}"

# Remove existing .repo to avoid partial state (explicit and safe)
if [[ -d .repo ]]; then
echo "Removing existing .repo to avoid partial state"
rm -rf .repo
fi
# --- Initialize and Sync Repo ---
mkdir -p "$WORKDIR"
cd "$WORKDIR"

# Repo init + sync with retry for transient network errors
echo "Running repo init -u $MANIFEST_URL -b $BRANCH"
"$repo_cmd" init --depth=1 -u "$MANIFEST_URL" -b "$BRANCH" || { echo "repo init failed"; exit 4; }
echo "Running repo init -u ${MANIFEST_URL} -b ${FINAL_BRANCH}"
"$REPO_BIN" init -u "${MANIFEST_URL}" -b "${FINAL_BRANCH}" --depth=1 --no-repo-verify

Copilot AI Nov 11, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The '--no-repo-verify' flag disables verification of the repo tool itself, which is a security risk. Consider removing this flag unless there's a specific reason to bypass verification, as it could allow execution of malicious code if the repo tool is compromised.

Suggested change
"$REPO_BIN" init -u "${MANIFEST_URL}" -b "${FINAL_BRANCH}" --depth=1 --no-repo-verify
"$REPO_BIN" init -u "${MANIFEST_URL}" -b "${FINAL_BRANCH}" --depth=1

Copilot uses AI. Check for mistakes.

MAX_ATTEMPTS=5
for attempt in $(seq 1 $MAX_ATTEMPTS); do
echo "repo sync attempt $attempt/$MAX_ATTEMPTS"
if "$repo_cmd" sync -c -j"$JOBS" --force-sync --no-clone-bundle --no-tags --fail-fast; then
echo "repo sync succeeded"
exit 0
fi
echo "repo sync failed; sleeping $((5 * attempt)) seconds and retrying..."
sleep $((5 * attempt))
for i in {1..5}; do
echo "repo sync attempt $i/5"
if "$REPO_BIN" sync -c -j"${JOBS}" --no-clone-bundle --no-tags --optimized-fetch --prune; then
echo "Repo sync successful."
exit 0
fi
if [ $i -lt 5 ]; then
echo "Repo sync failed. Retrying in $((15 * i)) seconds..."
sleep $((15 * i))
fi
done

echo "repo sync failed after $MAX_ATTEMPTS attempts"
exit 5
echo "ERROR: Repo sync failed after 5 attempts." >&2
exit 1
27 changes: 27 additions & 0 deletions motorola/kansas/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<!--
This file defines the remote repositories needed to build TWRP for this device.
The build system will automatically clone these into the correct paths.
-->

<!-- Remote server hosting the repositories -->
<remote name="github-personal" fetch="https://github.com/DUptain1993/" />

<!--
Kernel Repository
This provides the prebuilt kernel (Image.gz), dtb, and dtbo.img.
The BoardConfig.mk points to files inside this repository.
Change the repository name if you host it elsewhere.
-->
<project path="device/motorola/kansas/prebuilt" name="android_kernel_motorola_kansas" remote="github-personal" revision="main" />

<!--
Vendor Blobs Repository
This provides the proprietary files needed for hardware to function correctly.
It's cloned into the 'vendor/motorola/kansas' directory.
Change the repository name if you host it elsewhere.
-->
<project path="vendor/motorola/kansas" name="android_vendor_motorola_kansas" remote="github-personal" revision="main" />

</manifest>
Loading