feat(birdnet-pi): merge open PRs via API

This commit is contained in:
Alexandre
2025-08-19 21:34:01 +02:00
parent 1a418d1100
commit c5b456fcd9
2 changed files with 89 additions and 10 deletions

View File

@@ -36,6 +36,8 @@ ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templat
ARG CONFIGLOCATION="/config"
RUN chmod 744 /ha_lsio.sh && if grep -qr "lsio" /etc; then /ha_lsio.sh "$CONFIGLOCATION"; fi && rm /ha_lsio.sh
COPY merge_open_prs.sh /merge_open_prs.sh
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# hadolint ignore=DL3015,SC2016
RUN \
@@ -70,6 +72,11 @@ RUN \
# Download installer
curl -f -L -s -S "https://raw.githubusercontent.com/alexbelgium/BirdNET-Pi/main/newinstaller.sh" -o /newinstaller.sh && \
chmod 777 /newinstaller.sh && \
chmod +x /merge_open_prs.sh && \
/merge_open_prs.sh && \
chown -R 1000:1000 $HOME && \
chmod 777 $HOME/BirdNET-Pi/scripts/*.sh && \
sed -i "/CURRENT_TIMEZONE/s/$/ || true/" $HOME/BirdNET-Pi/scripts/install_birdnet.sh && \
\
# Use installer to modify other scripts
#######################################
@@ -86,18 +93,9 @@ RUN \
##################
# Use my repository
sed -i "s|Nachtzuster|alexbelgium|g" /newinstaller.sh && \
# Install open PR
sed -i '/^git clone/a for pr in $(curl -s https://api.github.com/repos/alexbelgium/BirdNET-Pi/pulls?state=open | jq -r ".[].number"); do echo "Merging PR #$pr" && git fetch origin pull/$pr/merge:pr-$pr && git merge --no-ff -m "Merge PR #$pr" pr-$pr || { echo "Skipping PR #$pr"; git merge --abort || true; }; done' /newinstaller.sh && \
# Avoid rebooting at end of installation
sed -i '/git clone -b \$branch --depth=1/d' /newinstaller.sh && \
sed -i "/reboot/d" /newinstaller.sh && \
# Use apt-get as without user action
sed -i "s|apt |apt-get |g" /newinstaller.sh && \
# Ensure chmod
sed -i "/git clone/a chown -R 1000:1000 $HOME" /newinstaller.sh && \
sed -i "/git clone/a chmod 777 \$HOME/BirdNET-Pi/scripts/*.sh" /newinstaller.sh && \
# Disable datetimectl
sed -i '/git clone/a sed -i "/CURRENT_TIMEZONE/s/$/ || true/" $HOME/BirdNET-Pi/scripts/install_birdnet.sh' /newinstaller.sh && \
# Remove all instances of sudo from the newinstaller
sed -i -e "s|== 0|== 7|g" -e "s|sudo -n true|true|g" -e "s|sudo -K|true|g" /newinstaller.sh && \
\
# Execute installer

View File

@@ -0,0 +1,81 @@
#!/bin/bash
set -e
update=yes
if [[ "$update" = "yes" ]]; then
repo="https://github.com/alexbelgium/BirdNET-Pi.git"
# repo="https://github.com/Nachtzuster/BirdNET-Pi.git"
branch="main"
echo "Update with $branch of $repo"
temp_dir="$(mktemp -d)"
target_dir="/home/${USER}/BirdNET-Pi"
# Parse owner/repo from the URL
_url_no_git="${repo%.git}"
_path="${_url_no_git#https://github.com/}"
owner="${_path%%/*}"
reponame="${_path#*/}"
# --- helper: list open PRs via GitHub API (unauthenticated) ----------------
list_open_prs() {
# prints PR numbers, one per line; returns non-zero if none or curl missing
command -v curl >/dev/null 2>&1 || return 1
local page=1 per_page=100 out
local -a all=() chunk=()
while :; do
out="$(curl -fsSL "https://api.github.com/repos/${owner}/${reponame}/pulls?state=open&per_page=${per_page}&page=${page}")" || break
[[ -z "$out" || "$out" == "[]" ]] && break
if command -v jq >/dev/null 2>&1; then
mapfile -t chunk < <(printf '%s' "$out" | jq -r '.[] | select(.draft == false) | .number')
else
# Fallback JSON scraping if jq is unavailable
mapfile -t chunk < <(printf '%s' "$out" | grep -o '"number":[[:space:]]*[0-9]\+' | grep -o '[0-9]\+')
fi
((${#chunk[@]}==0)) && break
all+=("${chunk[@]}")
((${#chunk[@]} < per_page)) && break
((page++))
done
((${#all[@]}==0)) && return 1
printf '%s\n' "${all[@]}"
}
# --- clone base ------------------------------------------------------------
git clone --quiet --branch "$branch" "$repo" "$temp_dir"
pushd "$temp_dir" >/dev/null
git fetch --quiet origin
git config user.name "Local PR Aggregator"
git config user.email "local@example.invalid"
git checkout -B with-open-prs "origin/${branch}"
# --- fetch & merge only OPEN PRs -------------------------------------------
mapfile -t prs < <(list_open_prs || true)
if ((${#prs[@]})); then
# Sort numerically (oldest first)
IFS=$'\n' prs=($(sort -n <<<"${prs[*]}")); unset IFS
echo "Open PR(s): ${prs[*]}"
for pr in "${prs[@]}"; do
echo "Fetching PR #${pr}"
if git fetch --quiet origin "pull/${pr}/head:pr-${pr}"; then
echo "Merging PR #${pr} into with-open-prs…"
if git merge --no-ff -X theirs --no-edit "pr-${pr}"; then
echo "✓ merged PR #${pr}"
else
echo "! Conflict merging PR #${pr}; aborting and skipping."
git merge --abort || true
git reset --hard
git checkout with-open-prs
fi
else
echo "! Could not fetch refs for PR #${pr}; skipping."
fi
done
else
echo "No open PRs detected (API unavailable or none open)."
fi
popd >/dev/null
rm -rf "$target_dir"
mv "$temp_dir" "$target_dir"
fi