别着急,坐和放宽
使用社交账号登录
Dependabot 自动管理项目依赖的三大功能:
| 功能 | 作用 | 默认状态 |
|---|---|---|
| Alerts | 发现安全漏洞时警报 | 公共仓库默认开启 |
| Security Updates | 自动修复安全漏洞 | 默认开启 |
| Version Updates | 定期更新到最新版本 | 需手动开启 |
步骤 1: 进入仓库 → Settings → Code security and analysis
步骤 2: 启用三个功能
✅ Dependabot alerts → Enable
✅ Dependabot security updates → Enable
✅ Dependabot version updates → Enable (会自动创建配置文件)
创建 .github/dependabot.yml:
常用配置项:
自动触发重新生成: 在 PR 中评论 @dependabot rebase
手动触发检查: Insights → Dependency graph → Dependabot → 点击刷新
GitHub Actions 是 GitHub 提供的 CI/CD 自动化平台,可以自动执行:
关键术语:
| 术语 | 说明 | 示例 |
|---|---|---|
| Workflow | 自动化流程,一个 YAML 文件 | ci.yml |
| Event | 触发条件 | push, pull_request |
| Job | 一组步骤,可并行执行 | test, build |
| Step | 单个任务 | 运行测试命令 |
| Action | 可复用的操作单元 | actions/checkout@v4 |
| Runner | 执行环境 | ubuntu-latest |
常用上下文变量:
设置密钥: 仓库 Settings → Secrets and variables → Actions → New repository secret
创建 .github/workflows/ci-cd.yml:
创建 .github/workflows/dependabot-auto-merge.yml:
创建 .github/workflows/coverage.yml:
创建 .github/workflows/publish.yml:
创建 .github/workflows/update-deps.yml:
创建 .github/workflows/format-check.yml:
创建 .github/workflows/performance.yml:
确保 package.json 包含这些脚本:
version: 2
updates:
# npm 依赖更新
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly" # 每周检查
day: "monday" # 周一
time: "02:00" # 凌晨2点
timezone: "Asia/Shanghai"
open-pull-requests-limit: 5 # 最多同时5个PR
labels:
- "dependencies" # PR标签
- "automerge"
# 忽略特定包
ignore:
- dependency-name: "react"
versions: ["17.x"] # 暂不升级到18
# 仅更新生产依赖
allow:
- dependency-type: "production"
# 自定义提交消息
commit-message:
prefix: "chore(deps)" # 提交前缀
Workflow (工作流)
├── Jobs (任务)
│ ├── Steps (步骤)
│ │ ├── Action 1
│ │ ├── Action 2
│ │ └── ...
项目根目录/
└── .github/
└── workflows/
├── ci.yml # 持续集成
├── deploy.yml # 自动部署
└── release.yml # 发布管理
# 工作流名称
name: CI
# 触发条件
on:
push:
branches: [main, develop] # 推送到指定分支时触发
pull_request:
branches: [main] # PR 到指定分支时触发
schedule:
- cron: '0 2 * * *' # 定时触发(每天凌晨2点)
workflow_dispatch: # 手动触发
# 任务
jobs:
job-name:
# 运行环境
runs-on: ubuntu-latest # ubuntu-latest, windows-latest, macos-latest
# 步骤
steps:
# 使用官方 Action
- uses: actions/checkout@v4
# 运行命令
- name: 步骤名称
run: echo "Hello World"
# 使用环境变量
- name: 使用变量
run: echo ${{ secrets.SECRET_NAME }}
env:
NODE_ENV: production
on:
# 代码推送
push:
branches: [main]
paths: # 仅当指定文件改变时触发
- 'src/**'
- 'package.json'
# Pull Request
pull_request:
types: [opened, synchronize, reopened]
# Issue 事件
issues:
types: [opened, labeled]
# Release 发布
release:
types: [published]
# 定时任务 (UTC 时间)
schedule:
- cron: '0 0 * * 0' # 每周日午夜
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
steps:
# 1. 检出代码
- uses: actions/checkout@v4
# 2. 设置 Node.js
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # 缓存依赖
# 3. 设置 Python
- uses: actions/setup-python@v5
with:
python-version: '3.11'
# 4. 缓存依赖
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# 5. 上传构建产物
- uses: actions/upload-artifact@v4
with:
name: build-files
path: dist/
# 6. 下载构建产物
- uses: actions/download-artifact@v4
with:
name: build-files
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
# 排除特定组合
exclude:
- os: windows-latest
node-version: 18
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm test
jobs:
# Job 1: 构建
build:
runs-on: ubuntu-latest
steps:
- run: npm run build
# Job 2: 测试 (依赖 build)
test:
needs: build # 等待 build 完成
runs-on: ubuntu-latest
steps:
- run: npm test
# Job 3: 部署 (依赖 test)
deploy:
needs: [build, test] # 等待多个 job
runs-on: ubuntu-latest
steps:
- run: npm run deploy
jobs:
deploy:
runs-on: ubuntu-latest
# 仅在 main 分支执行
if: github.ref == 'refs/heads/main'
steps:
# 仅在成功时执行
- name: 部署到生产环境
if: success()
run: npm run deploy
# 仅在失败时执行
- name: 发送失败通知
if: failure()
run: echo "部署失败"
# 总是执行
- name: 清理
if: always()
run: npm run cleanup
jobs:
deploy:
runs-on: ubuntu-latest
# Job 级别环境变量
env:
NODE_ENV: production
steps:
- name: 使用密钥
run: |
echo "API密钥: ${{ secrets.API_KEY }}"
echo "仓库名: ${{ github.repository }}"
echo "分支名: ${{ github.ref_name }}"
env:
# Step 级别环境变量
DEPLOY_ENV: staging
${{ github.repository }} # 仓库名: owner/repo
${{ github.ref_name }} # 分支或标签名
${{ github.sha }} # 提交 SHA
${{ github.actor }} # 触发用户
${{ github.event_name }} # 事件类型
${{ runner.os }} # 运行环境: Linux, Windows, macOS
${{ secrets.SECRET_NAME }} # 访问密钥
jobs:
job1:
runs-on: ubuntu-latest
# 定义输出
outputs:
version: ${{ steps.get-version.outputs.version }}
steps:
- id: get-version
run: echo "version=1.2.3" >> $GITHUB_OUTPUT
job2:
needs: job1
runs-on: ubuntu-latest
steps:
# 使用 job1 的输出
- run: echo "版本号: ${{ needs.job1.outputs.version }}"
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
# 定义全局环境变量
env:
NODE_VERSION: '20'
jobs:
# ==================== 代码质量检查 ====================
lint:
name: 代码检查
runs-on: ubuntu-latest
steps:
# 检出代码
- name: 检出代码
uses: actions/checkout@v4
# 设置 Node.js
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
# 安装依赖
- name: 安装依赖
run: npm ci
# ESLint 检查
- name: 运行 ESLint
run: npm run lint
# TypeScript 类型检查
- name: 类型检查
run: npm run type-check
# Prettier 格式检查
- name: 代码格式检查
run: npm run format:check
# ==================== 单元测试 ====================
test:
name: 单元测试
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: 安装依赖
run: npm ci
# 运行测试并生成覆盖率报告
- name: 运行测试
run: npm run test:coverage
# 上传覆盖率报告
- name: 上传覆盖率到 Codecov
uses: codecov/codecov-action@v4
with:
file: ./coverage/coverage-final.json
flags: unittests
name: codecov-umbrella
# ==================== 构建 ====================
build:
name: 构建项目
runs-on: ubuntu-latest
needs: [lint, test] # 等待检查和测试通过
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: 安装依赖
run: npm ci
# 构建项目
- name: 构建
run: npm run build
# 上传构建产物
- name: 上传构建产物
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 7 # 保留7天
# ==================== 部署到测试环境 ====================
deploy-staging:
name: 部署到测试环境
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/develop' # 仅 develop 分支
environment:
name: staging
url: https://staging.example.com
steps:
- uses: actions/checkout@v4
# 下载构建产物
- name: 下载构建产物
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
# 部署到服务器
- name: 部署到测试服务器
run: |
echo "部署到测试环境..."
# 这里添加实际部署命令
# 例如: rsync, scp, 或使用云服务 API
# ==================== 部署到生产环境 ====================
deploy-production:
name: 部署到生产环境
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main' # 仅 main 分支
environment:
name: production
url: https://example.com
steps:
- uses: actions/checkout@v4
- name: 下载构建产物
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: 部署到生产服务器
run: |
echo "部署到生产环境..."
# 实际部署命令
env:
DEPLOY_KEY: ${{ secrets.PRODUCTION_DEPLOY_KEY }}
name: Dependabot 自动合并
on:
pull_request:
types: [opened, synchronize]
permissions:
contents: write
pull-requests: write
jobs:
auto-merge:
name: 自动合并 Dependabot PR
runs-on: ubuntu-latest
# 仅处理 Dependabot 创建的 PR
if: github.actor == 'dependabot[bot]'
steps:
# 获取 Dependabot 元数据
- name: 获取更新信息
id: metadata
uses: dependabot/fetch-metadata@v2
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
# 自动批准 PR
- name: 批准 PR
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# 自动合并补丁和小版本更新
- name: 自动合并
# 仅合并 patch 和 minor 更新
if: |
steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
steps.metadata.outputs.update-type == 'version-update:semver-minor'
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# 为主版本更新添加标签
- name: 标记主版本更新
if: steps.metadata.outputs.update-type == 'version-update:semver-major'
run: gh pr edit "$PR_URL" --add-label "major-update,needs-review"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: 代码覆盖率检查
on:
pull_request:
branches: [main]
jobs:
coverage:
name: 检查测试覆盖率
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: 安装依赖
run: npm ci
- name: 运行测试并生成覆盖率
run: npm run test:coverage
# 生成覆盖率报告注释
- name: 覆盖率报告
uses: romeovs/[email protected]
with:
lcov-file: ./coverage/lcov.info
github-token: ${{ secrets.GITHUB_TOKEN }}
# 检查覆盖率阈值
- name: 检查覆盖率阈值
run: |
COVERAGE=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
echo "当前覆盖率: $COVERAGE%"
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "❌ 覆盖率低于 80%"
exit 1
else
echo "✅ 覆盖率达标"
fi
name: 发布 NPM 包
on:
release:
types: [published] # 创建 GitHub Release 时触发
jobs:
publish:
name: 发布到 NPM
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- name: 安装依赖
run: npm ci
- name: 构建
run: npm run build
- name: 运行测试
run: npm test
# 发布到 NPM
- name: 发布
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# 发送通知
- name: 发布成功通知
run: |
echo "✅ 版本 ${{ github.event.release.tag_name }} 已发布到 NPM"
name: 定时更新依赖
on:
schedule:
# 每周一凌晨 2 点执行 (UTC 时间,需要减8小时)
- cron: '0 18 * * 0'
workflow_dispatch: # 允许手动触发
jobs:
update:
name: 更新依赖
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/setup-node@v4
with:
node-version: '20'
# 更新依赖
- name: 更新所有依赖
run: |
npm update
npm outdated || true # 显示过期的包
# 运行测试确保更新后正常
- name: 运行测试
run: |
npm ci
npm test
# 创建 PR
- name: 创建更新 PR
uses: peter-evans/create-pull-request@v6
with:
commit-message: 'chore(deps): 更新依赖包'
title: '🔄 定时更新依赖包'
body: |
## 依赖更新
自动更新所有依赖到最新版本
- ✅ 测试已通过
- 📦 请检查更新日志
branch: deps/auto-update
labels: dependencies, automerge
name: 代码格式检查
on:
pull_request:
branches: [main, develop]
jobs:
format:
name: 检查代码格式
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: 安装依赖
run: npm ci
# 检查 Prettier 格式
- name: Prettier 检查
run: npm run format:check
# 如果格式不正确,自动修复并提交
- name: 自动修复格式
if: failure()
run: |
npm run format
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git add -A
git commit -m "style: 自动格式化代码"
git push
name: 性能测试
on:
pull_request:
branches: [main]
jobs:
lighthouse:
name: Lighthouse 性能测试
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: 安装依赖
run: npm ci
- name: 构建项目
run: npm run build
# 启动本地服务器
- name: 启动服务器
run: npm run preview &
# 等待服务器启动
- name: 等待服务器就绪
run: npx wait-on http://localhost:4173
# 运行 Lighthouse
- name: 运行 Lighthouse
uses: treosh/lighthouse-ci-action@v11
with:
urls: 'http://localhost:4173'
uploadArtifacts: true
temporaryPublicStorage: true
# 检查性能分数
- name: 检查性能阈值
run: |
echo "检查 Lighthouse 性能分数..."
# 添加性能阈值检查逻辑
{
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"test": "vitest",
"test:coverage": "vitest run --coverage",
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"format": "prettier --write \"src/**/*.{ts,tsx,css,md}\"",
"format:check": "prettier --check \"src/**/*.{ts,tsx,css,md}\"",
"type-check": "tsc --noEmit"
}
}