GitHub Actions:工作流自动化
GitHub Actions:工作流自动化
GitHub Actions简介
GitHub Actions是GitHub的原生CI/CD平台,允许在代码仓库中直接定义自动化工作流。
基础配置
工作流文件结构
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
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 linting
run: npm run lint
- name: Run tests
run: npm test
build:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push to registry
run: docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
事件触发
多种触发方式
on:
# Push触发
push:
branches: [main]
tags: ['v*']
paths:
- 'src/**'
- '!src/**/*.test.js'
# PR触发
pull_request:
types: [opened, synchronize, reopened]
# 定时触发
schedule:
- cron: '0 2 * * *'
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
矩阵构建
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [16, 18, 20]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
复用工作流
创建可复用工作流
# .github/workflows/reusable-deploy.yml
name: Reusable Deploy
on:
workflow_call:
inputs:
environment:
required: true
type: string
image:
required: true
type: string
secrets:
kubeconfig:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- uses: azure/k8s-set-context@v3
with:
kubeconfig: ${{ secrets.kubeconfig }}
- name: Deploy
run: |
kubectl set image deployment/myapp \
myapp=${{ inputs.image }} \
-n ${{ inputs.environment }}
调用可复用工作流
# .github/workflows/main.yml
jobs:
deploy-staging:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: staging
image: ghcr.io/${{ github.repository }}:${{ github.sha }}
secrets:
kubeconfig: ${{ secrets.KUBE_CONFIG }}
deploy-production:
needs: deploy-staging
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
image: ghcr.io/${{ github.repository }}:${{ github.sha }}
secrets:
kubeconfig: ${{ secrets.KUBE_CONFIG }}
if: github.ref == 'refs/heads/main'
自定义Actions
# action.yml
name: 'Deploy to Kubernetes'
description: 'Deploy application to Kubernetes cluster'
inputs:
image:
description: 'Docker image to deploy'
required: true
namespace:
description: 'Kubernetes namespace'
required: true
replicas:
description: 'Number of replicas'
required: false
default: '3'
runs:
using: 'composite'
steps:
- name: Deploy
shell: bash
run: |
kubectl set image deployment/myapp myapp=${{ inputs.image }} -n ${{ inputs.namespace }}
kubectl scale deployment myapp --replicas=${{ inputs.replicas }} -n ${{ inputs.namespace }}
实践:完整CI/CD工作流
# .github/workflows/ci-cd.yml
name: Complete CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
IMAGE: ghcr.io/${{ github.repository }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install & Test
run: |
npm ci
npm run lint
npm test
npm run build
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'HIGH,CRITICAL'
exit-code: '1'
build:
needs: [test, security]
runs-on: ubuntu-latest
if: github.event_name == 'push'
permissions:
contents: read
packages: write
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
steps:
- uses: actions/checkout@v4
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
tags: |
type=sha
type=ref,event=branch
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy-staging:
needs: build
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Set up kubectl
uses: azure/setup-kubectl@v3
- name: Configure kubeconfig
run: echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > $HOME/.kube/config
- name: Deploy to staging
run: |
kubectl set image deployment/myapp \
myapp=${{ env.IMAGE }}:${{ github.sha }} \
-n staging
kubectl rollout status deployment/myapp -n staging --timeout=300s
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: |
kubectl set image deployment/myapp \
myapp=${{ env.IMAGE }}:${{ github.sha }} \
-n production
kubectl rollout status deployment/myapp -n production --timeout=600s
常用Actions
# 缓存依赖
- uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# 上传制品
- uses: actions/upload-artifact@v3
with:
name: build-output
path: dist/
# 下载制品
- uses: actions/download-artifact@v3
with:
name: build-output
# Slack通知
- uses: slackapi/slack-github-action@v1
with:
payload: |
{"text": "Build succeeded: ${{ github.sha }}"}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
总结
GitHub Actions是GitHub原生的CI/CD解决方案。掌握工作流配置、复用和高级功能,可以构建高效的自动化交付流水线。