Published on

GitHub高阶功能指南

Authors
  • avatar
    Name
    Haoan Zhang
    Twitter

Git vs GitHub

GitHub高阶功能完全指南:从进阶到精通

1. GitHub Actions高级配置

1.1 复杂工作流编排

1.1.1 多作业并行执行

name: Complex CI/CD Pipeline
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14, 16, 18]
        database: [mysql, postgres]
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - name: Setup Database
        run: |
          if [ "${{ matrix.database }}" = "mysql" ]; then
            docker run --name mysql -e MYSQL_ROOT_PASSWORD=password -d mysql:8
          else
            docker run --name postgres -e POSTGRES_PASSWORD=password -d postgres:14
          fi
  
  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build Docker image
        run: docker build -t myapp:${{ github.sha }} .

1.1.2 条件执行与环境变量

name: Conditional Workflow
on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Deploy to Environment
        if: github.event_name == 'push'
        env:
          API_KEY: ${{ secrets.API_KEY }}
          ENV_NAME: ${{ github.ref == 'refs/heads/main' && 'prod' || 'staging' }}
        run: |
          echo "Deploying to $ENV_NAME"
          ./deploy.sh $API_KEY $ENV_NAME

1.2 自定义Actions

1.2.1 复合Actions示例

# .github/actions/custom-build/action.yml
name: 'Custom Build Process'
description: 'Performs our custom build process'
inputs:
  build-type:
    description: 'Type of build to perform'
    required: true
    default: 'production'
outputs:
  build-id:
    description: 'The ID of the build'
    value: ${{ steps.build.outputs.id }}
runs:
  using: "composite"
  steps:
    - id: build
      shell: bash
      run: |
        echo "Starting ${{ inputs.build-type }} build..."
        BUILD_ID=$(date +%s)
        echo "id=$BUILD_ID" >> $GITHUB_OUTPUT

使用自定义Action:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: ./.github/actions/custom-build
        with:
          build-type: 'staging'

2. 高级项目管理

2.1 GitHub Projects (Beta)版本

2.1.1 自动化工作流配置

# .github/workflows/project-automation.yml
name: Project Automation
on:
  issues:
    types: [opened, labeled]
  pull_request:
    types: [opened, ready_for_review]

jobs:
  project-automation:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/add-to-project@v0.5.0
        with:
          project-url: https://github.com/orgs/org-name/projects/1
          labeled: bug, enhancement

2.1.2 自定义视图配置

// 项目视图配置示例
{
  "fields": [
    {
      "id": "Status",
      "values": ["Todo", "In Progress", "Review", "Done"]
    },
    {
      "id": "Priority",
      "values": ["High", "Medium", "Low"]
    }
  ],
  "views": [
    {
      "name": "Development Board",
      "layout": "board",
      "group_by": "Status"
    }
  ]
}

2.2 高级Issue模板

2.2.1 复杂Issue表单

# .github/ISSUE_TEMPLATE/feature_request.yml
name: Feature Request
description: Suggest an idea for this project
title: "[Feature]: "
labels: ["enhancement"]
assignees:
  - project-maintainer
body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to suggest a new feature!
  
  - type: input
    id: contact
    attributes:
      label: Contact Details
      description: How can we get in touch with you if we need more info?
      placeholder: ex. email@example.com
    validations:
      required: false
  
  - type: textarea
    id: problem
    attributes:
      label: Is your feature request related to a problem?
      description: What problem are you trying to solve?
      placeholder: I'm always frustrated when...
    validations:
      required: true
  
  - type: dropdown
    id: priority
    attributes:
      label: Priority
      description: How important is this feature?
      options:
        - Critical
        - High
        - Medium
        - Low
    validations:
      required: true

3. 代码智能功能

3.1 CodeQL高级配置

3.1.1 自定义代码扫描

# .github/workflows/codeql-analysis.yml
name: "CodeQL Advanced Analysis"
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  schedule:
    - cron: '0 0 * * 0'

jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
      with:
        languages: javascript, python
        queries: security-extended,security-and-quality
    
    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2
      with:
        category: "/language:javascript"

3.2 依赖审查与更新

3.2.1 Dependabot高级配置

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "09:00"
      timezone: "Asia/Shanghai"
    
    ignore:
      - dependency-name: "lodash"
        versions: [">=4.0.0"]
    
    labels:
      - "dependencies"
      - "security"
    
    commit-message:
      prefix: "deps"
      include: "scope"
    
    pull-request-branch-name:
      separator: "-"
    
    reviewers:
      - "team-leads"
    
    assignees:
      - "dependency-manager"

4. 高级仓库配置

4.1 分支保护规则

4.1.1 详细配置示例

{
  "branch_protection_rules": [
    {
      "pattern": "main",
      "required_status_checks": {
        "strict": true,
        "contexts": [
          "continuous-integration/jenkins",
          "security/snyk"
        ]
      },
      "required_pull_request_reviews": {
        "required_approving_review_count": 2,
        "dismiss_stale_reviews": true,
        "require_code_owner_reviews": true
      },
      "enforce_admins": true,
      "restrictions": {
        "users": ["lead-dev"],
        "teams": ["core-team"]
      }
    }
  ]
}

4.2 高级安全设置

4.2.1 安全策略配置

# SECURITY.md
# Security Policy

## Supported Versions

| Version | Supported          |
| ------- | ------------------ |
| 5.1.x   | :white_check_mark: |
| 5.0.x   | :x:                |
| 4.0.x   | :white_check_mark: |
| < 4.0   | :x:                |

## Reporting a Vulnerability

1. **Do not** open an issue
2. Email security@company.com
3. Include detailed reproduction steps
4. We will respond within 48 hours

5. 高级API使用

5.1 GraphQL API查询

5.1.1 复杂查询示例

query {
  repository(owner: "octocat", name: "Hello-World") {
    issues(last: 20, states: OPEN) {
      edges {
        node {
          title
          url
          labels(first: 5) {
            edges {
              node {
                name
              }
            }
          }
          author {
            login
          }
          comments(first: 3) {
            edges {
              node {
                body
                author {
                  login
                }
              }
            }
          }
        }
      }
    }
  }
}

5.2 Webhooks高级配置

5.2.1 自定义Webhook处理

// webhook-handler.js
const crypto = require('crypto');

function verifyGithubWebhook(req, secret) {
  const signature = req.headers['x-hub-signature-256'];
  const hmac = crypto.createHmac('sha256', secret);
  const digest = 'sha256=' + hmac.update(JSON.stringify(req.body)).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}

app.post('/webhook', (req, res) => {
  if (!verifyGithubWebhook(req, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Unauthorized');
  }

  const event = req.headers['x-github-event'];
  switch (event) {
    case 'push':
      handlePushEvent(req.body);
      break;
    case 'pull_request':
      handlePullRequestEvent(req.body);
      break;
    // 处理其他事件...
  }

  res.status(200).send('OK');
});

6. 高级CI/CD配置

6.1 多环境部署

6.1.1 环境特定配置

# .github/workflows/deploy.yml
name: Multi-Environment Deployment
on:
  push:
    branches:
      - main
      - develop
  pull_request:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}
      
      - name: Deploy to Environment
        run: |
          if [ "${{ github.ref }}" = "refs/heads/main" ]; then
            ./deploy.sh production
          else
            ./deploy.sh staging
          fi

6.2 高级测试策略

6.2.1 并行测试执行

name: Advanced Testing
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1, 2, 3, 4]
        include:
          - shard: 1
            tests: "tests/unit/*"
          - shard: 2
            tests: "tests/integration/*"
          - shard: 3
            tests: "tests/e2e/*"
          - shard: 4
            tests: "tests/performance/*"
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Run Tests
        run: |
          npm ci
          npm test -- --shard=${{ matrix.shard }}/${{ strategy.job-total }} ${{ matrix.tests }}

7. 实践技巧与建议

7.1 工作流优化

  1. 使用工作流缓存
steps:
  - uses: actions/cache@v3
    with:
      path: |
        ~/.npm
        node_modules
      key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
  1. 并行作业优化
jobs:
  setup:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - id: set-matrix
        run: |
          echo "matrix=$(./generate-test-matrix.sh)" >> $GITHUB_OUTPUT
  
  test:
    needs: setup
    runs-on: ubuntu-latest
    strategy:
      matrix: ${{fromJson(needs.setup.outputs.matrix)}}

7.2 最佳实践建议

  1. 自动化标签管理
name: Label Management
on:
  issues:
    types: [opened, edited]
  pull_request:
    types: [opened, edited]

jobs:
  label:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/labeler@v4
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          configuration-path: .github/labeler.yml
  1. 代码所有者规则
# CODEOWNERS
# 默认所有者
*       @global-owner1 @global-owner2

# 特定文件/目录所有者
/docs/  @docs-team
*.js    @js-team
*.go    @go-team
/security/ @security-team