介绍创建操作的最佳做法
创建高质量的 GitHub Actions 需要遵循安全、可靠性和可用性的最佳做法。
质量行动的设计原则
单一责任原则
设计专注于做好一件事的行动,而不是企图解决多个问题。
# DON'T: Monolithic action that does everything
name: 'Build-Test-Deploy-Notify Action'
description: 'Builds app, runs tests, deploys to cloud, and sends notifications'
# DO: Focused, composable actions
name: 'Setup Node.js with Cache'
description: 'Sets up Node.js with intelligent dependency caching'
重点行动的优点:
- 更易于理解、测试和维护
- 可跨不同工作流方案重复使用
- 出现问题时进行更简单的调试
- 在复杂工作流中提高可组合性
可组合和可链接的设计
创建在工作流序列中配合良好的操作:
# Example of well-designed action chain
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js with cache
uses: myorg/setup-node-with-cache@v2
with:
node-version: "20"
- name: Run security audit
uses: myorg/security-audit@v1
- name: Build and test
uses: myorg/build-and-test@v3
with:
test-command: "npm test"
- name: Upload coverage
uses: myorg/upload-coverage@v1
with:
coverage-file: "coverage/lcov.info"
操作元数据与文档
完成action.yml的规范编写
name: "Secure Docker Build"
description: "Build and scan Docker images with security best practices"
author: "DevSecOps Team <team@company.com>"
# Visual identity in marketplace
branding:
icon: "shield"
color: "blue"
# Clear input definition
inputs:
dockerfile-path:
description: "Path to the Dockerfile"
required: true
default: "./Dockerfile"
image-name:
description: "Name for the built image"
required: true
registry-url:
description: "Container registry URL"
required: false
default: "ghcr.io"
security-scan:
description: "Enable security vulnerability scanning"
required: false
default: "true"
scan-severity:
description: "Minimum severity level for scan failures"
required: false
default: "HIGH"
# Expected outputs
outputs:
image-digest:
description: "SHA256 digest of the built image"
security-report:
description: "Path to security scan report"
image-size:
description: "Size of the built image in bytes"
runs:
using: "composite"
steps:
- name: Build Docker image
shell: bash
run: |
docker build -f ${{ inputs.dockerfile-path }} -t ${{ inputs.image-name }} .
echo "image-digest=$(docker inspect --format='{{index .RepoDigests 0}}' ${{ inputs.image-name }})" >> $GITHUB_OUTPUT
- name: Security scan
if: inputs.security-scan == 'true'
shell: bash
run: |
# Security scanning logic
trivy image --severity ${{ inputs.scan-severity }} ${{ inputs.image-name }}
完整的自述文件文档
# Secure Docker Build Action
Build and scan Docker images with integrated security best practices.
## Features
- Flexible Dockerfile path configuration
- Integrated security vulnerability scanning
- Detailed build and security reports
- Optimized for CI/CD pipelines
- Security-first design
## Usage
### Basic usage
```yaml
- name: Build and scan Docker image
uses: myorg/secure-docker-build@v2
with:
dockerfile-path: "./Dockerfile"
image-name: "my-app:latest"
```
高级配置
- name: Build with custom security settings
uses: myorg/secure-docker-build@v2
with:
dockerfile-path: "./docker/Dockerfile.prod"
image-name: "my-app:${{ github.sha }}"
registry-url: "myregistry.azurecr.io"
security-scan: "true"
scan-severity: "MEDIUM"
输入
| Input | Description | 必选 | 违约 |
|---|---|---|---|
dockerfile-path |
Dockerfile 的路径 | 是的 | ./Dockerfile |
image-name |
Docker 映像名称 | 是的 | - |
registry-url |
容器注册表 | 否 | ghcr.io |
security-scan |
启用安全扫描 | 否 | true |
scan-severity |
失败的最低严重性 | 否 | HIGH |
输出
| 输出 | Description |
|---|---|
image-digest |
生成的映像的 SHA256 摘要 |
security-report |
安全扫描报告的路径 |
image-size |
内置映像的大小(以字节为单位) |
安全注意事项
此作实现安全最佳做法:
- 使用 Trivy 进行漏洞扫描
- 非根容器运行
- 最小基础镜像建议
- 安全报告生成
## Version management and release strategy
### Semantic versioning implementation
```bash
# Release tagging strategy
git tag -a v1.0.0 -m "Initial stable release"
git tag -a v1.0.1 -m "Bug fix: Handle empty Dockerfile paths"
git tag -a v1.1.0 -m "Feature: Add multi-arch build support"
git tag -a v2.0.0 -m "Breaking: Change input parameter names"
# Major version tags for easy consumption
git tag -f v1 v1.1.0 # Point v1 to latest v1.x.x
git tag -f v2 v2.0.0 # Point v2 to latest v2.x.x
发布自动化工作流
name: Release Action
on:
release:
types: [published]
jobs:
tag-major-version:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Update major version tag
run: |
TAG=${GITHUB_REF#refs/tags/}
MAJOR_VERSION=$(echo $TAG | cut -d. -f1)
git config user.name "Release Bot"
git config user.email "release@company.com"
git tag -fa $MAJOR_VERSION -m "Point $MAJOR_VERSION to $TAG"
git push origin $MAJOR_VERSION --force
动作的安全最佳实践
输入验证和过滤
# In action.yml
inputs:
file-path:
description: "Path to file"
required: true
runs:
using: "composite"
steps:
- name: Validate inputs
shell: bash
run: |
# Validate file path to prevent directory traversal
FILE_PATH="${{ inputs.file-path }}"
# Check for dangerous characters
if [[ "$FILE_PATH" =~ \.\. ]]; then
echo "Invalid file path: contains '..' (directory traversal)"
exit 1
fi
# Ensure path is within workspace
REAL_PATH=$(realpath "$FILE_PATH" 2>/dev/null || echo "")
WORKSPACE_PATH=$(realpath "$GITHUB_WORKSPACE")
if [[ ! "$REAL_PATH" == "$WORKSPACE_PATH"* ]]; then
echo "File path outside workspace: $FILE_PATH"
exit 1
fi
echo "File path validated: $FILE_PATH"
安全机密处理
# Proper secret usage in composite actions
- name: Use secrets securely
shell: bash
env:
# Pass secrets through environment variables
API_TOKEN: ${{ inputs.api-token }}
run: |
# Never log secrets
echo "Authenticating with API..."
# Use secrets in secure contexts
curl -H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
https://api.example.com/data
# Clean up sensitive data
unset API_TOKEN
最低特权原则
# Define minimal permissions needed
permissions:
contents: read
security-events: write # Only if security scanning
packages: write # Only if publishing packages
jobs:
secure-action:
runs-on: ubuntu-latest
steps:
- name: Minimal permission usage
uses: myorg/secure-action@v2
with:
# Only pass necessary inputs
required-input: "value"
性能和效率指南
高效的资源使用
# Optimize action performance
runs:
using: "composite"
steps:
- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.cache/my-tool
key: ${{ runner.os }}-my-tool-${{ hashFiles('**/config.json') }}
- name: Parallel processing where possible
shell: bash
run: |
# Use background processes for independent tasks
task1 &
task2 &
task3 &
# Wait for all tasks to complete
wait
容器操作优化
# Dockerfile for container actions
FROM node:20-alpine
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
# Install only production dependencies
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# Copy application code
COPY . .
# Set proper ownership
RUN chown -R nextjs:nodejs /app
USER nextjs
ENTRYPOINT ["/entrypoint.sh"]
测试和质量保证
操作测试工作流
name: Test Action
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test-action:
runs-on: ubuntu-latest
strategy:
matrix:
test-case:
- name: "Basic functionality"
dockerfile-path: "./test/Dockerfile.basic"
expected-outcome: "success"
- name: "Security scan failure"
dockerfile-path: "./test/Dockerfile.vulnerable"
expected-outcome: "failure"
- name: "Custom configuration"
dockerfile-path: "./test/Dockerfile.custom"
security-scan: "false"
expected-outcome: "success"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Test action
id: test
uses: ./ # Test local action
with:
dockerfile-path: ${{ matrix.test-case.dockerfile-path }}
image-name: "test-image:latest"
security-scan: ${{ matrix.test-case.security-scan || 'true' }}
continue-on-error: ${{ matrix.test-case.expected-outcome == 'failure' }}
- name: Validate outcome
run: |
if [[ "${{ steps.test.outcome }}" == "${{ matrix.test-case.expected-outcome }}" ]]; then
echo "Test passed: ${{ matrix.test-case.name }}"
else
echo "Test failed: Expected ${{ matrix.test-case.expected-outcome }}, got ${{ steps.test.outcome }}"
exit 1
fi
市场和社区准则
市场提交准备
- 清除命名:使用描述性、可搜索的名称
- 质量自述文件:包括使用示例、输入/输出文档
- 适当的分类:选择适当的市场类别
- 版本稳定性:确保发布版本稳定并测试
社区参与
# Include community templates
# .github/ISSUE_TEMPLATE/bug_report.yml
name: Bug Report
description: File a bug report for this action
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug!
- type: input
id: action-version
attributes:
label: Action Version
description: Which version of the action are you using?
placeholder: v2.1.0
validations:
required: true
- type: textarea
id: workflow-snippet
attributes:
label: Workflow Configuration
description: Share your workflow configuration
render: yaml
validations:
required: true
遵循这些最佳做法可确保 GitHub Actions 对社区具有专业性、安全性、可维护性和价值。 专注于创建既能解决实际问题又易于使用和理解的操作。