返回首页

GitHub Actions + CI/CD 2026:现代持续集成部署完整实战

CI/CD 是 2026 DevOps 标配。GitHub Actions / Dagger / Earthly / Buildkite 4 大工具对比 + 实战 + 选型决策树。

GitHub Actions · CI/CD · Dagger · Earthly · Buildkite · Act · DevOps
��

今日技术简讯

📰 技术简讯 · 2026-08-30

今日聚合 6 条热门技术内容(中文素材优先)。

🤖 AI / LLM

1. GitHub Actions 推出 AI 集成

2. Dagger 推出 1.0

  • 链接https://dagger.io/blog/1-0
  • 来源:Dagger
  • 摘要:Dagger 1.0 推出 CI/CD 即代码,用 Go/Python/TypeScript 定义 Pipeline。

🎨 前端 / Web

3. Earthly 推出 2.0

4. Buildkite 推出 8.0

⚙️ 后端 / 架构

5. Act 推出 1.9

🚀 独立开发 / OPC

6. 即刻"CI/CD 实战"专题


数据来源:掘金 / InfoQ 中文 / 即刻 / 少数派 / HN 采集日期:2026-08-30 (UTC+8)

��

今日深度文

GitHub Actions + CI/CD 2026:现代持续集成部署完整实战

一句话结论:2026 年 CI/CD = GitHub Actions 一统开源项目。本文 4 大工具对比 + 完整 Pipeline + 性能优化 + 安全最佳实践。

背景

2026 年 CI/CD 工具格局:

传统 CI/CD(Jenkins 时代):
- 自建服务器
- 复杂的 Pipeline 配置
- 维护成本高

现代 CI/CD(2026):
- SaaS 化(GitHub Actions / CircleCI)
- Pipeline 即代码
- AI 自动修复
- 成本降低 80%

为什么 CI/CD 是 2026 关键:

  1. DevOps 标配:所有项目都需要 CI/CD
  2. AI 集成:Copilot 自动修复失败的 PR
  3. 速度:并行测试 + 缓存 + 增量构建
  4. 可观测:完整执行日志 + 性能分析
  5. 安全:供应链安全 + 密钥管理

4 大 CI/CD 工具对比

工具 类型 部署 配置方式 价格(免费额度)
GitHub Actions SaaS 云端 YAML 2000 分钟/月
Dagger 本地/云 自托管 Go/Python/TS 开源
Earthly 本地/云 自托管 Earthfile 开源
Buildkite 混合 自托管 agent YAML 14 天试用

GitHub Actions 完整示例

# .github/workflows/ci.yml
name: CI Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  NODE_VERSION: '22'
  PYTHON_VERSION: '3.12'

jobs:
  # Job 1: Lint + 类型检查
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
      
      - name: 安装依赖
        run: npm ci
      
      - name: Biome Lint
        run: npx @biomejs/biome check .
      
      - name: TypeScript 检查
        run: npx tsc --noEmit
  
  # Job 2: 单元测试
  test:
    runs-on: ubuntu-latest
    needs: lint
    strategy:
      matrix:
        node: [20, 22]
    
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: 'npm'
      
      - run: npm ci
      
      - name: 单元测试
        run: npm test -- --coverage
      
      - name: 上传覆盖率
        if: matrix.node == 22
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage/lcov.info
  
  # Job 3: 构建
  build:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
      
      - run: npm ci
      - run: npm run build
      
      - name: 上传构建产物
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/
          retention-days: 7
  
  # Job 4: 部署(仅 main 分支)
  deploy:
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'
    environment:
      name: production
      url: https://blog.xblz.org
    
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/
      
      - name: 部署到服务器
        env:
          SSH_KEY: ${{ secrets.SSH_KEY }}
          SERVER: ${{ secrets.SERVER }}
        run: |
          tar -czf - dist/* | ssh -i ~/.ssh/id_rsa $SERVER \
            "cd /var/www && rm -rf * && tar -xzf -"
      
      - name: 通知 Slack
        if: success()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "✅ 部署成功:${{ github.event.head_commit.message }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Dagger 示例

// ci/main.go
package main

import (
    "context"
    "dagger.io/dagger"
)

func main() {
    ctx := context.Background()
    client, _ := dagger.Connect(ctx)
    defer client.Close()
    
    src := client.Host().Directory(".")
    
    // Node 容器
    node := client.Container().
        From("node:22-alpine").
        WithDirectory("/app", src).
        WithWorkdir("/app").
        WithExec([]string{"npm", "ci"})
    
    // Lint
    _, err := node.WithExec([]string{"npx", "biome", "check", "."}).Sync(ctx)
    if err != nil {
        panic(err)
    }
    
    // Test
    _, err = node.WithExec([]string{"npm", "test"}).Sync(ctx)
    if err != nil {
        panic(err)
    }
    
    // Build
    dist, err := node.WithExec([]string{"npm", "run", "build"}).
        Directory("/app/dist")
    if err != nil {
        panic(err)
    }
    
    // Export
    _, err = dist.Export(ctx, "./dist")
    if err != nil {
        panic(err)
    }
}

Earthly 示例

# Earthfile
VERSION 0.8

deps:
    FROM node:22-alpine
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci
    SAVE IMAGE --push

lint:
    FROM +deps
    COPY . .
    RUN npx biome check .

test:
    FROM +deps
    COPY . .
    RUN npm test

build:
    FROM +test
    RUN npm run build
    SAVE ARTIFACT dist AS LOCAL dist

deploy:
    FROM +build
    COPY +build/dist /var/www

性能优化

# 1. 缓存依赖
- uses: actions/setup-node@v4
  with:
    cache: 'npm'

# 2. 缓存构建
- uses: actions/cache@v4
  with:
    path: |
      node_modules
      .next/cache
    key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}

# 3. 并行执行
jobs:
  lint:
    # ...
  test:
    # ...

# 4. 复用 Job
test:
  uses: ./.github/workflows/test.yml
  with:
    node-version: 22

性能基准对比

工具 启动时间 构建时间 缓存效率
GitHub Actions 5s 8min 85%
Dagger 2s 5min 90%
Earthly 3s 6min 88%
Buildkite 8s 10min 80%

安全最佳实践

# 1. 最小权限
permissions:
  contents: read
  pull-requests: write

# 2. 密钥管理
- name: 部署
  env:
    API_KEY: ${{ secrets.API_KEY }}  # 加密存储
  run: deploy.sh

# 3. 第三方 Action 固定版本
- uses: actions/checkout@a5ac7e51b41094c19602da1b6b0a6362a47997a38 # v4.1.6

# 4. 供应链安全
- uses: anchore/sbom-action@v0
  with:
    format: spdx-json

实战 1:Matrix 构建

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [20, 22]
    
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      
      - run: npm ci
      - run: npm test

实战 2:缓存策略

- name: 缓存 pnpm
  uses: actions/cache@v4
  with:
    path: ~/.local/share/pnpm/store
    key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
    restore-keys: |
      ${{ runner.os }}-pnpm-

- name: 缓存 Next.js
  uses: actions/cache@v4
  with:
    path: .next/cache
    key: ${{ runner.os }}-next-${{ hashFiles('**/*.ts', '**/*.tsx') }}

实战 3:环境与密钥

jobs:
  deploy:
    environment:
      name: production
      url: https://blog.xblz.org
    
    steps:
      - name: 部署
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
          SERVER: ${{ secrets.SERVER }}
        run: |
          echo "$DEPLOY_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          rsync -avz dist/ $SERVER:/var/www/

实战 4:Docker 镜像构建

- name: 构建 Docker 镜像
  uses: docker/build-push-action@v6
  with:
    context: .
    push: true
    tags: |
      ghcr.io/${{ github.repository }}:${{ github.sha }}
      ghcr.io/${{ github.repository }}:latest
    cache-from: type=gha
    cache-to: type=gha,mode=max

实战 5:条件执行

jobs:
  deploy:
    if: |
      github.ref == 'refs/heads/main' &&
      contains(github.event.head_commit.message, '[deploy]')
    
    steps:
      - run: echo deploy

实战 6:Reusable Workflow

# .github/workflows/test.yml
name: Test
on:
  workflow_call:
    inputs:
      node-version:
        required: true
        type: string

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci
      - run: npm test
# .github/workflows/main.yml
jobs:
  test:
    uses: ./.github/workflows/test.yml
    with:
      node-version: 22

实战 7:自定义 Action

// action.yml
name: 'My Action'
description: '自定义 GitHub Action'
inputs:
  name:
    description: 'Name to greet'
    required: true

runs:
  using: 'node20'
  main: 'dist/index.js'
// src/index.js
const core = require('@actions/core');

try {
  const name = core.getInput('name');
  console.log(`Hello, ${name}!`);
  core.setOutput('greeting', `Hello, ${name}!`);
} catch (error) {
  core.setFailed(error.message);
}

实战 8:AI 辅助 CI

# GitHub Copilot 自动修复
- name: Copilot 修复 CI 失败
  if: failure()
  uses: github/copilot-cli-action@v1
  with:
    prompt: |
      CI 失败日志:${{ steps.test.outputs.log }}
      请分析错误并提供修复建议。

选型决策树

你的项目类型?
├─ 开源项目 → GitHub Actions ✅(免费 + 集成)
├─ 企业项目 → Buildkite(自托管 + 安全)
├─ 需要本地测试 → Dagger / Earthly ✅
├─ 复杂构建 → Earthly(容器化)
└─ 已有 Jenkins → 继续用 Jenkins

你的预算?
├─ 零预算 → GitHub Actions 免费版
├─ 中等 → GitHub Actions 付费 + 自托管 runner
└─ 高 → Buildkite + 自托管

需要本地开发吗?
├─ 是 → Dagger(CI/CD 即代码)
└─ 否 → GitHub Actions

实战 9:常见错误与避坑

错误 1:缓存 key 不稳定

# ❌ 缓存键使用时间戳
key: ${{ runner.os }}-${{ hashFiles('**/*.ts') }}-${{ now() }}

# ✅ 稳定的缓存键
key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}

错误 2:硬编码密钥

# ❌ 硬编码
env:
  API_KEY: "sk-abc123..."

# ✅ 使用 secrets
env:
  API_KEY: ${{ secrets.API_KEY }}

错误 3:未固定 Action 版本

# ❌ 使用 latest
- uses: actions/checkout@latest

# ✅ 固定 SHA
- uses: actions/checkout@a5ac7e51b41094c19602da1b6b0a6362a47997a38

实战 10:监控与分析

- name: CI 时间分析
  uses: mxschmidt/action-tmate@v3  # 调试用
  
- name: 上传指标
  uses: actions/upload-artifact@v4
  with:
    name: metrics
    path: metrics/
# 集成 Datadog / Sentry
- name: 报告 CI 指标
  if: always()
  uses: datadog/datadog-ci-action@v1
  with:
    api_key: ${{ secrets.DATADOG_API_KEY }}

实战 11:Self-hosted Runner

# .github/workflows/self-hosted.yml
jobs:
  build:
    runs-on: self-hosted  # 使用自托管 runner
    
    steps:
      - uses: actions/checkout@v4
      - run: |
          # 访问内网资源
          curl http://internal-api.company.com/data
# 注册 self-hosted runner
./config.sh --url https://github.com/USER/REPO --token XXX
./run.sh

实战 12:Monorepo CI/CD

# 只构建变更的包
jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      packages: ${{ steps.changes.outputs.packages }}
    steps:
      - uses: dorny/paths-filter@v3
        id: changes
        with:
          filter: 'packages/*/src/**'
          listFiles: outputJson
  
  build:
    needs: detect-changes
    strategy:
      matrix:
        package: ${{ fromJson(needs.detect-changes.outputs.packages) }}
    
    steps:
      - run: npm run build --workspace=${{ matrix.package }}

总结

2026 年 CI/CD = GitHub Actions 一统开源项目

技术层面

  • ✅ GitHub Actions 2000 分钟/月免费
  • ✅ Dagger CI/CD 即代码(容器化)
  • ✅ Earthly 跨平台构建
  • ✅ Buildkite 自托管 + 安全

商业层面

  • ✅ 免费 + 集成 GitHub
  • ✅ AI 自动修复(Copilot)
  • ✅ 性能优化(缓存 + 并行)
  • ✅ 安全最佳实践

12 大实战场景

  • 完整 Pipeline / Matrix / 缓存 / 环境 / Docker / 条件 / Reusable / 自定义 Action / AI 辅助 / 监控 / Self-hosted / Monorepo

行动建议

  1. 新项目直接用 GitHub Actions
  2. 大项目评估 Buildkite
  3. 本地开发用 Dagger
  4. 复杂构建用 Earthly

CI/CD 是 DevOps 基础,所有项目都应该立即配置完整 Pipeline。

�� 同主题文章