# GitHub Actions
GitHub Actions 工作流创建、安全加固与版本管理,适用于 CI/CD 流水线。
- 涵盖工作流文件编写(`.yml`)、通过 `gh release view` 更新 Action 版本,以及密钥管理、脚本注入防护等安全最佳实践
- 明确禁止反模式:使用过时的 Action 版本、硬编码敏感凭证、输入值注入漏洞、误用 `pull_request_target` 事件、重复配置已预装工具
- 推荐最小权限原则、对不可信第三方 Action 使用 SHA 哈希固定(SHA pinning),以及通过环境变量隔离敏感数据
- 包含常用触发事件(`push`、`pull_request`、`schedule`、`workflow_dispatch`、`release`)和典型 CI/CD 场景所需的权限范围
> ⚠️ 提示:涉及 GitHub Actions 工作流执行与结果查看、Issue/PR 管理等 `gh` CLI 操作,请一并加载 `github` 技能参考。
## 反模式警示(Anti-patterns)
### 1. 使用过时的 Action 版本
```yaml
# ❌ 过due 版本 —— 最常见错误
uses: actions/checkout@v4 # 当前最新主版本为 v6 时
# ✅ 使用最新主版本(先用 gh release view 确认)
uses: actions/checkout@v6
```
确保获得最新版本带来的性能优化与安全补丁。
版本查询命令:
```bash
gh release view --repo {owner}/{repo} --json tagName --jq '.tagName'
# 示例
gh release view --repo actions/checkout --json tagName --jq '.tagName'
gh release view --repo oven-sh/setup-bun --json tagName --jq '.tagName'
```
> 💡 提示:在安全敏感环境或使用低信任度第三方 Action 时,建议采用 [SHA 固定](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions)(如 `@a1b2c3...`)。
### 2. 硬编码敏感信息
```yaml
# ❌ 危险:明文硬编码
env:
API_KEY: "sk-1234567890"
DATABASE_PASSWORD: "mypassword123"
# ✅ 安全:使用 secrets
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
```
密码、API Key 等敏感信息一旦泄露,将直接导致安全事件。所有高敏感数据必须存储于仓库或组织级 Secrets 中,并通过 `${{ secrets.XXX }}` 引用。
> 🔗 参考:[Using secrets in GitHub Actions](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions)
### 3. 输入值注入漏洞(Script Injection)
```yaml
# ❌ 危险:直接拼接 github.event 字段(易受注入)
run: echo "${{ github.event.issue.title }}"
run: gh issue comment ${{ github.event.issue.number }} --body "${{ github.event.comment.body }}"
# ✅ 安全:通过环境变量传递,避免 shell 解析风险
env:
ISSUE_TITLE: ${{ github.event.issue.title }}
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
echo "$ISSUE_TITLE"
gh issue comment ${{ github.event.issue.number }} --body "$COMMENT_BODY"
```
恶意用户可能在 Issue 标题或 Comment 内注入任意 shell 命令。应始终避免将未过滤的事件字段直接用于 `run` 行。
> 🔗 参考:[Understanding the risk of script injections](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#understanding-the-risk-of-script-injections)
### 4. 误用 `pull_request_target` 事件
```yaml
# ⚠️ 高危:在可信上下文中执行 fork 的代码
on: pull_request_target
steps:
- uses: actions/checkout@v{N}
with:
ref: ${{ github.event.pull_request.head.sha }} # ❌ 极度危险!
```
`pull_request_target` 允许 fork 发起的 PR 访问仓库 Secrets,若同时检出其代码,可能导致恶意逻辑执行。
> 🔗 参考:[Events that trigger workflows: `pull_request_target`](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target)
### 5. 对已预装工具重复配置
```yaml
# ❌ 冗余:Node.js、npm、npx 等已预装,无需 setup
steps:
- uses: actions/setup-node@v{N}
- run: npx some-command
# ✅ 直接使用
steps:
- run: npx some-command
- run: python script.py
- run: docker build .
```
重复安装会延长流水线耗时,并产生不必要的网络请求。
✅ **已预装工具**(Ubuntu/macOS/Windows runner):
`Node.js`, `npm`, `npx`, `Python`, `pip`, `Ruby`, `gem`, `Go`, `Docker`, `git`, `gh`, `curl`, `wget`, `jq`, `yq`
❌ **需手动安装的常见工具**:
`Bun`, `Deno`, `Rust`, `Zig`, `pnpm`, `Poetry`, `Ruff`
🔍 查看完整预装清单:
- Ubuntu:[Ubuntu2404-Readme.md](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md)
- macOS:[macos-15-Readme.md](https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md)
- Windows:[Windows2022-Readme.md](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md)
## 最佳实践(Best Practices)
### 最小权限原则(Principle of Least Privilege)
权限应在尽可能细粒度的层级声明(`workflow` > `job` > `step`),范围越窄越安全:
```yaml
# ✅ 推荐:在 job 级别声明仅需权限
jobs:
build:
permissions:
contents: read # 仅读取代码所需
```
> 🔗 参考:[Modifying the permissions for the GITHUB_TOKEN](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token)
## 推荐工作流结构
```yaml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
# 版本请先用 gh release view 确认
- uses: actions/checkout@v{N}
- name: Setup Bun
uses: oven-sh/setup-bun@v{N}
```
## 常用触发事件
```yaml
on:
push: # 推送代码时
branches: [main]
pull_request: # 创建或更新 PR 时
branches: [main]
workflow_dispatch: # 手动触发
schedule: # 定时触发
- cron: "0 0 * * 1" # 每周一 00:00 UTC
release: # 发布新版本时
types: [published]
workflow_call: # 被其他工作流调用时
```
## 常用权限配置
```yaml
permissions:
contents: read # CI 构建/测试、代码检出
contents: write # 提交/推送代码
pull-requests: write # PR 评论机器人
issues: write # Issue 评论
packages: write # 发布包(需配合 contents: write)
id-token: write # OIDC 云身份认证(需配合 contents: read)
```
## 常用 Action 列表
```yaml
# 版本请统一通过 gh release view --repo {owner}/{repo} --json tagName --jq '.tagName' 查询
steps:
- uses: actions/cache@v{N} # 依赖缓存
- uses: actions/checkout@v{N} # 代码检出
- uses: actions/download-artifact@v{N} # 下载产物
- uses: actions/upload-artifact@v{N} # 上传产物
- uses: oven-sh/setup-bun@v{N} # 安装 Bun
```