Action开发实战踩坑指南与核心技巧总结
从零开始,GitHub Actions其实没那么复杂
之前一直觉得Actions是个很高大上的东西,看得眼花缭乱。直到最近项目需要自动化部署,不得不硬着头皮研究,才发现其实没想象中那么复杂。今天分享下我的实战经验,希望能帮到同样困惑的朋友。
核心就是创建一个.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
以上是我踩坑后的总结,希望对你有帮助。这个技巧的拓展用法还有很多,后续会继续分享这类博客。

暂无评论