playwright-slack-report-burak 3.0.11 → 3.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/SlackReporter.js +117 -27
- package/package.json +1 -1
|
@@ -114,41 +114,120 @@ class SlackReporter {
|
|
|
114
114
|
this.log(`🔍 [GitHub Actions Detection] No jobs found in workflow run`);
|
|
115
115
|
return null;
|
|
116
116
|
}
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
|
|
118
|
+
this.log(`🔍 [GitHub Actions Detection] Found ${jobs.length} total jobs in workflow run`);
|
|
119
|
+
|
|
120
|
+
// Helper function to normalize job names by removing shard indicators
|
|
121
|
+
// e.g., "Run tests (shard 3/4)" -> "Run tests"
|
|
122
|
+
const normalizeJobName = (name) => {
|
|
123
|
+
if (!name) return '';
|
|
124
|
+
// Remove common matrix patterns: (shard X/Y), (X, Y), [X], etc.
|
|
125
|
+
return name
|
|
126
|
+
.replace(/\s*\(shard\s+\d+\/\d+\)/gi, '')
|
|
127
|
+
.replace(/\s*\(\d+\/\d+\)/g, '')
|
|
128
|
+
.replace(/\s*\(\d+,\s*\d+\)/g, '')
|
|
129
|
+
.replace(/\s*\[\d+\]/g, '')
|
|
130
|
+
.trim();
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Group jobs by normalized name to find matrix jobs
|
|
119
134
|
const jobGroups = {};
|
|
120
135
|
for (const job of jobs) {
|
|
121
136
|
const jobName = job.name || '';
|
|
122
|
-
|
|
123
|
-
|
|
137
|
+
const normalizedName = normalizeJobName(jobName);
|
|
138
|
+
if (!jobGroups[normalizedName]) {
|
|
139
|
+
jobGroups[normalizedName] = [];
|
|
124
140
|
}
|
|
125
|
-
jobGroups[
|
|
141
|
+
jobGroups[normalizedName].push(job);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
this.log(`🔍 [GitHub Actions Detection] Grouped into ${Object.keys(jobGroups).length} job group(s)`);
|
|
145
|
+
for (const [groupName, groupJobs] of Object.entries(jobGroups)) {
|
|
146
|
+
this.log(`🔍 Group "${groupName}": ${groupJobs.length} job(s)`);
|
|
126
147
|
}
|
|
148
|
+
|
|
127
149
|
// Find the job group that contains the current job
|
|
128
150
|
let currentJob = null;
|
|
129
151
|
let jobGroup = null;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
152
|
+
|
|
153
|
+
// Strategy 1: Find the currently running job (status: in_progress or completed recently)
|
|
154
|
+
const runningJobs = jobs.filter(j => j.status === 'in_progress' || j.status === 'queued');
|
|
155
|
+
this.log(`🔍 [GitHub Actions Detection] Found ${runningJobs.length} running/queued job(s)`);
|
|
156
|
+
|
|
157
|
+
if (runningJobs.length === 1) {
|
|
158
|
+
// Perfect - only one job is running, must be us
|
|
159
|
+
currentJob = runningJobs[0];
|
|
160
|
+
const normalizedName = normalizeJobName(currentJob.name);
|
|
161
|
+
jobGroup = jobGroups[normalizedName];
|
|
162
|
+
this.log(`🔍 [GitHub Actions Detection] Matched by running status: "${currentJob.name}"`);
|
|
163
|
+
} else if (runningJobs.length > 1) {
|
|
164
|
+
// Multiple running jobs - try to match by job ID or name
|
|
165
|
+
for (const job of runningJobs) {
|
|
166
|
+
// Check if this job's name contains the GITHUB_JOB id
|
|
167
|
+
// But be more specific - avoid matching "Generate test matrix" when looking for "test"
|
|
168
|
+
const jobIdLower = currentJobId.toLowerCase();
|
|
169
|
+
const jobNameLower = (job.name || '').toLowerCase();
|
|
170
|
+
|
|
171
|
+
// Match if job name starts with or equals the job ID (more specific)
|
|
172
|
+
if (jobNameLower.startsWith(jobIdLower) ||
|
|
173
|
+
jobNameLower.includes(`${jobIdLower} `) ||
|
|
174
|
+
jobNameLower.includes(`${jobIdLower}(`) ||
|
|
175
|
+
jobNameLower === jobIdLower) {
|
|
176
|
+
currentJob = job;
|
|
177
|
+
const normalizedName = normalizeJobName(job.name);
|
|
178
|
+
jobGroup = jobGroups[normalizedName];
|
|
179
|
+
this.log(`🔍 [GitHub Actions Detection] Matched running job by ID match: "${job.name}"`);
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Still no match? Take the first running job that looks like a test job
|
|
185
|
+
if (!currentJob) {
|
|
186
|
+
for (const job of runningJobs) {
|
|
187
|
+
if (job.name && (job.name.includes('shard') || job.name.includes('test') || job.name.includes('matrix'))) {
|
|
188
|
+
currentJob = job;
|
|
189
|
+
const normalizedName = normalizeJobName(job.name);
|
|
190
|
+
jobGroup = jobGroups[normalizedName];
|
|
191
|
+
this.log(`🔍 [GitHub Actions Detection] Matched by test-like name: "${job.name}"`);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
135
195
|
}
|
|
136
196
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
197
|
+
|
|
198
|
+
// Strategy 2: If no running job found, look at all jobs
|
|
199
|
+
if (!currentJob) {
|
|
200
|
+
this.log(`🔍 [GitHub Actions Detection] No running job matched, checking all jobs`);
|
|
201
|
+
for (const job of jobs) {
|
|
202
|
+
const jobIdLower = currentJobId.toLowerCase();
|
|
203
|
+
const jobNameLower = (job.name || '').toLowerCase();
|
|
204
|
+
|
|
205
|
+
if (jobNameLower.startsWith(jobIdLower) ||
|
|
206
|
+
jobNameLower.includes(`${jobIdLower} `) ||
|
|
207
|
+
jobNameLower.includes(`${jobIdLower}(`)) {
|
|
208
|
+
currentJob = job;
|
|
209
|
+
const normalizedName = normalizeJobName(job.name);
|
|
210
|
+
jobGroup = jobGroups[normalizedName];
|
|
211
|
+
this.log(`🔍 [GitHub Actions Detection] Matched job by name: "${job.name}"`);
|
|
144
212
|
break;
|
|
145
213
|
}
|
|
146
214
|
}
|
|
147
215
|
}
|
|
148
|
-
|
|
216
|
+
|
|
217
|
+
// Fallback: Use the largest job group (likely the matrix jobs)
|
|
149
218
|
if (!jobGroup || jobGroup.length === 0) {
|
|
150
|
-
|
|
151
|
-
|
|
219
|
+
this.log(`🔍 [GitHub Actions Detection] Could not match job, using largest job group`);
|
|
220
|
+
let largestGroup = [];
|
|
221
|
+
let largestGroupName = '';
|
|
222
|
+
for (const [groupName, groupJobs] of Object.entries(jobGroups)) {
|
|
223
|
+
if (groupJobs.length > largestGroup.length) {
|
|
224
|
+
largestGroup = groupJobs;
|
|
225
|
+
largestGroupName = groupName;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
jobGroup = largestGroup;
|
|
229
|
+
currentJob = jobGroup[0];
|
|
230
|
+
this.log(`🔍 [GitHub Actions Detection] Using largest group "${largestGroupName}" with ${jobGroup.length} job(s)`);
|
|
152
231
|
}
|
|
153
232
|
// Sort jobs by name or ID to get consistent ordering
|
|
154
233
|
jobGroup.sort((a, b) => {
|
|
@@ -157,13 +236,23 @@ class SlackReporter {
|
|
|
157
236
|
}
|
|
158
237
|
return a.id - b.id;
|
|
159
238
|
});
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
239
|
+
|
|
240
|
+
// Find index of current job in the sorted group
|
|
241
|
+
const currentJobIndex = jobGroup.findIndex(j => j.id === currentJob?.id || j.name === currentJob?.name);
|
|
242
|
+
|
|
243
|
+
// Try to extract shard number from job name (e.g., "shard 3/4" -> index 2)
|
|
244
|
+
let shardIndex = currentJobIndex >= 0 ? currentJobIndex : 0;
|
|
245
|
+
if (currentJob && currentJob.name) {
|
|
246
|
+
const shardMatch = currentJob.name.match(/shard\s+(\d+)\/(\d+)/i);
|
|
247
|
+
if (shardMatch) {
|
|
248
|
+
const shardNum = parseInt(shardMatch[1], 10);
|
|
249
|
+
const totalFromName = parseInt(shardMatch[2], 10);
|
|
250
|
+
// Convert to 0-based index (shard 3/4 -> index 2)
|
|
251
|
+
shardIndex = shardNum - 1;
|
|
252
|
+
this.log(`🔍 [GitHub Actions Detection] Extracted shard info from name: ${shardNum}/${totalFromName} -> index ${shardIndex}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
167
256
|
const totalShards = jobGroup.length;
|
|
168
257
|
this.log(`🔍 [GitHub Actions Detection] Detected via API:`);
|
|
169
258
|
this.log(`🔍 Total jobs in group: ${totalShards}`);
|
|
@@ -491,3 +580,4 @@ class SlackReporter {
|
|
|
491
580
|
}
|
|
492
581
|
}
|
|
493
582
|
exports.default = SlackReporter;
|
|
583
|
+
|
package/package.json
CHANGED