aeb574980b
Sync Wikis to GitHub / Export wikis to GitHub (push) Successful in 8s
No more hardcoded repo list — queries Gitea API for all orgs and repos that have wikis enabled. Falls back to hardcoded list if no GITEA_TOKEN is set. Authored-by: Moko Consulting
168 lines
5.1 KiB
Bash
168 lines
5.1 KiB
Bash
#!/usr/bin/env bash
|
|
# sync-wikis-to-github.sh — Export all Gitea wikis to a consolidated GitHub repo
|
|
#
|
|
# Clones each Gitea wiki, copies pages into project-named subdirectories,
|
|
# and pushes to mokoconsulting-tech/wiki on GitHub.
|
|
#
|
|
# Structure:
|
|
# wiki/
|
|
# README.md
|
|
# moko-platform/
|
|
# Home.md
|
|
# SITE_MONITORING.md
|
|
# ...
|
|
# MokoOnyx/
|
|
# Home.md
|
|
# ...
|
|
#
|
|
# Usage:
|
|
# sync-wikis-to-github.sh # sync all
|
|
# sync-wikis-to-github.sh MokoOnyx # sync one project
|
|
#
|
|
set -euo pipefail
|
|
|
|
GITEA_URL="${GITEA_URL:-https://git.mokoconsulting.tech}"
|
|
GITHUB_ORG="${GITHUB_ORG:-mokoconsulting-tech}"
|
|
GITHUB_WIKI_REPO="${GITHUB_WIKI_REPO:-wiki}"
|
|
GH_TOKEN="${GH_TOKEN:-$(cat ~/.github-token 2>/dev/null || echo "")}"
|
|
TMPDIR="$(mktemp -d)"
|
|
trap 'rm -rf "$TMPDIR"' EXIT
|
|
|
|
log() { echo "[$(date '+%H:%M:%S')] $*"; }
|
|
|
|
if [[ -z "$GH_TOKEN" ]]; then
|
|
log "ERROR: GH_TOKEN not set"
|
|
exit 1
|
|
fi
|
|
|
|
# Auto-discover repos with wikis from Gitea API
|
|
GITEA_TOKEN="${GITEA_TOKEN:-$(cat ~/.gitea-token 2>/dev/null || echo "")}"
|
|
declare -A REPOS=()
|
|
|
|
if [[ -n "$GITEA_TOKEN" ]]; then
|
|
log "Auto-discovering repos with wikis..."
|
|
for ORG in MokoConsulting ClarksvilleFurs; do
|
|
PAGE=1
|
|
while true; do
|
|
RESPONSE=$(curl -sf -H "Authorization: token ${GITEA_TOKEN}" \
|
|
"${GITEA_URL}/api/v1/orgs/${ORG}/repos?page=${PAGE}&limit=50" 2>/dev/null)
|
|
[[ -z "$RESPONSE" || "$RESPONSE" == "[]" ]] && break
|
|
|
|
REPO_LIST=$(echo "$RESPONSE" | python3 -c "
|
|
import sys, json
|
|
repos = json.load(sys.stdin)
|
|
for r in repos:
|
|
if r.get('has_wiki') and not r.get('archived'):
|
|
name = r['name']
|
|
owner = r['owner']['login']
|
|
print(f'{owner}/{name}|{name}')
|
|
" 2>/dev/null)
|
|
|
|
while IFS='|' read -r full_name display; do
|
|
[[ -n "$full_name" ]] && REPOS["$full_name"]="$display"
|
|
done <<< "$REPO_LIST"
|
|
|
|
PAGE=$((PAGE + 1))
|
|
[[ $(echo "$RESPONSE" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null) -lt 50 ]] && break
|
|
done
|
|
done
|
|
log "Found ${#REPOS[@]} repos with wikis"
|
|
else
|
|
# Fallback to hardcoded list
|
|
REPOS=(
|
|
["MokoConsulting/moko-platform"]="moko-platform"
|
|
["MokoConsulting/MokoOnyx"]="MokoOnyx"
|
|
["MokoConsulting/MokoWaaS"]="MokoWaaS"
|
|
["MokoConsulting/monitor-mcp"]="monitor-mcp"
|
|
["MokoConsulting/deploy-mcp"]="deploy-mcp"
|
|
["MokoConsulting/ssh-mcp"]="ssh-mcp"
|
|
["MokoConsulting/backup-mcp"]="backup-mcp"
|
|
["MokoConsulting/joomla-api-mcp"]="joomla-api-mcp"
|
|
["MokoConsulting/Template-Client-WaaS"]="Template-Client-WaaS"
|
|
["ClarksvilleFurs/client-waas-clarksvillefurs"]="client-clarksvillefurs"
|
|
)
|
|
fi
|
|
|
|
FILTER="${1:-}"
|
|
|
|
# Clone the GitHub wiki repo
|
|
log "Cloning ${GITHUB_ORG}/${GITHUB_WIKI_REPO}..."
|
|
WIKI_DIR="${TMPDIR}/wiki"
|
|
git clone --quiet "https://${GH_TOKEN}@github.com/${GITHUB_ORG}/${GITHUB_WIKI_REPO}.git" "$WIKI_DIR" 2>/dev/null || {
|
|
mkdir -p "$WIKI_DIR"
|
|
cd "$WIKI_DIR"
|
|
git init -b main --quiet
|
|
git remote add origin "https://${GH_TOKEN}@github.com/${GITHUB_ORG}/${GITHUB_WIKI_REPO}.git"
|
|
}
|
|
|
|
cd "$WIKI_DIR"
|
|
git config user.email "gitea-actions[bot]@mokoconsulting.tech"
|
|
git config user.name "gitea-actions[bot]"
|
|
|
|
SYNCED=0
|
|
|
|
for GITEA_REPO in "${!REPOS[@]}"; do
|
|
PROJECT="${REPOS[$GITEA_REPO]}"
|
|
|
|
if [[ -n "$FILTER" && "$PROJECT" != "$FILTER" && "$GITEA_REPO" != *"$FILTER"* ]]; then
|
|
continue
|
|
fi
|
|
|
|
log "Exporting wiki: ${GITEA_REPO} → ${PROJECT}/"
|
|
|
|
# Clone Gitea wiki
|
|
WIKI_CLONE="${TMPDIR}/${PROJECT}.wiki"
|
|
if ! git clone --quiet "${GITEA_URL}/${GITEA_REPO}.wiki.git" "$WIKI_CLONE" 2>/dev/null; then
|
|
log " SKIP: no wiki"
|
|
continue
|
|
fi
|
|
|
|
# Copy wiki pages to project subdirectory
|
|
mkdir -p "${WIKI_DIR}/${PROJECT}"
|
|
rm -rf "${WIKI_DIR}/${PROJECT}"/*
|
|
|
|
# Copy all .md files, flatten any subdirectories
|
|
find "$WIKI_CLONE" -name "*.md" -not -path "*/.git/*" | while read -r f; do
|
|
cp "$f" "${WIKI_DIR}/${PROJECT}/"
|
|
done
|
|
|
|
PAGE_COUNT=$(find "${WIKI_DIR}/${PROJECT}" -name "*.md" | wc -l)
|
|
log " ${PAGE_COUNT} pages"
|
|
SYNCED=$((SYNCED + 1))
|
|
|
|
rm -rf "$WIKI_CLONE"
|
|
done
|
|
|
|
# Generate README index
|
|
cat > "${WIKI_DIR}/README.md" << 'HEADER'
|
|
# Moko Consulting — Wiki Archive
|
|
|
|
Consolidated backup of all project wikis from [Gitea](https://git.mokoconsulting.tech).
|
|
|
|
> **Source of truth:** Gitea wikis. This repo is a read-only mirror.
|
|
|
|
## Projects
|
|
|
|
HEADER
|
|
|
|
for PROJECT in $(ls -d */ 2>/dev/null | sed 's|/||' | sort); do
|
|
COUNT=$(find "${PROJECT}" -name "*.md" | wc -l)
|
|
echo "- [**${PROJECT}**](${PROJECT}/) — ${COUNT} pages" >> "${WIKI_DIR}/README.md"
|
|
done
|
|
|
|
echo "" >> "${WIKI_DIR}/README.md"
|
|
echo "---" >> "${WIKI_DIR}/README.md"
|
|
echo "*Last synced: $(date -u '+%Y-%m-%d %H:%M UTC')*" >> "${WIKI_DIR}/README.md"
|
|
|
|
# Commit and push
|
|
git add -A
|
|
if ! git diff --cached --quiet 2>/dev/null; then
|
|
git commit --quiet -m "docs: sync wikis from Gitea ($(date -u '+%Y-%m-%d %H:%M UTC'))"
|
|
git push --force origin HEAD:main 2>&1 | tail -3
|
|
log "Pushed to ${GITHUB_ORG}/${GITHUB_WIKI_REPO}"
|
|
else
|
|
log "No changes to push"
|
|
fi
|
|
|
|
log "Done. Synced ${SYNCED} project wikis."
|