
GitHub Actions CI/CD别再手动部署了毒舌时刻这代码写得跟网红滤镜似的——仅供参考。各位前端同行咱们今天聊聊 GitHub Actions。别告诉我你还在手动部署那感觉就像每次出门都走路——能到但太慢了。为什么你需要 GitHub Actions最近看到一个项目每次发布都要手动打包、上传、重启服务器耗时 1 小时还经常出错。我就想问你是在做开发还是在做运维反面教材# 反面教材手动部署流程 # 1. 本地构建 $ npm run build # ⏱️ 5分钟 # 2. 压缩文件 $ tar -czf dist.tar.gz dist/ # 3. 上传到服务器 $ scp dist.tar.gz userserver:/tmp/ # ⏱️ 10分钟取决于网速 # 4. SSH 登录服务器 $ ssh userserver # 5. 备份旧版本 $ cp -r /var/www/app /var/www/app-backup-$(date %Y%m%d) # 6. 解压新版本 $ cd /var/www $ tar -xzf /tmp/dist.tar.gz # 7. 安装依赖 $ npm install --production # ⏱️ 5分钟 # 8. 重启服务 $ pm2 restart app # 9. 验证部署 # 打开浏览器手动检查 # ⏱️ 10分钟 # 总计30-60分钟 # 出错概率50% # 心情指数毒舌点评这流程发布一次要 1 小时你是在写代码还是在做苦力GitHub Actions 的正确姿势1. 基础工作流# 正确姿势自动 CI/CD # .github/workflows/ci.yml name: CI/CD Pipeline on: push: branches: [main, develop] pull_request: branches: [main] jobs: # 代码检查 lint: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 cache: npm - name: Install dependencies run: npm ci - name: Run linter run: npm run lint # 单元测试 test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 cache: npm - name: Install dependencies run: npm ci - name: Run tests run: npm run test:ci - name: Upload coverage uses: codecov/codecov-actionv3 with: files: ./coverage/lcov.info # 构建 build: runs-on: ubuntu-latest needs: [lint, test] steps: - uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 cache: npm - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Upload build artifacts uses: actions/upload-artifactv3 with: name: build-files path: dist/2. 自动部署到 Vercel# 正确姿势自动部署到 Vercel # .github/workflows/deploy-vercel.yml name: Deploy to Vercel on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 - name: Install Vercel CLI run: npm install --global vercellatest - name: Deploy to Production run: vercel --prod --token${{ secrets.VERCEL_TOKEN }} env: VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}3. 部署到服务器# 正确姿势自动部署到服务器 # .github/workflows/deploy-server.yml name: Deploy to Server on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 cache: npm - name: Install dependencies run: npm ci - name: Build run: npm run build env: NODE_ENV: production API_URL: ${{ secrets.API_URL }} - name: Deploy to server uses: appleboy/scp-actionmaster with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_KEY }} source: dist/ target: /var/www/app strip_components: 1 - name: Restart server uses: appleboy/ssh-actionmaster with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_KEY }} script: | cd /var/www/app npm install --production pm2 restart app4. Docker 部署# 正确姿势Docker 自动构建和推送 # .github/workflows/docker.yml name: Docker Build and Deploy on: push: branches: [main] tags: [v*] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build-and-push: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout uses: actions/checkoutv4 - name: Set up Docker Buildx uses: docker/setup-buildx-actionv3 - name: Login to Container Registry uses: docker/login-actionv3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-actionv5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | typeref,eventbranch typeref,eventpr typesemver,pattern{{version}} typesemver,pattern{{major}}.{{minor}} - name: Build and push uses: docker/build-push-actionv5 with: context: . push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: typegha cache-to: typegha,modemax - name: Deploy to server uses: appleboy/ssh-actionmaster with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_KEY }} script: | cd /var/www/app docker-compose pull docker-compose up -d docker system prune -f毒舌点评这才叫现代 CI/CD提交代码自动部署无需人工干预。实战技巧GitHub Actions 最佳实践1. 矩阵构建# 正确姿势多环境测试 # .github/workflows/matrix.yml name: Matrix Build on: [push, pull_request] jobs: test: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] node-version: [18, 20, 21] steps: - uses: actions/checkoutv4 - name: Setup Node.js ${{ matrix.node-version }} uses: actions/setup-nodev4 with: node-version: ${{ matrix.node-version }} - name: Install dependencies run: npm ci - name: Run tests run: npm test2. 缓存优化# 正确姿势缓存加速 # .github/workflows/cached.yml name: Cached Build on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 - name: Cache dependencies uses: actions/cachev3 with: path: | ~/.npm ${{ github.workspace }}/.next/cache key: ${{ runner.os }}-nextjs-${{ hashFiles(**/package-lock.json) }}-${{ hashFiles(**.[jt]s, **.[jt]sx) }} restore-keys: | ${{ runner.os }}-nextjs-${{ hashFiles(**/package-lock.json) }}- - name: Install dependencies run: npm ci - name: Build run: npm run build3. 环境管理# 正确姿势多环境部署 # .github/workflows/environments.yml name: Multi-Environment Deploy on: push: branches: [develop, main] jobs: deploy-staging: if: github.ref refs/heads/develop runs-on: ubuntu-latest environment: name: staging url: https://staging.example.com steps: - name: Deploy to Staging run: echo Deploying to staging... deploy-production: if: github.ref refs/heads/main runs-on: ubuntu-latest environment: name: production url: https://example.com steps: - name: Deploy to Production run: echo Deploying to production...4. 通知集成# 正确姿势部署通知 # .github/workflows/notify.yml name: Deploy with Notification on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 # ... 部署步骤 ... - name: Notify Slack on Success if: success() uses: 8398a7/action-slackv3 with: status: ${{ job.status }} text: ✅ 部署成功 webhook_url: ${{ secrets.SLACK_WEBHOOK }} - name: Notify Slack on Failure if: failure() uses: 8398a7/action-slackv3 with: status: ${{ job.status }} text: ❌ 部署失败 webhook_url: ${{ secrets.SLACK_WEBHOOK }}5. 安全扫描# 正确姿势安全检查 # .github/workflows/security.yml name: Security Scan on: push: branches: [main] pull_request: branches: [main] schedule: - cron: 0 0 * * 0 # 每周日运行 jobs: security: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Run npm audit run: npm audit --audit-levelmoderate - name: Run CodeQL Analysis uses: github/codeql-action/initv2 with: languages: javascript - name: Autobuild uses: github/codeql-action/autobuildv2 - name: Perform CodeQL Analysis uses: github/codeql-action/analyzev2 - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-actionmaster with: scan-type: fs format: sarif output: trivy-results.sarif6. 常见陷阱# 陷阱1不使用缓存 - name: Install dependencies run: npm ci # ❌ 每次都重新安装 # 正确做法使用缓存 ✅ # 陷阱2硬编码敏感信息 - name: Deploy run: | echo password123 | docker login -u user --password-stdin # ❌ 安全风险 # 正确做法使用 secrets ✅ - name: Deploy run: | echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USER }} --password-stdin # 陷阱3不设置超时 jobs: deploy: runs-on: ubuntu-latest # ❌ 可能无限运行 # 正确做法设置超时 ✅ jobs: deploy: runs-on: ubuntu-latest timeout-minutes: 30最后想说的GitHub Actions 不是可选的是现代 CI/CD 的标准。别再手动部署了——用上 GitHub Actions你的发布流程会自动化 100%。记住好的部署应该是自动的提交代码就能自动测试、构建、部署。GitHub Actions 让这一切变得简单。