-
Notifications
You must be signed in to change notification settings - Fork 4
fixing Pipeline #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fixing Pipeline #74
Conversation
WalkthroughCI configuration updated to remove two publishing jobs, redirect workflow triggers from master to e2e-modular branch, and enhance E2E Slack notifications with comprehensive Mochawesome result parsing, test metrics computation, and formatted failure reporting. Changes
Sequence Diagram(s)sequenceDiagram
participant E2E as E2E Tests
participant Config as CI Config
participant Mochawesome as Mochawesome JSON
participant Logic as Result Processing Logic
participant File as Failed Tests File
participant Slack as Slack Webhook
E2E->>Mochawesome: Generate test results
Config->>Logic: Trigger E2E Slack step
Logic->>Mochawesome: Validate & parse JSON
Logic->>Logic: Extract totals (passes, failures, pending)
Logic->>Logic: Extract & format timing metrics
alt Test Failures Exist
Logic->>File: Generate failing tests report
Logic->>Slack: Construct failure message<br/>(details + links)
else All Tests Pass
Logic->>Slack: Construct success message<br/>(summary + links)
end
Slack->>Slack: Post notification
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes The changes involve job removals (straightforward) and branch filter updates (simple), but the E2E Slack notification enhancement introduces moderately dense inline shell logic with multiple processing steps—parsing, validation, metric extraction, conditional formatting, and file generation—all contained within a single step, requiring careful review of logic correctness and edge cases. Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Yooo! You forgot to bump the version in package.json! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.circleci/config.yml(2 hunks)
🔇 Additional comments (5)
.circleci/config.yml (5)
170-173: Branch filter change is intentional and appropriate.Redirecting the install-and-publish workflow to trigger on the
e2e-modularbranch instead ofmasteraligns with the PR's goal of fixing the pipeline on a feature branch. This prevents unintended publishes during development.
178-181: Branch filter change is intentional and appropriate.Redirecting the e2e-tests workflow to trigger on the
e2e-modularbranch instead ofmasteraligns with the PR's goal. Tests will run on the feature branch before merging to master.
1-10: Publishing jobs removal aligns with pipeline-fixing goals.The removal of
publish-npm-packageandpublish-github-releasejobs (per AI summary) is appropriate while fixing the pipeline on a feature branch. This prevents accidental publishes and allows focused testing one2e-modularbefore production workflow is restored.
123-124: Consider using a more robust field check to identify failing tests.The jq query relies on the
.failboolean field, which is documented as sometimes present in test objects. A more resilient approach would check.state === "failed"instead, which is a standard field in mochawesome test objects. The current query could silently fail to report tests if the.failfield is inconsistent or missing across mochawesome versions.The suggestion to add debugging output is helpful—it would catch this issue early. Additionally, consider refactoring the query to:
- jq -r '.results[] | .suites[] | select(.failures > 0) | {suite: .title, tests: [.tests[] | select(.fail) | .title]} | select(.tests | length > 0) | + jq -r '.results[] | .suites[] | select(.failures > 0) | {suite: .title, tests: [.tests[] | select(.state == "failed") | .title]} | select(.tests | length > 0) |Manually verify the query with a sample mochawesome report from your environment to confirm the selected field produces the expected output.
118-120: Artifact URL path doesn't match where artifacts are stored; Slack notifications will return 404 errors.The
store_artifactsstep stores from/home/circleci/e2e-sdk-modular/reportswith destinationtest-report, but the Slack message hardcodes an artifact URL referencing/tmp/mochawesome-report/mochawesome.htmlwhich isn't being stored. The artifact path must match the stored location and destination prefix.Update the Slack message URLs (lines 142, 151) to reference the correct artifact path:
-*Report:* <https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/tmp/mochawesome-report/mochawesome.html|View HTML Report> +*Report:* <https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/test-report/mochawesome.html|View HTML Report>Alternatively, verify that the HTML report is actually being generated and stored in
/home/circleci/e2e-sdk-modular/reports/mochawesome.htmlas part of the npm test-all-chains command.Likely an incorrect or invalid review comment.
| name: Parse and send test results to Slack | ||
| when: always | ||
| command: | | ||
| MOCHAWESOME_JSON_FILE=/home/circleci/e2e-sdk-modular/reports/aggregated-report.json | ||
| FAILED_TESTS_FILE=failed-tests.txt | ||
| # same parsing + slack notification script as before... | ||
| publish-npm-package: | ||
| working_directory: ~/etherspot-modular-sdk | ||
| docker: | ||
| - image: cimg/node:20.11.1 | ||
| auth: | ||
| username: $DOCKERHUB_USER | ||
| password: $DOCKERHUB_PASSWORD | ||
| steps: | ||
| - checkout | ||
| - run: | ||
| name: Install Bun | ||
| command: | | ||
| curl -fsSL https://bun.sh/install | bash | ||
| echo 'export BUN_INSTALL="$HOME/.bun"' >> $BASH_ENV | ||
| echo 'export PATH="$BUN_INSTALL/bin:$PATH"' >> $BASH_ENV | ||
| source $BASH_ENV | ||
| - restore_cache: | ||
| key: dependency-cache-{{ checksum "bun.lockb" }} | ||
| - run: | ||
| name: Authenticate with registry | ||
| command: echo "//registry.npmjs.org/:_authToken=$ETHERSPOT_NPM_TOKEN" > ~/etherspot-modular-sdk/.npmrc | ||
| - run: | ||
| name: Install dependencies | ||
| command: bun install | ||
| - run: | ||
| name: Build Etherpot Prime SDK | ||
| command: bun run build | ||
| - run: | ||
| name: Publish package to npm | ||
| command: | | ||
| cd ~/etherspot-modular-sdk | ||
| bun publish --access public | ||
| - run: | ||
| name: Announce Publish | ||
| command: | | ||
| chmod +x .circleci/announcePublish.sh | ||
| .circleci/announcePublish.sh "Etherspot Modular SDK" "$(node -e "console.log(require('./package.json').version)")" | ||
| if [ ! -f "$MOCHAWESOME_JSON_FILE" ]; then | ||
| echo "❌ Aggregated mochawesome report not found at $MOCHAWESOME_JSON_FILE" | ||
| exit 0 | ||
| fi | ||
| TOTAL_SUITES=$(jq '.stats.suites' $MOCHAWESOME_JSON_FILE) | ||
| TOTAL_PASSES=$(jq '.stats.passes' $MOCHAWESOME_JSON_FILE) | ||
| TOTAL_PENDING=$(jq '.stats.pending' $MOCHAWESOME_JSON_FILE) | ||
| TOTAL_FAILURES=$(jq '.stats.failures' $MOCHAWESOME_JSON_FILE) | ||
| START_TIME=$(jq -r '.stats.start' $MOCHAWESOME_JSON_FILE) | ||
| END_TIME=$(jq -r '.stats.end' $MOCHAWESOME_JSON_FILE) | ||
| DURATION_MS=$(jq -r '.stats.duration' $MOCHAWESOME_JSON_FILE) | ||
| publish-github-release: | ||
| docker: | ||
| - image: ardd97/ghr | ||
| steps: | ||
| - checkout | ||
| - run: | ||
| name: "Publish Release on GitHub" | ||
| command: | | ||
| PACKAGE_VERSION="$(jq .version package.json -r)" | ||
| echo $PACKAGE_VERSION | ||
| ghr -t "${GITHUB_TOKEN}" -u "${CIRCLE_PROJECT_USERNAME}" -r "${CIRCLE_PROJECT_REPONAME}" -c "${CIRCLE_SHA1}" "$PACKAGE_VERSION" | ||
| START_TIME_FORMATTED=$(date -d "$START_TIME" "+%Y-%m-%d %H:%M:%S") | ||
| END_TIME_FORMATTED=$(date -d "$END_TIME" "+%Y-%m-%d %H:%M:%S") | ||
| DURATION_MIN=$(awk "BEGIN {printf \"%.2f\",${DURATION_MS}/60000}") | ||
| jq -r '.results[] | .suites[] | select(.failures > 0) | {suite: .title, tests: [.tests[] | select(.fail) | .title]} | select(.tests | length > 0) | | ||
| "*Suite:* \(.suite)\n*Failing Tests:* \n\(.tests | map("- " + .) | join("\n"))\n"' $MOCHAWESOME_JSON_FILE > $FAILED_TESTS_FILE | ||
| if [ -s $FAILED_TESTS_FILE ]; then | ||
| MESSAGE=$(cat $FAILED_TESTS_FILE) | ||
| SLACK_MESSAGE=":x: *E2E Tests Failed :x: *\n\ | ||
| *Project:* ${CIRCLE_PROJECT_REPONAME}\n\ | ||
| *Triggered by:* ${CIRCLE_USERNAME}\n\ | ||
| *Branch:* ${CIRCLE_BRANCH}\n\ | ||
| *Commit:* <https://github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}|${CIRCLE_SHA1}>\n\n\ | ||
| *Test Summary:*\n\ | ||
| *Total Suites:* ${TOTAL_SUITES}\n\ | ||
| *Passes:* ${TOTAL_PASSES}\n\ | ||
| *Pending:* ${TOTAL_PENDING}\n\ | ||
| *Failures:* ${TOTAL_FAILURES}\n\ | ||
| *Start Time:* ${START_TIME_FORMATTED}\n\ | ||
| *End Time:* ${END_TIME_FORMATTED}\n\ | ||
| *Duration:* ${DURATION_MIN} minutes\n\n\ | ||
| *Failed Tests:*\n${MESSAGE}\n\ | ||
| *Report:* <https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/tmp/mochawesome-report/mochawesome.html|View HTML Report>\n\ | ||
| *Job:* <https://circleci.com/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/${CIRCLE_BUILD_NUM}|View Job>" | ||
| else | ||
| SLACK_MESSAGE=":white_check_mark: All E2E tests passed\n\ | ||
| *Project:* ${CIRCLE_PROJECT_REPONAME}\n\ | ||
| *Triggered by:* ${CIRCLE_USERNAME}\n\ | ||
| *Branch:* ${CIRCLE_BRANCH}\n\ | ||
| *Commit:* <https://github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}|${CIRCLE_SHA1}>\n\ | ||
| *Job:* <https://circleci.com/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/${CIRCLE_BUILD_NUM}|View Job>\n\ | ||
| *Report:* <https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/tmp/mochawesome-report/mochawesome.html|View HTML Report>\n\ | ||
| \n*Test Summary:*\n\ | ||
| *Total Suites:* ${TOTAL_SUITES}\n\ | ||
| *Passes:* ${TOTAL_PASSES}\n\ | ||
| *Pending:* ${TOTAL_PENDING}\n\ | ||
| *Failures:* ${TOTAL_FAILURES}\n\ | ||
| *Start Time:* ${START_TIME_FORMATTED}\n\ | ||
| *End Time:* ${END_TIME_FORMATTED}\n\ | ||
| *Duration:* ${DURATION_MIN} minutes" | ||
| fi | ||
| curl -X POST -H 'Content-type: application/json' --data '{"text":"'"$SLACK_MESSAGE"'"}' $E2E_SLACK_WEBHOOK_URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add defensive error handling to fail fast on script errors.
The script lacks error handling. If jq commands fail or environment variables are missing, execution continues and may produce incomplete or misleading Slack messages. Add set -e at the start of the command block to fail on errors.
command: |
+ set -e
+ set -u # Fail on undefined variables
MOCHAWESOME_JSON_FILE=/home/circleci/e2e-sdk-modular/reports/aggregated-report.json
FAILED_TESTS_FILE=failed-tests.txt
if [ ! -f "$MOCHAWESOME_JSON_FILE" ]; then
echo "❌ Aggregated mochawesome report not found at $MOCHAWESOME_JSON_FILE"
exit 0
fi
+
+ # Validate jq command availability
+ if ! command -v jq &> /dev/null; then
+ echo "❌ jq is not installed"
+ exit 1
+ fiThis ensures the step fails visibly if dependencies are missing or commands fail unexpectedly.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| name: Parse and send test results to Slack | |
| when: always | |
| command: | | |
| MOCHAWESOME_JSON_FILE=/home/circleci/e2e-sdk-modular/reports/aggregated-report.json | |
| FAILED_TESTS_FILE=failed-tests.txt | |
| # same parsing + slack notification script as before... | |
| publish-npm-package: | |
| working_directory: ~/etherspot-modular-sdk | |
| docker: | |
| - image: cimg/node:20.11.1 | |
| auth: | |
| username: $DOCKERHUB_USER | |
| password: $DOCKERHUB_PASSWORD | |
| steps: | |
| - checkout | |
| - run: | |
| name: Install Bun | |
| command: | | |
| curl -fsSL https://bun.sh/install | bash | |
| echo 'export BUN_INSTALL="$HOME/.bun"' >> $BASH_ENV | |
| echo 'export PATH="$BUN_INSTALL/bin:$PATH"' >> $BASH_ENV | |
| source $BASH_ENV | |
| - restore_cache: | |
| key: dependency-cache-{{ checksum "bun.lockb" }} | |
| - run: | |
| name: Authenticate with registry | |
| command: echo "//registry.npmjs.org/:_authToken=$ETHERSPOT_NPM_TOKEN" > ~/etherspot-modular-sdk/.npmrc | |
| - run: | |
| name: Install dependencies | |
| command: bun install | |
| - run: | |
| name: Build Etherpot Prime SDK | |
| command: bun run build | |
| - run: | |
| name: Publish package to npm | |
| command: | | |
| cd ~/etherspot-modular-sdk | |
| bun publish --access public | |
| - run: | |
| name: Announce Publish | |
| command: | | |
| chmod +x .circleci/announcePublish.sh | |
| .circleci/announcePublish.sh "Etherspot Modular SDK" "$(node -e "console.log(require('./package.json').version)")" | |
| if [ ! -f "$MOCHAWESOME_JSON_FILE" ]; then | |
| echo "❌ Aggregated mochawesome report not found at $MOCHAWESOME_JSON_FILE" | |
| exit 0 | |
| fi | |
| TOTAL_SUITES=$(jq '.stats.suites' $MOCHAWESOME_JSON_FILE) | |
| TOTAL_PASSES=$(jq '.stats.passes' $MOCHAWESOME_JSON_FILE) | |
| TOTAL_PENDING=$(jq '.stats.pending' $MOCHAWESOME_JSON_FILE) | |
| TOTAL_FAILURES=$(jq '.stats.failures' $MOCHAWESOME_JSON_FILE) | |
| START_TIME=$(jq -r '.stats.start' $MOCHAWESOME_JSON_FILE) | |
| END_TIME=$(jq -r '.stats.end' $MOCHAWESOME_JSON_FILE) | |
| DURATION_MS=$(jq -r '.stats.duration' $MOCHAWESOME_JSON_FILE) | |
| publish-github-release: | |
| docker: | |
| - image: ardd97/ghr | |
| steps: | |
| - checkout | |
| - run: | |
| name: "Publish Release on GitHub" | |
| command: | | |
| PACKAGE_VERSION="$(jq .version package.json -r)" | |
| echo $PACKAGE_VERSION | |
| ghr -t "${GITHUB_TOKEN}" -u "${CIRCLE_PROJECT_USERNAME}" -r "${CIRCLE_PROJECT_REPONAME}" -c "${CIRCLE_SHA1}" "$PACKAGE_VERSION" | |
| START_TIME_FORMATTED=$(date -d "$START_TIME" "+%Y-%m-%d %H:%M:%S") | |
| END_TIME_FORMATTED=$(date -d "$END_TIME" "+%Y-%m-%d %H:%M:%S") | |
| DURATION_MIN=$(awk "BEGIN {printf \"%.2f\",${DURATION_MS}/60000}") | |
| jq -r '.results[] | .suites[] | select(.failures > 0) | {suite: .title, tests: [.tests[] | select(.fail) | .title]} | select(.tests | length > 0) | | |
| "*Suite:* \(.suite)\n*Failing Tests:* \n\(.tests | map("- " + .) | join("\n"))\n"' $MOCHAWESOME_JSON_FILE > $FAILED_TESTS_FILE | |
| if [ -s $FAILED_TESTS_FILE ]; then | |
| MESSAGE=$(cat $FAILED_TESTS_FILE) | |
| SLACK_MESSAGE=":x: *E2E Tests Failed :x: *\n\ | |
| *Project:* ${CIRCLE_PROJECT_REPONAME}\n\ | |
| *Triggered by:* ${CIRCLE_USERNAME}\n\ | |
| *Branch:* ${CIRCLE_BRANCH}\n\ | |
| *Commit:* <https://github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}|${CIRCLE_SHA1}>\n\n\ | |
| *Test Summary:*\n\ | |
| *Total Suites:* ${TOTAL_SUITES}\n\ | |
| *Passes:* ${TOTAL_PASSES}\n\ | |
| *Pending:* ${TOTAL_PENDING}\n\ | |
| *Failures:* ${TOTAL_FAILURES}\n\ | |
| *Start Time:* ${START_TIME_FORMATTED}\n\ | |
| *End Time:* ${END_TIME_FORMATTED}\n\ | |
| *Duration:* ${DURATION_MIN} minutes\n\n\ | |
| *Failed Tests:*\n${MESSAGE}\n\ | |
| *Report:* <https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/tmp/mochawesome-report/mochawesome.html|View HTML Report>\n\ | |
| *Job:* <https://circleci.com/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/${CIRCLE_BUILD_NUM}|View Job>" | |
| else | |
| SLACK_MESSAGE=":white_check_mark: All E2E tests passed\n\ | |
| *Project:* ${CIRCLE_PROJECT_REPONAME}\n\ | |
| *Triggered by:* ${CIRCLE_USERNAME}\n\ | |
| *Branch:* ${CIRCLE_BRANCH}\n\ | |
| *Commit:* <https://github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}|${CIRCLE_SHA1}>\n\ | |
| *Job:* <https://circleci.com/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/${CIRCLE_BUILD_NUM}|View Job>\n\ | |
| *Report:* <https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/tmp/mochawesome-report/mochawesome.html|View HTML Report>\n\ | |
| \n*Test Summary:*\n\ | |
| *Total Suites:* ${TOTAL_SUITES}\n\ | |
| *Passes:* ${TOTAL_PASSES}\n\ | |
| *Pending:* ${TOTAL_PENDING}\n\ | |
| *Failures:* ${TOTAL_FAILURES}\n\ | |
| *Start Time:* ${START_TIME_FORMATTED}\n\ | |
| *End Time:* ${END_TIME_FORMATTED}\n\ | |
| *Duration:* ${DURATION_MIN} minutes" | |
| fi | |
| curl -X POST -H 'Content-type: application/json' --data '{"text":"'"$SLACK_MESSAGE"'"}' $E2E_SLACK_WEBHOOK_URL | |
| name: Parse and send test results to Slack | |
| when: always | |
| command: | | |
| set -e | |
| set -u # Fail on undefined variables | |
| MOCHAWESOME_JSON_FILE=/home/circleci/e2e-sdk-modular/reports/aggregated-report.json | |
| FAILED_TESTS_FILE=failed-tests.txt | |
| if [ ! -f "$MOCHAWESOME_JSON_FILE" ]; then | |
| echo "❌ Aggregated mochawesome report not found at $MOCHAWESOME_JSON_FILE" | |
| exit 0 | |
| fi | |
| # Validate jq command availability | |
| if ! command -v jq &> /dev/null; then | |
| echo "❌ jq is not installed" | |
| exit 1 | |
| fi | |
| TOTAL_SUITES=$(jq '.stats.suites' $MOCHAWESOME_JSON_FILE) | |
| TOTAL_PASSES=$(jq '.stats.passes' $MOCHAWESOME_JSON_FILE) | |
| TOTAL_PENDING=$(jq '.stats.pending' $MOCHAWESOME_JSON_FILE) | |
| TOTAL_FAILURES=$(jq '.stats.failures' $MOCHAWESOME_JSON_FILE) | |
| START_TIME=$(jq -r '.stats.start' $MOCHAWESOME_JSON_FILE) | |
| END_TIME=$(jq -r '.stats.end' $MOCHAWESOME_JSON_FILE) | |
| DURATION_MS=$(jq -r '.stats.duration' $MOCHAWESOME_JSON_FILE) | |
| START_TIME_FORMATTED=$(date -d "$START_TIME" "+%Y-%m-%d %H:%M:%S") | |
| END_TIME_FORMATTED=$(date -d "$END_TIME" "+%Y-%m-%d %H:%M:%S") | |
| DURATION_MIN=$(awk "BEGIN {printf \"%.2f\",${DURATION_MS}/60000}") | |
| jq -r '.results[] | .suites[] | select(.failures > 0) | {suite: .title, tests: [.tests[] | select(.fail) | .title]} | select(.tests | length > 0) | | |
| "*Suite:* \(.suite)\n*Failing Tests:* \n\(.tests | map("- " + .) | join("\n"))\n"' $MOCHAWESOME_JSON_FILE > $FAILED_TESTS_FILE | |
| if [ -s $FAILED_TESTS_FILE ]; then | |
| MESSAGE=$(cat $FAILED_TESTS_FILE) | |
| SLACK_MESSAGE=":x: *E2E Tests Failed :x: *\n\ | |
| *Project:* ${CIRCLE_PROJECT_REPONAME}\n\ | |
| *Triggered by:* ${CIRCLE_USERNAME}\n\ | |
| *Branch:* ${CIRCLE_BRANCH}\n\ | |
| *Commit:* <https://github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}|${CIRCLE_SHA1}>\n\n\ | |
| *Test Summary:*\n\ | |
| *Total Suites:* ${TOTAL_SUITES}\n\ | |
| *Passes:* ${TOTAL_PASSES}\n\ | |
| *Pending:* ${TOTAL_PENDING}\n\ | |
| *Failures:* ${TOTAL_FAILURES}\n\ | |
| *Start Time:* ${START_TIME_FORMATTED}\n\ | |
| *End Time:* ${END_TIME_FORMATTED}\n\ | |
| *Duration:* ${DURATION_MIN} minutes\n\n\ | |
| *Failed Tests:*\n${MESSAGE}\n\ | |
| *Report:* <https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/tmp/mochawesome-report/mochawesome.html|View HTML Report>\n\ | |
| *Job:* <https://circleci.com/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/${CIRCLE_BUILD_NUM}|View Job>" | |
| else | |
| SLACK_MESSAGE=":white_check_mark: All E2E tests passed\n\ | |
| *Project:* ${CIRCLE_PROJECT_REPONAME}\n\ | |
| *Triggered by:* ${CIRCLE_USERNAME}\n\ | |
| *Branch:* ${CIRCLE_BRANCH}\n\ | |
| *Commit:* <https://github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/commit/${CIRCLE_SHA1}|${CIRCLE_SHA1}>\n\ | |
| *Job:* <https://circleci.com/gh/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/${CIRCLE_BUILD_NUM}|View Job>\n\ | |
| *Report:* <https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/tmp/mochawesome-report/mochawesome.html|View HTML Report>\n\ | |
| \n*Test Summary:*\n\ | |
| *Total Suites:* ${TOTAL_SUITES}\n\ | |
| *Passes:* ${TOTAL_PASSES}\n\ | |
| *Pending:* ${TOTAL_PENDING}\n\ | |
| *Failures:* ${TOTAL_FAILURES}\n\ | |
| *Start Time:* ${START_TIME_FORMATTED}\n\ | |
| *End Time:* ${END_TIME_FORMATTED}\n\ | |
| *Duration:* ${DURATION_MIN} minutes" | |
| fi | |
| curl -X POST -H 'Content-type: application/json' --data '{"text":"'"$SLACK_MESSAGE"'"}' $E2E_SLACK_WEBHOOK_URL |
🤖 Prompt for AI Agents
In .circleci/config.yml around lines 100 to 162 the shell command block that
parses the mochawesome report lacks defensive error handling; add a fail-fast
shell setting by enabling "set -e" (and optionally "set -o pipefail" and "set
-u") at the start of the command block so the step exits immediately on any
command failure or unset variable, preventing continuation with incomplete data
and ensuring the job fails visibly when jq or env variables are missing.
| *End Time:* ${END_TIME_FORMATTED}\n\ | ||
| *Duration:* ${DURATION_MIN} minutes\n\n\ | ||
| *Failed Tests:*\n${MESSAGE}\n\ | ||
| *Report:* <https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/tmp/mochawesome-report/mochawesome.html|View HTML Report>\n\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify artifact path construction matches CircleCI's artifact URL structure.
The Slack message links to /tmp/mochawesome-report/mochawesome.html within the CircleCI artifact URL, but the artifacts are stored from /home/circleci/e2e-sdk-modular/reports (line 97). Verify that the artifact path in the Slack links aligns with where the actual HTML report file is located.
Confirm the correct artifact path by checking:
- Where the mochawesome HTML report is generated in the e2e test repository
- Whether the artifact destination path (line 98:
destination: test-report) affects the URL structure - The actual CircleCI artifact URL that should be used
Also applies to: 151-151
I'll verify the artifact path construction by examining the CircleCI configuration and understanding how CircleCI constructs artifact URLs.
---
🏁 Script executed:
```shell
#!/bin/bash
# Read the CircleCI config to examine artifact configuration and Slack messages
cat .circleci/config.yml
Length of output: 7974
🌐 Web query:
CircleCI artifact URL structure path construction
💡 Result:
Short answer — don’t guess the host; call the artifacts API and use the returned URL. Key facts and how the URL is formed:
-
List artifacts via the API (v1.1 or v2) and use the returned "url" field — e.g. GET /project/:vcs/:org/:repo/:build_num/artifacts (v1.1) or /project/{project-slug}/{job_number}/artifacts (v2). The API response contains the full download URLs. [1][4]
-
Artifact file URLs you’ll see are hosted on CircleCI’s artifact hosts and include a host-prefix + node index + the artifact path, e.g.:
- https://--gh.circle-artifacts.com/0/<path/to/file>
- or the older output host form: https://output.circle-artifacts.com/output/job//artifacts/0/<path/to/file>
Use the exact "url" returned by the API rather than constructing hosts by hand. [1][2]
-
Path rules:
- The artifact "path" in the API is relative to the project working directory (or to the optional store_artifacts.destination prefix). Use destination to add a prefix. [3]
- Filenames are Java URLEncoder-encoded in the stored URL (spaces, special chars encoded). [3]
- If you included .. in your store path, CircleCI strips .. when constructing the artifact URL. [2]
Recommended workflow:
- Call the artifacts API for the job/build to get the artifact objects.
- Use the returned "url" fields (they already include authentication/host). If you need programmatic downloads, pass your Circle-Token in the request headers. [1][4]
Sources: CircleCI API & artifacts docs and support notes. [1][2][3][4]
Fix incorrect artifact path in Slack message URLs.
The Slack message hardcodes /tmp/mochawesome-report/mochawesome.html, but CircleCI artifact URLs must include the destination prefix. Since store_artifacts (line 98) sets destination: test-report, the artifact URL should be test-report/<filename> in the CircleCI artifact URL structure. The current path /tmp/mochawesome-report/mochawesome.html will result in broken links.
Update lines 142 and 151 to use the correct path that aligns with the destination: test-report setting (e.g., test-report/aggregated-report.json or the appropriate filename from the reports directory).
🤖 Prompt for AI Agents
In .circleci/config.yml around lines 142 and 151, the Slack message links point
to /tmp/mochawesome-report/... which is incorrect because store_artifacts uses
destination: test-report; update both links to use the artifact destination
prefix (e.g., test-report/mochawesome.html and
test-report/aggregated-report.json or the actual filenames generated) so the
CircleCI artifact URLs resolve correctly; change the hardcoded /tmp/... paths to
test-report/<filename> in the Slack message templates.
fixes pipeline and slack alerts
Summary by CodeRabbit
Chores
Tests