# 在 GitHub Actions 中创建并测试同仓库内的复合动作

## 摘要
本文介绍如何在同一仓库内创建复合动作(Composite Action),并通过相对路径在 workflow 的 `uses` 字段中引用该动作,完成封装与测试。

## 什么是复合动作
复合动作允许你将一系列工作流作业步骤收集到一个单一动作中,从而可以在多个工作流中作为单个作业步骤运行。相比可复用工作流,复合动作更适合将特定任务逻辑打包成可复用的单元。

## 创建同仓库复合动作的步骤
1. **准备脚本文件**
在仓库内创建子文件夹(推荐 `.github/actions`),并在其中放置执行脚本,例如 `goodbye.sh`。确保脚本具有执行权限:
```bash
chmod +x goodbye.sh
git add --chmod=+x -- goodbye.sh
git commit -m "Add goodbye script"
git push
```

2. **编写动作元数据文件**
在相同文件夹中创建 `action.yml`,定义输入、输出及运行步骤。示例如下:
```yaml
name: 'Hello World'
description: 'Greet someone'
inputs:
who-to-greet:
description: 'Who to greet'
required: true
default: 'World'
outputs:
random-number:
description: "Random number"
value: ${{ steps.random-number-generator.outputs.random-number }}
runs:
using: "composite"
steps:
- name: Set Greeting
run: echo "Hello $INPUT_WHO_TO_GREET."
shell: bash
env:
INPUT_WHO_TO_GREET: ${{ inputs.who-to-greet }}
- name: Random Number Generator
id: random-number-generator
run: echo "random-number=$(echo $RANDOM)" >> $GITHUB_OUTPUT
shell: bash
- name: Set GitHub Path
run: echo "$GITHUB_ACTION_PATH" >> $GITHUB_PATH
shell: bash
env:
GITHUB_ACTION_PATH: ${{ github.action_path }}
- name: Run goodbye.sh
run: goodbye.sh
shell: bash
```
提交并推送该文件:
```bash
git add action.yml
git commit -m "Add action"
git push
```

3. **添加版本标签(可选)**
为动作添加 Git 标签以便引用特定版本:
```bash
git tag -a -m "Description of this release" v1
git push --follow-tags
```

## 在工作流中引用同仓库复合动作
在 `.github/workflows/main.yml` 中使用相对路径引用同仓库内的复合动作。假设动作位于 `.github/actions/hello-world-composite-action`,写法如下:
```yaml
on: [push]
jobs:
hello_world_job:
runs-on: ubuntu-latest
name: A job to say hello
steps:
- uses: actions/checkout@v6
- id: foo
uses: ./.github/actions/hello-world-composite-action
with:
who-to-greet: 'Mona the Octocat'
- run: echo random-number "${{ steps.foo.outputs.random-number }}"
```
注意 `uses` 字段前缀为 `./`,表示引用当前仓库内的动作路径。

## 测试与验证
1. 触发工作流(如推送代码)
2. 在 GitHub Actions 页面查看运行结果
3. 预期输出包括:问候语、随机数及 goodbye.sh 脚本执行内容
4. 若出现错误,检查 `action.yml` 语法、脚本权限及路径是否正确

## 安全提示
始终警惕未信任输入,避免将用户数据直接用于命令构造。参考 GitHub 安全使用指南处理潜在攻击风险。

信息来源