GitHub Actions 步骤Step #
步骤(Step)是作业中的最小执行单元,可以执行命令或使用Action。本节深入探讨步骤的各个方面。
步骤概述 #
什么是步骤? #
步骤是作业中的执行单元,具有以下特点:
- 在同一作业中顺序执行
- 可以运行shell命令或使用Action
- 可以访问文件系统和环境变量
- 可以设置输出供后续步骤使用
步骤类型 #
yaml
steps:
# 运行命令
- run: echo "Hello World"
# 使用Action
- uses: actions/checkout@v4
# 带名称的步骤
- name: My Step
run: echo "Hello"
运行命令 #
基本命令 #
yaml
steps:
- run: echo "Hello World"
- run: npm install
- run: npm test
多行命令 #
yaml
steps:
- name: Multiple commands
run: |
echo "Line 1"
echo "Line 2"
echo "Line 3"
使用变量 #
yaml
steps:
- name: Use environment variables
run: |
echo "Runner OS: ${{ runner.os }}"
echo "Repository: ${{ github.repository }}"
echo "Branch: ${{ github.ref_name }}"
Shell选择 #
yaml
steps:
- name: Using bash
run: echo $PATH
shell: bash
- name: Using sh
run: echo $PATH
shell: sh
- name: Using PowerShell
run: Write-Host "Hello"
shell: pwsh
- name: Using cmd
run: echo Hello
shell: cmd
- name: Using Python
run: print("Hello")
shell: python
工作目录 #
yaml
steps:
- name: Run in subdirectory
working-directory: ./app
run: |
pwd
ls -la
使用Action #
基本用法 #
yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
带参数的Action #
yaml
steps:
- uses: actions/checkout@v4
with:
repository: owner/repo
ref: main
token: ${{ secrets.GITHUB_TOKEN }}
path: ./checkout-dir
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: subdir/package-lock.json
本地Action #
yaml
steps:
- uses: ./.github/actions/my-action
with:
param1: value1
Docker Action #
yaml
steps:
- uses: docker://alpine:3.8
with:
args: echo "Hello from Docker"
条件执行 #
基本条件 #
yaml
steps:
- name: Only on main branch
if: github.ref == 'refs/heads/main'
run: echo "This is main branch"
- name: Only on push event
if: github.event_name == 'push'
run: echo "This is a push event"
状态函数 #
yaml
steps:
- name: Previous step
run: exit 0
- name: On success
if: success()
run: echo "Previous steps succeeded"
- name: On failure
if: failure()
run: echo "Previous steps failed"
- name: Always run
if: always()
run: echo "This always runs"
- name: On cancelled
if: cancelled()
run: echo "Workflow was cancelled"
组合条件 #
yaml
steps:
- name: Complex condition
if: github.ref == 'refs/heads/main' && success()
run: echo "Main branch and success"
- name: With matrix
if: matrix.node == '20' && matrix.os == 'ubuntu-latest'
run: echo "Specific matrix configuration"
环境变量 #
步骤级环境变量 #
yaml
steps:
- name: With environment variables
env:
MY_VAR: value
ANOTHER_VAR: another
run: |
echo $MY_VAR
echo $ANOTHER_VAR
使用Secrets #
yaml
steps:
- name: Use secrets
env:
API_KEY: ${{ secrets.API_KEY }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
run: |
echo "Using API_KEY"
# 不要打印secrets的值!
动态环境变量 #
yaml
steps:
- name: Set dynamic env
id: set-env
run: echo "MY_VAR=dynamic_value" >> $GITHUB_ENV
- name: Use dynamic env
run: echo $MY_VAR
输出变量 #
设置输出 #
yaml
steps:
- id: set-output
name: Set output
run: |
echo "name=value" >> $GITHUB_OUTPUT
echo "version=1.0.0" >> $GITHUB_OUTPUT
- name: Use output
run: |
echo "Name: ${{ steps.set-output.outputs.name }}"
echo "Version: ${{ steps.set-output.outputs.version }}"
多行输出 #
yaml
steps:
- id: multiline
name: Set multiline output
run: |
{
echo "content<<EOF"
echo "Line 1"
echo "Line 2"
echo "Line 3"
echo "EOF"
} >> $GITHUB_OUTPUT
- name: Use multiline output
run: |
echo "${{ steps.multiline.outputs.content }}"
JSON输出 #
yaml
steps:
- id: json-output
name: Set JSON output
run: |
echo "data={\"name\":\"test\",\"value\":123}" >> $GITHUB_OUTPUT
- name: Use JSON output
run: |
echo "Name: ${{ fromJson(steps.json-output.outputs.data).name }}"
echo "Value: ${{ fromJson(steps.json-output.outputs.data).value }}"
继续执行 #
continue-on-error #
yaml
steps:
- name: Might fail
run: exit 1
continue-on-error: true
- name: Will still run
run: echo "This runs even if previous step failed"
条件继续 #
yaml
steps:
- name: Conditional continue
run: exit 1
continue-on-error: ${{ github.ref != 'refs/heads/main' }}
超时设置 #
yaml
steps:
- name: Long running task
run: ./long-script.sh
timeout-minutes: 10
工作流命令 #
设置环境变量 #
yaml
steps:
- name: Set env var
run: echo "MY_VAR=hello" >> $GITHUB_ENV
- name: Use env var
run: echo $MY_VAR
添加系统路径 #
yaml
steps:
- name: Add to PATH
run: echo "$HOME/mybin" >> $GITHUB_PATH
- name: Use new path
run: my-custom-command
输出分组 #
yaml
steps:
- name: Grouped output
run: |
echo "::group::My group title"
echo "Line 1"
echo "Line 2"
echo "::endgroup::"
掩码值 #
yaml
steps:
- name: Mask secret
run: echo "::add-mask::${{ secrets.MY_SECRET }}"
- name: Use masked value
run: echo "The value is masked in logs"
调试消息 #
yaml
steps:
- name: Debug output
run: |
echo "::debug::This is a debug message"
echo "::warning::This is a warning"
echo "::error::This is an error"
步骤摘要 #
yaml
steps:
- name: Generate summary
run: |
echo "## Build Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "✅ Build succeeded" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Test Results" >> $GITHUB_STEP_SUMMARY
echo "| Test | Status |" >> $GITHUB_STEP_SUMMARY
echo "|------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Unit | ✅ |" >> $GITHUB_STEP_SUMMARY
echo "| E2E | ✅ |" >> $GITHUB_STEP_SUMMARY
步骤示例 #
检出代码 #
yaml
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整历史
设置语言环境 #
yaml
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: true
缓存依赖 #
yaml
steps:
- name: Cache node modules
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
上传制品 #
yaml
steps:
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: my-artifact
path: dist/
retention-days: 5
下载制品 #
yaml
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: my-artifact
path: ./downloaded
部署 #
yaml
steps:
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
- name: Deploy to AWS S3
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --follow-symlinks
env:
AWS_S3_BUCKET: ${{ secrets.S3_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
完整示例 #
yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test -- --coverage
env:
CI: true
- name: Build
run: npm run build
- name: Upload coverage
if: success()
uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage/
- name: Upload build
if: success()
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
- name: Generate summary
if: always()
run: |
echo "## Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "✅ Build completed" >> $GITHUB_STEP_SUMMARY
最佳实践 #
1. 使用有意义的名称 #
yaml
steps:
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm test
2. 合理使用条件 #
yaml
steps:
- name: Deploy to production
if: github.ref == 'refs/heads/main'
run: ./deploy.sh production
- name: Notify on failure
if: failure()
run: ./notify.sh
3. 使用环境变量 #
yaml
steps:
- name: Build
env:
NODE_ENV: production
run: npm run build
4. 设置超时 #
yaml
steps:
- name: Long running task
timeout-minutes: 10
run: ./long-script.sh
5. 使用步骤摘要 #
yaml
steps:
- name: Summary
if: always()
run: |
echo "## Results" >> $GITHUB_STEP_SUMMARY
echo "Status: ${{ job.status }}" >> $GITHUB_STEP_SUMMARY
下一步学习 #
小结 #
- 步骤是作业中的最小执行单元
- 可以运行命令或使用Action
- 支持条件执行和状态检查
- 可以设置和使用输出变量
- 支持环境变量和工作目录配置
- 使用工作流命令增强功能
- 遵循最佳实践提高可读性和可维护性
最后更新:2026-03-28