From d16f6847a83e2c0a024e2b440eca5b94f9ae7c8c Mon Sep 17 00:00:00 2001 From: bryan Date: Sat, 8 Aug 2026 13:40:41 -0400 Subject: [PATCH] Add packages/feeds cherrypick support --- README.md | 3 +- openwrtbuilder | 106 ++++++++++++++++++++++++++++++------------------- profiles | 2 +- 3 files changed, 68 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 4658ac0..e1fb376 100755 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Profile keys: | `packages` | No | Space-separated package list. Prefix with `-` to remove a package in Image Builder or source config generation. | | `kconfigs` | No | Space-separated Kconfig symbols. In `imagebuilder` mode only `CONFIG_TARGET_ROOTFS_PARTSIZE=` is used (mapped to `ROOTFS_PARTSIZE`). In `source` mode all entries are written to `.config` seed. | | `files` | No | Host directory containing custom overlay files. In `imagebuilder` mode this is passed as `FILES=`. In `source` mode contents are synced into `/files/` before build. Defaults to `/src/files`. | -| `cherrypicks` | No | Space-separated entries in `URL@branch:commit` form. Each commit is fetched and cherry-picked in `source` mode. | +| `cherrypicks` | No | Space-separated source-mode cherry-picks in `URL@branch:commit` form. The target is inferred from the repo basename: `openwrt` applies to the main source tree, any other basename applies to `feeds/` after feeds update/install. | | `branches` | No | Space-separated `URL@branch` entries to merge into the source worktree in `source` mode. | | `release` | No | Default release/ref for the profile (for example `snapshot`, `25.12.4`). CLI `--release` overrides it. | | `clean` | No | Optional source cleanup step (`clean`, `targetclean`, `dirclean`, `distclean`). CLI `--clean` overrides it. | @@ -64,6 +64,7 @@ Notes: * The profile file uses associative arrays (`declare -Ag name=( [key]="value" ... )`). * `packages`, `kconfigs`, `cherrypicks`, and `branches` are parsed as scalar whitespace-separated strings. +* `cherrypicks` entries always use `URL@branch:commit` format; target selection is automatic from repo basename. * If a profile-specific `files` path is configured, it must exist. ## Examples diff --git a/openwrtbuilder b/openwrtbuilder index f55fcb7..bda3ea7 100755 --- a/openwrtbuilder +++ b/openwrtbuilder @@ -525,8 +525,48 @@ from_source() { local seed_file="$BUILD_DIR/.config" local worktree_meta="$SRC_DIR/.git/worktrees/source-$REF" local pkg kconfig commit description rootfs_kconfig + local cherrypick url_branch branch url remote feed_dir repo_name local -a make_opts + preprocess_cherrypick() { + local spec="$1" + + url_branch="${spec%:*}" + if [[ "$url_branch" == *"@"* ]]; then + url="${url_branch%@*}" + branch="${url_branch#*@}" + else + url="$url_branch" + branch="" + fi + commit="${spec##*:}" + repo_name="${url%.git}" + repo_name="${repo_name##*/}" + remote="$repo_name" + remote=${remote//[^A-Za-z0-9._-]/_} + [[ -z $remote ]] && remote="cherry" + } + + apply_cherrypick() { + local repo_dir="$1" + + if ! git -C "$repo_dir" remote | grep -q "^$remote$"; then + execute git -C "$repo_dir" remote add "$remote" "$url" + else + execute git -C "$repo_dir" remote set-url "$remote" "$url" + fi + + execute git -C "$repo_dir" fetch "$remote" "$branch" + + if ! git -C "$repo_dir" cat-file -e "$commit^{commit}" 2>/dev/null; then + debug "Commit $commit not found after fetching from $remote; skipping" + return 0 + fi + + execute git -C "$repo_dir" merge-base --is-ancestor "$commit" HEAD || + execute git -C "$repo_dir" cherry-pick "$commit" + } + echo "Building from source is under development" # Convert filesystem to corresponding KCONFIG value @@ -607,42 +647,11 @@ from_source() { fi fi - # Add cherrypicks + # Apply OpenWrt-targeted cherrypicks before branch merges. for cherrypick in $CHERRYPICKS; do - url_branch="${cherrypick%:*}" - commit="${cherrypick##*:}" - branch="" - url="$url_branch" - if [[ "$url_branch" == *"@"* ]]; then - url="${url_branch%@*}" - branch="${url_branch#*@}" - fi - - remote="${url%.git}" - remote="${remote##*/}" - remote=${remote//[^A-Za-z0-9._-]/_} - [[ -z $remote ]] && remote="cherry" - - if ! git -C "$BUILD_DIR" remote | grep -q "^$remote$"; then - execute git -C "$BUILD_DIR" remote add "$remote" "$url" - else - execute git -C "$BUILD_DIR" remote set-url "$remote" "$url" - fi - - if [[ -n $branch ]]; then - execute git -C "$BUILD_DIR" fetch "$remote" "$branch" - else - execute git -C "$BUILD_DIR" fetch "$remote" - fi - - # Verify commit exists before attempting cherry-pick - if ! git -C "$BUILD_DIR" cat-file -e "$commit^{commit}" 2>/dev/null; then - debug "Commit $commit not found after fetching from $remote; skipping" - continue - fi - - execute git -C "$BUILD_DIR" merge-base --is-ancestor "$commit" HEAD || - execute git -C "$BUILD_DIR" cherry-pick "$commit" + preprocess_cherrypick "$cherrypick" + [[ "$repo_name" == "openwrt" ]] || continue + apply_cherrypick "$BUILD_DIR" done # Merge entire branches @@ -676,7 +685,7 @@ from_source() { continue fi done - + # Print commit info commit=$(git -C "$BUILD_DIR" rev-parse HEAD) description=$(git -C "$BUILD_DIR" describe --always --dirty) @@ -687,10 +696,10 @@ from_source() { # Enter worktree execute pushd "$BUILD_DIR" || return 1 - + # Begin OpenWRT build process ((DEBUG)) && make_opts+=("V=sc") - + # Cleanup build environment: heavy clean only when --reset was used earlier # make clean # compiled output # make targetclean # compiled output, toolchain @@ -701,14 +710,29 @@ from_source() { else debug "Skipping cleanup step" fi - + # Use a custom (faster) mirror local mirror_prefix="${USER_MIRROR:-github.com/openwrt}" execute sed -i -E "s;git.openwrt.org/(feed|project);${mirror_prefix};" feeds.conf.default # Update package feed - ./scripts/feeds update -a -f && - ./scripts/feeds install -a -f + if ! ./scripts/feeds update -a -f || ! ./scripts/feeds install -a -f; then + echo "Error: feeds update/install failed" + return 1 + fi + + # Apply feed-targeted cherrypicks after feeds are checked out/updated. + for cherrypick in $CHERRYPICKS; do + preprocess_cherrypick "$cherrypick" + [[ "$repo_name" == "openwrt" ]] && continue + + feed_dir="$BUILD_DIR/feeds/$repo_name" + if [[ ! -d "$feed_dir/.git" ]]; then + debug "Feed repo '$repo_name' not found at $feed_dir; skipping" + continue + fi + apply_cherrypick "$feed_dir" + done # Apply custom files overlay for source builds. # execute rm -rf "$BUILD_DIR/files" diff --git a/profiles b/profiles index b78c753..99e876d 100644 --- a/profiles +++ b/profiles @@ -45,7 +45,7 @@ declare -Ag router=( kmod-fs-btrfs btrfs-progs block-mount \ smcroute avahi-daemon" # Backport tailscale 1.102.2 to 25.12 branch - [cherrypicks]="https://github.com/openwrt/openwrt@main:ce9a0ff3fb88d037080aaf95af92ac5da4fcfdba" + [cherrypicks]="https://github.com/openwrt/packages@master:58708c70345b31897b08ad1697d8bf4f3c022972" [kconfigs]="${default_kconfigs[*]} \ CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=32 \ CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y"