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
54 changes: 39 additions & 15 deletions .github/workflows/desktop-download-badges.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Refreshes the per-platform desktop download counters behind the README badges.
# Refreshes the desktop and combined download counters behind the README badges.
#
# shields.io cannot do this on its own: its asset wildcards silently report 0
# (a tag whose .dmg had 39,877 downloads returns 0 for `*.dmg`), exact asset
Expand All @@ -11,6 +11,10 @@
name: Desktop Download Badges

on:
push:
branches: [main]
paths:
- .github/workflows/desktop-download-badges.yml
schedule:
# Once a day is plenty; the counters move slowly and the API is rate-limited.
- cron: '17 4 * * *'
Expand All @@ -33,7 +37,7 @@ jobs:
ref: badges
persist-credentials: true

- name: Sum the .dmg and .exe download counts
- name: Refresh download counts
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Desktop installers shipped from this repo up to v0.1.0 and move to
Expand All @@ -52,7 +56,18 @@ jobs:

# An empty suffix matches every asset, which is what the combined
# counter wants; `endswith("")` is true for any string.
write_badge() {
write_endpoint() {
local label="$1" message="$2" out="$3"
jq -n --arg label "$label" --arg message "$message" '{
schemaVersion: 1,
label: $label,
message: $message,
color: "4D6BFE"
}' > "$out"
echo "${label}: ${message}"
}

write_desktop_badge() {
local suffix="$1" label="$2" out="$3"
local total
total="$(jq --arg s "$suffix" '
Expand All @@ -61,20 +76,29 @@ jobs:
| .download_count
] | add // 0
' releases.json)"
jq -n --arg label "$label" --arg message "$total" '{
schemaVersion: 1,
label: $label,
message: $message,
color: "4D6BFE"
}' > "$out"
echo "${label}: ${total}"
write_endpoint "$label" "$total" "$out"
}

write_badge '.dmg' 'macOS .dmg' desktop-dmg.json
write_badge '.exe' 'Windows .exe' desktop-exe.json
write_desktop_badge '.dmg' 'macOS .dmg' desktop-dmg.json
write_desktop_badge '.exe' 'Windows .exe' desktop-exe.json
# The shields `github/downloads/.../total` route reads one repository,
# so the combined counter has to be summed here like the other two.
write_badge '' 'desktop' desktop-total.json
write_desktop_badge '' 'desktop' desktop-total.json

# Match the site: desktop and npm can represent the same users, so
# publish the larger counter instead of adding them together.
npm_downloads="$(
curl --fail --silent --show-error --location \
--retry 3 --retry-all-errors --connect-timeout 10 --max-time 30 \
'https://api.npmjs.org/downloads/point/last-year/%40pymodel%2Fpythinker-code' \
| jq -er '.downloads | numbers | select(. >= 0 and floor == .)'
)"
desktop_downloads="$(jq -er '.message | tonumber' desktop-total.json)"
downloads="$(
jq -n --argjson desktop "$desktop_downloads" --argjson npm "$npm_downloads" \
'[$desktop, $npm] | max'
)"
write_endpoint 'downloads' "$downloads" downloads-total.json

rm -f releases.json

Expand All @@ -85,10 +109,10 @@ jobs:
git config user.email 'github-actions[bot]@users.noreply.github.com'
# Stage before comparing: a document added in this run is untracked,
# and `git diff` on an untracked path reports no change at all.
git add desktop-dmg.json desktop-exe.json desktop-total.json
git add desktop-dmg.json desktop-exe.json desktop-total.json downloads-total.json
if git diff --cached --quiet; then
echo 'Counts unchanged; nothing to publish.'
exit 0
fi
git commit -m 'chore: refresh desktop download counts'
git commit -m 'chore: refresh download counts'
git push origin badges
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

### A coding agent you can run as a desktop app

[![release](https://img.shields.io/npm/v/@pymodel/pythinker-code?style=flat-square&label=release&color=4f46e5)](https://www.npmjs.com/package/@pymodel/pythinker-code)
[![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FPyModel%2Fpythinker-code%2Fbadges%2Fdesktop-total.json&style=flat-square&label=downloads&labelColor=000000&color=dfb317)](https://code.pythinker.com/)
[![license](https://img.shields.io/badge/license-MIT-16a34a?style=flat-square)](LICENSE)
[![release](https://img.shields.io/github/v/release/PyModel/pythinker-desktop-releases?style=flat-square&label=release&color=4f46e5)](https://github.com/PyModel/pythinker-desktop-releases/releases/latest)
[![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FPyModel%2Fpythinker-code%2Fbadges%2Fdownloads-total.json&style=flat-square&label=downloads&labelColor=000000&color=dfb317)](https://code.pythinker.com/)
[![macOS](https://img.shields.io/badge/macOS-e5e7eb?style=flat-square&logo=apple&logoColor=000000)](https://code.pythinker.com/) | [![Windows](https://img.shields.io/badge/Windows-e5e7eb?style=flat-square&logo=data:image/svg%2Bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+V2luZG93cyAxMTwvdGl0bGU+PHBhdGggZmlsbD0iIzAwNzhENCIgZD0iTTAsMEgxMS4zNzdWMTEuMzcySDBaTTEyLjYyMywwSDI0VjExLjM3MkgxMi42MjNaTTAsMTIuNjIzSDExLjM3N1YyNEgwWm0xMi42MjMsMEgyNFYyNEgxMi42MjMiLz48L3N2Zz4=)](https://code.pythinker.com/)
[![Node.js](https://img.shields.io/badge/Node.js-24.15%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](package.json)
[![visitors](https://komarev.com/ghpvc/?username=PyModel-pythinker-code&label=visitors&color=4f46e5&style=flat-square)](https://github.com/PyModel/pythinker-code)
Expand Down
Loading