Files
go-template-container-webse…/update_child_repos.sh
Bryan Joshua Pedini 75769dcff6
All checks were successful
Update Child Repos / update (push) Successful in 5s
finally fixed the permissions thingamagic for the shit script
2026-01-02 15:07:02 +01:00

219 lines
6.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
N8N_HOST="https://n8n.bjphoster.com"
WEBHOOK_ID="7c3cf611-e700-4bc0-b108-7d6be458dae6"
WEBHOOK_URL="${N8N_HOST}/webhook/${WEBHOOK_ID}"
CONFLICT_WEBHOOK_ID=""
CONFLICT_WEBHOOK_URL="${N8N_HOST}/webhook/${CONFLICT_WEBHOOK_ID}"
TEMPLATE_REPO_DIR=$(pwd)
TEMPLATE_BRANCH="main"
CURRENT_COMMIT_ID=$(git rev-parse HEAD)
COMMIT_MESSAGE="Template updates (commit: ${CURRENT_COMMIT_ID:0:7})"
PREVIOUS_COMMIT_ID=$(git log --format="%H" -n 2 HEAD | tail -n 1)
if [ "${PREVIOUS_COMMIT_ID}" = "${CURRENT_COMMIT_ID}" ]; then
FILES_CHANGED=""
else
FILES_CHANGED=$(git diff --name-only "${PREVIOUS_COMMIT_ID}" "${CURRENT_COMMIT_ID}" | tr '\n' ' ')
fi
is_file_changed() {
local file_to_check="$1"
if [ -z "${FILES_CHANGED}" ]; then
return 1
fi
for changed_file in ${FILES_CHANGED}; do
if [ "${changed_file}" = "${file_to_check}" ]; then
return 0
fi
done
return 1
}
FILES_TO_UPDATE="${FILES_TO_UPDATE:-config.yaml.example
deploy.sh
dockerfile
main.go
makefile
routes.go
templates/html/version.html
type_webserver.go
vars.example
version.go
version.sh}"
FILES_TO_UPDATE=$(echo "${FILES_TO_UPDATE}" | tr '\n' ' ' | sed 's/ */ /g' | sed 's/^ *//;s/ *$//')
echo "Fetching repository list from ${WEBHOOK_URL}..."
JSON_RESPONSE=$(curl -s -f "${WEBHOOK_URL}")
echo "Parsing repository URLs..."
CLONE_URLS=$(echo "${JSON_RESPONSE}" | jq -r '.clone_url[]?')
if [ -z "${CLONE_URLS}" ]; then
echo "Error: No clone_url found in response or array is empty"
echo "Response: ${JSON_RESPONSE}"
exit 0
fi
declare -a REPOS_WITH_CONFLICTS=()
while IFS= read -r clone_url; do
if [ -z "${clone_url}" ]; then
continue
fi
echo ""
echo "Processing repository: ${clone_url}"
repo_name=$(basename "${clone_url}" .git)
git clone "${clone_url}" "${repo_name}" &>/dev/null
pushd "${repo_name}" >/dev/null
TEMPLATE_REMOTE_NAME="template"
git remote add "${TEMPLATE_REMOTE_NAME}" "${TEMPLATE_REPO_DIR}"
git fetch "${TEMPLATE_REMOTE_NAME}" "${TEMPLATE_BRANCH}" &>/dev/null
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ -n "${FILES_TO_UPDATE}" ]; then
files_changed=false
conflicted_files=()
for file in ${FILES_TO_UPDATE}; do
if ! is_file_changed "${file}"; then
continue
fi
if ! git show "${TEMPLATE_REMOTE_NAME}/${TEMPLATE_BRANCH}:${file}" >/dev/null 2>&1; then
continue
fi
template_content=$(git show "${TEMPLATE_REMOTE_NAME}/${TEMPLATE_BRANCH}:${file}" 2>/dev/null || true)
if [ -f "${file}" ]; then
current_content=$(cat "${file}" 2>/dev/null || true)
current_permissions=$(stat -c "%a" "${file}" 2>/dev/null || echo "644")
template_permissions=$(pushd "${TEMPLATE_REPO_DIR}" >/dev/null && stat -c "%a" "${file}" 2>/dev/null || echo "644" && popd >/dev/null)
if [ "${current_content}" = "${template_content}" ] && [ "${current_permissions}" = "${template_permissions}" ]; then
continue
fi
file_diff=$(git diff "${PREVIOUS_COMMIT_ID}" "${CURRENT_COMMIT_ID}" -- "${file}" 2>/dev/null || true)
if [ -n "${file_diff}" ]; then
tmp_current=$(mktemp)
tmp_diff=$(mktemp)
echo "${current_content}" > "${tmp_current}"
echo "${file_diff}" > "${tmp_diff}"
if patch --dry-run "${tmp_current}" "${tmp_diff}" >/dev/null 2>&1; then
patch "${tmp_current}" "${tmp_diff}" >/dev/null 2>&1
patched_content=$(cat "${tmp_current}")
if [ "${current_content}" != "${patched_content}" ]; then
echo "${patched_content}" > "${file}"
git add "${file}"
files_changed=true
echo "Merged updates for ${file} in ${repo_name}"
fi
else
echo "Merge conflict detected in ${repo_name}:${file} - preserving local changes"
conflicted_files+=("${file}")
fi
rm -f "${tmp_current}" "${tmp_diff}"
else
echo "File ${file} has local changes in ${repo_name} - preserving local changes"
conflicted_files+=("${file}")
fi
template_permissions=$(pushd "${TEMPLATE_REPO_DIR}" >/dev/null && stat -c "%a" "${file}" 2>/dev/null || echo "644" && popd >/dev/null)
current_permissions=$(stat -c "%a" "${file}" 2>/dev/null || echo "644")
if [ "${current_permissions}" != "${template_permissions}" ]; then
chmod "${template_permissions}" "${file}" 2>/dev/null || true
git add "${file}"
files_changed=true
echo "Updated permissions for ${file} in ${repo_name}"
fi
else
echo "Adding new file ${file} from template to ${repo_name}"
mkdir -p "$(dirname "${file}")"
echo "${template_content}" > "${file}"
template_permissions=$(pushd "${TEMPLATE_REPO_DIR}" >/dev/null && stat -c "%a" "${file}" 2>/dev/null || echo "644" && popd >/dev/null)
chmod "${template_permissions}" "${file}" 2>/dev/null || true
git add "${file}"
files_changed=true
fi
done
if [ ${#conflicted_files[@]} -gt 0 ]; then
REPOS_WITH_CONFLICTS+=("${repo_name}")
repo_var="CONFLICTS_${repo_name//-/_}"
eval "declare -g -a ${repo_var}=($(printf '"%s" ' "${conflicted_files[@]}"))"
fi
if [ "$files_changed" = true ] && [ ${#conflicted_files[@]} -eq 0 ]; then
if ! git diff --cached --quiet; then
git commit -m "${COMMIT_MESSAGE}"
git push
echo "Pushed updates to ${repo_name}"
fi
fi
else
if git merge "${TEMPLATE_REMOTE_NAME}/${TEMPLATE_BRANCH}" \
--no-edit \
--no-ff \
--message "${COMMIT_MESSAGE}"; then
echo "Template merge successful for ${repo_name}"
git push
else
echo "Warning: Merge conflicts detected in ${repo_name}"
popd >/dev/null
rm -rf "${repo_name}"
continue
fi
fi
popd >/dev/null
rm -rf "${repo_name}"
done <<< "${CLONE_URLS}"
if [ ${#REPOS_WITH_CONFLICTS[@]} -gt 0 ]; then
conflict_json="{"
conflict_json+="\"conflicts\":["
for i in "${!REPOS_WITH_CONFLICTS[@]}"; do
repo="${REPOS_WITH_CONFLICTS[$i]}"
repo_var="CONFLICTS_${repo//-/_}"
if [ $i -gt 0 ]; then
conflict_json+=","
fi
conflict_json+="{\"repository\":\"${repo}\",\"files\":["
declare -n files_array="${repo_var}"
for j in "${!files_array[@]}"; do
if [ $j -gt 0 ]; then
conflict_json+=","
fi
conflict_json+="\"${files_array[$j]}\""
done
conflict_json+="]}"
unset -n files_array
done
conflict_json+="]}"
curl -s -X POST "${CONFLICT_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d "${conflict_json}" >/dev/null 2>&1 || true
fi
echo ""
echo "All repositories processed successfully!"