4
4
pull_request :
5
5
types : [opened, reopened, synchronize, edited]
6
6
7
+ # 并发控制,确保相同PR的工作流不会同时运行多个实例
7
8
concurrency :
8
9
group : ${{ github.workflow }}-${{ github.event.number || github.sha }}
9
10
cancel-in-progress : true
10
11
11
12
jobs :
12
- parse-components :
13
- name : Parse Affected Components
13
+ detect-changed-files :
14
+ name : Detect Changed Files
14
15
runs-on : ubuntu-latest
15
16
outputs :
16
- testComponents : ${{ steps.parseTitle.outputs.testComponents }}
17
- testclis : ${{ steps.parsetestCli.outputs.testClis }}
17
+ # 输出三个变量供后续任务使用
18
+ changed_components : ${{ steps.find-changed-components.outputs.changed_components }} # 自动检测到的变更组件
19
+ manual_components : ${{ steps.parse-title.outputs.manual_components }} # 从PR标题手动指定的组件
20
+ testclis : ${{ steps.parse-test-cli.outputs.testClis }} # 测试命令列表
18
21
steps :
19
- - name : Parse Title
20
- id : parseTitle
22
+ # 检出代码,需要完整历史以便比较变更
23
+ - name : Checkout code
24
+ uses : actions/checkout@v3
25
+ with :
26
+ fetch-depth : 0 # 获取完整的git历史,用于检测文件变更
27
+
28
+ # 使用tj-actions/changed-files获取PR中所有变更的文件
29
+ - name : Get changed files
30
+ id : changed-files
31
+ uses : tj-actions/changed-files@v41
32
+ with :
33
+ files_separator : ' ,' # 使用逗号分隔文件列表
34
+
35
+ # 根据变更的文件自动识别受影响的组件
36
+ - name : Find changed components
37
+ id : find-changed-components
38
+ uses : actions/github-script@v6
39
+ with :
40
+ script : |
41
+ const changedFiles = '${{ steps.changed-files.outputs.all_changed_files }}'.split(',');
42
+
43
+ // 定义组件文件路径的匹配规则,用于从文件路径中提取组件名称
44
+ const componentPaths = [
45
+ { pattern: /^packages\/renderless\/src\/(.+?)\//, group: 1 }, // 逻辑层组件
46
+ { pattern: /^packages\/vue\/src\/(.+?)\//, group: 1 }, // Vue组件
47
+ { pattern: /^examples\/sites\/demos\/pc\/app\/(.+?)\//, group: 1 } // 示例组件
48
+ ];
49
+
50
+ // 从文件路径中提取组件名称
51
+ const components = new Set();
52
+ changedFiles.forEach(file => {
53
+ for (const rule of componentPaths) {
54
+ const match = file.match(rule.pattern);
55
+ if (match && match[rule.group]) {
56
+ // 获取组件名,去除可能的子目录
57
+ const componentName = match[rule.group].split('/')[0];
58
+ components.add(componentName);
59
+ }
60
+ }
61
+ });
62
+
63
+ // 构建E2E测试的组件过滤器表达式
64
+ if (components.size > 0) {
65
+ // 构建符合E2E测试命令需要的过滤表达式格式
66
+ const componentFilters = Array.from(components)
67
+ .map(comp => `"\\/app\\/${comp}\\/"`)
68
+ .join(' ');
69
+
70
+ console.log(`检测到变更的组件: ${Array.from(components).join(', ')}`);
71
+ core.setOutput('changed_components', componentFilters);
72
+ } else {
73
+ console.log('没有检测到变更的组件');
74
+ core.setOutput('changed_components', '');
75
+ }
76
+
77
+ # 从PR标题中解析手动指定的组件列表
78
+ - name : Parse Title for Manual Components
79
+ id : parse-title
21
80
uses : actions/github-script@v6
22
81
with :
23
82
script : |
24
83
const prTitle = context.payload.pull_request.title
84
+ // 匹配PR标题中的 [component1, component2] 格式
25
85
const regex = /\[(.*?)\]/
26
86
const matches = prTitle.match(regex)
27
87
if (matches && matches.length > 1 && matches[1]) {
88
+ // 处理和格式化手动指定的组件列表
28
89
let components = matches[1]
29
90
.split(',')
30
91
.map((c) => c.trim())
31
- .filter((c) => /^[a-z\-\/]+$/.test(c))
92
+ .filter((c) => /^[a-z\-\/]+$/.test(c)) // 确保组件名符合规范
32
93
.map((c) => `"\\/app\\/${c}\\/"`)
33
- components = [...new Set(components)].join(' ')
34
- core.setOutput('testComponents ', components)
94
+ components = [...new Set(components)].join(' ') // 去重并转为字符串
95
+ core.setOutput('manual_components ', components)
35
96
} else {
36
- const warningString =`**[e2e-test-warn]**
37
- The component to be tested is missing.
38
-
39
- The title of the Pull request should look like "fix(vue-renderless): [action-menu, alert] fix xxx bug".
40
-
41
- Please make sure you've read our [contributing guide](https://github.com/opentiny/tiny-vue/blob/dev/CONTRIBUTING.md)
42
- `
43
- core.setOutput('tip', warningString)
44
- core.warning(warningString)
97
+ core.setOutput('manual_components', '')
45
98
}
46
- - name : generate user-tip.txt
47
- if : ${{ steps.parseTitle.outputs.tip }}
99
+
100
+ # 当没有检测到任何组件时,生成警告提示
101
+ - name : Generate warning if no components detected
102
+ id : warning
103
+ if : ${{ steps.find-changed-components.outputs.changed_components == '' && steps.parse-title.outputs.manual_components == '' }}
48
104
run : |
49
105
cat << EOF > user-tip.txt
50
- ${{ steps.parseTitle.outputs.tip }}
106
+ **[e2e-test-warn]**
107
+ 没有检测到要测试的组件。
108
+
109
+ 系统会自动检测PR中变更的组件文件,或者您可以在PR标题中使用[component1, component2]格式手动指定要测试的组件。
110
+ 例如: "fix(vue-renderless): [action-menu, alert] fix xxx bug"
111
+
112
+ 请确保您已阅读我们的[贡献指南](https://github.com/opentiny/tiny-vue/blob/dev/CONTRIBUTING.md)
51
113
EOF
52
- - name : Upload User Tip
53
- if : ${{ steps.parseTitle.outputs.tip }}
114
+ echo "warning=true" >> $GITHUB_OUTPUT
115
+
116
+ # 上传警告信息作为工作流制品
117
+ - name : Upload warning
118
+ if : ${{ steps.warning.outputs.warning }}
54
119
uses : actions/upload-artifact@v4
55
120
with :
56
121
name : user-tip
57
122
path : user-tip.txt
58
- retention-days : 1
59
- - name : Save PR number
60
- if : ${{ steps.parseTitle.outputs.tip }}
61
- run : echo ${{ github.event.number }} > ./pr-id.txt
123
+ retention-days : 1 # 保留1天
62
124
63
- - name : Upload PR number
64
- if : ${{ steps.parseTitle.outputs.tip }}
65
- uses : actions/upload-artifact@v4
66
- with :
67
- name : pr
68
- path : ./pr-id.txt
125
+ # 解析测试命令配置
69
126
- name : Parse Test Cli
70
- id : parsetestCli
127
+ id : parse-test-cli
71
128
uses : actions/github-script@v6
72
129
with :
73
130
script : |
131
+ // 从GitHub变量中获取测试命令列表,如果未配置则使用默认命令
74
132
const testClis = '${{ vars.PLAYWRIGHT_CLIS }}' ? '${{ vars.PLAYWRIGHT_CLIS }}'.split(',') : ['pnpm test:e2e3']
75
- core.setOutput('testclis ', JSON.stringify(testClis))
133
+ core.setOutput('testClis ', JSON.stringify(testClis))
76
134
135
+ # PR测试任务,运行实际的E2E测试
77
136
pr-test :
78
- if : ${{ needs.parse-components.outputs.testComponents }}
79
- strategy :
80
- matrix :
81
- testcli : ${{ fromJson(needs.parse-components.outputs.testclis) }}
82
-
83
137
name : PR E2E Test
84
- needs : parse-components
138
+ needs : detect-changed-files # 依赖前一个任务的输出
85
139
runs-on : ubuntu-latest
140
+ # 只有当检测到变更组件或手动指定组件时才运行测试
141
+ if : ${{ needs.detect-changed-files.outputs.changed_components != '' || needs.detect-changed-files.outputs.manual_components != '' }}
142
+ strategy :
143
+ matrix :
144
+ testcli : ${{ fromJson(needs.detect-changed-files.outputs.testclis) }} # 使用矩阵策略运行多个测试命令
86
145
env :
87
- TEST_COMPONENTS : ${{ needs.parse-components.outputs.testComponents }}
146
+ # 合并自动检测和手动指定的组件列表
147
+ TEST_COMPONENTS : ${{ needs.detect-changed-files.outputs.changed_components }} ${{ needs.detect-changed-files.outputs.manual_components }}
88
148
steps :
149
+ # 检出代码
89
150
- uses : actions/checkout@v3
151
+
152
+ # 设置pnpm
90
153
- name : Setup pnpm
91
154
uses : pnpm/action-setup@v2
92
155
156
+ # 设置Node.js环境
93
157
- name : Setup node
94
158
uses : actions/setup-node@v3
95
159
with :
96
160
node-version : 20
161
+
162
+ # 缓存Playwright浏览器安装,加速工作流
97
163
- name : Cache Playwright Installation
98
164
uses : actions/cache@v3
99
165
with :
100
166
path : ~/.cache/ms-playwright
101
167
key : playwright-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
168
+
169
+ # 获取pnpm缓存目录
102
170
- name : Get pnpm store directory
103
171
id : pnpm-cache
104
172
run : |
105
173
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
106
174
175
+ # 设置pnpm缓存
107
176
- uses : actions/cache@v3
108
177
name : Setup pnpm cache
109
178
with :
@@ -112,11 +181,19 @@ jobs:
112
181
restore-keys : |
113
182
${{ runner.os }}-pnpm-store-
114
183
184
+ # 安装依赖
115
185
- name : Install dependencies
116
186
run : pnpm i --no-frozen-lockfile
117
187
188
+ # 安装Playwright浏览器
118
189
- name : Install Playwright browsers
119
190
run : pnpm install:browser --with-deps chromium
120
191
192
+ # 显示要测试的组件列表,便于调试
193
+ - name : Show detected components
194
+ run : |
195
+ echo "Testing components: $TEST_COMPONENTS"
196
+
197
+ # 运行E2E测试
121
198
- name : E2E Test
122
- run : ${{ matrix.testcli }} ${{ env.TEST_COMPONENTS }} --retries=1 --workers=2
199
+ run : ${{ matrix.testcli }} ${{ env.TEST_COMPONENTS }} --retries=1 --workers=2 # 带重试和并行工作进程
0 commit comments