feat: Add automated repository statistics tracking

- Created GitHub Action to update stats daily at 2 AM UTC
- Added dynamic badges to README for stars, forks, downloads, version
- Added placeholder section for detailed statistics
- Workflow also supports manual trigger via workflow_dispatch
This commit is contained in:
Aaron Bockelie 2025-09-24 23:17:15 -05:00
parent e4d8a19eba
commit 37a640c8fa
2 changed files with 148 additions and 0 deletions

138
.github/workflows/update-stats.yml vendored Normal file
View file

@ -0,0 +1,138 @@
name: Update Repository Stats
on:
schedule:
# Run daily at 2 AM UTC
- cron: '0 2 * * *'
workflow_dispatch: # Allow manual trigger
jobs:
update-stats:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Fetch repository statistics
id: stats
run: |
# Get basic repo stats
REPO_DATA=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}")
STARS=$(echo "$REPO_DATA" | jq '.stargazers_count')
FORKS=$(echo "$REPO_DATA" | jq '.forks_count')
WATCHERS=$(echo "$REPO_DATA" | jq '.watchers_count')
# Get release download stats
RELEASES_DATA=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/releases")
TOTAL_DOWNLOADS=$(echo "$RELEASES_DATA" | jq '[.[] | .assets[].download_count] | add')
LATEST_VERSION=$(echo "$RELEASES_DATA" | jq -r '.[0].tag_name')
LATEST_DOWNLOADS=$(echo "$RELEASES_DATA" | jq '.[0].assets | map(.download_count) | add')
# Get traffic data (if available)
VIEWS_DATA=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/traffic/views" || echo '{"count":0,"uniques":0}')
VIEWS=$(echo "$VIEWS_DATA" | jq '.count // 0')
UNIQUE_VISITORS=$(echo "$VIEWS_DATA" | jq '.uniques // 0')
# Get clone data (if available)
CLONES_DATA=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/traffic/clones" || echo '{"count":0,"uniques":0}')
CLONES=$(echo "$CLONES_DATA" | jq '.count // 0')
UNIQUE_CLONERS=$(echo "$CLONES_DATA" | jq '.uniques // 0')
# Output variables for next step
echo "stars=$STARS" >> $GITHUB_OUTPUT
echo "forks=$FORKS" >> $GITHUB_OUTPUT
echo "watchers=$WATCHERS" >> $GITHUB_OUTPUT
echo "total_downloads=$TOTAL_DOWNLOADS" >> $GITHUB_OUTPUT
echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT
echo "latest_downloads=$LATEST_DOWNLOADS" >> $GITHUB_OUTPUT
echo "views=$VIEWS" >> $GITHUB_OUTPUT
echo "unique_visitors=$UNIQUE_VISITORS" >> $GITHUB_OUTPUT
echo "clones=$CLONES" >> $GITHUB_OUTPUT
echo "unique_cloners=$UNIQUE_CLONERS" >> $GITHUB_OUTPUT
echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
- name: Update README with statistics
run: |
# Create the stats section content
cat > stats.md << 'EOF'
## 📊 Repository Statistics
<!-- STATS:START -->
<!-- Last updated: ${{ steps.stats.outputs.date }} -->
### 🌟 Community Engagement
| Metric | Count |
|--------|-------|
| ⭐ Stars | ${{ steps.stats.outputs.stars }} |
| 🍴 Forks | ${{ steps.stats.outputs.forks }} |
| 👀 Watchers | ${{ steps.stats.outputs.watchers }} |
| 👁️ Views (14 days) | ${{ steps.stats.outputs.views }} (${{ steps.stats.outputs.unique_visitors }} unique) |
| 📥 Clones (14 days) | ${{ steps.stats.outputs.clones }} (${{ steps.stats.outputs.unique_cloners }} unique) |
### 📦 Release Downloads
| Version | Downloads |
|---------|-----------|
| **Total All Versions** | **${{ steps.stats.outputs.total_downloads }}** |
| Latest (${{ steps.stats.outputs.latest_version }}) | ${{ steps.stats.outputs.latest_downloads }} |
<!-- STATS:END -->
EOF
# Check if README has stats section
if grep -q "<!-- STATS:START -->" README.md; then
# Update existing stats section
awk '
/<!-- STATS:START -->/ {print; system("cat stats.md | sed \"1,/<!-- STATS:START -->/d\" | sed \"/<!-- STATS:END -->/,\\$d\""); f=1}
/<!-- STATS:END -->/ {if(f) {print; f=0} else print}
!f {print}
' README.md > README.tmp && mv README.tmp README.md
else
# Add stats section before the first ## heading or at the end
awk '
!added && /^## / {
system("cat stats.md")
print ""
added=1
}
{print}
END {
if (!added) {
print ""
system("cat stats.md")
}
}
' README.md > README.tmp && mv README.tmp README.md
fi
rm stats.md
- name: Check for changes
id: check_changes
run: |
if git diff --quiet README.md; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT
fi
- name: Commit and push changes
if: steps.check_changes.outputs.changed == 'true'
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add README.md
git commit -m "chore: Update repository statistics [skip ci]"
git push

View file

@ -1,5 +1,11 @@
# Obsidian MCP Plugin
![GitHub stars](https://img.shields.io/github/stars/aaronsb/obsidian-mcp-plugin?style=social)
![GitHub forks](https://img.shields.io/github/forks/aaronsb/obsidian-mcp-plugin?style=social)
![Downloads](https://img.shields.io/github/downloads/aaronsb/obsidian-mcp-plugin/total?color=blue)
![Latest Release](https://img.shields.io/github/v/release/aaronsb/obsidian-mcp-plugin?include_prereleases&label=version)
![License](https://img.shields.io/github/license/aaronsb/obsidian-mcp-plugin)
**Give AI semantic agency over your knowledge graph**
This plugin connects your Obsidian vault to AI assistants through MCP (Model Context Protocol), giving them the ability to understand and navigate your notes as a connected knowledge graph, not just isolated files. Through semantic hints and graph traversal, AI gains the agency to explore concepts, follow connections, and synthesize information across your entire vault.
@ -9,6 +15,10 @@ This plugin connects your Obsidian vault to AI assistants through MCP (Model Con
- Claude Code/Continue.dev (VS Code)
- Any platform that supports local MCP servers
<!-- STATS:START -->
<!-- Repository statistics will be automatically updated here daily -->
<!-- STATS:END -->
## Why Semantic MCP?
Traditional file access gives AI a narrow view - one document at a time. This plugin transforms that into **semantic agency**: