GitHub Actions 完整DevOps流程 #
本节通过一个完整的DevOps示例,展示从代码到生产的全流程自动化。
DevOps概述 #
DevOps流程 #
text
代码提交 → CI检查 → 构建 → 测试 → 部署Staging → 验证 → 部署Production → 监控
核心原则 #
- 自动化一切
- 持续集成
- 持续部署
- 快速反馈
- 安全第一
项目结构 #
text
project/
├── .github/
│ ├── workflows/
│ │ ├── ci.yml
│ │ ├── cd.yml
│ │ ├── security.yml
│ │ └── release.yml
│ └── actions/
│ └── setup/
│ └── action.yml
├── src/
├── tests/
├── kubernetes/
│ ├── deployment.yaml
│ └── service.yaml
├── Dockerfile
└── package.json
CI工作流 #
yaml
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CI: true
NODE_VERSION: '20'
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: npm run lint
- run: npm run format:check
type-check:
name: Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: npm run type-check
test:
name: Test
needs: [lint, type-check]
runs-on: ubuntu-latest
strategy:
matrix:
node: [18, 20]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- run: npm ci
- run: npm run test:coverage
- if: matrix.node == '20'
uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage/
build:
name: Build
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
CD工作流 #
yaml
# .github/workflows/cd.yml
name: CD
on:
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
inputs:
environment:
type: choice
options: [staging, production]
default: staging
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
environment: ${{ steps.set.outputs.environment }}
version: ${{ steps.set.outputs.version }}
steps:
- id: set
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT
elif [ "${{ github.ref_type }}" == "tag" ]; then
echo "environment=production" >> $GITHUB_OUTPUT
else
echo "environment=staging" >> $GITHUB_OUTPUT
fi
echo "version=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT
build-image:
needs: prepare
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
image: ${{ steps.build.outputs.image }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: build
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.version }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
needs: [prepare, build-image]
runs-on: ubuntu-latest
environment: ${{ needs.prepare.outputs.environment }}
steps:
- uses: actions/checkout@v4
- uses: azure/k8s-set-context@v3
with:
kubeconfig: ${{ secrets.KUBE_CONFIG }}
- uses: azure/k8s-deploy@v4
with:
namespace: ${{ needs.prepare.outputs.environment }}
manifests: kubernetes/
images: ${{ needs.build-image.outputs.image }}
verify:
needs: [prepare, deploy]
runs-on: ubuntu-latest
steps:
- name: Health check
run: |
url="https://${{ needs.prepare.outputs.environment }}.example.com/health"
for i in {1..30}; do
if curl -sf "$url"; then
echo "Health check passed"
exit 0
fi
sleep 10
done
echo "Health check failed"
exit 1
notify:
needs: [prepare, build-image, deploy, verify]
if: always()
runs-on: ubuntu-latest
steps:
- uses: slackapi/slack-github-action@v1
with:
channel-id: 'deployments'
slack-message: |
${{ job.status == 'success' && ':rocket:' || ':x:' }} Deployment ${{ job.status }}
Environment: ${{ needs.prepare.outputs.environment }}
Version: ${{ needs.prepare.outputs.version }}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
安全扫描工作流 #
yaml
# .github/workflows/security.yml
name: Security
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * *'
jobs:
codeql:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v2
with:
languages: javascript
- uses: github/codeql-action/analyze@v2
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'CRITICAL,HIGH'
dependency-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: npm audit --audit-level=high
- uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
secret-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
发布工作流 #
yaml
# .github/workflows/release.yml
name: Release
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- name: Build
run: npm run build
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: dist/*
generate_release_notes: true
- name: Publish to NPM
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Composite Action #
yaml
# .github/actions/setup/action.yml
name: 'Setup Node.js'
description: 通过的DevOps示例,学习如何构建从代码到生产的自动化流程。
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
shell: bash
run: npm ci
Kubernetes配置 #
yaml
# kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: IMAGE_PLACEHOLDER
ports:
- containerPort: 3000
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
监控和告警 #
Prometheus指标 #
yaml
- name: Expose metrics
uses: prometheus/client_golang
告警规则 #
yaml
- name: Alert on high error rate
if: failure()
uses: slackapi/slack-github-action@v1
最佳实践 #
1. 使用环境保护 #
yaml
environment: production
2. 使用OIDC认证 #
yaml
permissions:
id-token: write
3. 使用并发控制 #
yaml
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
4. 使用最小权限 #
yaml
permissions:
contents: read
5. 添加健康检查 #
yaml
- name: Health check
run: curl -sf https://example.com/health
下一步学习 #
小结 #
- DevOps实现全流程自动化
- 使用多个工作流分离关注点
- 使用Composite Action复用配置
- 使用环境保护生产环境
- 添加安全扫描
- 设置监控和告警
- 使用Kubernetes进行容器编排
最后更新:2026-03-28