github: traffic: Rewrite fetch and updates

This commit is contained in:
remittor
2026-01-15 14:35:24 +03:00
parent 6518c4e72c
commit 4c5860b809
+171 -43
View File
@@ -2,79 +2,207 @@ name: Collect GitHub Traffic
on: on:
schedule: schedule:
- cron: "0 2 * * *" - cron: "0 4 * * *" # 04:00 UTC
workflow_dispatch: workflow_dispatch:
inputs: inputs:
date:
description: "Date (YYYY-MM-DD), default today (UTC)"
required: false
dry_run: dry_run:
description: "Only show result (w/o commit)" description: "Only show result (w/o commit)"
required: true
default: "false"
type: choice
options:
- true
- false
init_pages:
description: "Create gh-pages branch"
required: true
default: "false"
type: choice
options:
- true
- false
reset:
description: "Reset stat files (full clean)"
required: false required: false
default: "false" default: "false"
type: choice
options:
- true
- false
permissions: permissions:
contents: write contents: write
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
API_CLONES: https://api.github.com/repos/${{ github.repository }}/traffic/clones
API_VIEWS: https://api.github.com/repos/${{ github.repository }}/traffic/views
WORK_DIR: ./traffic
jobs: jobs:
traffic: traffic:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Create gh-pages branch if missing
if: github.event.inputs.init_pages == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
set -e
git clone https://x-access-token:${GH_TOKEN}@github.com/${REPO}.git repo
cd repo
git config user.name "github-actions"
git config user.email "github-actions@github.com"
if git show-ref --verify --quiet refs/heads/gh-pages; then
echo "gh-pages already exists"
exit 0
fi
echo "Creating empty gh-pages branch"
git checkout --orphan gh-pages
git rm -rf .
mkdir -p ${{ env.WORK_DIR }}
touch ${{ env.WORK_DIR }}/clones.svg
echo "# gh-pages" > README.md
git add README.md ${{ env.WORK_DIR }}/*
git commit -m "init gh-pages"
git push origin gh-pages
- name: Checkout gh-pages - name: Checkout gh-pages
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
ref: gh-pages ref: gh-pages
path: gh-pages fetch-depth: 0
- name: Fetch traffic data - name: Configure git
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
- name: Reset traffic data (on demand)
if: github.event.inputs.reset == 'true'
env:
WORK_DIR: ${{ env.WORK_DIR }}
run: |
echo "Reset requested — clean traffic dir"
if [ -d $WORK_DIR ]; then
cd $WORK_DIR
rm -f ./*
git add -A
git commit -m "Reset traffic stats" || true
git push
fi
- name: Ensure traffic JSON files exist
env:
WORK_DIR: ${{ env.WORK_DIR }}
run: |
mkdir -p $WORK_DIR
cd $WORK_DIR
for FILE in clones.json clones_uniq.json views.json views_uniq.json; do
if [ ! -f "$FILE" ]; then
echo '{"total":0,"last_update":"","daily":{}}' > "$FILE"
fi
done
- name: Fetch traffic data (clones + views)
working-directory: ${{ env.WORK_DIR }}
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INPUT_DATE: ${{ github.event.inputs.date }} INPUT_DATE: ${{ github.event.inputs.date }}
run: |
set -e
fetch_data () {
API="$1"
OUT="$2"
echo "API response ($OUT)"
HTTP=$( curl -s -w "%{http_code}" -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" "$API" -o "$OUT" )
if [ "$HTTP" != "200" ]; then
echo "API error ($HTTP):"
cat "$OUT"
exit 11
fi
echo "::group::GitHub Traffic API raw response ($OUT)"
cat "$OUT" | jq .
echo "::endgroup::"
}
fetch_data "$API_CLONES" clones_api.json
fetch_data "$API_VIEWS" views_api.json
UPDATED_AT=$( date -u +"%Y-%m-%dT%H:%M:%SZ" )
echo "UPDATED_AT=$UPDATED_AT" >> $GITHUB_ENV
- name: Update traffic JSON files
working-directory: ${{ env.WORK_DIR }}
env:
DRY_RUN: ${{ github.event.inputs.dry_run }} DRY_RUN: ${{ github.event.inputs.dry_run }}
run: | run: |
set -e set -e
OWNER="${{ github.repository_owner }}" update_json() {
REPO="$(basename ${{ github.repository }})" local UPDATES=$1
if [ -n "$INPUT_DATE" ]; then local KEY=$2
TODAY="$INPUT_DATE" local FIELD=$3
else local FILE=$4
TODAY=$(date -u +%F) echo "[$FILE] : TOTAL = $( jq -r '.total' $FILE ) (old)"
fi DAYS=$( jq ".${KEY} | length" "$UPDATES" )
API="https://api.github.com/repos/$OWNER/$REPO/traffic/clones" echo "Updating $FILE ($DAYS days)"
DATA=$( curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" "$API" ) jq \
COUNT=$( echo "$DATA" | jq '.clones[-1].count // 0' ) --arg key "$KEY" \
mkdir -p gh-pages/traffic --arg field "$FIELD" \
FILE="gh-pages/traffic/clones.json" --arg updated_at "$UPDATED_AT" \
if [ ! -f "$FILE" ]; then --argjson updates "$(cat $UPDATES)" '
echo '{"total":0,"daily":{}}' > "$FILE" . // { daily: {} }
fi | .daily as $old
TOTAL=$( jq '.total' "$FILE" ) | .daily = (
TOTAL_NEW=$((TOTAL + COUNT)) reduce $updates[$key][] as $date ($old;
jq \ .[ ($date.timestamp | split("T")[0]) ] = $date[$field]
--arg date "$TODAY" \ )
--argjson count "$COUNT" \ )
--argjson total "$TOTAL_NEW" \ | .total = ( .daily | to_entries | map(.value) | add // 0 )
' | .last_update = $updated_at
.total = $total ' "$FILE" > "$FILE.tmp"
| .last_update = $date mv "$FILE.tmp" "$FILE"
| .daily[$date] = $count echo "[$FILE] : TOTAL = $( jq -r '.total' $FILE ) (new)"
' "$FILE" > "$FILE.tmp" git add "$FILE"
mv "$FILE.tmp" "$FILE" }
echo "Date: $TODAY" update_json clones_api.json clones count clones.json
echo "Clones per day: $COUNT" update_json clones_api.json clones uniques clones_uniq.json
echo "TOTAL_NEW: $TOTAL_NEW" update_json views_api.json views count views.json
update_json views_api.json views uniques views_uniq.json
if [ "$DRY_RUN" = "true" ]; then if [ "$DRY_RUN" = "true" ]; then
echo "DRY-RUN: changes not be saved!" echo "DRY-RUN: changes not be saved!"
exit 0
fi fi
- name: Generate badge_clones.svg
if: github.event.inputs.dry_run != 'true'
working-directory: ${{ env.WORK_DIR }}
run: |
if git diff --cached --quiet; then
echo "No changes for update badges"
exit 0
fi
create_badge () {
FILE="$1"
FNAME="$2"
LABEL="$3"
COLOR="${4:-green}"
BTYPE="${5:-downloads}"
TOTAL=$( jq -r '.total' "$FILE" )
UPDATED_AT=$( jq -r '.last_update' "$FILE" )
curl -s "https://img.shields.io/badge/${BTYPE}-${TOTAL}-${COLOR}?label=${LABEL}&style=flat" -o "$FNAME"
git add "$FNAME"
}
create_badge clones.json clones.svg downloads green
create_badge clones_uniq.json clones_uniq.svg downloads blue
create_badge views.json views.svg views green
create_badge views_uniq.json views_uniq.svg unique%20views blue
- name: Commit & push - name: Commit & push
if: github.event.inputs.dry_run != 'true' if: github.event.inputs.dry_run != 'true'
working-directory: ${{ env.WORK_DIR }}
run: | run: |
cd gh-pages if git diff --cached --quiet; then
git config user.name "github-actions" echo "No changes to commit"
git config user.email "github-actions@github.com" exit 0
git add traffic/clones.json fi
git commit -m "traffic: update clones stats" || exit 0 git commit -m "traffic: update clones stats for $(date -u +%F)"
git push git push