Files
hassio-addons/addons_updater/rootfs/etc/cont-init.d/99-run.sh
Alexandre 500c083c5e fix(updater): publish the version the image holds, not the app's newest release (#3061)
The immich addons do not build immich, they build FROM
ghcr.io/imagegenius/immich, a rebuild that lags immich upstream by days to
weeks. updater.json tracked immich-app/immich, so the addon was published as
3.2.0 two days after that release while the image behind the floating :3 tag
still carried immich 3.1.0 (issue #3060), and because the stored upstream
version already read 3.2.0, nothing would have rebuilt the addon once the
image caught up.

Add source: container, which resolves the exact image reference the addon
builds from and reads org.opencontainers.image.version out of it, and point
the four immich addons at it. The manifest digest is recorded alongside the
version so that a publisher republishing the same version under new content
is not mistaken for no change. An image with nothing readable leaves the
addon untouched.

Written as inline curl and jq, in the style of the dockerhub branch above it.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 16:49:40 +02:00

511 lines
24 KiB
Bash
Executable File

#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
##########
# UPDATE #
##########
bashio::log.info "Starting $(lastversion --version)"
if bashio::config.true "dry_run"; then
bashio::log.warning "Dry run mode : on"
fi
bashio::log.info "Checking status of referenced repositories..."
VERBOSE=$(bashio::config 'verbose')
if bashio::config.true "date_iso8601"; then
DATE_FORMAT="+%Y-%m-%d"
else
DATE_FORMAT="+%d-%m-%Y"
fi
# Version published in the addon configuration, which is the one Home
# Assistant compares; the upstream tag lives in updater.json instead
function config_version() {
local folder="$1"
if [ -f "$folder/config.json" ]; then
jq -r '.version // empty' "$folder/config.json"
elif [ -f "$folder/config.yaml" ]; then
sed -n 's/^version:[[:space:]]*//p' "$folder/config.yaml" \
| head -n 1 \
| sed -e 's/[[:space:]]*#.*$//' -e 's/^"//' -e 's/"$//' \
| sed -e "s/^'//" -e "s/'$//"
fi
}
# Escape a version so that sed treats it as plain text on both sides
function sed_pattern() {
printf '%s' "$1" | sed -e 's/[]\/$*.^[]/\\&/g'
}
function sed_replacement() {
printf '%s' "$1" | sed -e 's/[\/&]/\\&/g'
}
#Defining github value
LOGINFO="... github authentification" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
GITUSER=$(bashio::config 'gituser')
GITMAIL=$(bashio::config 'gitmail')
git config --system http.sslVerify false
git config --system credential.helper 'cache --timeout 7200'
git config --system user.name "${GITUSER}"
if [[ "$GITMAIL" != "null" ]]; then git config --system user.email "${GITMAIL}"; fi
if bashio::config.has_value 'gitapi'; then
LOGINFO="... setting github API" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
GITHUB_API_TOKEN=$(bashio::config 'gitapi')
export GITHUB_API_TOKEN
fi
#Create or update local version
REPOSITORY=$(bashio::config 'repository')
BASENAME=$(basename "https://github.com/$REPOSITORY")
if [ ! -d "/data/$BASENAME" ]; then
LOGINFO="... cloning ${REPOSITORY}" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
cd /data/ || exit
git clone "https://github.com/${REPOSITORY}"
else
LOGINFO="... updating ${REPOSITORY}" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
cd "/data/$BASENAME" || exit
DEFAULT_BRANCH=$(git remote show origin | sed -n '/HEAD branch/s/.*: //p')
git pull --rebase origin > /dev/null || git reset --hard "origin/${DEFAULT_BRANCH}" > /dev/null
git pull --rebase origin > /dev/null || (rm -r "/data/$BASENAME" && git clone "https://github.com/${REPOSITORY}")
fi
LOGINFO="... parse addons" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
# Go through all folders, add to filters if not existing
cd /data/"$BASENAME" || exit
for f in */; do
if [ -f /data/"$BASENAME"/"$f"/updater.json ]; then
SLUG=${f//\//}
# Rebase
LOGINFO="... updating ${REPOSITORY}" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
cd "/data/$BASENAME" || exit
git pull --rebase &> /dev/null || git reset --hard &> /dev/null
git pull --rebase &> /dev/null
#Define the folder addon
LOGINFO="... $SLUG : checking slug exists in repo" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
cd /data/"${BASENAME}"/"${SLUG}" || {
bashio::log.error "$SLUG addon not found in this repository. Exiting."
continue
}
# Get variables
UPSTREAM=$(jq -r .upstream_repo updater.json)
BETA=$(jq -r .github_beta updater.json)
FULLTAG=$(jq -r .github_fulltag updater.json)
HAVINGASSET=$(jq -r .github_havingasset updater.json)
SOURCE=$(jq -r .source updater.json)
FILTER_TEXT=$(jq -r .github_tagfilter updater.json)
EXCLUDE_TEXT=$(jq -r .github_exclude updater.json)
EXCLUDE_TEXT="${EXCLUDE_TEXT:-zzzzzzzzzzzzzzzz}"
PAUSED=$(jq -r .paused updater.json)
DATE="$(date "$DATE_FORMAT")"
LASTDIGEST=""
BYDATE=$(jq -r .dockerhub_by_date updater.json)
# Number of elements to check in dockerhub
if grep -q "dockerhub_list_size" updater.json; then
LISTSIZE=$(jq -r .dockerhub_list_size updater.json)
else
LISTSIZE=100
fi
#Skip if paused
if [[ "$PAUSED" = true ]]; then
bashio::log.magenta "... $SLUG addon updates are paused, skipping"
continue
fi
#Find current version
LOGINFO="... $SLUG : get current version" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
CURRENT=$(jq .upstream_version updater.json) \
|| {
bashio::log.error "$SLUG addon upstream tag not found in updater.json. Exiting."
continue
}
if [[ "$SOURCE" = dockerhub ]]; then
# Use dockerhub as upstream
# shellcheck disable=SC2116
LOGINFO="... Source is dockerhub" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
#Prepare tag flag
if [ "${FILTER_TEXT}" = "null" ] || [ "${FILTER_TEXT}" = "" ]; then
FILTER_TEXT=""
else
LOGINFO="... $SLUG : filter_text is on" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
FILTER_TEXT="&name=$FILTER_TEXT"
fi
#Prepare tag flag
if [ "${EXCLUDE_TEXT}" = "null" ] || [ "${EXCLUDE_TEXT}" = "" ]; then
EXCLUDE_TEXT="zzzzzzzzzzzzzzzzzz"
fi
DOCKERHUB_REPO="${UPSTREAM%%/*}"
DOCKERHUB_IMAGE=$(echo "$UPSTREAM" | cut -d "/" -f2)
LASTVERSION=$(
curl -f -L -s --fail "https://hub.docker.com/v2/repositories/${DOCKERHUB_REPO}/${DOCKERHUB_IMAGE}/tags?page_size=$LISTSIZE$FILTER_TEXT" \
| jq '.results | .[] | .name' -r \
| sed -e '/.*latest.*/d' \
| sed -e '/.*dev.*/d' \
| sed -e '/.*nightly.*/d' \
| sed -e '/.*beta.*/d' \
| sed -e "/.*$EXCLUDE_TEXT.*/d" \
| sort -V \
| tail -n 1
)
[ "${BETA}" = true ] \
&& LASTVERSION=$(
curl -f -L -s --fail "https://hub.docker.com/v2/repositories/${DOCKERHUB_REPO}/${DOCKERHUB_IMAGE}/tags?page_size=$LISTSIZE$FILTER_TEXT" \
| jq '.results | .[] | .name' -r \
| sed -e '/.*latest.*/d' \
| sed -e '/.*dev.*/!d' \
| sed -e "/.*$EXCLUDE_TEXT.*/d" \
| sort -V \
| tail -n 1
)
[ "${BYDATE}" = true ] \
&& LASTVERSION=$(
curl -f -L -s --fail "https://hub.docker.com/v2/repositories/${DOCKERHUB_REPO}/${DOCKERHUB_IMAGE}/tags?page_size=${LISTSIZE}&ordering=last_updated$FILTER_TEXT" \
| jq '.results | .[] | .name' -r \
| sed -e '/.*latest.*/d' \
| sed -e '/.*dev.*/d' \
| sed -e '/.*nightly.*/d' \
| sed -e "/.*$EXCLUDE_TEXT.*/d" \
| sort -V \
| tail -n 1
) \
&& DATE=$(
curl -f -L -s --fail "https://hub.docker.com/v2/repositories/${DOCKERHUB_REPO}/${DOCKERHUB_IMAGE}/tags/?page_size=${LISTSIZE}&ordering=last_updated$FILTER_TEXT" \
| jq '.results[] | select(.name==$LASTVERSION) | .last_updated' -r --arg LASTVERSION "$LASTVERSION"
) \
&& DATE="${DATE%T*}" \
&& DATE="$(date -d "$DATE" "$DATE_FORMAT")" \
&& LASTVERSION="$LASTVERSION-$DATE"
LOGINFO="... $SLUG : bydate is true, version is $LASTVERSION" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
elif [[ "$SOURCE" = container ]]; then
# The addon builds FROM an image someone else publishes rather
# than from the application itself, so the version to publish is
# the one inside that image and not the newest release of the
# application repository, which the image can lag by weeks
LOGINFO="... Source is container" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
ACCEPT="application/vnd.oci.image.index.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.v2+json"
REGISTRY="${UPSTREAM%%/*}"
IMAGE="${UPSTREAM#*/}"
IMAGEREPO="${IMAGE%:*}"
BASEURL="https://$REGISTRY/v2/$IMAGEREPO"
HEADERS="$(mktemp)"
# The digest the tag resolves to is the one the registry answers
# with, and it moves whenever anything behind the tag does
TOKEN="$(curl -f -L -s "https://$REGISTRY/token?scope=repository:$IMAGEREPO:pull&service=$REGISTRY" | jq -r '.token // empty')" || true
MANIFEST="$(curl -f -L -s -D "$HEADERS" -H "Authorization: Bearer $TOKEN" -H "Accept: $ACCEPT" "$BASEURL/manifests/${IMAGE##*:}")" || true
LASTDIGEST="$(sed -n 's/^[Dd]ocker-[Cc]ontent-[Dd]igest:[[:space:]]*//p' "$HEADERS" | tr -d '\r')"
rm -f "$HEADERS"
# A multi architecture tag answers with an index, whose first
# image is read: the attestations buildx attaches alongside
# describe no architecture and hold no image configuration
CHILD="$(echo "$MANIFEST" | jq -r 'first(.manifests[]? | select(.platform.os == "linux" and .platform.architecture != "unknown") | .digest) // empty')" || true
if [ -n "$CHILD" ]; then
MANIFEST="$(curl -f -L -s -H "Authorization: Bearer $TOKEN" -H "Accept: $ACCEPT" "$BASEURL/manifests/$CHILD")" || true
fi
# Publishers record the application version of an image in its
# OCI label, which is what the addon actually ships
LASTVERSION="$(curl -f -L -s -H "Authorization: Bearer $TOKEN" "$BASEURL/blobs/$(echo "$MANIFEST" | jq -r '.config.digest // empty')" \
| jq -r '.config.Labels["org.opencontainers.image.version"] // empty')" || true
if [ -z "$LASTVERSION" ] || [ -z "$LASTDIGEST" ]; then
bashio::log.warning "... $SLUG : no version could be read from $UPSTREAM, skipping"
continue
fi
else
# Use source as upstream
ARGUMENTS="--at $SOURCE"
LASTVERSION_REPO="$UPSTREAM"
if [ "${SOURCE}" = "codeberg" ]; then
# Codeberg is a hosted Gitea instance; pass the repository as a full URL for lastversion
CODEBERG_BASE_URL="https://codeberg.org"
ARGUMENTS="--at gitea"
LASTVERSION_REPO="${CODEBERG_BASE_URL}/${UPSTREAM}"
LOGINFO="... $SLUG : source is codeberg (gitea, using ${CODEBERG_BASE_URL})" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
else
LOGINFO="... $SLUG : source is $SOURCE" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
fi
#Prepare tag flag
if [ "${FULLTAG}" = true ]; then
LOGINFO="... $SLUG : github_fulltag is on" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
ARGUMENTS="$ARGUMENTS --format tag"
else
LOGINFO="... $SLUG : github_fulltag is off" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
fi
#Prepare tag flag
if [ "${HAVINGASSET}" = true ]; then
LOGINFO="... $SLUG : asset_only tag is on" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
ARGUMENTS="$ARGUMENTS --having-asset"
else
LOGINFO="... $SLUG : asset_only is off" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
fi
#Prepare tag flag
if [ "${FILTER_TEXT}" = "null" ] || [ "${FILTER_TEXT}" = "" ]; then
FILTER_TEXT=""
else
LOGINFO="... $SLUG : filter_text is on" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
ARGUMENTS="$ARGUMENTS --only $FILTER_TEXT"
fi
#Prepare tag flag
if [ "${EXCLUDE_TEXT}" = "null" ] || [ "${EXCLUDE_TEXT}" = "" ]; then
EXCLUDE_TEXT=""
else
LOGINFO="... $SLUG : github_exclude is on" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
ARGUMENTS="$ARGUMENTS --exclude $EXCLUDE_TEXT"
fi
#If beta flag, select beta version
if [ "${BETA}" = true ]; then
LOGINFO="... $SLUG : beta is on" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
ARGUMENTS="$ARGUMENTS --pre"
else
LOGINFO="... $SLUG : beta is off" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
fi
# If failure, checks if there is packages that could be used
function test_packages() {
if [ "$VERBOSE" = true ]; then
# shellcheck disable=SC2086
bashio::log.info "source : $SOURCE and LASTVERSION : $(lastversion "$UPSTREAM" $ARGUMENTS 2>&1 || true)"
fi
# shellcheck disable=SC2086
if [[ "$SOURCE" == *"github"* ]] && [[ "$(lastversion "$UPSTREAM" $ARGUMENTS 2>&1 || true)" == *"No release"* ]]; then
# Is there a package
bashio::log.warning "No version found, looking if packages available"
last_packages="$(curl -s -L https://github.com/"$UPSTREAM"/packages | sed -n "s/.*\/container\/package\/\([^\"]*\).*/\1/p")" || true
last_package="$(echo "$last_packages" | head -n 1)" || true
if [[ "$(echo -n "$last_packages" | grep -c '^')" -gt 0 ]]; then
bashio::log.warning "A total of $(echo -n "$last_packages" | grep -c '^') packages were found, using $last_package"
LASTVERSION=""
LASTVERSION="$(curl -s -L https://github.com/"$UPSTREAM"/pkgs/container/"$last_package" | sed -n "s/.*?tag=\([^\"]*\)\">.*/\1/p" \
| sed -e '/.*latest.*/d' \
| sed -e '/.*dev.*/d' \
| sed -e '/.*nightly.*/d' \
| sed -e '/.*beta.*/d' \
| sort -V \
| tail -n 1)" || true
if [[ "$LASTVERSION" == "" ]]; then
# Continue to next
bashio::log.warning "No packages found"
set_continue=true
else
bashio::log.info "Found tag $LASTVERSION"
echo "$LASTVERSION"
fi
else
# Continue to next
bashio::log.warning "No packages found"
set_continue=true
fi
else
# Continue to next
set_continue=true
fi
}
# shellcheck disable=SC2086
LASTVERSION="$(lastversion "$LASTVERSION_REPO" $ARGUMENTS || test_packages)"
# Codeberg fallback: lastversion may not support custom Gitea hosts in older builds
if [[ -z "$LASTVERSION" && "${SOURCE}" = "codeberg" ]]; then
LOGINFO="... $SLUG : attempting Codeberg API fallback" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
RELEASES_URL="https://codeberg.org/api/v1/repos/${UPSTREAM}/releases"
JQ_FILTER='.[] | select(.draft == false)'
if [ "$BETA" != true ]; then
JQ_FILTER='.[] | select(.draft == false and .prerelease == false)'
fi
CODEBERG_TAGS=$(curl -fsSL "$RELEASES_URL" | jq -r "$JQ_FILTER | .tag_name" || true)
if [ -n "$CODEBERG_TAGS" ]; then
if [ -n "$FILTER_TEXT" ]; then
CODEBERG_TAGS=$(echo "$CODEBERG_TAGS" | grep "$FILTER_TEXT" || true)
fi
if [ -n "$EXCLUDE_TEXT" ]; then
CODEBERG_TAGS=$(echo "$CODEBERG_TAGS" | sed "/${EXCLUDE_TEXT}/d")
fi
CODEBERG_TAGS=$(echo "$CODEBERG_TAGS" | sed '/^$/d' | sort -V)
LASTVERSION=$(echo "$CODEBERG_TAGS" | tail -n 1)
fi
if [ -n "$LASTVERSION" ] && [ "$FULLTAG" != true ]; then
LASTVERSION="${LASTVERSION#v}"
fi
if [ -z "$LASTVERSION" ]; then
bashio::log.warning "... $SLUG : unable to determine Codeberg release"
set_continue=true
fi
fi
# Continue if issue
if [[ "${set_continue:-false}" == true ]]; then
continue
fi
fi
# Add brackets
LASTVERSION='"'${LASTVERSION}'"'
# Skip if current or last version is empty (would corrupt files by replacing all "" occurrences)
if [ "${CURRENT}" = '""' ] || [ "${LASTVERSION}" = '""' ]; then
bashio::log.warning "... $SLUG : skipping update due to empty version string (current=${CURRENT}, latest=${LASTVERSION})"
continue
fi
# What the addon was last built against. A container source adds the
# digest of the image: a publisher rebuilding the same version, for a
# base image fix or a packaging revision, repoints the tag at new
# content under an unchanged label, and only the digest says so
CURRENTSTATE="$CURRENT"
LASTSTATE="$LASTVERSION"
if [[ "$SOURCE" = container ]]; then
CURRENTSTATE="$CURRENT $(jq -r '.upstream_digest // ""' updater.json)"
LASTSTATE="$LASTVERSION $LASTDIGEST"
fi
# Update if needed
if [ "${CURRENTSTATE}" != "${LASTSTATE}" ]; then
LOGINFO="... $SLUG : update from ${CURRENT} to ${LASTVERSION}" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
ADDONFOLDER="/data/${BASENAME}/${SLUG}"
# Version currently published, before any file is touched
CONFIGVERSION="$(config_version "$ADDONFOLDER" || true)"
if [ -z "$CONFIGVERSION" ]; then
bashio::log.error "... $SLUG : no version found in the addon config, skipping"
continue
fi
# Home Assistant hides an update when it can compare both
# versions and the new one is not strictly newer, and cannot
# order tags such as "version-bf9e0b4f" at all. The addon
# version is therefore derived from the upstream tag, which
# stays untouched in updater.json so that the same upstream
# release is never published twice
if ! ADDONVERSION="$(python3 /usr/bin/ha_version.py --current "$CONFIGVERSION" --upstream "${LASTVERSION//\"/}")"; then
bashio::log.error "... $SLUG : no Home Assistant compliant version derived from ${LASTVERSION}, skipping"
continue
fi
if [ "$ADDONVERSION" != "${LASTVERSION//\"/}" ]; then
bashio::log.blue "... $SLUG : Home Assistant would not offer ${LASTVERSION//\"/} as an update of $CONFIGVERSION, addon version set to $ADDONVERSION"
fi
#Change all instances of version, the addon config excluded as
#its version can now differ from the upstream tag
LOGINFO="... $SLUG : updating files" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
CURRENTPATTERN="$(sed_pattern "$CURRENT")"
LASTVERSIONTEXT="$(sed_replacement "$LASTVERSION")"
for files in "Dockerfile" "build.json" "build.yaml"; do
if [ -f "$ADDONFOLDER/$files" ]; then
sed -i "s/${CURRENTPATTERN}/${LASTVERSIONTEXT}/g" "$ADDONFOLDER/$files"
fi
done
# Remove " and modify version
LASTVERSION=${LASTVERSION//\"/}
CURRENT=${CURRENT//\"/}
if [ -f "$ADDONFOLDER/config.json" ]; then
# Piping jq into sponge would empty the file if jq fails
if CONFIGJSON="$(jq --arg variable "$ADDONVERSION" '.version = $variable' "$ADDONFOLDER/config.json")"; then
printf '%s\n' "$CONFIGJSON" > "$ADDONFOLDER/config.json" # Replace version tag
fi
elif [ -f "$ADDONFOLDER/config.yaml" ]; then
sed -i "/^version:/c\version: \"$ADDONVERSION\"" "$ADDONFOLDER/config.yaml"
fi
# Leave the addon untouched rather than committing a version
# Home Assistant would not offer
if [ "$(config_version "$ADDONFOLDER")" != "$ADDONVERSION" ]; then
bashio::log.error "... $SLUG : version $ADDONVERSION could not be written in the addon config, reverting"
git checkout -- "$ADDONFOLDER"
continue
fi
# Replace upstream tag and date, keeping the file intact if jq
# fails as a truncated updater.json would lose the addon source
if ! UPDATERJSON="$(jq --arg version "$LASTVERSION" --arg date "$DATE" --arg digest "${LASTDIGEST:-}" \
'.upstream_version = $version | .last_update = $date | if $digest == "" then . else .upstream_digest = $digest end' \
"$ADDONFOLDER/updater.json")"; then
bashio::log.error "... $SLUG : updater.json could not be updated, reverting"
git checkout -- "$ADDONFOLDER"
continue
fi
printf '%s\n' "$UPDATERJSON" > "$ADDONFOLDER/updater.json"
#Update changelog
touch "$ADDONFOLDER/CHANGELOG.md"
if [ "$ADDONVERSION" != "$LASTVERSION" ]; then
sed -i "1i - Upstream tag : $LASTVERSION" "$ADDONFOLDER/CHANGELOG.md"
fi
if [[ "$SOURCE" == *"github"* ]]; then
sed -i "1i - Update to latest version from $UPSTREAM (changelog : https://github.com/${UPSTREAM%/}/releases)" "$ADDONFOLDER/CHANGELOG.md"
else
sed -i "1i - Update to latest version from $UPSTREAM" "$ADDONFOLDER/CHANGELOG.md"
fi
sed -i "1i ## ${ADDONVERSION} (${DATE})" "$ADDONFOLDER/CHANGELOG.md"
sed -i "1i\ " "$ADDONFOLDER/CHANGELOG.md"
LOGINFO="... $SLUG : files updated" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
#Git commit and push
git add -A # add all modified files
git commit -m "Updater bot : $SLUG updated to ${ADDONVERSION} (upstream ${LASTVERSION})" > /dev/null
LOGINFO="... $SLUG : push to github" && if [ "$VERBOSE" = true ]; then bashio::log.info "$LOGINFO"; fi
git remote set-url origin "https://${GITUSER}:${GITHUB_API_TOKEN}@github.com/${REPOSITORY}" &> /dev/null
# Push
if ! bashio::config.true "dry_run"; then
git push &> /dev/null
fi
#Log
bashio::log.yellow "... $SLUG updated to ${ADDONVERSION} (upstream ${CURRENT} to ${LASTVERSION})"
else
bashio::log.green "... $SLUG is up-to-date ${CURRENT}"
fi
fi
done || true # Continue even if issue
# Clean dry run
if bashio::config.true "dry_run"; then
rm -r /data/*
fi
bashio::log.info "Addons update completed"