
单独看到skills这个词大部分人会觉得这就是某个笔记仓库或者课程大纲根本不值得多看一眼。但如果你把它理解成 GitHub 官方开源的那套交互式技能课程系统整个场景就完全不一样了。我最早是在给团队设计新人 onboarding 流程时注意到它的原本想省事直接丢一堆文档链接出去结果越研究越觉得这套东西的价值不在“学什么”而在“怎么验证你学会了”。它把课程直接做成了仓库把答题卡做成了分支和 Pull Request把自动判题交给了 GitHub Actions这一整套思路放到今天依然非常值得拆开讲。1. skills 不是文档合集而是一套能自动判题的“课程即仓库”系统1.1 为什么我会关注到这套机制先说结论GitHub Skills 是一套由官方维护的交互式课程入口在github.com/skills。它的核心思想是你别看教学视频也别做选择题直接在一个真实仓库里动手完成一系列 Git 操作系统通过后台自动化脚本检查你的操作结果然后给出下一步指引。我第一次体验的时候最强烈的感受是“这不是教程这是考试”。因为普通文档教程最多告诉你“应该怎么改”但 skills 课程会真的检查你有没有改对。改错了机器人不会把答案告诉你而是提示你“还差什么”改对了它会自动放行进入下一步。这种反馈闭环才是它区别于普通 README 教程的关键。从工程角度来看这套系统可以拆成三层层面作用典型技术载体课程内容层告诉学习者要做什么Markdown 文件、issue 评论操作执行层学习者实际完成 Git 操作分支、提交、Pull Request自动判题层校验操作结果并推进流程GitHub Actions GitHub API理解了这三层你就能明白为什么我说它不是一个单纯的仓库而是一套完整的“课程即仓库”系统。1.2 官方课程的真实形态官方目前比较有代表性的课程有这么几个Introduction to GitHub面向完全零基础的人教分支、提交、PR。Communicate using Markdown通过实践学 Markdown 语法。Reviewing pull requests模拟代码评审流程。Resolve merge conflicts专门练冲突解决。GitHub Pages发布一个静态站点。Hello GitHub Actions自己写一个最简工作流。每个课程本质上都是一个公开仓库里面除了学习材料还有隐藏的自动化校验脚本。当你在github.com/skills页面点击某个课程系统会用你的账号创建一个课程仓库副本然后把初始 issue 和评论全部配置好。整个过程看起来像“报名成功”实际上是在背后做了一次仓库模板实例化。这个设计真的很聪明。传统学习平台要把“理论讲解”和“实验环境”分开搭但 GitHub Skills 把这两者焊死在同一个仓库里。你学习 Git 的地方就是一个真正的 Git 仓库你练习 PR 的地方就是一个真正会被 CI 检查的 PR。技能和工具的运行环境完全一致学完就是会用了不存在“课上会了、工作里不会”的断层。2. 跑一遍 Introduction to GitHub拆解自动化课程的前 20 分钟2.1 点击 Start 后仓库会发生什么我建议所有人都亲自跑一遍 Introduction to GitHub不是为了学 Git而是为了体验背后的自动化流程。点下 Start 之后GitHub 会先创建一个课程仓库命名一般类似skills-introduction-to-github。这个仓库不是空仓库里面已经放好了初始文件、issue 模板、PR 模板以及一套用来判题的 Actions 工作流。紧接着系统会自动在这个仓库里开一个 issue机器人会在 issue 中留言告诉你第一步要做什么。这里有一个必须留意的细节整个体验是从 issue 开始的而不是从 README 开始的。原因是 issues 就是天然的“对话上下文”。机器人通过评论和标签判断你进行到哪一步你回复评论、提交代码、打开 PR它都能感知到。一套课程就是一场由机器人引导的对话而不是一篇单向输出的文章。2.2 机器人如何知道你完成了任务很多人以为这套流程是靠“文件存在”来判断是否完成实际上不止如此。官方课程的判题逻辑大多由 GitHub Actions 工作流实现脚本会实时读取仓库状态、分支信息、PR 内容。某种意义上你可以把每一步都理解成一条自动化测试用例。以 Introduction to GitHub 里的一个典型步骤举例机器人让你创建一个新分支。你在新分支上修改文件并推送。GitHub Actions 监听到新的推送自动拉取你的提交。脚本检查分支名、文件路径、文件内容是否符合预期。符合预期就回复一条祝贺信息并告诉你怎么进入下一步。这套判题逻辑和 CI 没本质区别。唯一不同的地方是普通 CI 检查的是代码对不对skills 检查的是操作步骤对不对而且它还会把检查结果以“人话”形式写回评论。对新手来说这种体验非常友好因为报错信息不是编译器的堆栈而是“你的分支名应该是 xxx”这样具体明确的提示。2.3 分支与 PR 是考试Git 操作是答题卡这套课程设计里最妙的一点是把 Git 操作本身当成了答题卡。传统考试里学生做一套题然后老师批改。但在这里你不存在单独的“作答区域”。你创建的分支、推送的提交、填写的 PR 标题全部既是操作过程又是答案本身。机器人评审的不是“你说你会不会”而是“你有没有真的做到”。这意味着学习者主观上没法“假装学会”因为每个操作都留痕。另一方面这也对课程设计者提出了更高的要求你给的任务必须能被程序自动判断对错。如果是开放性任务就必须设计一个可接受的“答案范围”否则自动化流程就会失效。后面自建课程时这一条是核心矛盾。3. 自己造一门 skills 课程模板结构与工作流写法3.1 官方模板的目录结构到底是什么意思要自建 skills 课程官方提供一个模板仓库skills/skills-template直接点 “Use this template” 就能生成你自己的课程仓库。模板目录虽然看着多但真正核心的其实就三类东西. ├── .github │ ├── steps │ │ ├── 0-welcome.md │ │ └── 1-first-step.md │ └── workflows │ ├── 1-welcome.yml │ └── 2-first-step.yml ├── responses │ ├── 0-welcome.md │ └── 1-first-step.md ├── course-details.md └── README.md我解释一下它们的分工.github/steps/定义每步骤的元数据包括步骤名和这个步骤要做什么。它主要用来生成课程导航让学习者在 issue 里能对应到当前进度。.github/workflows/真正的判题核心。每个工作流监听一个特定事件并调用 GitHub API 或者脚本去判断学习者有没有完成当前步骤。responses/机器人回复内容的源文件。判题通过后工作流会读取这些 Markdown 文件把提示信息以评论的形式发出去。template 里默认有两个步骤也就是“欢迎”和“第一次操作”。你完全可以按这个结构加第三个、第四个步骤核心逻辑就是“多写一个 step 文件 多写一个 workflow 多写一个 response 文件”。3.2 一个最小可运行的工作流示例下面这个例子是我基于官方模板思路整理出来的。它监听一个 PR 的打开和同步事件然后检查 PR 里有没有一个包含指定内容的新文件。name: Check learner PR on: pull_request: types: [opened, synchronize] branches: - main permissions: pull-requests: write issues: write contents: read jobs: evaluate: runs-on: ubuntu-latest steps: - name: Checkout PR head uses: actions/checkoutv4 with: ref: ${{ github.event.pull_request.head.sha }} - name: Evaluate completion uses: actions/github-scriptv7 with: script: | const fs require(fs); const content fs.readFileSync(profile.md, utf8); const passed content.includes(name:) content.includes(bio:); const body passed ? 你已经完成了这一步可以继续下一步。 : 还没有看到预期的内容请确认 profile.md 里同时包含 name 和 bio 字段。; await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: body });这个工作流做了三件事先把 PR 的最新代码 checkout 出来再用脚本检查文件内容最后把结果写成评论。对一门小型课程来说这个骨架已经够用了。如果你的课程内容更复杂比如要求学习者先创建分支、再改三个文件、最后打开 PR那就在同一个 workflow 里加更多fs.readFileSync检查即可。3.3 步骤依赖与状态传递的两种常见做法自建课程很快会遇到一个问题课程有多个步骤如何知道学习者已经完成了第 1 步然后才放行第 2 步我见过比较有效的方案有两种。第一种是“渐进式文件”也就是每一步完成后脚本在仓库里生成一个隐藏的进度文件比如.skills/progress.json。第 2 步的工作流先去读这个文件如果发现里面没有step1: done就拒绝判定通过。这种方法的好处是状态一目了然缺点是学习者可能误删文件导致流程卡住。第二种是“标签法”每一步完成后工作流用 GitHub API 给当前 issue 或 PR 打一个标签比如step-1-complete。第 2 步的工作流监听这个标签或者读取 issue 的标签列表来确认前置步骤已经完成。因为标签是平台层面维护的数据不容易被学习者误操作稳定性更高。我自己更推荐第二种。原因很简单GitHub 的标签对象天然适合做状态机。而且在 issue 详情页里学习者能直接看到当前进度标签体验也更直观。4. 自建过程中容易翻车的五个细节4.1 token 权限与 403第一次写完工作流我碰到的第一个问题就是机器人评论发不出去报错是Resource not accessible by integration。原因不复杂仓库默认的工作流权限可能是只读的Actions 里的GITHUB_TOKEN没有权限去调 issues API 写评论。解决办法是去仓库的Settings - Actions - General - Workflow permissions里把权限改成 “Read and write permissions”。同时我也建议在每个 workflow 文件顶部显式声明permissions字段宁可写得清楚一点也不要依赖全局默认配置。这个习惯能避免很多莫名其妙的权限问题尤其是当课程仓库后来被别人 fork 或者复制时。4.2 pull_request 的事件陷阱在判题工作流里监听pull_request事件看起来很自然但要注意如果学习者是从 fork 仓库发 PR那么pull_request事件的GITHUB_TOKEN权限是受限的历史上很多攻击都利用了这个漏洞。更稳妥的做法是要求学习者在课程仓库内部新建分支也就是“同一仓库内 PR”而不是 fork 后再 PR。对于教学场景这样要求反而更简单还能顺带演示标准的仓库内协作流程。如果你确实需要支持 fork PR就得考虑用pull_request_target但这个事件会引入比较高的安全风险因为脚本运行在目标仓库的上下文里。除非你能严格校验 PR 内容否则我不建议在课程场景里用。4.3 多步骤课程的状态管理多步骤课程的另一大坑是“评论和状态分裂”。有时候学习者已经完成了当前步骤但机器人没有及时出现在正确的 issue 里。我做内训课程时为了让多步骤流程更稳定会把每一步的“通过评论”和“进入下一步说明”放在同一条评论里同时给 issue 打一个进度标签。这样即使学习者中途离开好几周回来只要看一眼评论历史就知道自己该干什么。另外工作流之间是独立触发的它们彼此之间没有先后顺序保证所以你一定要在每一步的判题脚本里判断“前一步是否满足”。不要在一个工作流里依赖另一个工作流的执行顺序那是脆弱的。4.4 学习者体验细节自动化课程很容易忽略人机交互细节我踩过的体验问题主要有两个。一个是 Actions 排队慢。用户提交以后如果仓库用的是免费公共运行器有时候要等几十秒甚至几分钟。新手会误以为自己操作错了然后就重复提交结果触发更多工作流。对策是在每步引导文案里明确写一句“等待 1-2 分钟是正常的”能省掉大量困惑。另一个是机器人回复的信息量。判题不通过时不要只说“不对”要尽量指出具体缺口。比如上面例子里的回复“请确认 profile.md 里同时包含 name 和 bio 字段”就是合格提示。但如果你说“检查一下文件内容吧”新手根本不知道从哪儿查起。判题脚本的回复文案本质上就是你给学生的唯一反馈值得多花时间打磨。4.5 面向企业内部时的可见性与入口官方 skills 页面对公共仓库开放但企业内训往往要放在私有仓库里这时候直接套用官方“点击 Start 自动创建仓库副本”的流程是行不通的。我的做法是准备一个私有模板仓库然后自己写一个很小的自动化入口要么用 GitHub Classroom 来做仓库分发要么在团队内部维护一个触发按钮每次调用 GitHub API 基于模板创建新仓库。对于小团队我更推荐简单粗暴的方案把模板仓库直接暴露给成员让他们用 “Use this template” 自建副本然后在 README 里写清楚“第一周完成课程仓库里的全部两个 issue”。这样成本最低也很实用。自动化只是锦上添花不是必须。5. 把它迁移到团队内训后我的真实使用感受5.1 新人 onboarding 场景我基于 skills 模板给团队搭过一套为期两周的 Git 协作训练课目标很简单让新人会建分支、会提 PR、会处理 review comment、会解决冲突。以前这些内容靠老员工轮流讲讲的人累听的人也就记个大概。现在直接把任务写进仓库新人在真实仓库里操作有问题就发给机器人判定老员工只需要在最后 review 一下代码质量不用机械重复基础的 Git 命令。实际用下来新人的上手速度明显快于只看文档的批次。最典型的变化是遇到问题时他们敢直接查日志、看 Actions 输出而不是第一反应就找个人问。因为课程里的自动化反馈已经把“试错”这件事变成安全操作错了也不会有人嘲笑改就行。5.2 与文档相比的价值和成本不过我也要泼一点冷水。自建一套 skills 课程的成本主要不在仓库模板而在每一条判题逻辑的打磨。你写出的每一个“通过/不通过”判断都是在替未来所有学习者做“质量把关”。如果课程开放性太强判题脚本会极其难写如果课程约束太死学习者又缺少自由发挥的空间。理想的课程设计是“任务范围清晰但操作路径允许差异”比如要求生成一个符合格式的 profile.md但不限制具体内容。这个平衡点需要试运营一两批学员之后才能找到。官方课程看起来顺滑是因为已经经历过很多轮真实反馈你自己建的课程不可能一步到位。所以在迁移到内训之前最好先在团队里找两三个志愿者试跑跑完再正式开放。这个步骤不能省省了后面就是几十个人同时来提报错你一个人根本回不过来。5.3 根据我的经验怎样的团队适合这套方案最后说点实际判断标准。如果你所在团队已经有比较成熟的文档文化只是缺实操练习那 skills 式课程是非常好的补充如果你的团队连最基础的仓库规范都没定我建议先把规范落地再做课程否则课程里教的习惯和团队实际流程不一致会适得其反。我个人用过之后最大的体会是一套好的自动化技能课本质上是把“老师傅带人”的经验沉淀成了可重复执行的程序。它不需要替代文档也不该替代人工 review但它能帮你把最基础的、重复性的教学工作收口让真正有经验的人有精力去处理那些自动化判断不了的、更需要人情味和判断力的问题。这件事无论对培训新人还是对团队规范化都值得投入。