Files
ruvnet__ruflo/.github/workflows/clone-tracker.yml
ruv 1cd98afaa1 feat(data): clone tracker with 13-day cron + RVF + proof, bump downloads badge to 22.2M+
GitHub only retains 14 days of clone-traffic data, and there's no
third-party archive of historic clones. So we ship our own tracker:

- `scripts/track-clones.mjs` — fetches clones for 5 ruflo-ecosystem
  repos (ruflo, agentdb, agentic-flow, ruvector, ruv-FANN) and npm
  downloads for headline packages. Produces three artifacts:
  - `data/clone-data.rvf` — RuVector vector store (RvfDatabase,
    10-dim per snapshot for similarity search across time)
  - `data/clone-data.ledger.json` — append-only chronology with
    per-repo breakdown (human-readable in PR diffs)
  - `data/clone-data.proof.json` — provenance manifest with
    SHA-256 over the ledger
- `.github/workflows/clone-tracker.yml` — runs every 13 days at
  06:17 UTC + on workflow_dispatch + on edits to the tracker.
  Commits the new snapshot back to main as `ruflo-bot`.

README badges now show:
- `ecosystem downloads 22.2M+` (sum across claude-flow + ruflo +
  @claude-flow/* + agentdb + agentic-flow + ruvector/* — 152 npm
  packages, last 12 months: 22,275,946 as of 2026-05-19)
- `git clones 14d 115k` (linked to the live ledger)

Initial snapshot captured at run time. Sources/formula documented
in `data/clone-data.proof.json` so any reader can verify the
claim by re-running the script.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-05-19 19:18:39 -04:00

85 lines
3.0 KiB
YAML

name: Clone Tracker (14-day rolling)
# GitHub's clone API only retains 14 days. We run every 13 days so we always
# catch the full window with a 24h safety margin. The job appends a snapshot
# to `data/clone-data.rvf` (RuVector vector store) + `data/clone-data.ledger.json`
# (chronological JSON), regenerates `data/clone-data.proof.json` with a fresh
# SHA-256 over the ledger, and commits the result back to main.
#
# Schedule: every 13 days at 06:17 UTC (off-peak; avoids the :00 mark to
# spread cron load).
#
# Why we own this rather than rely on a third-party traffic-tracker: GitHub's
# clone API requires push access, so we'd have to give a stranger our token.
# Running it ourselves keeps the data path inside the repo and signed.
on:
schedule:
- cron: '17 6 */13 * *'
workflow_dispatch:
# Allow manual runs (e.g., after a release announcement to capture the spike).
push:
branches: [main]
paths:
- 'scripts/track-clones.mjs'
- '.github/workflows/clone-tracker.yml'
permissions:
contents: write # to push the snapshot commit
actions: read
concurrency:
group: clone-tracker
cancel-in-progress: false
jobs:
track:
name: Snapshot clones for ruflo ecosystem
runs-on: ubuntu-latest
steps:
- name: Checkout main
uses: actions/checkout@v4
with:
ref: main
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install root deps (for @ruvector/rvf binding)
run: npm install --legacy-peer-deps --no-audit --no-fund --ignore-scripts
- name: Run clone tracker
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node scripts/track-clones.mjs
- name: Show resulting artifacts
run: |
ls -la data/clone-data.* 2>/dev/null || echo "(no artifacts produced)"
echo ""
echo "--- proof ---"
cat data/clone-data.proof.json
- name: Commit + push snapshot
run: |
git config user.name "ruflo-bot"
git config user.email "ruflo-bot@users.noreply.github.com"
git add data/clone-data.rvf data/clone-data.ledger.json data/clone-data.proof.json
if git diff --cached --quiet; then
echo "No changes to commit (snapshot identical to previous?)"
exit 0
fi
SNAP_COUNT=$(node -e "console.log(JSON.parse(require('fs').readFileSync('data/clone-data.proof.json','utf8')).ledger_snapshot_count)")
CLONES=$(node -e "console.log(JSON.parse(require('fs').readFileSync('data/clone-data.proof.json','utf8')).latest_snapshot.clones_14d.toLocaleString())")
git commit -m "chore(data): clone snapshot #${SNAP_COUNT} — ${CLONES} clones (14d)
Auto-generated by .github/workflows/clone-tracker.yml.
Source: GitHub Traffic API (14-day rolling window).
Co-Authored-By: ruflo-bot <ruflo-bot@users.noreply.github.com>"
git push origin main