install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/ci-cd" ~/.claude/skills/majiayu000-claude-skill-registry-ci-cd && rm -rf "$T"
manifest:
skills/data/ci-cd/SKILL.mdsource content
CI/CD 流水线配置
概述
Jenkins、GitLab CI、GitHub Actions 等 CI/CD 工具配置技能。
GitHub Actions
基础工作流
# .github/workflows/ci.yml name: CI on: push: branches: [main, develop] pull_request: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Run tests run: npm test - name: Build run: npm run build
矩阵构建
jobs: test: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] node-version: [16, 18, 20] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm ci - run: npm test
Docker 构建与推送
jobs: docker: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push uses: docker/build-push-action@v5 with: context: . push: true tags: user/app:${{ github.sha }}
部署到 Kubernetes
jobs: deploy: runs-on: ubuntu-latest needs: build steps: - uses: actions/checkout@v4 - name: Configure kubectl uses: azure/k8s-set-context@v3 with: kubeconfig: ${{ secrets.KUBE_CONFIG }} - name: Deploy run: | kubectl set image deployment/app app=user/app:${{ github.sha }} kubectl rollout status deployment/app
GitLab CI
基础配置
# .gitlab-ci.yml stages: - build - test - deploy variables: DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA build: stage: build image: docker:latest services: - docker:dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $DOCKER_IMAGE . - docker push $DOCKER_IMAGE test: stage: test image: node:18 script: - npm ci - npm test coverage: '/Coverage: \d+\.\d+%/' deploy: stage: deploy image: bitnami/kubectl:latest script: - kubectl set image deployment/app app=$DOCKER_IMAGE only: - main environment: name: production url: https://app.example.com
多环境部署
.deploy_template: &deploy_template stage: deploy image: bitnami/kubectl:latest script: - kubectl config use-context $KUBE_CONTEXT - kubectl set image deployment/app app=$DOCKER_IMAGE deploy_staging: <<: *deploy_template variables: KUBE_CONTEXT: staging environment: name: staging only: - develop deploy_production: <<: *deploy_template variables: KUBE_CONTEXT: production environment: name: production only: - main when: manual
Jenkins
Jenkinsfile(声明式)
// Jenkinsfile pipeline { agent any environment { DOCKER_IMAGE = "user/app:${BUILD_NUMBER}" DOCKER_CREDENTIALS = credentials('docker-hub') } stages { stage('Checkout') { steps { checkout scm } } stage('Build') { steps { sh 'npm ci' sh 'npm run build' } } stage('Test') { steps { sh 'npm test' } post { always { junit 'test-results/*.xml' } } } stage('Docker Build') { steps { sh "docker build -t ${DOCKER_IMAGE} ." } } stage('Docker Push') { steps { sh "echo ${DOCKER_CREDENTIALS_PSW} | docker login -u ${DOCKER_CREDENTIALS_USR} --password-stdin" sh "docker push ${DOCKER_IMAGE}" } } stage('Deploy') { when { branch 'main' } steps { sh "kubectl set image deployment/app app=${DOCKER_IMAGE}" } } } post { always { cleanWs() } success { slackSend channel: '#deployments', message: "Build ${BUILD_NUMBER} succeeded" } failure { slackSend channel: '#deployments', message: "Build ${BUILD_NUMBER} failed" } } }
Jenkinsfile(脚本式)
node { stage('Checkout') { checkout scm } stage('Build') { sh 'npm ci' sh 'npm run build' } stage('Test') { try { sh 'npm test' } finally { junit 'test-results/*.xml' } } if (env.BRANCH_NAME == 'main') { stage('Deploy') { sh 'kubectl apply -f k8s/' } } }
通用模式
语义化版本发布
# GitHub Actions name: Release on: push: tags: - 'v*' jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Get version id: version run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT - name: Build run: npm run build - name: Create Release uses: softprops/action-gh-release@v1 with: files: dist/* generate_release_notes: true
缓存依赖
# GitHub Actions - name: Cache node modules uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- # GitLab CI cache: key: ${CI_COMMIT_REF_SLUG} paths: - node_modules/
并行测试
# GitHub Actions jobs: test: runs-on: ubuntu-latest strategy: matrix: shard: [1, 2, 3, 4] steps: - uses: actions/checkout@v4 - run: npm ci - run: npm test -- --shard=${{ matrix.shard }}/4
条件执行
# GitHub Actions jobs: deploy: if: github.ref == 'refs/heads/main' && github.event_name == 'push' runs-on: ubuntu-latest steps: - run: echo "Deploying..." # GitLab CI deploy: rules: - if: $CI_COMMIT_BRANCH == "main" when: manual - if: $CI_COMMIT_TAG when: always
常见场景
场景 1:PR 检查
name: PR Check on: pull_request: types: [opened, synchronize, reopened] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run lint test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm test
场景 2:定时任务
name: Scheduled Job on: schedule: - cron: '0 2 * * *' # 每天凌晨2点 jobs: cleanup: runs-on: ubuntu-latest steps: - run: echo "Running cleanup..."
场景 3:手动触发
name: Manual Deploy on: workflow_dispatch: inputs: environment: description: 'Environment to deploy' required: true default: 'staging' type: choice options: - staging - production jobs: deploy: runs-on: ubuntu-latest steps: - run: echo "Deploying to ${{ inputs.environment }}"
故障排查
| 问题 | 排查方法 |
|---|---|
| 构建失败 | 查看日志、本地复现 |
| 权限问题 | 检查 secrets、token |
| 缓存失效 | 检查 cache key |
| 超时 | 增加 timeout、优化步骤 |