GitHub Actions 动作Action #
动作(Action)是GitHub Actions中的可重用代码单元,执行特定任务。本节深入探讨Action的类型、使用方式和创建方法。
Action概述 #
什么是Action? #
Action是可重用的代码单元,可以:
- 执行特定任务(如检出代码、设置环境)
- 封装复杂逻辑
- 跨工作流共享和复用
- 发布到Marketplace供他人使用
Action类型 #
GitHub Actions支持三种类型的Action:
| 类型 | 描述 | 执行速度 |
|---|---|---|
| JavaScript Action | 使用Node.js编写 | 最快 |
| Docker Action | 使用Docker容器 | 较慢 |
| Composite Action | 组合多个步骤 | 中等 |
使用Action #
基本语法 #
yaml
steps:
- uses: owner/repo@version
版本指定 #
yaml
steps:
# 使用具体版本(推荐)
- uses: actions/checkout@v4
# 使用SHA(最安全)
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
# 使用分支(不推荐用于生产)
- uses: actions/checkout@main
传递参数 #
yaml
steps:
- uses: actions/checkout@v4
with:
repository: owner/repo
ref: main
token: ${{ secrets.GITHUB_TOKEN }}
path: ./src
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
registry-url: 'https://registry.npmjs.org'
使用环境变量 #
yaml
steps:
- uses: actions/setup-node@v4
with:
node-version: '20'
env:
NODE_ENV: production
常用Action #
代码检出 #
yaml
steps:
- uses: actions/checkout@v4
完整配置:
yaml
steps:
- uses: actions/checkout@v4
with:
repository: owner/repo # 仓库名
ref: main # 分支或标签
token: ${{ secrets.GITHUB_TOKEN }} # 访问令牌
ssh-key: ${{ secrets.SSH_KEY }} # SSH密钥
ssh-known-hosts: '' # 已知主机
ssh-strict: true # 严格SSH检查
persist-credentials: true # 保存凭证
path: ./src # 检出路径
clean: true # 清理工作区
fetch-depth: 1 # 获取深度
lfs: false # 是否获取LFS
submodules: false # 是否获取子模块
设置语言环境 #
yaml
# Node.js
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
# Python
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
# Go
- uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: true
# Java
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'maven'
# Ruby
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
缓存 #
yaml
- uses: actions/cache@v4
with:
path: |
~/.npm
~/.cache
key: ${{ runner.os }}-cache-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-cache-
制品管理 #
yaml
# 上传
- uses: actions/upload-artifact@v4
with:
name: my-artifact
path: dist/
retention-days: 5
# 下载
- uses: actions/download-artifact@v4
with:
name: my-artifact
path: ./downloaded
GitHub Pages部署 #
yaml
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
publish_branch: gh-pages
cname: example.com
Docker操作 #
yaml
# 登录
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# 构建
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
JavaScript Action #
目录结构 #
text
my-action/
├── action.yml
├── index.js
├── package.json
└── node_modules/
action.yml #
yaml
name: 'My Action'
description: 理解GitHub Actions动作的概念、类型和使用方式。
author: 'Your Name'
inputs:
my-input:
description: 'Input description'
required: true
default: 'default value'
outputs:
my-output:
description: 'Output description'
runs:
using: 'node20'
main: 'dist/index.js'
branding:
icon: 'check-circle'
color: 'green'
index.js #
javascript
const core = require('@actions/core');
const github = require('@actions/github');
try {
const myInput = core.getInput('my-input');
console.log(`Input: ${myInput}`);
const myOutput = 'output value';
core.setOutput('my-output', myOutput);
console.log(`Event: ${github.context.eventName}`);
console.log(`Repo: ${github.context.repo.owner}/${github.context.repo.repo}`);
} catch (error) {
core.setFailed(error.message);
}
package.json #
json
{
"name": "my-action",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"@actions/core": "^1.10.1",
"@actions/github": "^6.0.0"
}
}
使用工具包 #
javascript
const core = require('@actions/core');
const github = require('@actions/github');
const exec = require('@actions/exec');
const io = require('@actions/io');
const toolCache = require('@actions/tool-cache');
// 输入输出
const input = core.getInput('input', { required: true });
core.setOutput('output', 'value');
core.setSecret('secret-value');
// 环境变量
core.exportVariable('MY_VAR', 'value');
// 路径
core.addPath('/path/to/bin');
// 调试
core.debug('Debug message');
core.warning('Warning message');
core.error('Error message');
// 组输出
core.startGroup('Group name');
console.log('Inside group');
core.endGroup();
// 掩码
core.setSecret('secret-value');
// 执行命令
await exec.exec('node', ['--version']);
// 文件操作
await io.cp('source', 'dest');
await io.mv('source', 'dest');
await io.rmRF('path');
// 下载工具
const toolPath = await toolCache.downloadTool('https://example.com/tool');
Docker Action #
目录结构 #
text
my-docker-action/
├── action.yml
├── Dockerfile
└── entrypoint.sh
action.yml #
yaml
name: 'My Docker Action'
description: 理解GitHub Actions动作的概念、类型和使用方式。
author: 'Your Name'
inputs:
my-input:
description: 'Input description'
required: true
default: 'default'
outputs:
my-output:
description: 'Output description'
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.my-input }}
env:
MY_ENV: value
branding:
icon: 'box'
color: 'blue'
Dockerfile #
dockerfile
FROM alpine:3.18
RUN apk add --no-cache bash
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh #
bash
#!/bin/bash
set -e
# 获取输入
INPUT="${1}"
echo "Input: $INPUT"
# 设置输出
echo "my-output=value" >> $GITHUB_OUTPUT
# 设置环境变量
echo "MY_VAR=value" >> $GITHUB_ENV
# 执行任务
echo "Hello from Docker Action"
Composite Action #
目录结构 #
text
my-composite-action/
└── action.yml
action.yml #
yaml
name: 'My Composite Action'
description: 理解GitHub Actions动作的概念、类型和使用方式。
inputs:
node-version:
description: 'Node.js version'
required: true
default: '20'
runs:
using: 'composite'
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- name: Install dependencies
shell: bash
run: npm ci
- name: Run tests
shell: bash
run: npm test
使用Composite Action #
yaml
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/my-composite
with:
node-version: '18'
本地Action #
目录结构 #
text
.github/
└── actions/
└── my-action/
└── action.yml
使用本地Action #
yaml
steps:
- uses: ./.github/actions/my-action
with:
param: value
发布到Marketplace #
准备发布 #
- 确保action.yml完整
- 添加README.md
- 添加LICENSE
- 创建Git标签
发布步骤 #
bash
# 创建标签
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
# 在GitHub上发布
# 进入仓库 → Releases → Draft a new release
版本管理 #
bash
# 主版本标签
git tag v1
git tag v1.0
git tag v1.0.0
# 更新主版本标签
git tag -f v1
git push origin v1 --force
Action最佳实践 #
1. 使用具体版本 #
yaml
# 推荐
- uses: actions/checkout@v4
# 最安全
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
# 不推荐
- uses: actions/checkout@main
2. 验证Action来源 #
yaml
# 使用官方Action
- uses: actions/checkout@v4
# 使用知名组织Action
- uses: docker/login-action@v3
# 审查第三方Action
- uses: third-party/action@v1
3. 使用缓存加速 #
yaml
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
4. 处理敏感信息 #
yaml
- uses: my-action@v1
with:
token: ${{ secrets.MY_TOKEN }}
env:
API_KEY: ${{ secrets.API_KEY }}
完整示例 #
创建一个简单的JavaScript Action #
yaml
# action.yml
name: 'Hello World'
description: 理解GitHub Actions动作的概念、类型和使用方式。
inputs:
who-to-greet:
description: 'Who to greet'
required: true
default: 'World'
outputs:
time:
description: 'The time we greeted'
runs:
using: 'node20'
main: 'dist/index.js'
javascript
// index.js
const core = require('@actions/core');
const whoToGreet = core.getInput('who-to-greet');
console.log(`Hello ${whoToGreet}!`);
const time = new Date().toTimeString();
core.setOutput('time', time);
使用自定义Action #
yaml
jobs:
hello:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/hello
id: hello
with:
who-to-greet: 'GitHub Actions'
- run: echo "Time was ${{ steps.hello.outputs.time }}"
下一步学习 #
- Marketplace动作 - 探索更多Action
- 自定义动作 - 创建自己的Action
- 组合动作 - 学习Composite Action
小结 #
- Action是可重用的代码单元
- 支持JavaScript、Docker和Composite三种类型
- 使用具体版本确保稳定性
- 可以创建本地Action或发布到Marketplace
- 使用工具包简化开发
- 遵循最佳实践确保安全性和可维护性
最后更新:2026-03-28