|
@@ -20,20 +20,111 @@ outputs:
|
|
|
runs:
|
|
runs:
|
|
|
using: composite
|
|
using: composite
|
|
|
steps:
|
|
steps:
|
|
|
- - name: Initialize and Sync Kernel Repository
|
|
|
|
|
- id: sync
|
|
|
|
|
|
|
+ # - name: Initialize and Sync Kernel Repository
|
|
|
|
|
+ # id: sync
|
|
|
|
|
+ # shell: bash
|
|
|
|
|
+ # working-directory: ${{ github.workspace }}/kernel
|
|
|
|
|
+ # run: |
|
|
|
|
|
+ # FORMATTED_BRANCH="${{ inputs.android_version }}-${{ inputs.kernel_version }}-${{ inputs.os_patch_level }}"
|
|
|
|
|
+ # repo init -u https://android.googlesource.com/kernel/manifest -b common-${FORMATTED_BRANCH} --depth=1 --partial-clone --clone-filter=blob:limit=10M
|
|
|
|
|
+ # REMOTE_BRANCH=$(git ls-remote https://android.googlesource.com/kernel/common ${FORMATTED_BRANCH})
|
|
|
|
|
+ # DEFAULT_MANIFEST_PATH=.repo/manifests/default.xml
|
|
|
|
|
+ # DEPRECATED=false
|
|
|
|
|
+ # if grep -q deprecated <<< $REMOTE_BRANCH; then
|
|
|
|
|
+ # sed -i "s/\"${FORMATTED_BRANCH}\"/\"deprecated\/${FORMATTED_BRANCH}\"/g" $DEFAULT_MANIFEST_PATH
|
|
|
|
|
+ # echo "⚠ Note: Branch ${FORMATTED_BRANCH} is considered deprecated."
|
|
|
|
|
+ # DEPRECATED=true
|
|
|
|
|
+ # fi
|
|
|
|
|
+ # echo "deprecated=$DEPRECATED" >> $GITHUB_OUTPUT
|
|
|
|
|
+ # repo sync -c -j$(nproc --all) --fail-fast --no-tags --force-sync --no-clone-bundle
|
|
|
|
|
+
|
|
|
|
|
+ - name: Download manifest.xml for branch
|
|
|
shell: bash
|
|
shell: bash
|
|
|
working-directory: ${{ github.workspace }}/kernel
|
|
working-directory: ${{ github.workspace }}/kernel
|
|
|
run: |
|
|
run: |
|
|
|
FORMATTED_BRANCH="${{ inputs.android_version }}-${{ inputs.kernel_version }}-${{ inputs.os_patch_level }}"
|
|
FORMATTED_BRANCH="${{ inputs.android_version }}-${{ inputs.kernel_version }}-${{ inputs.os_patch_level }}"
|
|
|
- repo init -u https://android.googlesource.com/kernel/manifest -b common-${FORMATTED_BRANCH} --depth=1 --partial-clone --clone-filter=blob:limit=10M
|
|
|
|
|
- REMOTE_BRANCH=$(git ls-remote https://android.googlesource.com/kernel/common ${FORMATTED_BRANCH})
|
|
|
|
|
- DEFAULT_MANIFEST_PATH=.repo/manifests/default.xml
|
|
|
|
|
- DEPRECATED=false
|
|
|
|
|
- if grep -q deprecated <<< $REMOTE_BRANCH; then
|
|
|
|
|
- sed -i "s/\"${FORMATTED_BRANCH}\"/\"deprecated\/${FORMATTED_BRANCH}\"/g" $DEFAULT_MANIFEST_PATH
|
|
|
|
|
- echo "⚠ Note: Branch ${FORMATTED_BRANCH} is considered deprecated."
|
|
|
|
|
- DEPRECATED=true
|
|
|
|
|
- fi
|
|
|
|
|
- echo "deprecated=$DEPRECATED" >> $GITHUB_OUTPUT
|
|
|
|
|
- repo sync -c -j$(nproc --all) --fail-fast --no-tags --force-sync --no-clone-bundle
|
|
|
|
|
|
|
+ MANIFEST_URL="https://android.googlesource.com/kernel/manifest/+/refs/heads/common-${FORMATTED_BRANCH}/default.xml?format=TEXT"
|
|
|
|
|
+ echo "Fetching manifest from $MANIFEST_URL"
|
|
|
|
|
+ curl -fsSL "$MANIFEST_URL" | base64 -d > manifest.xml
|
|
|
|
|
+
|
|
|
|
|
+ - name: Fast Parallel Archive Download
|
|
|
|
|
+ shell: python
|
|
|
|
|
+ working-directory: ${{ github.workspace }}/kernel
|
|
|
|
|
+ run: |
|
|
|
|
|
+ import xml.etree.ElementTree as ET
|
|
|
|
|
+ import subprocess
|
|
|
|
|
+ import os, glob, shutil
|
|
|
|
|
+ from concurrent.futures import ThreadPoolExecutor
|
|
|
|
|
+
|
|
|
|
|
+ MAX_WORKERS = (os.cpu_count() or 2) * 4
|
|
|
|
|
+ NPROC = int(subprocess.check_output("nproc", shell=True).strip())
|
|
|
|
|
+
|
|
|
|
|
+ def sync_project(task):
|
|
|
|
|
+ name, path, url, strip, rev, linkfiles, copyfiles = task
|
|
|
|
|
+ if path not in ["./", "."]:
|
|
|
|
|
+ os.makedirs(path, exist_ok=True)
|
|
|
|
|
+ print(f"Syncing: {name} -> {path}")
|
|
|
|
|
+ try:
|
|
|
|
|
+ aria_cmd = f"aria2c -x16 -s16 -k1M -j5 --file-allocation=none -o {name}.tar.gz '{url}'"
|
|
|
|
|
+ subprocess.run(aria_cmd, shell=True, check=True)
|
|
|
|
|
+ tar_cmd = f"tar -I 'pigz -p {NPROC} -b 256' -x --record-size=1M -C {path} {strip} -f {name}.tar.gz"
|
|
|
|
|
+ subprocess.run(tar_cmd, shell=True, check=True)
|
|
|
|
|
+ os.remove(f"{name}.tar.gz")
|
|
|
|
|
+ # Handle linkfiles and copyfiles
|
|
|
|
|
+ top_dir = os.getcwd()
|
|
|
|
|
+ for src_rel, dest_rel in linkfiles:
|
|
|
|
|
+ src_path = os.path.join(top_dir, path, src_rel)
|
|
|
|
|
+ dest_path = os.path.join(top_dir, dest_rel)
|
|
|
|
|
+ os.makedirs(os.path.dirname(dest_path), exist_ok=True)
|
|
|
|
|
+ if os.path.lexists(dest_path): os.remove(dest_path)
|
|
|
|
|
+ rel_target = os.path.relpath(src_path, os.path.dirname(dest_path))
|
|
|
|
|
+ os.symlink(rel_target, dest_path)
|
|
|
|
|
+ print(f" [Link] {dest_rel} -> {src_rel}")
|
|
|
|
|
+ for src_rel, dest_rel in copyfiles:
|
|
|
|
|
+ src_path = os.path.join(top_dir, path, src_rel)
|
|
|
|
|
+ dest_path = os.path.join(top_dir, dest_rel)
|
|
|
|
|
+ os.makedirs(os.path.dirname(dest_path), exist_ok=True)
|
|
|
|
|
+ shutil.copy2(src_path, dest_path)
|
|
|
|
|
+ print(f" [Copy] {dest_rel} from {src_rel}")
|
|
|
|
|
+ print(f"Synced {name} successfully!")
|
|
|
|
|
+ return True
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ print(f"Failed to sync {name}: {e}")
|
|
|
|
|
+ return False
|
|
|
|
|
+
|
|
|
|
|
+ with open('manifest.xml', 'r') as f:
|
|
|
|
|
+ manifest_content = f.read()
|
|
|
|
|
+ root = ET.fromstring(manifest_content)
|
|
|
|
|
+ remotes = {r.get('name'): r.get('fetch').rstrip('/') for r in root.findall('remote')}
|
|
|
|
|
+ default = root.find('default')
|
|
|
|
|
+ def_remote = default.get('remote') if default is not None else None
|
|
|
|
|
+ def_rev = default.get('revision') if default is not None else None
|
|
|
|
|
+
|
|
|
|
|
+ sync_tasks = []
|
|
|
|
|
+ for project in root.findall('project'):
|
|
|
|
|
+ name = project.get('name')
|
|
|
|
|
+ path = project.get('path', name)
|
|
|
|
|
+ remote_name = project.get('remote', def_remote)
|
|
|
|
|
+ rev = project.get('revision', def_rev)
|
|
|
|
|
+ base_url = remotes.get(remote_name)
|
|
|
|
|
+ if not base_url: continue
|
|
|
|
|
+ if "github.com" in base_url:
|
|
|
|
|
+ url = f"{base_url}/{name}/archive/{rev}.tar.gz"
|
|
|
|
|
+ strip = "--strip-components=1"
|
|
|
|
|
+ elif "googlesource.com" in base_url:
|
|
|
|
|
+ url = f"{base_url}/{name}/+archive/{rev}.tar.gz"
|
|
|
|
|
+ strip = ""
|
|
|
|
|
+ elif "git.codelinaro.org" in base_url:
|
|
|
|
|
+ url = f"{base_url}/{name}/-/archive/{rev}.tar.gz"
|
|
|
|
|
+ strip = "--strip-components=1"
|
|
|
|
|
+ else:
|
|
|
|
|
+ continue
|
|
|
|
|
+ linkfiles = [(lf.get('src'), lf.get('dest')) for lf in project.findall('linkfile')]
|
|
|
|
|
+ copyfiles = [(cf.get('src'), cf.get('dest')) for cf in project.findall('copyfile')]
|
|
|
|
|
+ sync_tasks.append((name, path, url, strip, rev, linkfiles, copyfiles))
|
|
|
|
|
+
|
|
|
|
|
+ with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
|
|
|
|
|
+ results = list(executor.map(sync_project, sync_tasks))
|
|
|
|
|
+ if not all(results):
|
|
|
|
|
+ print("One or more projects failed to sync!")
|
|
|
|
|
+ exit(1)
|