Skip to content

Commit cb433ae

Browse files
theakshaypantchmouel
authored andcommitted
ci(e2e): consolidate Slack notifications for failures
Add notify_slack function to send a single combined message with all failed providers and test names instead of per-provider notifications. Signed-off-by: Akshay Pant <akshay.akshaypant@gmail.com> Co-authored-by: Claude Opus 4.5 (via Claude Code)
1 parent 9a230ff commit cb433ae

File tree

2 files changed

+153
-6
lines changed

2 files changed

+153
-6
lines changed

.github/workflows/e2e.yaml

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,9 @@ jobs:
400400
TEST_BITBUCKET_SERVER_API_URL: ${{ secrets.BITBUCKET_SERVER_API_URL }}
401401
TEST_BITBUCKET_SERVER_WEBHOOK_SECRET: ${{ secrets.BITBUCKET_SERVER_WEBHOOK_SECRET }}
402402
run: |
403-
./hack/gh-workflow-ci.sh run_e2e_tests
403+
mkdir -p /tmp/logs
404+
./hack/gh-workflow-ci.sh run_e2e_tests 2>&1 | tee -a /tmp/logs/e2e-test-output.log
405+
exit ${PIPESTATUS[0]}
404406
405407
- name: Collect logs
406408
if: ${{ always() }}
@@ -422,11 +424,21 @@ jobs:
422424
name: logs-e2e-tests-${{ matrix.provider }}
423425
path: /tmp/logs
424426

425-
- name: Report Status
426-
if: ${{ always() && github.ref_name == 'main' && github.event_name == 'schedule' }}
427-
uses: ravsamhq/notify-slack-action@v2
427+
notify-slack:
428+
name: Notify Slack on Failures
429+
runs-on: ubuntu-latest
430+
needs: e2e-tests
431+
if: ${{ always() && github.ref_name == 'main' && github.event_name == 'schedule' }}
432+
steps:
433+
- uses: actions/checkout@v6
434+
- name: Download all artifacts
435+
uses: actions/download-artifact@v4
428436
with:
429-
status: ${{ job.status }}
430-
notify_when: "failure"
437+
path: artifacts
438+
pattern: logs-e2e-tests-*
439+
440+
- name: Send Slack notification
431441
env:
432442
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
443+
run: |
444+
./hack/gh-workflow-ci.sh notify_slack artifacts

hack/gh-workflow-ci.sh

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,133 @@ detect_panic() {
212212
fi
213213
}
214214

215+
notify_slack() {
216+
# Required env vars: SLACK_WEBHOOK_URL, GITHUB_REPOSITORY, GITHUB_REF_NAME, GITHUB_SERVER_URL, GITHUB_RUN_ID, GITHUB_SHA
217+
# Required argument: artifacts directory path
218+
local artifacts_dir="${1:-artifacts}"
219+
local slack_webhook_url="${SLACK_WEBHOOK_URL}"
220+
221+
if [[ -z "${slack_webhook_url}" ]]; then
222+
echo "SLACK_WEBHOOK_URL is not set, skipping Slack notification"
223+
return 0
224+
fi
225+
226+
if [[ ! -d "${artifacts_dir}" ]]; then
227+
echo "Artifacts directory '${artifacts_dir}' not found"
228+
return 1
229+
fi
230+
231+
echo "Scanning artifacts in: ${artifacts_dir}"
232+
233+
local failure_details=""
234+
local failed_providers=""
235+
236+
# Use find to get provider directories (more reliable than glob)
237+
local provider_dirs
238+
provider_dirs=$(find "${artifacts_dir}" -maxdepth 1 -type d -name 'logs-e2e-tests-*' | sort)
239+
240+
if [[ -z "${provider_dirs}" ]]; then
241+
echo "No provider artifact directories found matching pattern: ${artifacts_dir}/logs-e2e-tests-*"
242+
return 0
243+
fi
244+
245+
echo "Found provider directories:"
246+
echo "${provider_dirs}"
247+
248+
while IFS= read -r provider_dir; do
249+
local provider
250+
provider=$(basename "${provider_dir}" | sed 's/logs-e2e-tests-//')
251+
echo "Processing provider: ${provider} (${provider_dir})"
252+
253+
# Extract failed test names from e2e test output log
254+
local failed_tests=""
255+
if [[ -f "${provider_dir}/e2e-test-output.log" ]]; then
256+
echo " Found e2e-test-output.log"
257+
failed_tests=$(grep -E "^--- FAIL:" "${provider_dir}/e2e-test-output.log" 2>/dev/null | sed 's/--- FAIL: //' | cut -d' ' -f1 | sort -u | paste -sd ',' - || true)
258+
if [[ -n "${failed_tests}" ]]; then
259+
echo " Failed tests: ${failed_tests}"
260+
else
261+
echo " No failed tests found in log"
262+
fi
263+
else
264+
echo " No e2e-test-output.log found"
265+
ls -la "${provider_dir}" 2>/dev/null || true
266+
fi
267+
268+
# Check if this provider had failures
269+
if [[ -n "${failed_tests}" ]]; then
270+
failed_providers="${failed_providers}${provider}, "
271+
# Use literal \n for Slack mrkdwn newlines (will be kept as-is in JSON)
272+
failure_details="${failure_details}• *${provider}*: ${failed_tests}\\n"
273+
fi
274+
done <<< "${provider_dirs}"
275+
276+
# Remove trailing comma and space
277+
failed_providers="${failed_providers%, }"
278+
279+
if [[ -z "${failure_details}" ]]; then
280+
echo "No failures detected, skipping Slack notification"
281+
return 0
282+
fi
283+
284+
# Remove trailing \n
285+
failure_details="${failure_details%\\n}"
286+
287+
local run_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
288+
local commit_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}"
289+
local short_sha="${GITHUB_SHA:0:7}"
290+
291+
# Build Slack message payload using jq to ensure proper JSON escaping
292+
local payload
293+
payload=$(jq -n \
294+
--arg repo "${GITHUB_REPOSITORY:-unknown}" \
295+
--arg branch "${GITHUB_REF_NAME:-unknown}" \
296+
--arg run_url "${run_url}" \
297+
--arg commit_url "${commit_url}" \
298+
--arg short_sha "${short_sha:-unknown}" \
299+
--arg failed_providers "${failed_providers}" \
300+
--arg failure_details "${failure_details}" \
301+
'{
302+
"blocks": [
303+
{
304+
"type": "header",
305+
"text": {
306+
"type": "plain_text",
307+
"text": "🔴 E2E Test Failures",
308+
"emoji": true
309+
}
310+
},
311+
{
312+
"type": "section",
313+
"text": {
314+
"type": "mrkdwn",
315+
"text": ("*Repository:* " + $repo + "\n*Branch:* " + $branch + "\n*Commit:* <" + $commit_url + "|" + $short_sha + ">\n*Workflow:* <" + $run_url + "|View Run>")
316+
}
317+
},
318+
{
319+
"type": "divider"
320+
},
321+
{
322+
"type": "section",
323+
"text": {
324+
"type": "mrkdwn",
325+
"text": ("*Failed Providers:* " + $failed_providers)
326+
}
327+
},
328+
{
329+
"type": "section",
330+
"text": {
331+
"type": "mrkdwn",
332+
"text": ("*Failure Details:*\n" + $failure_details)
333+
}
334+
}
335+
]
336+
}')
337+
338+
echo "Sending Slack notification for failed providers: ${failed_providers}"
339+
curl -s -X POST -H 'Content-type: application/json' --data "${payload}" "${slack_webhook_url}"
340+
}
341+
215342
help() {
216343
cat <<EOF
217344
Usage: $0 <command>
@@ -239,6 +366,11 @@ help() {
239366
output_logs
240367
Will output logs using snazzy formatting when available or otherwise through a simple
241368
python formatter. This makes debugging easier from the GitHub Actions interface.
369+
370+
notify_slack <artifacts_dir>
371+
Send a combined Slack notification for all failed E2E test providers.
372+
Parses test output logs from artifacts to extract failed test names.
373+
Required env vars: SLACK_WEBHOOK_URL, GITHUB_REPOSITORY, GITHUB_REF_NAME, GITHUB_SERVER_URL, GITHUB_RUN_ID
242374
EOF
243375
}
244376

@@ -258,6 +390,9 @@ collect_logs)
258390
output_logs)
259391
output_logs
260392
;;
393+
notify_slack)
394+
notify_slack "${2:-artifacts}"
395+
;;
261396
help)
262397
help
263398
exit 0

0 commit comments

Comments
 (0)