mirror of
https://github.com/mudler/LocalAI.git
synced 2026-08-02 03:20:12 -04:00
The star, fork, contributor and release counts were typed into the templates by hand, so they only moved when somebody remembered. They had already drifted: stars read 48,042 against 48,067, forks 4,314 against 4,320, and contributors 224 against 225. They move to website/data/stats.yaml, which .github/ci/refresh-site-counters.sh rewrites from the GitHub API, run weekly by a new workflow. The contributors and releases endpoints never report a total, so the script asks for one item per page and reads the count out of the Link header. It refuses to write a zero or a non-number, which is what a rate-limited or failed call looks like, and the workflow commits only when a number actually moved. The Discord count has no API behind it, so the script reads the existing value back and carries it through. The engine count was wrong in a second way. The hero said 18, the section heading said "Eighteen engines", the timeline said "Nineteen engines of our own", and the /engines/ page derived 19 from the data file. All of them now derive from that same file, so they cannot disagree again. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude Code:claude-opus-5[1m]
65 lines
2.5 KiB
Bash
Executable File
65 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Refreshes the counters shown on the landing page from the GitHub API.
|
|
#
|
|
# The numbers used to be typed into the templates by hand, which meant they
|
|
# only moved when somebody remembered, and a stale star count on the front
|
|
# page is worse than no star count. Everything the API can answer for lives
|
|
# in website/data/stats.yaml and is rewritten wholesale by this script.
|
|
#
|
|
# Anything the API cannot answer for (the Discord member count) is read back
|
|
# out of the existing file and carried through untouched.
|
|
set -euo pipefail
|
|
|
|
REPO="${REPO:-mudler/LocalAI}"
|
|
OUT="${OUT:-website/data/stats.yaml}"
|
|
|
|
# The contributors and releases endpoints are paginated and never report a
|
|
# total. Asking for one item per page makes the last page number equal to the
|
|
# item count, which the Link header hands over.
|
|
count_via_link_header() {
|
|
local path="$1" link last
|
|
link=$(gh api -i "${path}?per_page=1" 2>/dev/null | tr -d '\r' | grep -i '^link:' || true)
|
|
if [ -z "$link" ]; then
|
|
# No Link header means a single page, so count that page directly.
|
|
gh api "${path}?per_page=100" --jq 'length'
|
|
return
|
|
fi
|
|
last=$(sed -n 's/.*[?&]page=\([0-9]*\)>; rel="last".*/\1/p' <<<"$link")
|
|
[ -n "$last" ] || { gh api "${path}?per_page=100" --jq 'length'; return; }
|
|
printf '%s\n' "$last"
|
|
}
|
|
|
|
read -r stars forks < <(gh api "repos/${REPO}" --jq '"\(.stargazers_count) \(.forks_count)"')
|
|
contributors=$(count_via_link_header "repos/${REPO}/contributors")
|
|
releases=$(count_via_link_header "repos/${REPO}/releases")
|
|
|
|
# Not derivable from the GitHub API, so keep whatever is already on disk.
|
|
discord=$(sed -n 's/^discord: *\([0-9]*\).*/\1/p' "$OUT" 2>/dev/null | head -1)
|
|
discord="${discord:-0}"
|
|
|
|
for n in stars forks contributors releases; do
|
|
v="${!n}"
|
|
[[ "$v" =~ ^[0-9]+$ ]] && [ "$v" -gt 0 ] || {
|
|
echo "refusing to write: ${n} came back as '${v}'" >&2
|
|
exit 1
|
|
}
|
|
done
|
|
|
|
cat > "$OUT" <<YAML
|
|
# Counters shown on the landing page.
|
|
#
|
|
# The four GitHub fields are rewritten by .github/ci/refresh-site-counters.sh,
|
|
# which runs weekly from .github/workflows/refresh-site-counters.yml. Editing
|
|
# them by hand works but will be overwritten on the next run.
|
|
stars: ${stars}
|
|
forks: ${forks}
|
|
contributors: ${contributors}
|
|
releases: ${releases}
|
|
|
|
# The GitHub API cannot answer for this one, so it is maintained by hand and
|
|
# the refresh script carries it through untouched.
|
|
discord: ${discord}
|
|
YAML
|
|
|
|
echo "stars=${stars} forks=${forks} contributors=${contributors} releases=${releases} discord=${discord}"
|