# GitHub Actions 操作手册

## 1. 先说结论：GitHub Actions 是什么

GitHub Actions 是 GitHub 内置的自动化平台，本质上就是：

- 用 YAML 文件定义一套自动执行流程
- 当仓库里发生某些事件时自动触发
- 在 GitHub 提供的运行环境（Runner）里执行脚本或现成 Action
- 常见用途是 CI/CD，但不止于此

你可以把它理解成：

“把原本需要你手工执行的构建、测试、发布、打包、部署、通知等流程，交给 GitHub 自动跑。”

它最典型的价值有 4 个：

1. 自动化：代码 push / PR 后自动测试、构建、部署
2. 规范化：团队每次都按同样流程执行，减少人为遗漏
3. 可观测：每次运行都有日志、状态、产物、失败原因
4. 与 GitHub 深度集成：直接响应 push、pull_request、issue、release 等事件

官方文档依据：
- Understanding GitHub Actions
- Workflow syntax for GitHub Actions
- Building and testing Python
- Using secrets in GitHub Actions
- Store and share data with workflow artifacts
- Dependency caching
- Secure use reference

---

## 2. GitHub Actions 能做什么

最常见的使用场景：

### 2.1 持续集成 CI
- 提交代码后自动安装依赖
- 自动运行单元测试 / 集成测试
- 自动执行 lint / format / type check
- 自动生成测试报告

### 2.2 持续交付 / 持续部署 CD
- 合并到 main 后自动打包
- 自动构建 Docker 镜像
- 自动发布到 npm / PyPI / Docker Hub
- 自动部署到服务器 / 云平台 / Kubernetes / Vercel / Netlify

### 2.3 仓库自动化
- Issue 创建后自动打标签
- PR 自动分配 reviewer
- 自动检查 PR 标题或提交规范
- 自动同步文档、自动生成 changelog

### 2.4 研发辅助
- 定时任务（例如每天拉取数据、生成报表）
- 自动上传构建产物
- 多平台矩阵测试（Linux / macOS / Windows，Python 3.10 / 3.11 / 3.12）

---

## 3. 核心概念，一次搞懂

这是最重要的一部分。

### 3.1 Workflow
Workflow 是“工作流”，是完整自动化流程的定义文件。

- 以 YAML 编写
- 存放在仓库目录：`.github/workflows/`
- 一个仓库可以有多个 workflow

例如：
- `ci.yml`：测试与检查
- `deploy.yml`：部署流程
- `release.yml`：发布版本

### 3.2 Event
Event 是“触发事件”，即什么时候运行 workflow。

常见事件：
- `push`：推送代码时
- `pull_request`：PR 创建、更新时
- `workflow_dispatch`：手动触发
- `schedule`：定时触发
- `release`：创建 release 时
- `issues`：issue 被创建/编辑时

### 3.3 Job
Job 是 workflow 里的一个“任务单元”。

特点：
- 一个 workflow 可以有多个 job
- job 默认可以并行执行
- 也可以通过 `needs` 设置依赖顺序
- 每个 job 通常运行在独立 runner 上

例子：
- `lint`
- `test`
- `build`
- `deploy`

### 3.4 Step
Step 是 job 里的“步骤”。

例如一个 job 可以包含：
1. checkout 代码
2. 安装依赖
3. 运行测试
4. 上传产物

step 会按顺序执行。

### 3.5 Action
Action 是可复用的自动化组件。

你可以理解为：别人已经封装好的功能模块，你直接拿来用。

常见官方 / 社区 Action：
- `actions/checkout`：拉取仓库代码
- `actions/setup-python`：安装/配置 Python
- `actions/setup-node`：安装/配置 Node.js
- `actions/upload-artifact`：上传产物
- `actions/download-artifact`：下载产物
- `actions/cache`：缓存依赖

### 3.6 Runner
Runner 是真正执行 workflow 的机器。

类型：
- GitHub-hosted runner：GitHub 提供的 Ubuntu / Windows / macOS 虚拟机
- Self-hosted runner：你自己维护的机器

大多数团队一开始直接用 GitHub-hosted 就够了。

---

## 4. 工作原理：它到底是怎么跑起来的

一个典型流程如下：

1. 你把 workflow YAML 文件提交到仓库
2. GitHub 监听仓库事件
3. 事件满足触发条件时，启动一次 workflow run
4. GitHub 分配 runner
5. runner 按 job -> step 顺序执行
6. 结果显示在仓库的 Actions 页签
7. 成功 / 失败日志、产物、状态检查会保留下来

可以把它理解成：

事件 -> 触发 workflow -> 分配 runner -> 执行 job/step -> 输出结果

---

## 5. 最小可用示例：从 0 到 1

### 5.1 目录位置
在仓库下创建：

`.github/workflows/ci.yml`

### 5.2 最简单的工作流

```yaml
name: Hello Actions

on:
  workflow_dispatch:
  push:
    branches:
      - main

jobs:
  hello:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Print message
        run: echo "Hello GitHub Actions"
```

### 5.3 这段配置怎么理解
- `name`：工作流名称
- `on`：触发条件
- `workflow_dispatch`：允许手动触发
- `push.branches`：main 分支有 push 时触发
- `jobs.hello`：定义一个 job
- `runs-on`：指定 runner
- `uses`：使用现成 action
- `run`：执行 shell 命令

### 5.4 如何验证
提交后去仓库：
- `Actions` 页签
- 找到 `Hello Actions`
- 看是否成功执行

---

## 6. Workflow 文件的常见结构

一个标准 workflow 通常长这样：

```yaml
name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read

env:
  APP_ENV: test

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup runtime
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install deps
        run: npm ci

      - name: Run tests
        run: npm test
```

重点字段说明：

### 6.1 `name`
工作流名字。

### 6.2 `on`
触发方式。

常见写法：

```yaml
on: push
```

或：

```yaml
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:
  schedule:
    - cron: '0 2 * * *'
```

### 6.3 `permissions`
设置 `GITHUB_TOKEN` 权限。

建议默认最小化，比如：

```yaml
permissions:
  contents: read
```

如果 workflow 需要写入内容或发布，需要按需增加权限。

### 6.4 `env`
环境变量，可在 workflow / job / step 级别定义。

### 6.5 `jobs`
包含所有任务。

### 6.6 `runs-on`
指定运行环境，例如：
- `ubuntu-latest`
- `windows-latest`
- `macos-latest`

### 6.7 `steps`
任务中的步骤列表。

### 6.8 `uses`
调用 action。

### 6.9 `run`
执行 shell 命令。

### 6.10 `with`
给 action 传参数。

### 6.11 `needs`
定义 job 之间依赖。

例如：

```yaml
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: echo "test"

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - run: echo "deploy"
```

表示：先 `test`，成功后再 `deploy`。

---

## 7. 典型实战 1：Node.js 项目 CI

适合前端、Node 后端项目。

```yaml
name: Node CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint --if-present

      - name: Test
        run: npm test --if-present

      - name: Build
        run: npm run build --if-present
```

说明：
- `cache: npm` 可以复用依赖缓存，加快速度
- `--if-present` 能避免某些脚本未定义时报错

---

## 8. 典型实战 2：Python 项目 CI

这是 GitHub Docs 官方教程里最经典的场景之一。

```yaml
name: Python CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.11", "3.12"]

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: 'pip'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run tests
        run: pytest
```

这段 workflow 展示了两个关键点：
- 使用 `actions/setup-python`
- 使用 `matrix` 做多版本测试

### 8.1 什么是 matrix
矩阵策略会让同一个 job 用不同变量组合跑多次。

例如上面会跑 3 次：
- Python 3.10
- Python 3.11
- Python 3.12

这很适合：
- 多语言版本兼容性测试
- 多操作系统测试
- 多环境组合测试

---

## 9. 典型实战 3：构建产物上传 artifacts

当你想保留构建结果、测试报告、日志时，用 artifacts。

```yaml
name: Build and Archive

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build
        run: |
          mkdir -p dist
          echo "build result" > dist/app.txt

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: dist/
          retention-days: 5
```

适合保存：
- 构建后的二进制文件
- 前端打包产物
- 测试覆盖率报告
- 调试日志

### 9.1 artifact 和 cache 的区别
这是新手很容易混淆的点。

#### cache 的作用
- 用于复用“经常重复下载、变化不频繁”的文件
- 典型是依赖缓存
- 目标是加速 workflow

例如：
- npm 缓存
- pip 缓存
- Maven / Gradle 缓存

#### artifact 的作用
- 保存某次运行产出的文件
- 典型是构建结果、报告、日志
- 目标是查看、下载、跨 job 传递结果

一句话区分：
- cache = 为了更快
- artifact = 为了保存结果

---

## 10. 典型实战 4：部署流程

一个最常见的部署思路是：
- PR / push 时先跑测试
- 只有 main 分支且测试通过后才部署

示例：

```yaml
name: Deploy App

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "run tests here"

  deploy:
    needs: test
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - name: Deploy
        run: echo "deploy to production"
```

这里建议你进一步配合：
- `environment: production`
- 环境级 secrets
- 必要的审批机制（review required）

这样会更安全。

---

## 11. 如何在 GitHub 界面里使用

除了写 YAML，你还要会在 GitHub 页面上操作。

### 11.1 查看运行结果
仓库 -> `Actions` 页签

你能看到：
- 哪个 workflow 在运行
- 哪次运行成功/失败
- 哪个 job 失败
- 每个 step 的日志

### 11.2 手动触发 workflow
前提：workflow 里有 `workflow_dispatch`

然后：
- 进入 `Actions`
- 选择对应 workflow
- 点击 `Run workflow`
- 选择分支并执行

### 11.3 重新运行
失败后可以：
- Re-run all jobs
- Re-run failed jobs

### 11.4 下载 artifacts
进入某次 workflow run 后，可在页面下载上传的 artifact。

---

## 12. 如何用 GitHub CLI 管理 Actions

如果你平时在终端工作，`gh` 很方便。

### 12.1 查看 workflow 列表
```bash
gh workflow list
```

### 12.2 查看最近运行
```bash
gh run list --limit 10
```

### 12.3 查看某次运行详情
```bash
gh run view <RUN_ID>
```

### 12.4 查看失败日志
```bash
gh run view <RUN_ID> --log-failed
```

### 12.5 重跑
```bash
gh run rerun <RUN_ID>
gh run rerun <RUN_ID> --failed
```

### 12.6 手动触发 workflow
```bash
gh workflow run ci.yml --ref main
```

如果 workflow 定义了 `workflow_dispatch.inputs`，也可以传参数。

---

## 13. Secrets、变量和权限：必须会的安全基础

这是 GitHub Actions 最容易出事故的地方。

### 13.1 Secrets 是什么
Secrets 是敏感信息存储机制，常见用途：
- API Key
- SSH 私钥
- 云平台 Token
- Docker 登录凭证

不要把这些明文写进仓库。

### 13.2 Secrets 可以放在哪
GitHub 官方支持多级别：
- Repository secrets
- Environment secrets
- Organization secrets

建议：
- 单仓库专用：repository secrets
- 生产部署：environment secrets
- 多仓库共用：organization secrets

### 13.3 在 workflow 中使用 secrets
```yaml
env:
  API_KEY: ${{ secrets.API_KEY }}
```

或：

```yaml
- name: Call API
  run: curl -H "Authorization: Bearer $API_KEY" https://example.com
  env:
    API_KEY: ${{ secrets.API_KEY }}
```

### 13.4 常见安全原则
根据 GitHub 官方 secure use reference，推荐你遵循：

1. 最小权限原则
   - 默认给 `GITHUB_TOKEN` 最小权限
   - 能 `read` 就不要 `write`

2. 不要把 secret 直接写进脚本或仓库

3. 对第三方 action 保持谨慎
   - 尽量使用官方 action
   - 社区 action 尽量固定版本，而不是永远跟随最新 tag

4. 谨慎处理不可信输入
   - 比如 PR 标题、issue 内容、外部参数
   - 官方建议：优先用 action 参数或中间环境变量，不要直接拼接到 shell 脚本里

5. secret 泄漏后要立刻轮换

### 13.5 一个更安全的权限示例
```yaml
permissions:
  contents: read
```

如果要发布 release，才按需增加：

```yaml
permissions:
  contents: write
```

---

## 14. 常见触发方式大全

### 14.1 push
```yaml
on:
  push:
    branches: [main]
```

### 14.2 pull_request
```yaml
on:
  pull_request:
    branches: [main]
```

适合 PR 检查。

### 14.3 workflow_dispatch
```yaml
on:
  workflow_dispatch:
```

适合手动运行。

### 14.4 schedule
```yaml
on:
  schedule:
    - cron: '0 2 * * *'
```

适合夜间任务、定时报表、数据同步。

### 14.5 多事件组合
```yaml
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:
```

这是实际项目里最常用的一种组合。

---

## 15. 常见高级能力

### 15.1 job 依赖
```yaml
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - run: echo "lint"

  test:
    needs: lint
    runs-on: ubuntu-latest
    steps:
      - run: echo "test"

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - run: echo "deploy"
```

### 15.2 条件执行
```yaml
- name: Run only on main
  if: github.ref == 'refs/heads/main'
  run: echo "main only"
```

### 15.3 矩阵策略
```yaml
strategy:
  matrix:
    os: [ubuntu-latest, windows-latest]
    node: [18, 20]
```

### 15.4 缓存依赖
官方文档建议使用缓存来缩短运行时间。

例如 Node：
```yaml
- uses: actions/setup-node@v4
  with:
    node-version: 20
    cache: npm
```

例如 Python：
```yaml
- uses: actions/setup-python@v5
  with:
    python-version: '3.11'
    cache: 'pip'
```

### 15.5 环境变量
```yaml
env:
  APP_ENV: production
```

### 15.6 手动输入参数
```yaml
on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deploy environment'
        required: true
        type: choice
        options:
          - staging
          - production
```

---

## 16. 一个相对完整的 CI 示例

这是比较适合多数中小项目直接改造使用的模板。

```yaml
name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

jobs:
  lint-and-test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - name: Install
        run: npm ci

      - name: Lint
        run: npm run lint --if-present

      - name: Test
        run: npm test --if-present

      - name: Build
        run: npm run build --if-present

      - name: Upload dist
        if: success()
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/
          retention-days: 7
```

这个模板做了几件实用的事：
- 支持 push / PR / 手动触发
- 最小权限
- 并发控制，避免同一分支重复跑老任务
- 缓存 npm
- 构建成功后保存产物

---

## 17. 新手最常见问题与排查方法

### 17.1 workflow 没有触发
常见原因：
- YAML 文件没放在 `.github/workflows/`
- `on` 条件不匹配
- 分支名写错
- workflow 文件语法错误
- 仓库 Actions 功能被禁用

排查顺序：
1. 先确认文件路径
2. 再看触发条件
3. 再看 Actions 页签是否有语法错误提示

### 17.2 `uses:` 的 action 报错
常见原因：
- action 名字写错
- 版本不存在
- 第三方 action 不兼容

建议：
- 优先使用官方 action
- 优先固定稳定版本

### 17.3 依赖安装失败
常见原因：
- 锁文件和包管理器不一致
- runner 环境版本不对
- 网络或源问题

建议：
- Node 用 `npm ci`
- Python 明确版本并固定依赖
- 用缓存提高稳定性和速度

### 17.4 找不到 secret
常见原因：
- secret 名写错
- secret 存放层级不对
- fork PR 场景下 secret 不会像普通仓库那样传入 runner
- reusable workflow 不会自动继承 secret

### 17.5 日志看不出原因
建议：
- 给关键步骤拆分更细
- 避免把很多命令塞进一个 step
- 对关键变量输出非敏感调试信息
- 用 artifact 上传日志、报告、构建产物

---

## 18. 最佳实践：少走弯路版本

### 18.1 从简单开始
不要一开始就写很复杂的 pipeline。

推荐顺序：
1. 先做 CI：checkout -> install -> test
2. 再加 lint / build
3. 最后再加 deploy / artifact / matrix / environment

### 18.2 一个 workflow 只做一类职责
例如：
- `ci.yml` 做测试
- `deploy.yml` 做部署
- `release.yml` 做发布

这样可读性和可维护性更好。

### 18.3 默认最小权限
从：
```yaml
permissions:
  contents: read
```
开始。

### 18.4 优先使用官方 action
例如：
- `actions/checkout`
- `actions/setup-node`
- `actions/setup-python`
- `actions/upload-artifact`

### 18.5 使用缓存，但不要滥用
缓存适合依赖，不适合保存最终交付结果。

### 18.6 保留关键产物
测试报告、打包结果、部署日志尽量保留，方便排查。

### 18.7 对部署使用 environment
生产环境建议：
- 使用 environment secrets
- 设置审批
- 区分 staging / production

### 18.8 并发控制
对频繁 push 的分支，建议加：

```yaml
concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true
```

这样可以取消旧任务，避免资源浪费。

---

## 19. 推荐学习路径

如果你现在刚开始，建议按这个顺序学：

### 第 1 步：先会看
先能看懂一个基本 workflow：
- `on`
- `jobs`
- `steps`
- `uses`
- `run`

### 第 2 步：先做最小 CI
给自己的一个项目加：
- checkout
- 安装依赖
- test

### 第 3 步：再加缓存与 artifact
学会：
- cache 提速
- artifact 保留结果

### 第 4 步：再学 secrets 和 deployment
学会：
- repository/environment secrets
- 最小权限
- main 分支部署

### 第 5 步：最后学矩阵与复用
学会：
- `strategy.matrix`
- job 依赖
- reusable workflow

---

## 20. 给你一个落地操作清单

如果你今天就想把 GitHub Actions 用起来，按下面做：

### 场景 A：给现有项目加自动测试
1. 在仓库创建 `.github/workflows/ci.yml`
2. 写一个最小 CI workflow
3. push 到 GitHub
4. 打开 `Actions` 页面看结果
5. 根据错误修到跑通
6. 再增加 lint / build

### 场景 B：给项目加自动部署
1. 先把 CI 跑稳定
2. 在仓库配置 secrets
3. 单独创建 `deploy.yml`
4. 仅允许 main 分支或手动触发部署
5. 用 environment 区分 staging / production
6. 上线前先在测试环境验证

### 场景 C：团队协作场景
1. 让 PR 自动触发测试
2. 把 CI 状态设为分支保护条件
3. 测试必须通过才允许合并
4. 合并后自动打包/发布/部署

---

## 21. 一个真正实用的入门模板

如果你现在没有特定语言，我建议先用这个通用模板做起点：

```yaml
name: Basic CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Show environment
        run: |
          uname -a
          pwd
          ls -la

      - name: Run your commands
        run: |
          echo "Replace this with install / test / build"
```

你只需要把最后一步替换成自己的项目命令即可。

---

## 22. 一页速查版

### GitHub Actions = 什么
- GitHub 内置自动化平台
- 用 YAML 定义流程
- 监听仓库事件并自动执行

### 工作流文件放哪
- `.github/workflows/*.yml`

### 5 个核心概念
- Workflow：工作流
- Event：触发事件
- Job：任务
- Step：步骤
- Runner：执行环境

### 最常用事件
- `push`
- `pull_request`
- `workflow_dispatch`
- `schedule`

### 最常用 action
- `actions/checkout`
- `actions/setup-node`
- `actions/setup-python`
- `actions/upload-artifact`

### 最常用用途
- 自动测试
- 自动构建
- 自动部署
- 自动发布
- 自动仓库管理

### 最重要的 3 个最佳实践
1. 从简单 CI 开始
2. 权限最小化
3. secret、cache、artifact 分清用途

---

## 23. 你接下来最值得做的事

如果你想真正学会，而不是“看懂但不会用”，最好的下一步不是继续读文档，而是马上拿一个真实项目练 1 次。

推荐你现在就做：

1. 选一个自己的 GitHub 仓库
2. 新建 `.github/workflows/ci.yml`
3. 写一个最小 workflow
4. push 上去
5. 看 Actions 日志
6. 我再帮你逐步把它改成适合你项目的版本

如果你愿意，我下一步可以直接继续帮你做这 3 件事里的任意一个：

- 按你的项目技术栈，生成一份可直接用的 `ci.yml`
- 再整理一份“GitHub Actions 常见报错排查手册”
- 再整理一份“GitHub Actions 部署实战手册（Node / Python / Docker 版）”

---

## 24. 参考资料

本手册整理时参考的 GitHub 官方文档主题：
- Understanding GitHub Actions
- Workflow syntax for GitHub Actions
- Building and testing Python
- Using secrets in GitHub Actions
- Store and share data with workflow artifacts
- Dependency caching
- Secure use reference
