第199集:Python项目持续集成
课程目标
- 了解持续集成的基本概念
- 掌握持续集成的工作原理
- 学会使用GitHub Actions进行持续集成
- 掌握使用GitLab CI进行持续集成
- 了解Jenkins的基本使用
- 学会编写CI配置文件
- 理解自动化测试和构建在CI中的应用
一、持续集成基础
1.1 什么是持续集成?
持续集成(Continuous Integration,简称CI)是一种软件开发实践,开发团队频繁地将代码集成到共享仓库中,每次集成都会通过自动化构建和测试来验证代码的质量。
1.2 持续集成的好处
- 更早地发现代码错误
- 提高代码质量
- 减少集成问题
- 加快开发周期
- 增强团队协作
- 提高软件可靠性
1.3 持续集成的基本流程
1. 开发者提交代码到版本控制系统
2. CI系统自动检测代码变更
3. CI系统自动执行构建过程
4. CI系统自动运行测试
5. CI系统生成报告并通知结果二、常用的CI工具
2.1 GitHub Actions
GitHub Actions是GitHub提供的CI/CD服务,与GitHub仓库深度集成。
2.2 GitLab CI
GitLab CI是GitLab自带的CI/CD服务,功能强大且易于使用。
2.3 Jenkins
Jenkins是一个开源的自动化服务器,支持丰富的插件生态系统。
2.4 Travis CI
Travis CI是一个流行的托管式CI服务,支持多种编程语言。
2.5 CircleCI
CircleCI是一个现代的CI/CD平台,提供快速的构建环境。
三、GitHub Actions入门
3.1 GitHub Actions的基本概念
- Workflow: 工作流,一个完整的CI/CD流程
- Job: 任务,工作流中的一个步骤集合
- Step: 步骤,任务中的具体操作
- Action: 动作,预定义的可复用组件
- Runner: 运行器,执行工作流的环境
3.2 创建GitHub Actions配置文件
GitHub Actions的配置文件存放在.github/workflows/目录下,使用YAML格式。
name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: |
pytest
- name: Lint code
run: |
flake8 .3.3 工作流触发条件
on:
# 推送到main和develop分支时触发
push:
branches: [ main, develop ]
# 创建或更新pull request时触发
pull_request:
branches: [ main ]
# 定时触发(每天凌晨1点)
schedule:
- cron: "0 1 * * *"
# 手动触发
workflow_dispatch:3.4 构建矩阵
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
# 其他步骤...3.5 环境变量和密钥
jobs:
build:
runs-on: ubuntu-latest
env:
# 环境变量
DATABASE_URL: sqlite:///test.db
FLASK_ENV: testing
steps:
- uses: actions/checkout@v3
# 使用GitHub Secrets中的密钥
- name: Test with database
run: |
python -m pytest tests/
env:
API_KEY: ${{ secrets.API_KEY }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}四、GitLab CI入门
4.1 GitLab CI的基本概念
- Pipeline: 流水线,一个完整的CI/CD流程
- Job: 任务,流水线中的一个步骤集合
- Stage: 阶段,具有相同目标的任务集合
- Runner: 运行器,执行任务的环境
4.2 创建GitLab CI配置文件
GitLab CI的配置文件名为.gitlab-ci.yml,存放在仓库根目录下。
stages:
- test
- build
- deploy
variables:
DATABASE_URL: sqlite:///test.db
PYTHON_VERSION: "3.10"
# 测试阶段
test:
stage: test
image: python:$PYTHON_VERSION
script:
- pip install --upgrade pip
- pip install -r requirements.txt
- pytest tests/ -v
# 构建阶段
build:
stage: build
image: python:$PYTHON_VERSION
script:
- pip install --upgrade pip build
- python -m build
artifacts:
paths:
- dist/
only:
- main
# 部署阶段
deploy:
stage: deploy
image: python:$PYTHON_VERSION
script:
- pip install --upgrade pip twine
- twine upload --repository testpypi dist/* -u $TWINE_USERNAME -p $TWINE_PASSWORD
only:
- main
environment:
name: testpypi
url: https://test.pypi.org/project/my-package/4.3 阶段配置
stages:
- lint # 代码检查
- test # 测试
- coverage # 覆盖率报告
- build # 构建
- deploy_test # 测试环境部署
- deploy_prod # 生产环境部署4.4 缓存配置
cache:
paths:
- ~/.cache/pip/
- venv/
test:
stage: test
script:
- pip install virtualenv
- virtualenv venv
- source venv/bin/activate
- pip install -r requirements.txt
- pytest4.5 并行执行
test:
stage: test
script:
- pytest tests/test_main.py -v
parallel: 3五、Jenkins入门
5.1 Jenkins的安装
# Ubuntu/Debian
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins
# 启动Jenkins
sudo systemctl start jenkins
# 访问Jenkins
echo "访问 http://localhost:8080"5.2 Jenkins的基本配置
- 安装必要的插件
- 配置Python环境
- 配置版本控制系统
- 配置构建工具
- 配置通知
5.3 创建Jenkins任务
- 选择"新建任务"
- 输入任务名称,选择"自由风格的软件项目"
- 配置源代码管理
- 配置构建触发器
- 配置构建步骤
- 配置构建后操作
5.4 Jenkins Pipeline
Jenkins Pipeline使用Jenkinsfile来定义流水线,支持声明式和脚本式两种语法。
// 声明式Pipeline
pipeline {
agent any
environment {
DATABASE_URL = 'sqlite:///test.db'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install Dependencies') {
steps {
sh 'pip install -r requirements.txt'
}
}
stage('Test') {
steps {
sh 'pytest tests/ -v'
}
}
stage('Build') {
steps {
sh 'python -m build'
}
}
}
post {
success {
echo '构建成功!'
mail to: 'team@example.com', subject: '构建成功', body: '构建 #${BUILD_NUMBER} 成功完成'
}
failure {
echo '构建失败!'
mail to: 'team@example.com', subject: '构建失败', body: '构建 #${BUILD_NUMBER} 失败'
}
}
}六、CI中的自动化测试
6.1 单元测试
# GitHub Actions中的单元测试
- name: Run Unit Tests
run: |
python -m pytest tests/unit/ -v6.2 集成测试
# GitLab CI中的集成测试
integration_test:
stage: test
script:
- python -m pytest tests/integration/ -v
services:
- postgres:13
variables:
POSTGRES_DB: test_db
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_password6.3 端到端测试
# Jenkins中的端到端测试
stage('E2E Tests') {
steps {
sh 'python -m pytest tests/e2e/ -v'
}
}6.4 测试覆盖率
# GitHub Actions中的测试覆盖率
- name: Run Tests with Coverage
run: |
python -m pytest tests/ --cov=my_package --cov-report=xml
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: true七、CI中的代码质量检查
7.1 使用flake8检查代码风格
# GitHub Actions中的flake8检查
- name: Lint with flake8
run: |
pip install flake8
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics7.2 使用black自动格式化代码
# GitLab CI中的black格式化检查
lint:
stage: test
script:
- pip install black
- black --check .7.3 使用mypy进行类型检查
# Jenkins中的mypy类型检查
stage('Type Check') {
steps {
sh 'pip install mypy'
sh 'mypy my_package/'
}
}7.4 使用bandit检查安全问题
# GitHub Actions中的bandit安全检查
- name: Security Check with Bandit
run: |
pip install bandit
bandit -r my_package/ -x tests/八、CI/CD流水线示例
8.1 完整的GitHub Actions流水线
name: Python CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov flake8 black mypy bandit
- name: Lint with flake8
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Check formatting with black
run: |
black --check .
- name: Type check with mypy
run: |
mypy my_package/
- name: Security check with bandit
run: |
bandit -r my_package/ -x tests/
- name: Test with pytest
run: |
python -m pytest tests/ --cov=my_package --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
build:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip build
- name: Build package
run: |
python -m build
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: dist
path: dist/
deploy_testpypi:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: dist
path: dist/
- name: Install dependencies
run: |
python -m pip install --upgrade pip twine
- name: Deploy to TestPyPI
env:
TWINE_USERNAME: ${{ secrets.TESTPYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.TESTPYPI_PASSWORD }}
run: |
twine upload --repository testpypi dist/*九、CI最佳实践
9.1 保持CI流程简洁
- 避免在CI中执行不必要的任务
- 分离测试、构建和部署阶段
- 使用缓存提高构建速度
9.2 确保CI的可靠性
- 保持测试的独立性
- 使用稳定的依赖版本
- 定期维护CI配置
9.3 提供清晰的反馈
- 使用详细的测试报告
- 及时通知构建结果
- 提供修复建议
9.4 安全考虑
- 不要在CI配置中硬编码敏感信息
- 使用加密的环境变量
- 定期更新CI工具和插件
十、常见问题和解决方案
10.1 构建速度慢
- 使用缓存
- 优化测试用例
- 并行执行任务
10.2 测试失败
- 检查测试环境
- 检查依赖版本
- 检查代码变更
10.3 部署失败
- 检查部署环境
- 检查部署脚本
- 检查权限配置
10.4 CI配置复杂
- 使用模板化的配置
- 分离关注点
- 文档化CI流程
十一、总结
持续集成是现代软件开发的重要实践,通过本节课的学习,您应该掌握了:
- 持续集成的基本概念和好处
- GitHub Actions、GitLab CI和Jenkins的基本使用
- 如何编写CI配置文件
- 自动化测试和代码质量检查在CI中的应用
- CI的最佳实践
下一节课,我们将学习Python项目的持续部署,了解如何将CI和CD结合起来,实现自动化部署。