#!/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" COMMIT_ID=$(git log HEAD --oneline | awk '{print $1}' | head -n1) COMMIT_MESSAGE="Template updates (commit: $COMMIT_ID)" FILES_TO_UPDATE="${FILES_TO_UPDATE:-config.yaml.example deploy.sh dockerfile main.go makefile routes.go templates/html/version.html type_webserver.go 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}" pushd "${repo_name}" TEMPLATE_REMOTE_NAME="template" git remote add "${TEMPLATE_REMOTE_NAME}" "${TEMPLATE_REPO_DIR}" git fetch "${TEMPLATE_REMOTE_NAME}" "${TEMPLATE_BRANCH}" current_branch=$(git rev-parse --abbrev-ref HEAD) if [ -n "${FILES_TO_UPDATE}" ]; then files_changed=false conflicted_files=() merge_base=$(git merge-base HEAD "${TEMPLATE_REMOTE_NAME}/${TEMPLATE_BRANCH}" 2>/dev/null || true) for file in ${FILES_TO_UPDATE}; do if ! git show "${TEMPLATE_REMOTE_NAME}/${TEMPLATE_BRANCH}:${file}" >/dev/null 2>&1; then continue fi if [ -f "${file}" ] && [ -n "${merge_base}" ] && git show "${merge_base}:${file}" >/dev/null 2>&1; then tmp_base=$(mktemp) tmp_template=$(mktemp) tmp_current=$(mktemp) git show "${merge_base}:${file}" > "${tmp_base}" 2>/dev/null git show "${TEMPLATE_REMOTE_NAME}/${TEMPLATE_BRANCH}:${file}" > "${tmp_template}" 2>/dev/null cp "${file}" "${tmp_current}" if git merge-file "${file}" "${tmp_base}" "${tmp_template}" 2>/dev/null; then git add "${file}" files_changed=true else echo "Conflict detected in ${repo_name}:${file}" conflicted_files+=("${file}") cp "${tmp_current}" "${file}" git checkout HEAD -- "${file}" >/dev/null 2>&1 || true fi rm -f "${tmp_base}" "${tmp_template}" "${tmp_current}" else if git checkout "${TEMPLATE_REMOTE_NAME}/${TEMPLATE_BRANCH}" -- "${file}" 2>/dev/null; then files_changed=true fi 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 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 rm -rf "${repo_name}" continue fi fi popd 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!"