
GitHub Actions / Workflows / Agents 学习指南
Github入门
GitHub Actions / Workflows / Agents 学习指南
面向:第一次在 GitHub 仓库页看到
Actions、Workflows、Agents三个入口,不确定它们分别是什么、自己的项目该不该用的人。
0. 一张表先分清
| 名称 | 是什么 | 谁在干活 | 需要写什么 | 典型用途 |
|---|---|---|---|---|
| Actions | GitHub 的自动化平台(CI/CD 基础设施) | GitHub 提供的云端机器(或你自己的机器) | 平台本身不用写,写的是 workflow | 承载所有自动化流程 |
| Workflows | 跑在 Actions 上的流程定义,一个 YAML 一个 workflow | 同上 | .github/workflows/*.yml |
测试、构建、发布、定时任务 |
| Agents | GitHub 的 AI 编码代理入口(Copilot 代理等) | AI 在云端容器里改代码 | 不用写 YAML,写清楚任务(issue) | 让 AI 接任务、开 PR |
一句话记忆:
- Actions = 平台;Workflow = 平台上的一个流程;Action(单数)= 流程里可复用的一个零件。
- Agents = 会写代码的 AI,不是 CI。
注意
Actions和Agents只差一个字母,但完全是两类东西。
1. GitHub Actions 是什么
1.1 它解决什么问题
没有 CI 时的开发循环是:
本地改代码 → 手动跑一遍 → 记得跑测试 → 记得看有没有漏文件 → 推送人会忘,机器不会。Actions 把"推送后该自动做的事"交给 GitHub:
git push → GitHub 自动启动一台干净机器 → 装依赖 → 跑检查 → 给你一个红/绿结果它的价值不在"能跑代码"(你本机也能跑),而在于:
- 干净环境:每次都是一台全新机器,能暴露"只在我电脑上能跑"的问题;
- 一致性:不依赖你本机装了什么;
- 留痕:每次提交都有检查结果,PR 上直接可见;
- 门禁:配合分支保护,检查不过就不允许合并。
1.2 核心概念(由大到小)
Workflow(.github/workflows/xxx.yml)
└─ Job(一个 job 跑在一台机器上)
└─ Step(job 里的一个步骤,按顺序执行)
├─ run: shell 命令
└─ uses: 调用一个现成的 Action(如 actions/checkout)| 概念 | 说明 |
|---|---|
| Workflow | 一个 YAML 文件 = 一条流水线,可被多个事件触发 |
| Job | 一个任务,默认并行运行,各自跑在独立的虚拟机上 |
| Step | Job 内的步骤,串行执行,共享同一个文件系统 |
| Runner | 执行 Job 的机器:GitHub 托管(ubuntu-latest / windows-latest / macos-latest)或自托管 |
| Action | 可复用的步骤单元,来自 Marketplace 或你自己的仓库;用 uses: 引用 |
| Event | 触发条件:push、pull_request、schedule、workflow_dispatch 等 |
1.3 生命周期要点(新手最容易踩)
- 每个 job 是一台新机器。上一个 job 装的东西、生成的文件,下一个 job 看不到,除非用
actions/upload-artifact/download-artifact传递。 - 同一 job 内的 step 共享状态,
cd只影响当前 step(每个run都是新的 shell),所以要写working-directory或每次cd。 - 工作目录默认是仓库根,即
$GITHUB_WORKSPACE。 - 默认没有代码,第一步几乎永远是
actions/checkout。 - 日志是公开的(公开仓库),别在里面打印密钥。
2. Workflows 详解
2.1 位置与命名
仓库根/
└── .github/
└── workflows/
├── ci.yml # 一个文件 = 一个 workflow
└── release.yml # 可以有多个- 目录必须是
.github/workflows/,大小写敏感。 - 文件名任意,
.yml或.yaml都行。 - 新建后只要推到默认分支,就会出现在
Actions页左侧列表。
2.2 最小可用骨架
name: CI # workflow 名称,显示在 Actions 页
on: # 触发事件
push:
branches: [main]
pull_request:
jobs:
check: # job 的 id(自定义)
runs-on: ubuntu-latest # 跑在哪类机器上
steps:
- uses: actions/checkout@v4 # 拉取代码
- uses: actions/setup-python@v5 # 安装 Python
with:
python-version: '3.14'
- run: python -m pip install -r requirements.txt
- run: python -m pip check
- run: python -m compileall -q agent model rag utils2.3 常用触发器
| 写法 | 何时触发 |
|---|---|
on: push |
任意分支推送 |
on: push: branches: [main] |
只推 main 时 |
on: push: tags: ['v*'] |
推 tag 时 |
on: pull_request |
开/更新 PR 时 |
on: workflow_dispatch |
手动点按钮触发(可带 inputs) |
on: schedule: - cron: '0 2 * * *' |
定时(UTC 时间!) |
on: release: types: [published] |
发布 Release 时 |
workflow_dispatch 带参数示例:
on:
workflow_dispatch:
inputs:
environment:
description: '要部署的环境'
required: true
default: 'staging'
type: choice
options: [staging, production]2.4 jobs 之间的依赖
jobs:
test:
runs-on: ubuntu-latest
steps: [...]
build:
needs: test # test 成功后才跑
runs-on: ubuntu-latest
steps: [...]没有 needs 时,多个 job 并行执行。
2.5 环境变量与密钥
env: # 全局环境变量
PYTHONUNBUFFERED: '1'
jobs:
test:
runs-on: ubuntu-latest
env:
APP_ENV: ci # job 级
steps:
- run: echo "运行在 $APP_ENV"
env:
DEBUG: '0' # step 级密钥只能来自仓库设置,不能写在 YAML 里:
仓库 → Settings → Secrets and variables → Actions → New repository secret然后引用:
- run: python -m pytest
env:
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}要点:
secrets在日志里会被自动打码,但自己echo出来仍然有风险,别这么干。- 来自 fork 的 PR 拿不到 secrets(这是安全设计),所以开源项目的 PR CI 不能依赖密钥。
- 公开仓库的日志人人可见。
2.6 缓存与产物
缓存依赖(大幅缩短安装时间):
- uses: actions/setup-python@v5
with:
python-version: '3.14'
cache: 'pip' # 自动缓存 pip 下载或手写:
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}产物(跨 job 传递文件 / 留存结果):
- uses: actions/upload-artifact@v4
with:
name: test-report
path: reports/
retention-days: 72.7 矩阵(一个 job 跑多组配置)
strategy:
fail-fast: false
matrix:
python-version: ['3.12', '3.13', '3.14']
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}会产生 3 × 2 = 6 个并行 job。注意矩阵会成倍消耗额度。
2.8 并发控制(避免重复跑)
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true同一分支连续推送时,自动取消上一次还在跑的流程。
2.9 表达式与常用上下文
if: github.event_name == 'push'
if: github.ref == 'refs/heads/main'
${{ runner.os }} # Linux / Windows / macOS
${{ github.sha }} # 提交哈希
${{ github.ref_name }} # 分支名
${{ hashFiles('requirements.txt') }}2.10 权限(安全重点)
GITHUB_TOKEN 是 GitHub 自动注入的临时令牌,默认权限可能偏大。显式收窄:
permissions:
contents: read需要写 PR 评论或发布时再按需加 pull-requests: write / issues: write。
3. Agents 是什么
3.1 它和 Actions 的根本区别
| Actions / Workflows | Agents | |
|---|---|---|
| 执行者 | 你写好的脚本 | AI 模型 |
| 输入 | 事件(push、PR…) | 一个任务描述(通常是 issue) |
| 输出 | 检查结果、构建产物 | 一个改好代码的 PR |
| 可预测性 | 确定性执行 | 概率性,需要人 review |
Agents 不是 CI 的替代品,而是"把一部分编码工作外包给 AI"。
3.2 GitHub 上的 Agents 具体指什么
新版 GitHub 仓库页的 Agents 入口,主要对应两类东西:
-
Copilot 编码代理(Copilot coding agent)
- 把 issue 指派给 Copilot(
Assignees里选 Copilot); - 它在云端启动一个隔离环境,读代码、改代码、跑测试、迭代;
- 完成后开一个 PR,作者是它,你需要 review 后合并。
- 把 issue 指派给 Copilot(
-
Agent HQ / 第三方代理接入
- GitHub 把 Claude、Codex 等第三方编码代理统一到同一入口管理;
- 概念同上:给任务、等 PR、人审查。
(界面细节会随版本变化,但"派任务 → 云端干活 → 开 PR"这条主线不变。)
3.3 它需要什么前置条件
- 有可用的 Copilot 订阅(额度按套餐计);
- 仓库启用 Copilot / 代理功能;
- 任务描述要清楚:改哪个文件、期望行为、验收标准;
- 分支保护通常要求 PR 必须经过人工 review 才能合并。
3.4 什么时候值得用
适合:
- 重复性的小改动(补测试、改文档、重命名、修 lint);
- issue 描述足够明确、验收标准可执行;
- 团队有多人 review,能兜住 AI 的错误。
不适合:
- 需求模糊、"你看着办"的任务;
- 涉及密钥、部署、生产数据的改动;
- 强依赖本地环境(需要本机 Ollama、本地数据库)的任务——云端跑不起来;
- 单人项目里为了省事跳过设计讨论,最后 review 成本更高。
3.5 限制与风险
- 环境限制:它跑在 GitHub 的容器里,访问不到你本机的 Ollama、本地服务和私有网络。
- 不能保证正确:产出的是"看起来合理"的补丁,必须跑测试 + 人审。
- 额度:代理执行会消耗 Copilot 配额,长任务可能排队或失败。
- 权限:它对仓库的写权限由平台策略控制,敏感仓库要谨慎开启。
- 审计:所有动作都在 PR 里留痕,这是优点,也意味着不能偷偷改。
4. 三者怎么选
你希望"提交后自动检查/构建/发布" → Actions + Workflows
你希望"AI 帮你写代码并开 PR" → Agents
你希望"定时跑个脚本" → Actions + schedule
你只是想让项目能跑起来 → 都不需要判断标准很简单:
- 有没有可以自动判定的结果(能通过/失败)→ 有,才谈 CI;
- 是不是需要重复执行(每次推送都要)→ 是,才值得写成 workflow;
- 任务能不能用一段清晰的自然语言描述→ 能,才谈 Agents。
5. 实战:给本项目加最小 CI(示例)
以下只是示例文件,没有放进仓库。要启用时新建
.github/workflows/ci.yml即可。
5.1 为什么这么设计
本项目有三个"CI 跑不了"的事实:
- 嵌入模型在本机 Ollama:
qwen3-embedding:0.6b,GitHub 机器上没有; - 聊天模型需要 DeepSeek API Key:CI 不该持有真实密钥;
- 知识库
chroma_db/没有进版本库:需要重新向量化才能用。
所以 CI 只做不依赖外部服务的检查:
- 依赖能否按
requirements.txt装成功; - 语法能否编译;
- 模块能否互相导入(这条最有价值——今天修工具名时,正是
react_agent.py导入不存在的名字会直接 ImportError)。
5.2 示例 YAML
name: CI
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
env:
# 仅占位:构造 ChatOpenAI 需要非空 key;CI 不会发起真实请求
DEEPSEEK_API_KEY: sk-ci-placeholder
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.14'
cache: 'pip'
- name: 安装依赖
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
- name: 依赖一致性
run: python -m pip check
- name: 语法编译
run: python -m compileall -q app.py agent model rag utils
- name: 模块导入
run: |
python -c "import utils.config_handler"
python -c "import model.factory"
python -c "import rag.vector_store"
python -c "import agent.react_agent"5.3 逐段解释
| 片段 | 作用 |
|---|---|
permissions: contents: read |
只读权限,最小化,防供应链攻击 |
DEEPSEEK_API_KEY: sk-ci-placeholder |
让模型工厂能构造客户端;ChatOpenAI 构造时只校验字符串非空,不发请求 |
cache: 'pip' |
按 requirements.txt 哈希缓存 pip 下载,后续跑得快 |
pip check |
抓版本冲突 |
compileall |
抓语法错误,不需要任何外部服务 |
python -c "import ..." |
抓 import 断链、循环依赖、改名漏改 |
不 import app.py |
它是 Streamlit 脚本,直接导入会执行界面代码,日志会充满警告 |
5.4 本地预演(推之前先自测)
python -m pip check
python -m compileall -q app.py agent model rag utils
python -c "import agent.react_agent"本机跑得通,CI 基本也能过;跑不通就先别推。
5.5 它验证不了什么(必须知道)
- RAG 检索是否准确 —— 需要真实向量库 + 嵌入模型;
- Agent 是否真的调用工具 —— 需要真实模型接口;
- 提示词效果 —— 需要人工看输出;
- 报告生成是否合理 —— 同上。
这些只能本地跑:
python -m rag.vector_store
python -m agent.react_agent
python -m streamlit run app.py6. 安全要点(比配置更重要)
6.1 密钥永远不进代码
.env必须在.gitignore里(本项目已配置);- 仓库里只放
.env.example(占位符); - CI 需要密钥时用
Settings → Secrets,不要写进 YAML; - 公开仓库的 Actions 日志是公开的。
6.2 pull_request_target 的经典陷阱
# 危险示例:在目标分支上下文里 checkout PR 代码并执行
on: pull_request_target
jobs:
test:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- run: python evil_script.py # ← 陌生人提交的代码拿到了 secretspull_request_target 拥有目标仓库的 secrets 和写权限,再执行 PR 里的代码,就等于把密钥交给陌生人的 PR。
规则:普通 PR 检查用 pull_request;确实需要 pull_request_target 时,不要 checkout PR 的代码去执行。
6.3 第三方 Action 要锁版本
- uses: actions/checkout@v4 # 可接受(官方)
- uses: some-user/some-action@v1 # 风险较高,作者可以改 v1 指向
- uses: some-user/some-action@<40位commit sha> # 最稳,内容不可变6.4 最小权限
permissions:
contents: read只在需要时增加(发布 Release、评论 PR 等)。
7. 费用与配额(大致规则)
- 公开仓库的 GitHub 托管 runner 通常免费;
- 私有仓库每月有免费分钟数,超出按分钟计费;
- Windows / macOS runner 的计费倍率高于 Linux;
- Agents(Copilot 代理) 消耗 Copilot 订阅额度,与 Actions 分钟数不是同一套计量;
- 具体额度以
Settings → Billing里显示的为准,平台会调整。
省钱要点:
- 优先
ubuntu-latest(最便宜、启动最快); - 用
cache: 'pip'减少重复下载; - 别把矩阵开太大;
- 用
concurrency取消重复运行; - 只对 main 和 PR 触发,别对每个分支的每次 push 都跑。
8. 调试与排查
| 现象 | 常见原因 |
|---|---|
| 工作流根本不出现 | YAML 不在 .github/workflows/,或文件后缀不是 .yml/.yaml,或推到非默认分支 |
报 Invalid workflow file |
YAML 缩进错误、键名拼错(GitHub 对 schema 校验很严) |
command not found |
没装依赖,或 shell 不同(Linux 默认 bash,注意 source 与 .\ 差异) |
No such file or directory |
忘了 actions/checkout,或工作目录不对 |
| 依赖装不上 | runner 的 Python 版本与项目不匹配;检查 setup-python 的 python-version |
| 缓存不生效 | key 里加了会变的内容(如时间戳) |
| 密钥是空的 | fork PR 拿不到 secrets;或 secret 名字拼错 |
| 时区不对 | schedule 的 cron 用 UTC |
| 检查通过了但本地失败 | runner 是 Linux,路径/大小写敏感,Windows 上的问题暴露不出来 |
9. 常见误区
- 把 Actions 当"运行环境":它只跑你写的流程,不会替你托管应用。要做公网服务得另找部署平台。
- 以为 job 之间共享文件:不共享,必须用 artifacts 或重新生成。
- 在 CI 里跑需要密钥的端到端测试:开源项目做不到(fork PR 无 secrets),而且成本高。
- 把
Agents当成 CI:它是 AI 写代码,不是自动检查。 - 误以为 workflow 一提交就生效:必须推到默认分支(或该分支已存在该文件)才会被识别。
- YAML 里写
echo ${{ secrets.X }}调试:日志可能泄漏。 - 用
pull_request_target图省事:这是 GitHub 安全公告里的高频问题。
10. Checklist
给仓库加 CI 前:
- 存在可自动判定通过/失败的检查项
- 检查项不依赖本机私有服务(Ollama、本地 DB、私有网络)
- 需要密钥的步骤已经想清楚:要么不放进 CI,要么走 Secrets
-
.env、虚拟环境、运行产物都在.gitignore里 - 本地先手动跑通 CI 里的每一条命令
- 设置
permissions: contents: read - 第三方 action 锁版本(重要的锁 SHA)
考虑使用 Agents 前:
- 任务能用一段清晰文字描述,且有可验证的验收标准
- 改动不涉及密钥、部署、生产数据
- 有人在 PR 上做 review
- 任务不依赖本机环境
11. 速查表
# 常用骨架
name: CI
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.14'
cache: 'pip'
- run: python -m pip install -r requirements.txt| 需求 | 写法 |
|---|---|
| 手动触发 | on: workflow_dispatch |
| 定时(UTC) | on: schedule: [{ cron: '0 2 * * *' }] |
| 并行多版本 | strategy: matrix |
| 依赖前一个 job | needs: <job-id> |
| 取消重复运行 | concurrency: { group: ..., cancel-in-progress: true } |
| 传文件给下一个 job | upload-artifact / download-artifact |
| 读密钥 | ${{ secrets.NAME }} |
| 概念 | 一句话 |
|---|---|
| Actions | 自动化平台 |
| Workflow | 一个 YAML 流水线 |
| Action | 流水线里的可复用零件 |
| Agent | 会写代码的 AI |
编写日期:2026-11-07。GitHub 界面与配额会随版本调整,具体以官方文档与仓库设置页为准。
评论 (0)
还没有评论,来写第一条吧~