Update Stats Monitor #173
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Update Stats Monitor | |
| on: | |
| schedule: | |
| - cron: '17 5 * * *' | |
| timezone: America/New_York | |
| - cron: '47 6 * * *' | |
| timezone: America/New_York | |
| workflow_dispatch: # Allow manual trigger | |
| jobs: | |
| update-stats: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| - name: Fetch and Update Stats | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| run: | | |
| STATS_FILE=".github/stats/clone-history.json" | |
| # 1. Load existing stats or initialize | |
| if [ -f "$STATS_FILE" ]; then | |
| BASELINE_UNIQUES=$(jq -r '.baselineUniques // 0' "$STATS_FILE") | |
| BASELINE_CLONES=$(jq -r '.baselineClones // 0' "$STATS_FILE") | |
| DAILY_UNIQUES=$(jq -c '.dailyCounts // {}' "$STATS_FILE") | |
| DAILY_CLONES=$(jq -c '.dailyClones // {}' "$STATS_FILE") | |
| else | |
| BASELINE_UNIQUES=0 | |
| # GitHub traffic history started on 2026-04-11 in this file, so seed | |
| # the missing 2026-04-09 and 2026-04-10 clone totals here. | |
| BASELINE_CLONES=780 | |
| DAILY_UNIQUES="{}" | |
| DAILY_CLONES="{}" | |
| mkdir -p .github/stats | |
| fi | |
| # 2. Fetch traffic data from GitHub API | |
| if ! TRAFFIC_DATA=$(gh api repos/fiorastudio/buddy/traffic/clones 2>/tmp/api_error); then | |
| echo "Warning: Error fetching traffic data (likely permissions): $(cat /tmp/api_error)" | |
| TRAFFIC_DATA='{"clones":[]}' | |
| fi | |
| # 3. Merge new data into daily maps using jq | |
| NEW_DAILY_UNIQUES=$(echo "$TRAFFIC_DATA" | jq -c --argjson existing "$DAILY_UNIQUES" ' | |
| .clones | reduce .[] as $item ($existing; | |
| .[$item.timestamp[0:10]] = $item.uniques | |
| ) | |
| ') | |
| NEW_DAILY_CLONES=$(echo "$TRAFFIC_DATA" | jq -c --argjson existing "$DAILY_CLONES" ' | |
| .clones | reduce .[] as $item ($existing; | |
| .[$item.timestamp[0:10]] = $item.count | |
| ) | |
| ') | |
| # 4. Recalculate totals (Baseline + Sum of Daily) | |
| UNIQUES_SUM=$(echo "$NEW_DAILY_UNIQUES" | jq '[.[]] | add // 0') | |
| CLONES_SUM=$(echo "$NEW_DAILY_CLONES" | jq '[.[]] | add // 0') | |
| NEW_TOTAL_UNIQUES=$((BASELINE_UNIQUES + UNIQUES_SUM)) | |
| NEW_TOTAL_CLONES=$((BASELINE_CLONES + CLONES_SUM)) | |
| # 5. Update the JSON file | |
| TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") | |
| jq -n \ | |
| --arg baselineUniques "$BASELINE_UNIQUES" \ | |
| --arg baselineClones "$BASELINE_CLONES" \ | |
| --arg totalUniques "$NEW_TOTAL_UNIQUES" \ | |
| --arg totalClones "$NEW_TOTAL_CLONES" \ | |
| --arg time "$TIMESTAMP" \ | |
| --argjson dailyCounts "$NEW_DAILY_UNIQUES" \ | |
| --argjson dailyClones "$NEW_DAILY_CLONES" \ | |
| '{ | |
| baselineUniques: ($baselineUniques | tonumber), | |
| baselineClones: ($baselineClones | tonumber), | |
| totalUniques: ($totalUniques | tonumber), | |
| totalClones: ($totalClones | tonumber), | |
| lastUpdated: $time, | |
| dailyCounts: $dailyCounts, | |
| dailyClones: $dailyClones | |
| }' > "$STATS_FILE" | |
| echo "Updated totalClones: $NEW_TOTAL_CLONES, totalUniques: $NEW_TOTAL_UNIQUES" | |
| # 6. Update README.md with both numbers | |
| FORMATTED_CLONES=$(printf "%'d" $NEW_TOTAL_CLONES) | |
| FORMATTED_UNIQUES=$(printf "%'d" $NEW_TOTAL_UNIQUES) | |
| CLONES_TEXT="${FORMATTED_CLONES}+" | |
| RESCUED_TEXT="${FORMATTED_UNIQUES}+" | |
| # Calculate weeks alive since April 10, 2026 | |
| LAUNCH_EPOCH=$(date -d "2026-04-10" +%s) | |
| TODAY_EPOCH=$(date -d today +%s) | |
| DAYS_ALIVE=$(( (TODAY_EPOCH - LAUNCH_EPOCH) / 86400 )) | |
| WEEKS_ALIVE=$((DAYS_ALIVE / 7)) | |
| WEEKS_TEXT="~${WEEKS_ALIVE} weeks" | |
| # Update clones count | |
| sed -i "s/\*\*🚀 [0-9,]*+ clones · [0-9,]*+ buddies rescued or hatched · [0-9]* weeks in the wild\*\*/\*\*🚀 ${CLONES_TEXT} clones · ${RESCUED_TEXT} buddies rescued or hatched · ${WEEKS_ALIVE} weeks in the wild\*\*/" README.md | |
| # Update buddies rescued/hatched count | |
| sed -i "s/\*\*🐾 [0-9,]*+ Buddies Rescued & Hatched · Our terminal companions are finally coming home\.\*\*/\*\*🐾 ${RESCUED_TEXT} Buddies Rescued \& Hatched · Our terminal companions are finally coming home.\*\*/" README.md | |
| sed -i "s|!\[Buddies Rescued\](https://img.shields.io/badge/buddies_rescued-[0-9,]*+-green?style=flat-square&logo=gitlfs)|!\[Buddies Rescued\](https://img.shields.io/badge/buddies_rescued-${RESCUED_TEXT}-green?style=flat-square\&logo=gitlfs)|" README.md | |
| sed -i "s/[0-9,]*+ buddies rescued or hatched/${RESCUED_TEXT} buddies rescued or hatched/" README.md | |
| sed -i "s/~[0-9]* weeks\? in the wild/${WEEKS_TEXT} in the wild/" README.md | |
| EXPECTED_HEADLINE="**🚀 ${CLONES_TEXT} clones · ${RESCUED_TEXT} buddies rescued or hatched · ${WEEKS_ALIVE} weeks in the wild**" | |
| if ! grep -Fq "$EXPECTED_HEADLINE" README.md; then | |
| echo "README headline did not update to the expected stats line." | |
| echo "Expected: $EXPECTED_HEADLINE" | |
| exit 1 | |
| fi | |
| # 7. Commit and push directly to master | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| git add README.md "$STATS_FILE" | |
| if ! git diff --cached --quiet; then | |
| git commit -m "chore: update stats — ${CLONES_TEXT} clones, ${RESCUED_TEXT} rescued, ${WEEKS_TEXT} in the wild [skip ci]" | |
| git push origin master | |
| else | |
| echo "No changes to commit." | |
| fi |