Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 54 additions & 7 deletions .github/workflows/clone-stats.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,45 @@ jobs:
- name: Switch to stats branch
run: git checkout -B stats

- name: Restore existing stats history
run: |
if git show origin/stats:stats/clone_history.json >/tmp/clone_history.json 2>/dev/null; then
mkdir -p stats
cp /tmp/clone_history.json stats/clone_history.json
fi

- name: Fetch clone stats from GitHub API
run: |
TOKEN="${TRAFFIC_TOKEN:-${{ github.token }}}"
curl -fsSL \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/traffic/clones" \
-o traffic.json
API_URL="https://api.github.com/repos/${{ github.repository }}/traffic/clones"

fetch_traffic() {
local token="$1"
local code
code=$(curl -sS -L \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/vnd.github+json" \
-o traffic.json \
-w "%{http_code}" \
"${API_URL}")
echo "${code}"
}

if [ -n "${TRAFFIC_TOKEN}" ]; then
STATUS=$(fetch_traffic "${TRAFFIC_TOKEN}")

if [ "${STATUS}" = "401" ] || [ "${STATUS}" = "403" ]; then
echo "TRAFFIC_TOKEN was rejected (${STATUS}); retrying with github.token fallback."
STATUS=$(fetch_traffic "${{ github.token }}")
fi
else
STATUS=$(fetch_traffic "${{ github.token }}")
fi

if [ "${STATUS}" -lt 200 ] || [ "${STATUS}" -ge 300 ]; then
echo "Failed to fetch clone traffic (HTTP ${STATUS}). Response:"
cat traffic.json
exit 1
fi

# Fail early with a clear message if GitHub API did not return usable traffic data.
if [ "$(jq -r 'has("count") and has("uniques")' traffic.json)" != "true" ]; then
Expand All @@ -44,13 +75,29 @@ jobs:
run: |
COUNT=$(jq '.count' traffic.json)
UNIQUES=$(jq '.uniques' traffic.json)

if [ -f stats/clone_history.json ]; then
jq -s '
(.[0] + .[1])
| sort_by(.timestamp)
| group_by(.timestamp)
| map(max_by(.count))
' stats/clone_history.json <(jq '.clones' traffic.json) > stats/clone_history_merged.json
else
jq '.clones' traffic.json > stats/clone_history_merged.json
fi

mv stats/clone_history_merged.json stats/clone_history.json
TOTAL_COUNT=$(jq '[.[].count] | add // 0' stats/clone_history.json)

mkdir -p stats
echo "{ \"count\": $COUNT, \"uniques\": $UNIQUES }" > stats/clones.json
echo "{ \"count\": $COUNT, \"uniques\": $UNIQUES, \"total_count\": $TOTAL_COUNT }" > stats/clones.json

- name: Commit and push to stats branch
run: |
git config --global user.name "github-actions"
git config --global user.email "actions@github.com"
git add stats/clone_history.json
git add stats/clones.json
git commit -m "Update clone stats" || exit 0
git push origin stats --force
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<p><b>Centralize. Unify. Govern.</b></p>

![Clones (14d total)](https://img.shields.io/badge/dynamic/json?color=blue&label=Clones%20(14d%20total)&query=count&url=https://raw.githubusercontent.com/Sendipad/uph/stats/clones.json)
![Clones (all-time)](https://img.shields.io/badge/dynamic/json?color=blue&label=Clones%20(all-time)&query=total_count&url=https://raw.githubusercontent.com/Sendipad/uph/stats/clones.json)
![Unique cloners (14d)](https://img.shields.io/badge/dynamic/json?color=informational&label=Unique%20cloners%20(14d)&query=uniques&url=https://raw.githubusercontent.com/Sendipad/uph/stats/clones.json)
[![CI develop](https://img.shields.io/github/actions/workflow/status/Sendipad/uph/ci.yml?branch=develop&job=test_v17&label=CI%20develop)](https://github.com/Sendipad/uph/actions/workflows/ci.yml)
[![CI v16](https://img.shields.io/github/actions/workflow/status/Sendipad/uph/ci.yml?branch=develop&job=test_v16&label=CI%20v16)](https://github.com/Sendipad/uph/actions/workflows/ci.yml)
Expand Down
3 changes: 2 additions & 1 deletion stats/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ This folder is used by the clone-stats GitHub Action.
If you do not see recent data, trigger the **Update Clone Stats** workflow manually and wait for cache refresh.

- If clone totals stay empty, add a `TRAFFIC_TOKEN` repository secret (classic PAT with `repo` scope) so the workflow can access the traffic API reliably.
- `stats/clones.json` now stores both `count` (total clones in last 14 days) and `uniques` (unique cloners in last 14 days).
- `stats/clones.json` stores `count` (total clones in last 14 days), `uniques` (unique cloners in last 14 days), and `total_count` (cumulative clones tracked over time).
- `stats/clone_history.json` stores daily clone snapshots so cumulative totals survive the 14-day API window.