chore: rename the project to ghglance

The Marketplace rejects ghstats as an action name, so the repo, Go module,
binary, and action share the name ghglance instead. The demo workflow keeps
reading the existing GHSTATS_TOKEN repo secret.
This commit is contained in:
tiennm99 committed 2026-10-03 13:38:15 +07:00
1 parent 8c1f139990
commit 3fc8a59de6
102 files changed
+238 -173

No files matched your search

+6 -6
View File
@@ -27,8 +27,8 @@ jobs:
go-version: "1.26"
cache: true
- name: Build ghstats
run: go build -trimpath -ldflags="-s -w" -o ghstats .
- name: Build ghglance
run: go build -trimpath -ldflags="-s -w" -o ghglance .
- name: Render every card for every theme
env:
@@ -36,7 +36,7 @@ jobs:
run: |
rm -rf demo
mkdir -p demo
./ghstats \
./ghglance \
-user "${{ github.repository_owner }}" \
-themes all \
-tz Asia/Saigon \
@@ -49,11 +49,11 @@ jobs:
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.repository }}
run: |
themes=$(./ghstats -list-themes)
themes=$(./ghglance -list-themes)
# Lightweight index so readers don't have to load ~975 images at once.
{
echo "# ghstats demo gallery"
echo "# ghglance demo gallery"
echo
echo "Every card rendered for [\`$OWNER\`](https://github.com/$OWNER) in every supported theme. Click a theme to open its gallery page — each page embeds 16 SVGs, so only the theme you're reviewing is fetched."
echo
@@ -87,7 +87,7 @@ jobs:
printf '</tr>\n'
}
{
printf '# ghstats — %s\n\n' "$theme"
printf '# ghglance — %s\n\n' "$theme"
printf '[← back to index](../README.md)\n\n'
printf 'Rendered for [`%s`](https://github.com/%s). 16 SVGs laid out to ' "$OWNER" "$OWNER"
printf 'match the author profile README table.\n\n'
+6 -6
View File
@@ -79,22 +79,22 @@ jobs:
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: "0"
run: |
bin=ghstats
[ "$GOOS" = windows ] && bin=ghstats.exe
bin=ghglance
[ "$GOOS" = windows ] && bin=ghglance.exe
mkdir -p dist
go build -trimpath -ldflags="-s -w" -o "dist/$bin" .
cd dist
if [ "$GOOS" = windows ]; then
zip "ghstats_${GOOS}_${GOARCH}.zip" "$bin"
zip "ghglance_${GOOS}_${GOARCH}.zip" "$bin"
else
tar -czf "ghstats_${GOOS}_${GOARCH}.tar.gz" "$bin"
tar -czf "ghglance_${GOOS}_${GOARCH}.tar.gz" "$bin"
fi
- uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
files: dist/ghstats_*.*
files: dist/ghglance_*.*
# Move the floating major-version tag (e.g. v1) to this release's commit so
# consumers using `uses: tiennm99/ghstats@v1` automatically pick up each new
# consumers using `uses: tiennm99/ghglance@v1` automatically pick up each new
# minor/patch release. Force-push is expected here — that's the point of a
# floating tag.
update-major-tag:
+2 -2
View File
@@ -1,4 +1,4 @@
# ghstats
# ghglance
Single-binary Go CLI that renders GitHub profile cards as SVG, wrapped by a
published GitHub Action. `main.go` parses flags → `internal/github` fetches →
@@ -15,7 +15,7 @@ them ships a half-wired feature or a README that lies:
3. `entrypoint.sh` — the `INPUT_*` → flag translation
4. `README.md` — **both** reference tables (Action inputs, CLI flags) **and
the runnable examples**: the workflow YAML under "Use as a GitHub Action"
and the `ghstats …` command under "Use as a CLI"
and the `ghglance …` command under "Use as a CLI"
5. `docs/system-architecture.md` — when the knob changes the fetch pipeline
or its query cost
+2 -2
View File
@@ -3,11 +3,11 @@ WORKDIR /src
COPY go.mod ./
RUN go mod download || true
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/ghstats .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/ghglance .
FROM alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d
RUN apk add --no-cache ca-certificates tzdata git
COPY --from=build /out/ghstats /usr/local/bin/ghstats
COPY --from=build /out/ghglance /usr/local/bin/ghglance
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
+20 -20
View File
@@ -1,16 +1,16 @@
# ghstats
# ghglance
> Generate SVG cards summarizing a GitHub user's profile — written in Go.
[![Marketplace](https://img.shields.io/badge/Marketplace-ghstats-2f81f7?logo=github)](https://github.com/marketplace/actions/ghstats)
[![Release](https://img.shields.io/github/v/release/tiennm99/ghstats?color=blue)](https://github.com/tiennm99/ghstats/releases/latest)
[![License](https://img.shields.io/github/license/tiennm99/ghstats?color=green)](./LICENSE)
[![Marketplace](https://img.shields.io/badge/Marketplace-ghglance-2f81f7?logo=github)](https://github.com/marketplace/actions/ghglance)
[![Release](https://img.shields.io/github/v/release/tiennm99/ghglance?color=blue)](https://github.com/tiennm99/ghglance/releases/latest)
[![License](https://img.shields.io/github/license/tiennm99/ghglance?color=green)](./LICENSE)
`ghstats` is a single-binary CLI (and a GitHub Action wrapping it) that fetches
`ghglance` is a single-binary CLI (and a GitHub Action wrapping it) that fetches
data for a GitHub user and writes a themed set of SVGs you can embed in your
profile README.
Marketplace listing: **[ghstats](https://github.com/marketplace/actions/ghstats)** · Source: [`tiennm99/ghstats`](https://github.com/tiennm99/ghstats)
Marketplace listing: **[ghglance](https://github.com/marketplace/actions/ghglance)** · Source: [`tiennm99/ghglance`](https://github.com/tiennm99/ghglance)
Cards rendered:
@@ -55,15 +55,15 @@ Live render against the author's profile, committed by [`.github/workflows/demo.
## In the wild
- [**tiennm99/tiennm99**](https://github.com/tiennm99/tiennm99) — author's profile README, refreshed daily via `tiennm99/ghstats@v1`. Two-per-row layout, dracula theme.
- [**tiennm99/tiennm99**](https://github.com/tiennm99/tiennm99) — author's profile README, refreshed daily via `tiennm99/ghglance@v1`. Two-per-row layout, dracula theme.
## Use as a GitHub Action (recommended)
Drop this in `.github/workflows/ghstats.yml` in your **profile repo** (the one
Drop this in `.github/workflows/ghglance.yml` in your **profile repo** (the one
named after your username):
```yaml
name: ghstats
name: ghglance
on:
schedule:
@@ -78,10 +78,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: tiennm99/ghstats@v1
- uses: tiennm99/ghglance@v1
with:
user: ${{ github.repository_owner }}
token: ${{ secrets.GHSTATS_TOKEN }} # classic PAT with read:user + repo
token: ${{ secrets.GHGLANCE_TOKEN }} # classic PAT with read:user + repo
themes: dracula,github_dark,tokyonight
tz: Asia/Saigon
include_forks: "true"
@@ -127,7 +127,7 @@ Then embed the cards in your `README.md`:
| `include_private` | `true` | Include private repos (requires PAT with `repo` scope; silently no-op otherwise) |
| `include_org_repos`| `false` | Count org-owned repos you administer toward stars, repo count, languages, top-starred (needs `read:org`) |
| `commit_changes` | `false` | Commit generated cards back to the repo |
| `commit_message` | `chore: update ghstats cards` | Commit message |
| `commit_message` | `chore: update ghglance cards` | Commit message |
| `commit_branch` | *(current ref)* | Target branch for auto-commit |
| `author_name` | `github-actions[bot]` | Commit author |
| `author_email` | `…@users.noreply.github.com` | Commit email |
@@ -135,28 +135,28 @@ Then embed the cards in your `README.md`:
## Use as a CLI
```sh
go install github.com/tiennm99/ghstats@latest
go install github.com/tiennm99/ghglance@latest
```
Or build from source:
```sh
git clone https://github.com/tiennm99/ghstats
cd ghstats
go build -o ghstats .
git clone https://github.com/tiennm99/ghglance
cd ghglance
go build -o ghglance .
```
Then:
```sh
export GITHUB_TOKEN=ghp_xxx
ghstats -user tiennm99 -themes dracula,github_dark -tz Asia/Saigon -out output
ghglance -user tiennm99 -themes dracula,github_dark -tz Asia/Saigon -out output
```
Add `-include-org-repos` to also count org-owned repos you administer:
```sh
ghstats -user tiennm99 -themes dracula -include-org-repos -out output
ghglance -user tiennm99 -themes dracula -include-org-repos -out output
```
| Flag | Default | Description |
@@ -191,7 +191,7 @@ ghstats -user tiennm99 -themes dracula -include-org-repos -out output
## Themes
Run `ghstats -list-themes` for the full list (65 themes ported from
Run `ghglance -list-themes` for the full list (65 themes ported from
github-profile-summary-cards). Built-ins include `default`, `dark`, `dracula`,
`github`, `github_dark`, `tokyonight`, `onedark`, `nord_dark`, `nord_bright`,
`gruvbox`, `radical`, `synthwave`, `monokai`, `solarized`, `solarized_dark`,
@@ -230,7 +230,7 @@ reference render of every card in every theme, see the CI-built
The default `${{ github.token }}` can read public user data but will not see
your private-repo commits. For accurate stats, create a **classic** personal
access token with `read:user` and `repo`, save it as a repo secret (e.g.
`GHSTATS_TOKEN`), and pass it via the `token` input. `include_private`
`GHGLANCE_TOKEN`), and pass it via the `token` input. `include_private`
defaults to `true` so those commits are counted automatically once the token
has `repo` scope; pass `include_private: "false"` if you want to keep private
work out of the rendered cards even when the token can see it.
+2 -2
View File
@@ -1,4 +1,4 @@
name: ghstats
name: ghglance
description: Generate GitHub profile summary SVG cards (profile, languages, stats, productive time, contributions)
author: tiennm99
branding:
@@ -61,7 +61,7 @@ inputs:
commit_message:
description: Commit message used when commit_changes is true
required: false
default: "chore: update ghstats cards"
default: "chore: update ghglance cards"
commit_branch:
description: Branch to commit to (defaults to the current ref)
required: false
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — 2077
# ghglance — 2077
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats demo gallery
# ghglance demo gallery
Every card rendered for [`tiennm99`](https://github.com/tiennm99) in every supported theme. Click a theme to open its gallery page — each page embeds 16 SVGs, so only the theme you're reviewing is fetched.
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — algolia
# ghglance — algolia
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — apprentice
# ghglance — apprentice
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — aura
# ghglance — aura
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — aura_dark
# ghglance — aura_dark
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — ayu_mirage
# ghglance — ayu_mirage
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — bear
# ghglance — bear
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — blue_green
# ghglance — blue_green
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — blueberry
# ghglance — blueberry
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — buefy
# ghglance — buefy
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — calm
# ghglance — calm
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — chartreuse_dark
# ghglance — chartreuse_dark
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — city_lights
# ghglance — city_lights
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — cobalt
# ghglance — cobalt
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — cobalt2
# ghglance — cobalt2
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — codeSTACKr
# ghglance — codeSTACKr
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — darcula
# ghglance — darcula
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — dark
# ghglance — dark
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — date_night
# ghglance — date_night
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — default
# ghglance — default
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — discord_old_blurple
# ghglance — discord_old_blurple
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — dracula
# ghglance — dracula
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — flag_india
# ghglance — flag_india
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — github
# ghglance — github
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — github_dark
# ghglance — github_dark
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — gotham
# ghglance — gotham
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — graywhite
# ghglance — graywhite
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — great_gatsby
# ghglance — great_gatsby
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — gruvbox
# ghglance — gruvbox
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — highcontrast
# ghglance — highcontrast
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — holi
# ghglance — holi
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — jolly
# ghglance — jolly
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — kacho_ga
# ghglance — kacho_ga
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — maroongold
# ghglance — maroongold
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — material_palenight
# ghglance — material_palenight
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — merko
# ghglance — merko
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — midnight_purple
# ghglance — midnight_purple
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — moltack
# ghglance — moltack
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — monokai
# ghglance — monokai
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — moonlight
# ghglance — moonlight
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — nightowl
# ghglance — nightowl
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — noctis_minimus
# ghglance — noctis_minimus
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — nord_bright
# ghglance — nord_bright
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — nord_dark
# ghglance — nord_dark
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — ocean_dark
# ghglance — ocean_dark
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — omni
# ghglance — omni
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — onedark
# ghglance — onedark
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — outrun
# ghglance — outrun
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — panda
# ghglance — panda
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — prussian
# ghglance — prussian
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — radical
# ghglance — radical
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — react
# ghglance — react
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — rose_pine
# ghglance — rose_pine
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — shades_of_purple
# ghglance — shades_of_purple
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — slateorange
# ghglance — slateorange
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — solarized
# ghglance — solarized
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — solarized_dark
# ghglance — solarized_dark
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — swift
# ghglance — swift
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — synthwave
# ghglance — synthwave
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — tokyonight
# ghglance — tokyonight
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — transparent
# ghglance — transparent
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — vision_friendly_dark
# ghglance — vision_friendly_dark
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — vue
# ghglance — vue
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — yeblu
# ghglance — yeblu
[← back to index](../README.md)
+1 -1
View File
@@ -1,4 +1,4 @@
# ghstats — zenburn
# ghglance — zenburn
[← back to index](../README.md)
+1 -1
View File
@@ -66,7 +66,7 @@ Never write comments that describe what well-named code does (`// increment coun
## Testing
- Unit tests in the same package, no mocking of http.Client — we test rendering and pure helpers.
- Network tests are omitted; integration verification is manual (`./ghstats -token ...`).
- Network tests are omitted; integration verification is manual (`./ghglance -token ...`).
- `go vet ./...` clean before every commit.
## Commit conventions
+1 -1
View File
@@ -3,7 +3,7 @@
## Layout
```
ghstats/
ghglance/
├── main.go # CLI entry point; wires flags → fetchers → renderers
├── action.yml # GitHub Action metadata
├── entrypoint.sh # Action runtime; maps INPUT_* env → CLI flags
+13 -13
View File
@@ -6,10 +6,10 @@ Three consumption paths: **GitHub Action**, **prebuilt binaries**, **go install*
### Workflow template
File: `.github/workflows/ghstats.yml` in your profile repo.
File: `.github/workflows/ghglance.yml` in your profile repo.
```yaml
name: ghstats
name: ghglance
on:
schedule:
@@ -24,10 +24,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: tiennm99/ghstats@v1
- uses: tiennm99/ghglance@v1
with:
user: ${{ github.repository_owner }}
token: ${{ secrets.GHSTATS_TOKEN }}
token: ${{ secrets.GHGLANCE_TOKEN }}
themes: dracula,github_dark,tokyonight
tz: Asia/Saigon
# start_of_week: monday # optional; default sunday — rotates heatmap rows + weekday bars
@@ -38,7 +38,7 @@ jobs:
### Required secrets
`GHSTATS_TOKEN`: a **classic** personal access token with at minimum:
`GHGLANCE_TOKEN`: a **classic** personal access token with at minimum:
| Scope | Needed for |
| --- | --- |
@@ -47,7 +47,7 @@ jobs:
Fine-grained PATs and the default `${{ github.token }}` lack the introspection scope for contribution calendars in many orgs, so a classic PAT is recommended.
Create one at <https://github.com/settings/tokens> → "Generate new token (classic)" → select `read:user` (+ `repo` if needed) → save as repo secret `GHSTATS_TOKEN`.
Create one at <https://github.com/settings/tokens> → "Generate new token (classic)" → select `read:user` (+ `repo` if needed) → save as repo secret `GHGLANCE_TOKEN`.
### Embedding in README
@@ -84,29 +84,29 @@ Install:
```sh
# Linux x86_64 example
curl -L https://github.com/tiennm99/ghstats/releases/latest/download/ghstats_linux_amd64.tar.gz \
curl -L https://github.com/tiennm99/ghglance/releases/latest/download/ghglance_linux_amd64.tar.gz \
| tar xz
./ghstats -user YOUR_USERNAME
./ghglance -user YOUR_USERNAME
```
## 3. go install
```sh
go install github.com/tiennm99/ghstats@latest
go install github.com/tiennm99/ghglance@latest
```
Requires Go 1.26+. Puts the binary in `$(go env GOPATH)/bin`.
## Docker image
Published to `ghcr.io/tiennm99/ghstats:<tag>` on each `v*` release via `.github/workflows/release.yml` (buildx, multi-tag: exact version, major.minor, major, latest).
Published to `ghcr.io/tiennm99/ghglance:<tag>` on each `v*` release via `.github/workflows/release.yml` (buildx, multi-tag: exact version, major.minor, major, latest).
The Action itself uses a runner-built image by default (`image: Dockerfile` in `action.yml`). To switch to the pre-built image for faster cold starts, edit `action.yml`:
```yaml
runs:
using: docker
image: docker://ghcr.io/tiennm99/ghstats:v1
image: docker://ghcr.io/tiennm99/ghglance:v1
```
## Release process
@@ -117,12 +117,12 @@ runs:
3. On green, GHCR push + cross-platform binary artifacts happen automatically.
4. The `update-major-tag` job force-moves the floating major tag (e.g. `v1`)
to this release's commit after test + docker + binaries all pass.
Consumers pinned to `tiennm99/ghstats@v1` pick up the release on their
Consumers pinned to `tiennm99/ghglance@v1` pick up the release on their
next Action run without a workflow edit.
5. Docker base images and third-party actions are SHA-pinned (with version
comments) so mutable-tag changes upstream can't rewrite a released image.
6. **Marketplace:** the action is listed on the GitHub Marketplace as
[`ghstats`](https://github.com/marketplace/actions/ghstats); the listing
[`ghglance`](https://github.com/marketplace/actions/ghglance); the listing
name comes from `name:` in `action.yml`. Publishing is a web-UI step —
edit the GitHub release and tick "Publish this Action to the GitHub
Marketplace" — since `action-gh-release` cannot publish it.
+1 -1
View File
@@ -1,6 +1,6 @@
# Design Guidelines
Visual conventions for ghstats SVG cards. All cards share a single frame shape so they stack cleanly in a README — two cards sit side-by-side inside GitHub's ~816 px content column.
Visual conventions for ghglance SVG cards. All cards share a single frame shape so they stack cleanly in a README — two cards sit side-by-side inside GitHub's ~816 px content column.
## Card frame
+3 -3
View File
@@ -1,4 +1,4 @@
# ghstats — Product Development Requirements
# ghglance — Product Development Requirements
## One-liner
@@ -13,7 +13,7 @@ Single-binary Go CLI + GitHub Action that renders 15 themed SVG cards summarisin
- WakaTime-style editor telemetry.
- Cloning repos or running linguist locally (lowlighter/metrics territory). A future `-accurate-languages` mode may add per-commit REST classification; clone-mode is out of scope for v1.
- Real-time / per-request API server. ghstats is a scheduled batch renderer.
- Real-time / per-request API server. ghglance is a scheduled batch renderer.
## Value proposition vs alternatives
@@ -22,7 +22,7 @@ Single-binary Go CLI + GitHub Action that renders 15 themed SVG cards summarisin
| anuraghazra/github-readme-stats | JS | hosted service | No (byte-size only) |
| vn7n24fzkq/github-profile-summary-cards | TS | Action + hosted | No (primary-language-per-repo) |
| lowlighter/metrics (indepth) | JS | Action | Yes (clones + linguist-js) |
| **ghstats** | Go | Action + CLI | Partial (byte-weighted today; REST-per-commit planned) |
| **ghglance** | Go | Action + CLI | Partial (byte-weighted today; REST-per-commit planned) |
Distinguishing traits:
- **Single binary**: no Node, no Ruby, no Docker needed for CLI usage.
+5 -5
View File
@@ -1,7 +1,7 @@
#!/bin/sh
# Entrypoint for the ghstats GitHub Action.
# Entrypoint for the ghglance GitHub Action.
# Inputs are passed via INPUT_* environment variables (set by the Action runtime).
# This script translates them into ghstats CLI flags and optionally commits the
# This script translates them into ghglance CLI flags and optionally commits the
# generated SVGs back to the repository.
set -eu
@@ -18,7 +18,7 @@ include_forks="${INPUT_INCLUDE_FORKS:-true}"
include_private="${INPUT_INCLUDE_PRIVATE:-true}"
include_org_repos="${INPUT_INCLUDE_ORG_REPOS:-false}"
commit_changes="${INPUT_COMMIT_CHANGES:-false}"
commit_message="${INPUT_COMMIT_MESSAGE:-chore: update ghstats cards}"
commit_message="${INPUT_COMMIT_MESSAGE:-chore: update ghglance cards}"
commit_branch="${INPUT_COMMIT_BRANCH:-}"
author_name="${INPUT_AUTHOR_NAME:-github-actions[bot]}"
author_email="${INPUT_AUTHOR_EMAIL:-41898282+github-actions[bot]@users.noreply.github.com}"
@@ -30,8 +30,8 @@ fi
mkdir -p "$out"
echo "Running ghstats for user=$user themes=$themes out=$out"
ghstats \
echo "Running ghglance for user=$user themes=$themes out=$out"
ghglance \
-user "$user" \
-token "$token" \
-out "$out" \
+1 -1
View File
@@ -1,3 +1,3 @@
module github.com/tiennm99/ghstats
module github.com/tiennm99/ghglance
go 1.26
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"os"
"path/filepath"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
// Card renders one SVG for a Profile under the given theme.
+3 -3
View File
@@ -9,8 +9,8 @@ import (
"testing"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
func TestRenderAll(t *testing.T) {
@@ -35,7 +35,7 @@ func TestRenderAll(t *testing.T) {
{Name: "Python", Color: "#3572A5", Value: 150},
},
TopRepos: []github.RepoInfo{
{Owner: "tiennm99", Name: "ghstats", Stars: 42, PrimaryLanguage: "Go", PrimaryColor: "#00ADD8"},
{Owner: "tiennm99", Name: "ghglance", Stars: 42, PrimaryLanguage: "Go", PrimaryColor: "#00ADD8"},
{Owner: "tiennm99", Name: "some-app & <tool>", Stars: 17, PrimaryLanguage: "TypeScript", PrimaryColor: "#3178c6"},
{Owner: "tiennm99", Name: "fork-only", Stars: 99, IsFork: true},
},
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"strings"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type contributionsCard struct{}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"sort"
"strings"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type contributionsByYearCard struct{}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"strings"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type contributionsHeatmapCard struct{}
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"testing"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghglance/internal/github"
)
// GitHub's contributionCalendar is week-aligned, so a "last year" series for a
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"math"
"strings"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
// renderDonutCard draws a donut chart with a left-side legend. Shared by the
+2 -2
View File
@@ -1,8 +1,8 @@
package card
import (
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type mostCommitLanguageCard struct{}
@@ -1,8 +1,8 @@
package card
import (
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type mostCommitLanguageAllTimeCard struct{}
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"fmt"
"strings"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type productiveCard struct{}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"strings"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type productiveWeekdayCard struct{}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"strings"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type profileCard struct{}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"strings"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type recordsCard struct{}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"testing"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
// dayAt is a tiny helper so fixtures stay readable.
+2 -2
View File
@@ -1,8 +1,8 @@
package card
import (
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type reposPerLanguageCard struct{}
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"fmt"
"strings"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type statsCard struct{}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"strings"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type streakCard struct{}
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"fmt"
"strings"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
type topStarredReposCard struct{}
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"testing"
"time"
"github.com/tiennm99/ghstats/internal/github"
"github.com/tiennm99/ghstats/internal/theme"
"github.com/tiennm99/ghglance/internal/github"
"github.com/tiennm99/ghglance/internal/theme"
)
// TestPadToWeekGridRotatesByWeekStart checks that the leading blank pad
+1 -1
View File
@@ -69,7 +69,7 @@ func (c *Client) query(ctx context.Context, q string, vars map[string]any, out a
return fmt.Errorf("new request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", "ghstats")
req.Header.Set("User-Agent", "ghglance")
if c.token != "" {
req.Header.Set("Authorization", "bearer "+c.token)
}
+1 -1
View File
@@ -59,7 +59,7 @@ func TestRepoAffiliationsAndOwnership(t *testing.T) {
orgWrite := orgAdmin
orgWrite.ViewerPermission = "WRITE"
own := repoNode{Name: "ghstats"}
own := repoNode{Name: "ghglance"}
own.Owner = &struct {
Login string `json:"login"`
}{Login: "tiennm99"}
Loaded 100 of 102 files, more files were not shown because too many files have changed in this diff. Show more