一直以来我的 GitHub 主页都是光秃秃的,直到某天我决定好好打理一下。本以为只是写个 README 的事,没想到一路折腾下来,涉及了 GitHub Actions、YAML 解析、Python 脚本、还有各种第三方 API 的对接。这篇文章就把整个过程记录下来,希望对想美化主页的同学有帮助。
先看效果
最终的主页包含这些功能:
- 自我介绍 + 技术栈徽章
- GitHub 统计卡片 + 成就奖杯墙
- 自动更新的贡献图贪吃蛇
- 每 30 分钟自动同步的 GitHub 最近活动
- 每 6 小时自动从掘金同步的最新文章
- 基于真实简历的工作经历和项目展示
第一步:创建 Profile 仓库
GitHub 主页的秘密武器是一个和你用户名同名的仓库。比如我的用户名是 Magic0323,那就创建 Magic0323/Magic0323。这个仓库的 README.md 会直接展示在你的主页顶部。
可以用 gh 命令行创建,也可以直接在 GitHub 网页上新建。
第二步:README 内容设计
自我介绍
我用了一个 JavaScript 对象的形式来写自我介绍,前端开发者看起来会很亲切:
const magic = {
name: 'Magic0323',
title: 'Senior Frontend Engineer',
superpower: 'Turning coffee into code',
currently: ['leveling up', 'building cool stuff', 'chasing bugs'],
};
技术栈徽章
用 shields.io 的徽章来展示技术栈,简洁美观:

一行一个技术,分类排列(Core、Frameworks、AI & Agent、Build Tools 等)。
GitHub 统计卡片
用 github-readme-stats 一键生成:

支持多种主题,暗色系的 radical 主题视觉效果很好。
第三步:贪吃蛇动画的折腾史
这是整个过程中最曲折的部分。贪吃蛇动画会在你的贡献图上生成一条蛇,视觉效果非常酷。
尝试一:Platane/snk v3 直接生成 GIF
- uses: Platane/snk@v3
with:
outputs: |
dist/snake.gif
生成成功了,但 GIF 只有 7 帧、每帧 10ms,总长 70ms,一闪就过,根本看不出蛇在动。
尝试二:调整帧率参数
试了 ?duration=40、?delay=100 等各种参数,结果生成的 GIF 还是 10ms/帧——说明 v3 版本的 query 参数对 GIF 输出不起作用。
尝试三:后处理改帧率
试了三种方案全部失败:
- gifsicle — 安装失败
- ImageMagick —
convert -delay无效 - Python Pillow —
shell: python3不被 GitHub Actions 支持
最终方案:SVG
最终回退到 SVG 输出,这也是大多数人的做法。SVG 视觉效果一样好,只是不会动:
- uses: Platane/snk@v3
with:
outputs: |
dist/github-contribution-grid-snake.svg
dist/github-contribution-grid-snake-dark.svg?palette=github-dark
第四步:GitHub Actions 的连环坑
这是整篇文章最有价值的部分——我踩过的坑,你不需要再踩。
坑 1:YAML 中的花括号
在 GitHub Actions 的 YAML 文件中,run: | 块里的 {} 会导致 YAML 解析失败。即使是在 literal block scalar 中,GitHub Actions 的预处理器似乎也会尝试解析花括号。
❌ 会失败:
- name: Fetch articles
run: |
curl -d '{"user_id":"123","sort_type":2}' ...
✅ 解决方案:
把 Python 脚本抽成独立的 .py 文件放在仓库里,workflow 里只调用它:
- name: Run update script
run: python3 scripts/update-blog.py
坑 2:shell: python3 不被支持
GitHub Actions 不支持 shell: python3 配置。用这个配置会直接导致 workflow 解析失败。
❌ 会失败:
- name: Update
shell: python3
run: |
print("hello")
✅ 正确做法:
- name: Update
run: python3 -c "print('hello')"
或者用 heredoc:
- name: Update
run: |
python3 << 'EOF'
print("hello")
EOF
坑 3:workflow 文件名
我之前把文件命名为 blog.yml,结果 workflow 一直解析失败,显示文件名而不是 workflow name。改成 juejin-posts.yml 后问题消失——不知道是不是 blog.yml 在某些情况下被保留或冲突了。
坑 4:Personal Access Token 权限
用 fine-grained PAT 需要反复添加权限:
public_repo(创建仓库)workflow(推送 workflow 文件)contents: write(推送代码)actions: write(触发 workflow dispatch)
建议直接用一个 classic PAT 勾上 public_repo 和 workflow 省事。
第五步:自动同步掘金文章
既然在掘金写文章,自然希望同步到 GitHub 主页上。掘金有公开的 API:
curl -X POST "https://api.juejin.cn/content_api/v1/article/query_list" \
-H "Content-Type: application/json" \
-d '{"user_id":"你的用户ID","sort_type":2,"cursor":"0"}'
我写了一个 Python 脚本 scripts/update-blog.py,通过 workflow 每 6 小时自动拉取最新文章并更新 README。
第六步:Recent Activity 自动更新
用 jamesgeorge007/github-activity-readme 这个 action,每 30 分钟自动拉取你的 GitHub 操作记录:
- uses: jamesgeorge007/github-activity-readme@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
需要在 README 中埋入占位符:
<!--START_SECTION:activity-->
<!--END_SECTION:activity-->
最终架构
Magic0323/Magic0323/
├── README.md # 主页展示内容
├── scripts/
│ └── update-blog.py # 掘金文章同步脚本
└── .github/workflows/
├── snake.yml # 贪吃蛇动画(每天)
├── activity.yml # 最近活动(每30分钟)
└── juejin-posts.yml # 掘金文章(每6小时)
三个 workflow 各司其职,互不干扰。
写在最后
GitHub 主页不仅仅是一个简历展示页,它也可以是你学习、折腾、自动化实践的试验田。通过这次搭建,我不仅得到了一个满意的个人主页,还对 GitHub Actions 的 YAML 解析机制有了更深入的理解。
如果你也想搭一个,建议先从简单的 README 开始,再逐步加上自动化 workflow。一口吃不成胖子,但一次 commit 可以。
这篇文章本身也是通过 workflow 自动同步到主页的 😄
如果觉得有用,欢迎 Star Magic0323/Magic0323