程序员进阶工程师必备技能之工程化与研发效率建设(四)

简介: 教程来源 https://bgnno.cn/ 该CI/CD流水线基于GitHub Actions构建:CI阶段涵盖代码规范检查(Black/Isort/Ruff/Mypy)、单元与集成测试(含PostgreSQL/Redis服务)、Docker镜像构建及Trivy安全扫描;CD阶段支持语义化版本触发部署,采用Kubernetes蓝绿发布策略,含人工审批、健康验证与自动回滚,兼顾安全性与可靠性。

六、CI/CD流水线建设

6.1 完整的CI Pipeline

# .github/workflows/ci.yml - 完整的CI流水线
name: CI Pipeline

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

env:
  PYTHON_VERSION: '3.11'
  POETRY_VERSION: '1.5.0'

jobs:
  lint:
    name: Lint & Format
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: ${
  { env.PYTHON_VERSION }}

      - name: Install Poetry
        run: pip install poetry==${
  { env.POETRY_VERSION }}

      - name: Install dependencies
        run: poetry install --with dev

      - name: Run black check
        run: poetry run black --check src/

      - name: Run isort check
        run: poetry run isort --check-only src/

      - name: Run ruff lint
        run: poetry run ruff check src/

      - name: Run mypy type check
        run: poetry run mypy src/

  test-unit:
    name: Unit Tests
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v3

      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: ${
  { env.PYTHON_VERSION }}

      - name: Install Poetry
        run: pip install poetry==${
  { env.POETRY_VERSION }}

      - name: Install dependencies
        run: poetry install

      - name: Run unit tests
        run: |
          poetry run pytest tests/unit -v --cov=src --cov-report=xml --cov-report=term

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          file: ./coverage.xml
          flags: unittests
          name: codecov-umbrella

  test-integration:
    name: Integration Tests
    runs-on: ubuntu-latest
    needs: lint
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: testpass
          POSTGRES_DB: test_db
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

      redis:
        image: redis:7-alpine
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - uses: actions/checkout@v3

      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: ${
  { env.PYTHON_VERSION }}

      - name: Install Poetry
        run: pip install poetry==${
  { env.POETRY_VERSION }}

      - name: Install dependencies
        run: poetry install

      - name: Run integration tests
        env:
          DATABASE_URL: postgresql://postgres:testpass@localhost:5432/test_db
          REDIS_URL: redis://localhost:6379
        run: |
          poetry run pytest tests/integration -v --cov=src --cov-append

  build:
    name: Build & Package
    runs-on: ubuntu-latest
    needs: [test-unit, test-integration]
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v3

      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: ${
  { env.PYTHON_VERSION }}

      - name: Install Poetry
        run: pip install poetry==${
  { env.POETRY_VERSION }}

      - name: Build package
        run: poetry build

      - name: Build Docker image
        run: |
          docker build -t myapp:${
  { github.sha }} .
          docker tag myapp:${
  { github.sha }} myapp:latest

      - name: Save Docker image
        run: docker save myapp:${
  { github.sha }} -o myapp.tar

      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-artifacts
          path: |
            dist/
            myapp.tar
            Dockerfile

  security-scan:
    name: Security Scan
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/checkout@v3

      - name: Download artifacts
        uses: actions/download-artifact@v3
        with:
          name: build-artifacts

      - name: Load Docker image
        run: docker load -i myapp.tar

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${
  { github.sha }}
          format: 'sarif'
          output: 'trivy-results.sarif'

      - name: Upload Trivy results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: 'trivy-results.sarif'

6.2 CD流水线

# .github/workflows/cd.yml - CD流水线
name: CD Pipeline

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deployment environment'
        required: true
        default: 'staging'
        type: choice
        options:
          - staging
          - production

jobs:
  deploy-staging:
    name: Deploy to Staging
    runs-on: ubuntu-latest
    if: github.event_name == 'push' || github.event.inputs.environment == 'staging'
    environment: staging
    steps:
      - uses: actions/checkout@v3

      - name: Configure kubectl
        uses: azure/setup-kubectl@v3
        with:
          version: 'latest'

      - name: Set up Kubernetes config
        run: |
          mkdir -p $HOME/.kube
          echo "${
  { secrets.KUBE_CONFIG_STAGING }}" | base64 --decode > $HOME/.kube/config

      - name: Deploy to Kubernetes
        run: |
          # 更新镜像tag
          kubectl set image deployment/myapp myapp=myapp:${
  { github.sha }}
          # 滚动更新
          kubectl rollout status deployment/myapp

      - name: Run smoke tests
        run: |
          curl --retry 5 --retry-delay 10 --fail https://staging.myapp.com/health

      - name: Notify deployment
        uses: slackapi/slack-github-action@v1.24.0
        with:
          payload: |
            {
              "text": "✅ Deployment to STAGING completed successfully",
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "✅ Deployment to *STAGING* completed\nVersion: `${
  { github.sha }}`\nEnvironment: staging"
                  }
                }
              ]
            }
        env:
          SLACK_WEBHOOK_URL: ${
  { secrets.SLACK_WEBHOOK_URL }}

  deploy-production:
    name: Deploy to Production
    runs-on: ubuntu-latest
    needs: deploy-staging
    if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'production')
    environment: production
    steps:
      - uses: actions/checkout@v3

      - name: Manual approval gate
        uses: trstringer/manual-approval@v1
        with:
          secret: ${
  { github.TOKEN }}
          approvers: admin,lead-engineer
          minimum-approvals: 2
          issue-title: "Deploy to Production"

      - name: Blue-Green deployment
        run: |
          # 蓝绿部署脚本
          ./scripts/blue-green-deploy.sh

      - name: Verify deployment
        run: |
          # 验证健康检查
          ./scripts/verify-deployment.sh

      - name: Rollback on failure
        if: failure()
        run: |
          ./scripts/rollback.sh

      - name: Create deployment tag
        run: |
          git tag "deploy-$(date +%Y%m%d-%H%M%S)"
          git push --tags

      - name: Notify team
        uses: slackapi/slack-github-action@v1.24.0
        with:
          payload: |
            {
              "text": "🚀 Deployment to PRODUCTION completed successfully",
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "🚀 Deployment to *PRODUCTION* completed\nVersion: `${
  { github.sha }}`\nDeployed at: `$(date)`"
                  }
                }
              ]
            }
        env:
          SLACK_WEBHOOK_URL: ${
  { secrets.SLACK_WEBHOOK_URL }}

6.3 部署脚本示例

#!/bin/bash
# scripts/blue-green-deploy.sh - 蓝绿部署脚本

set -euo pipefail

# 配置
NAMESPACE="production"
APP_NAME="myapp"
NEW_VERSION="${GITHUB_SHA:-$(git rev-parse HEAD)}"
SERVICE_NAME="myapp-service"
INGRESS_NAME="myapp-ingress"

# 颜色
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'

echo "🚀 Starting Blue-Green deployment"

# 检测当前激活的环境
CURRENT_ACTIVE=$(kubectl get service $SERVICE_NAME -n $NAMESPACE -o jsonpath='{.spec.selector.environment}')
echo "Current active environment: $CURRENT_ACTIVE"

if [ "$CURRENT_ACTIVE" = "blue" ]; then
    NEW_ENV="green"
    OLD_ENV="blue"
else
    NEW_ENV="blue"
    OLD_ENV="green"
fi

echo "Deploying to $NEW_ENV environment"

# 1. 部署新版本
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: $APP_NAME-$NEW_ENV
  namespace: $NAMESPACE
spec:
  replicas: 3
  selector:
    matchLabels:
      app: $APP_NAME
      environment: $NEW_ENV
  template:
    metadata:
      labels:
        app: $APP_NAME
        environment: $NEW_ENV
    spec:
      containers:
      - name: app
        image: myapp:$NEW_VERSION
        ports:
        - containerPort: 8000
        env:
        - name: ENVIRONMENT
          value: "production"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: url
        readinessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 10
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
EOF

# 2. 等待新版本就绪
echo "Waiting for $NEW_ENV deployment to be ready..."
kubectl rollout status deployment/$APP_NAME-$NEW_ENV -n $NAMESPACE --timeout=300s

# 3. 健康检查
echo "Performing health check..."
POD_NAME=$(kubectl get pods -n $NAMESPACE -l app=$APP_NAME,environment=$NEW_ENV -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n $NAMESPACE $POD_NAME -- curl -s http://localhost:8000/health

if [ $? -ne 0 ]; then
    echo -e "${RED}❌ Health check failed! Aborting deployment${NC}"
    exit 1
fi

# 4. 切换到新环境
echo "Switching traffic to $NEW_ENV..."
kubectl patch service $SERVICE_NAME -n $NAMESPACE -p "{\"spec\":{\"selector\":{\"environment\":\"$NEW_ENV\"}}}"

# 5. 验证流量切换
echo "Verifying traffic switch..."
sleep 10

# 6. 如果切换成功,清理旧环境
echo "Cleaning up old environment ($OLD_ENV)..."
kubectl delete deployment $APP_NAME-$OLD_ENV -n $NAMESPACE --ignore-not-found

echo -e "${GREEN}✅ Blue-Green deployment completed successfully!${NC}"
echo "New version deployed to $NEW_ENV environment"

来源:
https://detxg.cn/

相关文章
|
2月前
|
人工智能 自然语言处理 安全
阿里云云部署OpenClaw集成钉钉
本文详解OpenClaw开源AI助手与钉钉的深度集成:支持群聊/单聊中自然语言交互,涵盖环境部署、钉钉应用创建、通道配置、机器人测试及多Agent绑定等全流程,并强调使用前须评估安全与合规性。
|
2月前
|
人工智能 自然语言处理 监控
阿里云百炼千问Qwen3.7-Max全面解析:核心能力、技术特性与订阅使用全指南
在智能应用与AI智能体飞速发展的2026年,大模型的推理能力、长文本处理、多模态理解以及工具调用能力,已经成为企业开发、科研创作、自动化办公的核心刚需。阿里云百炼正式推出**Qwen3.7-Max**旗舰大模型,作为通义千问系列综合实力最强的版本,直接对标国际主流高端闭源大模型,专为复杂逻辑推理、长周期自主任务、多模态分析、企业级业务场景打造。
1835 3
|
2月前
|
设计模式 人工智能 数据可视化
Agentic 设计模式拆解:6 种结构的优缺点与应用场景
本文系统梳理Agentic AI六大核心设计模式:单一、顺序、并行智能体,循环评审,协调者与子智能体,以及作为工具的子智能体。聚焦智能体、用户、模型与工具间的结构化交互,提炼可复用的工程骨架,助力规模化落地。
271 5
Agentic 设计模式拆解:6 种结构的优缺点与应用场景
|
4月前
|
人工智能 测试技术 调度
移动端 RPA 的架构重构:基于多模态视觉大模型的自动化调度系统压测复盘
本文复盘企业级移动端RPA重构实践,介绍如何以“侠客工坊”AI数字员工平台替代传统坐标录制方案:基于多模态大模型实现视觉语义决策、高并发多机型调度、零代码编排、异常自愈及MCP协议集成,显著提升自动化鲁棒性与运维效率。
325 10
|
3月前
|
监控 数据库
故障复盘写了30页PPT下次还是同样的问题——复盘到底该产出什么
每次大故障都开复盘会、写30页PPT,但3个月后同类问题又来。核心原因不是分析不到位——是产出物不对。本文给出复盘的5个标准产出物模板(时间线/5Why/Action列表/告警更新/SOP),以及如何用云效Projex跟踪改进项闭环。
495 2
|
3月前
|
存储 缓存 安全
大模型应用:大模型响应缓存技术完全指南:TTL 缓存装饰器的设计与落地.112
本文详解大模型应用中缓存装饰器的实战实现,直击响应慢、成本高两大痛点。从基础缓存出发,逐步升级为支持TTL过期、线程安全、LRU淘汰、异常防护及哈希键优化的生产级方案,显著提升响应速度、降低Token消耗、增强系统稳定性。
320 7
|
4月前
|
数据采集 人工智能 自然语言处理
舆情监控:如何让AI自动抓取新闻资讯,并生成每日摘要报告?
本文介绍一套AI驱动的自动化舆情监控方案:用站大爷隧道代理(高可用IP轮换)+ OpenClaw(零代码AI Agent)+ 大模型(智能摘要),7×24小时自动抓取、筛选、生成并推送结构化日报,彻底解决人工扫新闻耗时多、漏报频、易被封等问题。(239字)
1254 9
|
2月前
|
人工智能 安全 测试技术
别再让 Claude 乱改代码了!Claude Code 这 7 个权限配置让你的项目再也不翻车
还在为 Claude Code 的混乱操作头疼?本文总结 7 个核心权限配置,从上下文管理、提示技巧到环境配置全覆盖,让你的 AI 编程助手真正听话不翻车。
645 5
|
4月前
|
人工智能 自然语言处理 安全
【新人快速上手使用】小白也能上手的 OpenClaw 2.6.6 安装教程(技术分享)
OpenClaw(小龙虾)是2026年热门开源「数字员工」,支持Windows一键部署(5分钟搞定),本地运行、零代码、全自动办公。无需配置环境,可整理文件、发邮件、浏览器自动化等,隐私安全,小白友好。
|
3月前
|
人工智能 安全 机器人
一句话就能“劫持”你的AI?DZS 分层式自适应提示词注入攻击的防御机制框架 (HAA)来了!
本文介绍“DZS分层式自适应防御框架(HAA)”,一种无需微调、不改模型的提示词注入防御方案。已发布预印本(DOI:10.21203/rs.3.rs-9653510/v1),支持主流LLM,可有效识别并隔离恶意指令,守住AI任务边界。(239字)