Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -410,18 +410,7 @@ jobs:
command: |
[ "${CIRCLE_NODE_TOTAL:-1}" -gt 1 ] && [ "${CIRCLE_NODE_INDEX:-0}" -ne 0 ] && exit 0
[ "${VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP:-0}" = "1" ] && exit 0
[ -z "${CIRCLE_PULL_REQUEST}" ] && exit 0
[ -z "${GITHUB_TOKEN}" ] && exit 0
COVERAGE_CONTENT=$(sed '/./,$!d' /tmp/artifacts/coverage/phpunit/coverage.txt)
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments" \
-d "$(jq -n --arg body "\`\`\`
${COVERAGE_CONTENT}
\`\`\`" '{body: $body}')"
.circleci/post-coverage-comment.sh /tmp/artifacts/coverage/phpunit/coverage.txt

- run:
name: Upload code coverage reports to Codecov
Expand Down
69 changes: 69 additions & 0 deletions .circleci/post-coverage-comment.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
##
## Post code coverage summary as a PR comment on GitHub.
##
## Minimizes previous coverage comments before posting a new one.
##
## Environment variables:
## CIRCLE_PULL_REQUEST - CircleCI PR URL.
## GITHUB_TOKEN - GitHub token for API access.
## CIRCLE_PROJECT_USERNAME - GitHub org/user.
## CIRCLE_PROJECT_REPONAME - GitHub repo name.
##
## Usage:
## .circleci/post-coverage-comment.sh /path/to/coverage.txt

set -euo pipefail

COVERAGE_FILE="${1:-}"

if [ -z "${COVERAGE_FILE}" ] || [ ! -f "${COVERAGE_FILE}" ]; then
echo "ERROR: Coverage file not found: ${COVERAGE_FILE}" >&2
exit 1
fi

if [ -z "${CIRCLE_PULL_REQUEST:-}" ]; then
echo "Not a pull request. Skipping."
exit 0
fi

if [ -z "${GITHUB_TOKEN:-}" ]; then
echo "GITHUB_TOKEN is not set. Skipping."
exit 0
fi

COVERAGE_CONTENT=$(sed '/./,$!d' "${COVERAGE_FILE}")
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
Comment on lines +36 to +37

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

PR number extraction may fail for non-standard URL formats.

The extraction using cut -d'/' -f 7 assumes the URL always follows https://github.com/org/repo/pull/123 format. Consider adding validation.

🛡️ Proposed fix to add validation
 PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
+if ! [[ "${PR_NUMBER}" =~ ^[0-9]+$ ]]; then
+  echo "ERROR: Could not extract PR number from CIRCLE_PULL_REQUEST: ${CIRCLE_PULL_REQUEST}" >&2
+  exit 1
+fi
 REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
📝 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.

Suggested change
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
if ! [[ "${PR_NUMBER}" =~ ^[0-9]+$ ]]; then
echo "ERROR: Could not extract PR number from CIRCLE_PULL_REQUEST: ${CIRCLE_PULL_REQUEST}" >&2
exit 1
fi
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.circleci/post-coverage-comment.sh around lines 36 - 37, The PR number
extraction using PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7) can
fail for non-standard URLs; update the logic that sets PR_NUMBER to first check
CIRCLE_PULL_REQUEST is non-empty and matches a /pull/<digits> pattern (use a
regex to extract the digits), fall back to any existing CIRCLE_PR_NUMBER env var
if present, and if neither yields a valid numeric PR id, log a clear error and
exit; update the assignment and add the validation/exit handling around the
PR_NUMBER and CIRCLE_PULL_REQUEST symbols.


MARKER="<!-- coverage-circleci -->"

BODY=$(jq -n --arg body "**Code coverage (CircleCI)**
\`\`\`
${COVERAGE_CONTENT}
\`\`\`
${MARKER}" '{body: $body}')

# Minimize previous coverage comments.
COMMENTS_JSON=$(curl -s \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments?per_page=100")

EXISTING_IDS=$(echo "${COMMENTS_JSON}" | jq -r '.[] | select(.body | contains("<!-- coverage-circleci -->")) | .node_id')
Comment on lines +48 to +53

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add validation for the GET comments API response.

If the API returns an error (e.g., rate limiting, 404, auth failure), COMMENTS_JSON will contain an error object, not an array. The subsequent jq call will either fail or return unexpected results.

🛡️ Proposed fix to validate GET response
 # Minimize previous coverage comments.
 COMMENTS_JSON=$(curl -s \
   -H "Authorization: token ${GITHUB_TOKEN}" \
   -H "Accept: application/vnd.github.v3+json" \
   "https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments?per_page=100")
 
+# Validate response is a JSON array (not an error object).
+if ! echo "${COMMENTS_JSON}" | jq -e 'type == "array"' >/dev/null 2>&1; then
+  echo "WARNING: Failed to fetch existing comments. Proceeding without minimization." >&2
+  EXISTING_IDS=""
+else
-EXISTING_IDS=$(echo "${COMMENTS_JSON}" | jq -r '.[] | select(.body | contains("<!-- coverage-circleci -->")) | .node_id')
+  EXISTING_IDS=$(echo "${COMMENTS_JSON}" | jq -r '.[] | select(.body | contains("<!-- coverage-circleci -->")) | .node_id')
+fi
📝 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.

Suggested change
COMMENTS_JSON=$(curl -s \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments?per_page=100")
EXISTING_IDS=$(echo "${COMMENTS_JSON}" | jq -r '.[] | select(.body | contains("<!-- coverage-circleci -->")) | .node_id')
COMMENTS_JSON=$(curl -s \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments?per_page=100")
# Validate response is a JSON array (not an error object).
if ! echo "${COMMENTS_JSON}" | jq -e 'type == "array"' >/dev/null 2>&1; then
echo "WARNING: Failed to fetch existing comments. Proceeding without minimization." >&2
EXISTING_IDS=""
else
EXISTING_IDS=$(echo "${COMMENTS_JSON}" | jq -r '.[] | select(.body | contains("<!-- coverage-circleci -->")) | .node_id')
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.circleci/post-coverage-comment.sh around lines 48 - 53, The GET comments
response stored in COMMENTS_JSON must be validated before piping to jq to avoid
failures when the API returns an error object; update the curl invocation that
produces COMMENTS_JSON (and the logic around EXISTING_IDS) to capture and check
the HTTP status and/or ensure the response is a JSON array (e.g., split body and
status with curl -w or validate with jq 'if type=="array" then . else empty
end'), and on non-200 or non-array responses log the error body and exit or
treat EXISTING_IDS as empty so the subsequent jq/select pipeline using
EXISTING_IDS cannot crash.


for NODE_ID in ${EXISTING_IDS}; do
GRAPHQL_BODY=$(jq -n --arg id "${NODE_ID}" '{query: "mutation($id:ID!){minimizeComment(input:{subjectId:$id,classifier:OUTDATED}){minimizedComment{isMinimized}}}", variables: {id: $id}}')
curl -s -X POST \
-H "Authorization: bearer ${GITHUB_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.github.com/graphql" \
-d "${GRAPHQL_BODY}"
done
Comment on lines +55 to +62

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider logging GraphQL minimize failures.

The GraphQL minimize calls fail silently. While not critical (the new comment still posts), logging failures would help debug issues when stale comments aren't being minimized.

🔍 Proposed enhancement for visibility
 for NODE_ID in ${EXISTING_IDS}; do
   GRAPHQL_BODY=$(jq -n --arg id "${NODE_ID}" '{query: "mutation($id:ID!){minimizeComment(input:{subjectId:$id,classifier:OUTDATED}){minimizedComment{isMinimized}}}", variables: {id: $id}}')
-  curl -s -X POST \
+  MINIMIZE_RESPONSE=$(curl -s -X POST \
     -H "Authorization: bearer ${GITHUB_TOKEN}" \
     -H "Content-Type: application/json" \
     "https://api.github.com/graphql" \
-    -d "${GRAPHQL_BODY}"
+    -d "${GRAPHQL_BODY}")
+  if echo "${MINIMIZE_RESPONSE}" | jq -e '.errors' >/dev/null 2>&1; then
+    echo "WARNING: Failed to minimize comment ${NODE_ID}" >&2
+  fi
 done
📝 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.

Suggested change
for NODE_ID in ${EXISTING_IDS}; do
GRAPHQL_BODY=$(jq -n --arg id "${NODE_ID}" '{query: "mutation($id:ID!){minimizeComment(input:{subjectId:$id,classifier:OUTDATED}){minimizedComment{isMinimized}}}", variables: {id: $id}}')
curl -s -X POST \
-H "Authorization: bearer ${GITHUB_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.github.com/graphql" \
-d "${GRAPHQL_BODY}"
done
for NODE_ID in ${EXISTING_IDS}; do
GRAPHQL_BODY=$(jq -n --arg id "${NODE_ID}" '{query: "mutation($id:ID!){minimizeComment(input:{subjectId:$id,classifier:OUTDATED}){minimizedComment{isMinimized}}}", variables: {id: $id}}')
MINIMIZE_RESPONSE=$(curl -s -X POST \
-H "Authorization: bearer ${GITHUB_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.github.com/graphql" \
-d "${GRAPHQL_BODY}")
if echo "${MINIMIZE_RESPONSE}" | jq -e '.errors' >/dev/null 2>&1; then
echo "WARNING: Failed to minimize comment ${NODE_ID}" >&2
fi
done
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.circleci/post-coverage-comment.sh around lines 55 - 62, The minimize
GraphQL loop silently ignores failures; capture the curl response and HTTP
status for each NODE_ID (variables: EXISTING_IDS, NODE_ID, GRAPHQL_BODY) and log
failures including the NODE_ID and the response body/status so you can debug
when minimization fails; modify the loop to save curl output and exit code,
check for non-200 or an errors field in the GraphQL response, and emit a clear
echo/printf to stderr with NODE_ID and the returned error details.


# Post new coverage comment.
curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments" \
-d "${BODY}"
Comment on lines +65 to +69

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding error handling for the final POST request.

The script exits successfully regardless of whether the comment was actually posted. A failed POST (e.g., rate limiting, permission issues) would silently fail since curl -s suppresses errors and there's no response validation.

🛡️ Proposed fix to add response validation
 # Post new coverage comment.
-curl -s -X POST \
+RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
   -H "Authorization: token ${GITHUB_TOKEN}" \
   -H "Accept: application/vnd.github.v3+json" \
   "https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments" \
-  -d "${BODY}"
+  -d "${BODY}")
+
+HTTP_CODE=$(echo "${RESPONSE}" | tail -n1)
+if [ "${HTTP_CODE}" -lt 200 ] || [ "${HTTP_CODE}" -ge 300 ]; then
+  echo "ERROR: Failed to post comment. HTTP ${HTTP_CODE}" >&2
+  exit 1
+fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.circleci/post-coverage-comment.sh around lines 63 - 67, The final curl POST
in .circleci/post-coverage-comment.sh currently uses silent mode and doesn't
validate the response; change the invocation around the curl call (the block
that posts to
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments") to
capture the HTTP status or response body, enable error reporting (e.g., remove
-s or add -S/--fail and use -w '%{http_code}'), validate that the status is 2xx,
and on failure log the response and exit with a non-zero status so the script
fails when the comment POST does not succeed.

13 changes: 1 addition & 12 deletions .circleci/vortex-test-common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -276,18 +276,7 @@ jobs:
command: |
[ "${CIRCLE_NODE_TOTAL:-1}" -gt 1 ] && [ "${CIRCLE_NODE_INDEX:-0}" -ne 0 ] && exit 0
[ "${VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP:-0}" = "1" ] && exit 0
[ -z "${CIRCLE_PULL_REQUEST}" ] && exit 0
[ -z "${GITHUB_TOKEN}" ] && exit 0
COVERAGE_CONTENT=$(sed '/./,$!d' /tmp/artifacts/coverage/phpunit/coverage.txt)
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments" \
-d "$(jq -n --arg body "\`\`\`
${COVERAGE_CONTENT}
\`\`\`" '{body: $body}')"
.circleci/post-coverage-comment.sh /tmp/artifacts/coverage/phpunit/coverage.txt

- run:
name: Upload code coverage reports to Codecov
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build-test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,9 @@ jobs:
if: ${{ github.event_name == 'pull_request' && (matrix.instance == 0 || strategy.job-total == 1) && vars.VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP != '1' }}
uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2
with:
header: coverage-gha
message: |
**Code coverage (GitHub Actions)**
```
${{ env.COVERAGE_CONTENT }}
```
Expand Down
5 changes: 3 additions & 2 deletions .vortex/docs/content/continuous-integration/circleci.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -224,5 +224,6 @@ environment variable in **Project Settings → Environment Variables**. Default
is `90` (percent).

Coverage reports can be posted as PR comments. This requires a `GITHUB_TOKEN`
environment variable with permission to post comments. To disable PR comments,
set `VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP` to `1`.
environment variable with permission to post comments. Each new report replaces
the previous one — older comments are minimized to keep the PR timeline clean.
To disable PR comments, set `VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP` to `1`.
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,7 @@ Configure the threshold by setting the `VORTEX_CI_CODE_COVERAGE_THRESHOLD`
variable in **Settings → Secrets and variables → Actions → Variables**. Default
is `90` (percent).

Coverage reports are automatically posted as PR comments. To disable this, set
`VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP` to `1`.
Coverage reports are automatically posted as PR comments. Each new report
replaces the previous one — older comments are minimized to keep the PR
timeline clean. To disable this, set `VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP`
to `1`.
8 changes: 6 additions & 2 deletions .vortex/docs/content/tools/phpunit.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,12 @@ minimum percentage (default: `90`).

### PR comments

Coverage reports are posted as PR comments automatically. Set
`VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP` to `1` to disable.
Coverage reports are posted as PR comments automatically. Each new report
replaces the previous one — older comments are minimized to keep the PR
timeline clean. The comment includes a header indicating the CI source
(GitHub Actions or CircleCI).

Set `VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP` to `1` to disable.

### Ignoring lines from coverage

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,9 @@ jobs:
if: ${{ github.event_name == 'pull_request' && (matrix.instance == 0 || strategy.job-total == 1) && vars.VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP != '1' }}
uses: marocchino/sticky-pull-request-comment@__HASH__ # __VERSION__
with:
header: coverage-gha
message: |
**Code coverage (GitHub Actions)**
```
${{ env.COVERAGE_CONTENT }}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,7 @@ jobs:
command: |
[ "${CIRCLE_NODE_TOTAL:-1}" -gt 1 ] && [ "${CIRCLE_NODE_INDEX:-0}" -ne 0 ] && exit 0
[ "${VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP:-0}" = "1" ] && exit 0
[ -z "${CIRCLE_PULL_REQUEST}" ] && exit 0
[ -z "${GITHUB_TOKEN}" ] && exit 0
COVERAGE_CONTENT=$(sed '/./,$!d' /tmp/artifacts/coverage/phpunit/coverage.txt)
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments" \
-d "$(jq -n --arg body "\`\`\`
${COVERAGE_CONTENT}
\`\`\`" '{body: $body}')"
.circleci/post-coverage-comment.sh /tmp/artifacts/coverage/phpunit/coverage.txt

- run:
name: Upload code coverage reports to Codecov
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
##
## Post code coverage summary as a PR comment on GitHub.
##
## Minimizes previous coverage comments before posting a new one.
##
## Environment variables:
## CIRCLE_PULL_REQUEST - CircleCI PR URL.
## GITHUB_TOKEN - GitHub token for API access.
## CIRCLE_PROJECT_USERNAME - GitHub org/user.
## CIRCLE_PROJECT_REPONAME - GitHub repo name.
##
## Usage:
## .circleci/post-coverage-comment.sh /path/to/coverage.txt

set -euo pipefail

COVERAGE_FILE="${1:-}"

if [ -z "${COVERAGE_FILE}" ] || [ ! -f "${COVERAGE_FILE}" ]; then
echo "ERROR: Coverage file not found: ${COVERAGE_FILE}" >&2
exit 1
fi

if [ -z "${CIRCLE_PULL_REQUEST:-}" ]; then
echo "Not a pull request. Skipping."
exit 0
fi

if [ -z "${GITHUB_TOKEN:-}" ]; then
echo "GITHUB_TOKEN is not set. Skipping."
exit 0
fi

COVERAGE_CONTENT=$(sed '/./,$!d' "${COVERAGE_FILE}")
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"

MARKER="<!-- coverage-circleci -->"

BODY=$(jq -n --arg body "**Code coverage (CircleCI)**
\`\`\`
${COVERAGE_CONTENT}
\`\`\`
${MARKER}" '{body: $body}')

# Minimize previous coverage comments.
COMMENTS_JSON=$(curl -s \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments?per_page=100")

EXISTING_IDS=$(echo "${COMMENTS_JSON}" | jq -r '.[] | select(.body | contains("<!-- coverage-circleci -->")) | .node_id')

for NODE_ID in ${EXISTING_IDS}; do
GRAPHQL_BODY=$(jq -n --arg id "${NODE_ID}" '{query: "mutation($id:ID!){minimizeComment(input:{subjectId:$id,classifier:OUTDATED}){minimizedComment{isMinimized}}}", variables: {id: $id}}')
curl -s -X POST \
-H "Authorization: bearer ${GITHUB_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.github.com/graphql" \
-d "${GRAPHQL_BODY}"
done

# Post new coverage comment.
curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments" \
-d "${BODY}"
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,7 @@ jobs:
command: |
[ "${CIRCLE_NODE_TOTAL:-1}" -gt 1 ] && [ "${CIRCLE_NODE_INDEX:-0}" -ne 0 ] && exit 0
[ "${VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP:-0}" = "1" ] && exit 0
[ -z "${CIRCLE_PULL_REQUEST}" ] && exit 0
[ -z "${GITHUB_TOKEN}" ] && exit 0
COVERAGE_CONTENT=$(sed '/./,$!d' /tmp/artifacts/coverage/phpunit/coverage.txt)
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments" \
-d "$(jq -n --arg body "\`\`\`
${COVERAGE_CONTENT}
\`\`\`" '{body: $body}')"
.circleci/post-coverage-comment.sh /tmp/artifacts/coverage/phpunit/coverage.txt

- run:
name: Upload code coverage reports to Codecov
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
##
## Post code coverage summary as a PR comment on GitHub.
##
## Minimizes previous coverage comments before posting a new one.
##
## Environment variables:
## CIRCLE_PULL_REQUEST - CircleCI PR URL.
## GITHUB_TOKEN - GitHub token for API access.
## CIRCLE_PROJECT_USERNAME - GitHub org/user.
## CIRCLE_PROJECT_REPONAME - GitHub repo name.
##
## Usage:
## .circleci/post-coverage-comment.sh /path/to/coverage.txt

set -euo pipefail

COVERAGE_FILE="${1:-}"

if [ -z "${COVERAGE_FILE}" ] || [ ! -f "${COVERAGE_FILE}" ]; then
echo "ERROR: Coverage file not found: ${COVERAGE_FILE}" >&2
exit 1
fi

if [ -z "${CIRCLE_PULL_REQUEST:-}" ]; then
echo "Not a pull request. Skipping."
exit 0
fi

if [ -z "${GITHUB_TOKEN:-}" ]; then
echo "GITHUB_TOKEN is not set. Skipping."
exit 0
fi

COVERAGE_CONTENT=$(sed '/./,$!d' "${COVERAGE_FILE}")
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"

MARKER="<!-- coverage-circleci -->"

BODY=$(jq -n --arg body "**Code coverage (CircleCI)**
\`\`\`
${COVERAGE_CONTENT}
\`\`\`
${MARKER}" '{body: $body}')

# Minimize previous coverage comments.
COMMENTS_JSON=$(curl -s \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments?per_page=100")

EXISTING_IDS=$(echo "${COMMENTS_JSON}" | jq -r '.[] | select(.body | contains("<!-- coverage-circleci -->")) | .node_id')

for NODE_ID in ${EXISTING_IDS}; do
GRAPHQL_BODY=$(jq -n --arg id "${NODE_ID}" '{query: "mutation($id:ID!){minimizeComment(input:{subjectId:$id,classifier:OUTDATED}){minimizedComment{isMinimized}}}", variables: {id: $id}}')
curl -s -X POST \
-H "Authorization: bearer ${GITHUB_TOKEN}" \
-H "Content-Type: application/json" \
"https://api.github.com/graphql" \
-d "${GRAPHQL_BODY}"
done

# Post new coverage comment.
curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments" \
-d "${BODY}"
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,7 @@ jobs:
command: |
[ "${CIRCLE_NODE_TOTAL:-1}" -gt 1 ] && [ "${CIRCLE_NODE_INDEX:-0}" -ne 0 ] && exit 0
[ "${VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP:-0}" = "1" ] && exit 0
[ -z "${CIRCLE_PULL_REQUEST}" ] && exit 0
[ -z "${GITHUB_TOKEN}" ] && exit 0
COVERAGE_CONTENT=$(sed '/./,$!d' /tmp/artifacts/coverage/phpunit/coverage.txt)
PR_NUMBER=$(echo "${CIRCLE_PULL_REQUEST}" | cut -d'/' -f 7)
REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}"
curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO_SLUG}/issues/${PR_NUMBER}/comments" \
-d "$(jq -n --arg body "\`\`\`
${COVERAGE_CONTENT}
\`\`\`" '{body: $body}')"
.circleci/post-coverage-comment.sh /tmp/artifacts/coverage/phpunit/coverage.txt

- run:
name: Upload code coverage reports to Codecov
Expand Down
Loading
Loading