Action开发实战踩坑指南与核心技巧总结

Mr.诺一 工具 阅读 1,267
赞 16 收藏
二维码
手机扫码查看
反馈

从零开始,GitHub Actions其实没那么复杂

之前一直觉得Actions是个很高大上的东西,看得眼花缭乱。直到最近项目需要自动化部署,不得不硬着头皮研究,才发现其实没想象中那么复杂。今天分享下我的实战经验,希望能帮到同样困惑的朋友。

Action开发实战踩坑指南与核心技巧总结

核心就是创建一个.yml文件,放在项目的.github/workflows目录下。先看个最简单的例子:

name: CI/CD Pipeline
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '16'
    - run: npm install
    - run: npm run build

这段代码的意思是:当main分支有push的时候,执行构建任务。第一步是检出代码,第二步安装Node环境,然后安装依赖和构建。就这么简单。

踩坑提醒:这三点一定注意

这里注意我踩过好几次坑的地方:

  • 权限问题:如果要用SSH密钥或者访问私有仓库,记得在Settings->Secrets中添加对应的token
  • 缓存策略:npm install每次都要下载依赖很慢,可以用actions/cache来加速
  • 路径问题:默认工作目录是项目的根目录,如果构建脚本在子目录下要注意切换路径

缓存配置我建议直接用这种方式:

- name: Cache node modules
  uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

亲测有效,能节省一大半构建时间。

实际项目中的复杂场景

真实项目肯定比上面的例子复杂得多。比如我现在维护的一个项目,需要同时跑测试、构建、部署到多个环境。完整的配置长这样:

name: Full Deployment Pipeline
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  NODE_VERSION: '16'

jobs:
  test:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'
    steps:
    - uses: actions/checkout@v3
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ env.NODE_VERSION }}
    - name: Install dependencies
      run: npm ci
    - name: Run tests
      run: npm test -- --ci --coverage

  build-and-deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
    - uses: actions/checkout@v3
      
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ env.NODE_VERSION }}
        
    - name: Cache dependencies
      uses: actions/cache@v3
      with:
        path: ~/.npm
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
        
    - name: Install and Build
      run: |
        npm ci
        npm run build
        
    - name: Deploy to Production
      env:
        DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
      run: |
        curl -X POST https://jztheme.com/deploy 
        -H "Authorization: Bearer $DEPLOY_TOKEN" 
        -d "ref=${{ github.sha }}"

这个配置包含了几个要点:

环境变量设置:通过env全局定义NODE_VERSION,避免在每处重复声明。

条件执行:通过if判断不同的触发条件。PR只跑测试,main分支推送才部署。

依赖关系:build-and-deploy依赖test job,只有测试通过才会继续部署。

安全考虑:敏感信息通过secrets存储,不在配置文件中明文暴露。

高级技巧:矩阵构建和并行执行

有时候需要在多个环境中测试,比如不同Node版本。矩阵构建就很实用:

jobs:
  test-matrix:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14, 16, 18]
        os: [ubuntu-latest, windows-latest]
    steps:
    - uses: actions/checkout@v3
    - name: Setup Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm ci
    - run: npm test

这样就会在3个Node版本和2个操作系统上总共跑6个job,确保兼容性。不过要注意成本控制,矩阵太大会消耗大量计算资源。

并行执行也很有用,特别是在需要跑E2E测试的时候:

jobs:
  frontend-test:
    runs-on: ubuntu-latest
    steps:
    - run: npm run test:frontend
    
  backend-test:
    runs-on: ubuntu-latest
    steps:
    - run: npm run test:backend
    
  integration:
    needs: [frontend-test, backend-test]
    runs-on: ubuntu-latest
    steps:
    - run: npm run test:integration

前端后端测试可以同时进行,最后跑集成测试,大大缩短了整体等待时间。

监控和调试技巧

调试Actions其实挺痛苦的,因为不能像本地一样断点调试。几个实用技巧分享下:

开启Step调试:可以在step中添加run: echo “DEBUG: some value”来输出调试信息。

保存构建产物:用actions/upload-artifact保存构建结果,方便查看:

- name: Upload build artifacts
  uses: actions/upload-artifact@v3
  if: always()
  with:
    name: build-output
    path: dist/

这里的if: always()很重要,即使构建失败也要保存artifact,方便排查问题。

日志分组:对于比较复杂的构建流程,可以用grouping来组织日志:

- run: |
    echo "::group::Install Dependencies"
    npm ci
    echo "::endgroup::"
    
    echo "::group::Run Build"
    npm run build
    echo "::endgroup::"

这样在GitHub的日志界面就能折叠分组,看起来清爽很多。

成本控制和最佳实践

GitHub Actions的免费额度其实还挺 generous 的,但如果不加控制,项目多了也容易超标。几个建议:

  • 限制并发:在仓库设置中可以限制并发数,防止意外触发太多job
  • 合理设置触发条件:避免在每次commit都触发全量构建
  • 清理旧的workflow:定期检查不再使用的workflows

还有个小技巧,可以设置workflow_dispatch手动触发,配合自动触发使用:

on:
  push:
    branches: [main]
  workflow_dispatch:
    inputs:
      environment:
        description: 'Target environment'
        required: true
        default: 'staging'

这样既保留了自动化,又能手动控制某些特殊部署场景。

常见问题解决

实际使用中遇到的几个典型问题:

超时问题:默认timeout是6小时,但一般构建不会这么久。可以通过timeout-minutes调整:

jobs:
  build:
    timeout-minutes: 30

权限不够:如果需要写入仓库,要在permissions中明确声明:

permissions:
  contents: write
  pages: write

跨平台兼容:Windows和Linux的命令语法可能不同,建议统一使用bash:

- run: ./scripts/build.sh
  shell: bash

以上是我踩坑后的总结,希望对你有帮助。这个技巧的拓展用法还有很多,后续会继续分享这类博客。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论