一、GitHub Actions 概述
1.1 什么是 GitHub Actions?
GitHub Actions 是一个 CI/CD(持续集成/持续部署)平台,允许您自动化构建、测试和部署工作流程。
1.2 核心概念
- Workflow(工作流):可配置的自动化流程,由 YAML 文件定义
- Event(事件):触发工作流程的特定活动
- Job(作业):工作流程中的任务单元
本文详细介绍了 GitHub Actions 的核心概念、基本配置、触发事件、作业步骤、常用 Action 示例、环境变量与 Secrets 管理、缓存策略及高级功能。内容涵盖工作流复用、自托管运行器、Artifacts 处理,并提供安全性、性能优化和错误处理的实践建议,旨在帮助开发者构建高效的自动化 CI/CD 流程。
GitHub Actions 是一个 CI/CD(持续集成/持续部署)平台,允许您自动化构建、测试和部署工作流程。
在仓库中创建 .github/workflows/ 目录,并添加 YAML 文件:
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
on:
# 推送代码时触发
push:
branches:
- main
- 'releases/**'
tags:
- 'v*'
# 拉取请求时触发
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
# 定时触发
schedule:
- cron: '0 2 * * *' # 每天 UTC 时间 2:00
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
# 仓库事件触发
release:
types: [published]
# 问题事件触发
issues:
types: [opened, labeled]
jobs:
test:
runs-on: ubuntu-latest
name: Test on Ubuntu
env:
NODE_ENV: test
DATABASE_URL: ${{ secrets.DATABASE_URL }}
needs: [lint] # 等待 lint 作业完成
if: github.event_name == 'pull_request' # 条件执行
strategy:
matrix:
node-version: [14, 16, 18]
os: [ubuntu-latest, windows-latest]
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Run tests
run: |
npm ci
npm test -- --coverage
continue-on-error: false # 失败时停止
steps:
- name: Code Checkout
uses: actions/checkout@v3
- name: ESLint
uses: reviewdog/action-eslint@v1
- name: Run Unit Tests
uses: nick-fields/retry@v2
with:
timeout_minutes: 10
max_attempts: 3
command: npm test
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage/lcov.info
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
permissions:
contents: read
pages: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
name: Docker Build and Push
on:
push:
branches: [main]
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: myorg/myapp
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
env:
NODE_ENV: production
API_URL: https://api.example.com
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: production
url: https://myapp.com
steps:
- name: Use environment variables
run: |
echo "Database URL: ${{ secrets.DATABASE_URL }}"
echo "API Key: ${{ secrets.API_KEY }}"
在仓库 Settings → Secrets and variables → Actions 中添加:
steps:
- name: Use Secret
env:
SUPER_SECRET: ${{ secrets.MY_SECRET }}
run: |
echo "Secret length is ${#SUPER_SECRET}"
steps:
- uses: actions/checkout@v3
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm ci
# .github/workflows/reusable-workflow.yml
name: Reusable Workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
node-version:
required: false
type: string
default: '18'
secrets:
api-token:
required: true
jobs:
reusable-job:
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to ${{ inputs.environment }}"
- run: echo "Using Node ${{ inputs.node-version }}"
jobs:
build:
runs-on: [self-hosted, linux, x64, gpu]
steps:
- name: Create artifact
run: echo "Hello World" > hello.txt
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: my-artifact
path: hello.txt
retention-days: 7
# 在其他作业中下载
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: my-artifact
steps:
- name: Debug info
run: |
echo "Event: ${{ github.event_name }}"
echo "Ref: ${{ github.ref }}"
echo "SHA: ${{ github.sha }}"
echo "Actor: ${{ github.actor }}"
echo "Workflow: ${{ github.workflow }}"
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ github.event_name == 'pull_request' && failure() }}
# 最小权限原则
permissions:
contents: read
actions: read
checks: write
# 使用签名验证
- name: Verify commit signature
run: |
if ! git verify-commit ${{ github.sha }}; then
echo "Commit signature verification failed!"
exit 1
fi
steps:
- name: Try something
run: ./script.sh
continue-on-error: true
- name: Check failure
if: ${{ failure() && steps.previous-step.conclusion == 'failure' }}
run: echo "Previous step failed"
name: Full CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npm run lint
test:
runs-on: ${{ matrix.os }}
needs: lint
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [16, 18]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- run: npm ci
- run: npm test
- uses: actions/upload-artifact@v3
if: ${{ success() }}
with:
name: test-results-${{ matrix.os }}-${{ matrix.node-version }}
path: test-results/
deploy:
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main'
environment: production
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run build
- name: Deploy to Production
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /var/www/myapp
git pull
npm ci --production
pm2 restart myapp
本文涵盖了 GitHub Actions 的主要功能和最佳实践。根据具体需求,您可以选择合适的配置来优化您的自动化工作流程。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online