| 1 | name: Wiki monitor |
| 2 | |
| 3 | on: |
| 4 | schedule: |
| 5 | - cron: '0 */4 * * *' |
| 6 | workflow_dispatch: |
| 7 | |
| 8 | permissions: |
| 9 | contents: read |
| 10 | |
| 11 | jobs: |
| 12 | check: |
| 13 | runs-on: ubuntu-latest |
| 14 | steps: |
| 15 | - name: Restore last seen commit |
| 16 | id: cache-restore |
| 17 | uses: actions/cache/restore@v4 |
| 18 | with: |
| 19 | path: .wiki-monitor |
| 20 | key: wiki-monitor-${{ github.run_id }} |
| 21 | restore-keys: | |
| 22 | wiki-monitor- |
| 23 | |
| 24 | - name: Get latest wiki commit |
| 25 | id: wiki |
| 26 | shell: bash |
| 27 | run: | |
| 28 | set -euo pipefail |
| 29 | repo='${{ github.repository }}' |
| 30 | url="https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${repo}.wiki.git" |
| 31 | if ! sha=$(git ls-remote "$url" HEAD | awk '{print $1}'); then |
| 32 | echo 'exists=false' >> "$GITHUB_OUTPUT" |
| 33 | echo 'Wiki repo not found or inaccessible.' |
| 34 | exit 0 |
| 35 | fi |
| 36 | if [ -z "$sha" ]; then |
| 37 | echo 'exists=false' >> "$GITHUB_OUTPUT" |
| 38 | echo 'Wiki repo not found or empty.' |
| 39 | exit 0 |
| 40 | fi |
| 41 | echo 'exists=true' >> "$GITHUB_OUTPUT" |
| 42 | echo "sha=$sha" >> "$GITHUB_OUTPUT" |
| 43 | |
| 44 | - name: Send Telegram alert |
| 45 | if: steps.wiki.outputs.exists == 'true' |
| 46 | env: |
| 47 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 48 | TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} |
| 49 | TELEGRAM_CHAT_ID: '128365884' |
| 50 | REPO: ${{ github.repository }} |
| 51 | SKIP_EMAILS: 'a@rejetto.com' |
| 52 | run: | |
| 53 | set -euo pipefail |
| 54 | if [ -z "$TELEGRAM_BOT_TOKEN" ]; then |
| 55 | echo 'Missing TELEGRAM_BOT_TOKEN; skipping Telegram alert.' |
| 56 | exit 0 |
| 57 | fi |
| 58 | url="https://x-access-token:${GITHUB_TOKEN}@github.com/${REPO}.wiki.git" |
| 59 | mkdir -p .wiki-monitor |
| 60 | if [ ! -d .wiki-monitor/wiki ]; then |
| 61 | git clone --quiet --depth=50 "$url" .wiki-monitor/wiki |
| 62 | fi |
| 63 | cd .wiki-monitor/wiki |
| 64 | git fetch --quiet origin HEAD |
| 65 | git -c advice.detachedHead=false checkout --quiet FETCH_HEAD |
| 66 | latest_sha=$(git rev-parse HEAD) |
| 67 | last_seen_file=../last_seen |
| 68 | last_seen='' |
| 69 | if [ -f "$last_seen_file" ]; then |
| 70 | last_seen=$(cat "$last_seen_file") |
| 71 | fi |
| 72 | if [ -n "$last_seen" ] && ! git cat-file -e "$last_seen^{commit}" 2>/dev/null; then |
| 73 | git fetch --quiet --unshallow || true |
| 74 | fi |
| 75 | if [ -n "$last_seen" ] && ! git cat-file -e "$last_seen^{commit}" 2>/dev/null; then |
| 76 | echo "Last seen commit missing; resetting baseline to ${latest_sha}." |
| 77 | echo "$latest_sha" > "$last_seen_file" |
| 78 | exit 0 |
| 79 | fi |
| 80 | range='' |
| 81 | if [ -n "$last_seen" ]; then |
| 82 | range="${last_seen}..HEAD" |
| 83 | fi |
| 84 | commits=$(git log --format='%H|%an|%ae' ${range:+$range}) |
| 85 | if [ -z "$last_seen" ]; then |
| 86 | echo "$latest_sha" > "$last_seen_file" |
| 87 | echo 'Initialized last seen commit; skipping notification.' |
| 88 | exit 0 |
| 89 | fi |
| 90 | echo "Last seen: ${last_seen:-<none>}" |
| 91 | echo "Latest: ${latest_sha}" |
| 92 | notify='' |
| 93 | if [ -n "$commits" ]; then |
| 94 | echo 'Commits since last seen:' |
| 95 | echo "$commits" |
| 96 | while IFS='|' read -r sha author_name author_email; do |
| 97 | if [ -z "$sha" ]; then |
| 98 | continue |
| 99 | fi |
| 100 | if [ -n "$SKIP_EMAILS" ]; then |
| 101 | IFS=',' read -r -a skip_emails <<< "$SKIP_EMAILS" |
| 102 | for email in "${skip_emails[@]}"; do |
| 103 | if [ "${author_email}" = "${email}" ]; then |
| 104 | sha='' |
| 105 | break |
| 106 | fi |
| 107 | done |
| 108 | if [ -z "$sha" ]; then |
| 109 | continue |
| 110 | fi |
| 111 | fi |
| 112 | short_sha=$(echo "$sha" | cut -c1-7) |
| 113 | files=$(git diff-tree --no-commit-id --name-only -r "$sha" | tr '\n' ',' | sed 's/,$//') |
| 114 | if [ -z "$files" ]; then |
| 115 | files='(no file list)' |
| 116 | fi |
| 117 | notify="${notify}- ${short_sha} by ${author_name} files: ${files}\n" |
| 118 | done <<< "$commits" |
| 119 | fi |
| 120 | echo "$latest_sha" > "$last_seen_file" |
| 121 | if [ -z "$notify" ]; then |
| 122 | exit 0 |
| 123 | fi |
| 124 | message="Wiki updated by others:\n${notify}" |
| 125 | response=$(printf '%b' "$message" | \ |
| 126 | curl -sS -w '\nHTTP_STATUS=%{http_code}\n' -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ |
| 127 | -d "chat_id=${TELEGRAM_CHAT_ID}" \ |
| 128 | --data-urlencode "text@-" \ |
| 129 | -d "disable_web_page_preview=true") |
| 130 | echo "Telegram response:" |
| 131 | echo "$response" |
| 132 | |
| 133 | - name: Save last seen commit |
| 134 | if: steps.wiki.outputs.exists == 'true' |
| 135 | uses: actions/cache/save@v4 |
| 136 | with: |
| 137 | path: .wiki-monitor |
| 138 | key: wiki-monitor-${{ github.run_id }} |