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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Inspired by [Orta Therox](https://github.com/Orta). Thanks Orta for your outstan
| `size` | ❌ | `4` | Side length of each contribution block. ⚠️ Affects physics |
| `interval` | ❌ | `1.5` | Spacing between contribution blocks. ⚠️ Affects physics |
| `font-path` | ❌ | bundled font | Custom font file (`.ttf`/`.otf`), relative to the repository root, or an `http(s)` URL. ⚠️ Some fonts may fail to load |
| `token` | ❌ | - | GitHub token for the official GraphQL contributions API. When this input is set, or `GITHUB_TOKEN` is present in the environment, the official driver is preferred; otherwise the public gh-calendar API is used as a fallback. Pass `${{ secrets.GITHUB_TOKEN }}` |

### Reducing file size

Expand Down
1 change: 1 addition & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
| `size` | ❌ | `4` | 贡献方块边长。⚠️ 会影响物理表现 |
| `interval` | ❌ | `1.5` | 贡献方块间距。⚠️ 会影响物理表现 |
| `font-path` | ❌ | 内置字体 | 自定义字体文件(`.ttf`/`.otf`),相对仓库根目录,也可以直接给 `http(s)` 链接。⚠️ 部分字体可能无法正常加载 |
| `token` | ❌ | - | 用于官方 GraphQL 贡献数据接口的 GitHub token。设置该输入或环境中存在 `GITHUB_TOKEN` 时优先走官方渠道,否则回落到公开的 gh-calendar API。传入 `${{ secrets.GITHUB_TOKEN }}` 即可 |

### 减小文件体积

Expand Down
7 changes: 7 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ inputs:
or self-intersecting contours that the triangulation algorithm rejects, and some cannot
be parsed by opentype.js at all.
required: false
token:
description: >-
Optional GitHub token. When this input is set, or GITHUB_TOKEN is present
in the environment, contributions are fetched from the official GraphQL
API; otherwise the public gh-calendar API is used as a fallback.
Pass `${{ secrets.GITHUB_TOKEN }}`.
required: false

outputs:
svg-path:
Expand Down
144 changes: 131 additions & 13 deletions dist/index.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"ci-test": "bun test",
"build:web": "bun build src/web/index.html --outdir dist-web --minify",
"compare": "bun scripts/compare.ts",
"compare:contributions": "bun scripts/compareContributions.ts",
"format:write": "bun biome format --write .",
"format:check": "bun biome format .",
"lint": "bun biome lint .",
Expand Down
86 changes: 86 additions & 0 deletions scripts/compareContributions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* 对比两个贡献数据驱动的返回值是否严格相等。
*
* 需要 GITHUB_TOKEN 才能走官方 GraphQL 渠道:
* GITHUB_TOKEN=$(gh auth token) bun scripts/compareContributions.ts [username]
*/
import {
fetchContributionsFromCalendar,
fetchContributionsFromGraphql
} from '../src/utils/githubContributions'

const username = process.argv[2] ?? 'flycran'
const token = process.env.GITHUB_TOKEN?.trim()

if (!token) {
console.error('GITHUB_TOKEN is required to compare both drivers')
process.exit(1)
}

const [calendar, graphql] = await Promise.all([
fetchContributionsFromCalendar(username),
fetchContributionsFromGraphql(username, token)
])

const differences: string[] = []

if (calendar.total !== graphql.total) {
differences.push(`total: ${calendar.total} !== ${graphql.total}`)
}

if (calendar.contributions.length !== graphql.contributions.length) {
differences.push(
`weeks: ${calendar.contributions.length} !== ${graphql.contributions.length}`
)
}

const weekCount = Math.min(
calendar.contributions.length,
graphql.contributions.length
)

for (let week = 0; week < weekCount; week++) {
const left = calendar.contributions[week]
const right = graphql.contributions[week]

if (left.length !== right.length) {
differences.push(`week ${week} days: ${left.length} !== ${right.length}`)
continue
}

for (let day = 0; day < left.length; day++) {
const a = left[day]
const b = right[day]

if (a.date !== b.date) {
differences.push(`week ${week} day ${day} date: ${a.date} !== ${b.date}`)
}

if (a.intensity !== b.intensity) {
differences.push(`${a.date} intensity: ${a.intensity} !== ${b.intensity}`)
}

if (a.count !== b.count) {
differences.push(`${a.date} count: ${a.count} !== ${b.count}`)
}
}
}

const calendarDays = calendar.contributions.flat().length
const graphqlDays = graphql.contributions.flat().length

console.log(`total: ${calendar.total} / ${graphql.total}`)
console.log(
`weeks: ${calendar.contributions.length} / ${graphql.contributions.length}`
)
console.log(`days: ${calendarDays} / ${graphqlDays}`)

if (differences.length) {
console.error(`\nnot equal: ${differences.length} difference(s)`)
for (const difference of differences.slice(0, 20)) {
console.error(`- ${difference}`)
}
process.exit(1)
}

console.log('\nstrictly equal')
8 changes: 6 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ const inputSchema = z.object({
interval: nonNegativeNumber,
friction: nonNegativeNumber,
restitution: nonNegativeNumber,
'font-path': z.string()
'font-path': z.string(),
token: z.string()
})

/** 把 zod 校验失败整理成逐行可读的错误信息 */
Expand Down Expand Up @@ -105,7 +106,8 @@ export async function run(): Promise<void> {
interval: core.getInput('interval'),
friction: core.getInput('friction'),
restitution: core.getInput('restitution'),
'font-path': core.getInput('font-path')
'font-path': core.getInput('font-path'),
token: core.getInput('token')
})

if (!parsed.success) {
Expand All @@ -122,6 +124,8 @@ export async function run(): Promise<void> {
const animation = input.animation || undefined
const fontPath = input['font-path']

if (input.token.trim()) process.env.GITHUB_TOKEN = input.token.trim()

core.info(`Generating gravity SVG for user: ${username}`)
core.info(
`Text: "${text}", Font size: ${input['font-size'] ?? 48}, Shape: ${input.shape ?? 'circle'}, Text top: ${input['text-top'] ?? 50}, Background: ${backgroundColor}, Text color: ${textColor}`
Expand Down
Loading
Loading