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
96 changes: 63 additions & 33 deletions .github/scripts/handle_warning_violations.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@ fi
VIOLATION_DETAILS=""
if [ -f "tools/spectral/ipa/metrics/outputs/warning-violations.json" ]; then
VIOLATION_DETAILS=$(jq -r '
group_by(.code) |
map("• " + .[0].code + " (" + (length | tostring) + " violations)") |
join("\n")
group_by(.code) |
map(
"• " + .[0].code + " (" + (length | tostring) + " violations):\n" +
(map(" - " + .component_id) | join("\n"))
) |
join("\n\n")
' tools/spectral/ipa/metrics/outputs/warning-violations.json)
fi

# Check if warning ticket already exists
echo "Check if a jira ticket already exists."
EXISTING_TICKET=$(curl -H "Authorization: Bearer ${JIRA_API_TOKEN}" \
"https://jira.mongodb.org/rest/api/2/search?jql=project=CLOUDP AND summary~'Warning-level IPA violations' AND status!=Done" \
JQL_QUERY="project=CLOUDP AND summary~'Warning-level IPA violations' AND status NOT IN (Done, Resolved, Closed)"
EXISTING_TICKET=$(curl -G -H "Authorization: Bearer ${JIRA_API_TOKEN}" \
--data-urlencode "jql=${JQL_QUERY}" \
"https://jira.mongodb.org/rest/api/2/search" \
| jq -r '.issues[0].key // empty')

if [ -n "${EXISTING_TICKET}" ]; then
Expand All @@ -39,45 +44,70 @@ ${VIOLATION_DETAILS}

Total violations: ${WARNING_COUNT}"

echo "Jira ticket does not exists. Creating..."
# Create new Jira ticket
TICKET_RESPONSE=$(curl -X POST -H "Authorization: Bearer ${JIRA_API_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"fields\": {
\"project\": {\"key\": \"CLOUDP\"},
\"summary\": \"Warning-level IPA violations found\",
\"description\": \"${DESCRIPTION}\",
\"issuetype\": {\"name\": \"Task\"},
\"assignee\": {\"id\": \"${TEAM_ID}\"}
echo "Jira ticket does not exist. Creating..."
# Create new Jira ticket with properly escaped JSON (matching create_jira_ticket.sh format)
TICKET_PAYLOAD=$(jq -n \
--arg summary "Warning-level IPA violations found" \
--arg description "$DESCRIPTION" \
--arg teamId "$TEAM_ID" \
'{
fields: {
project: {id: "10984"},
summary: $summary,
description: $description,
issuetype: {id: "12"},
customfield_12751: [{id: $teamId}],
components: [{id: "35986"}]
}
}" \
}')

echo "Jira ticket payload:"
echo "${TICKET_PAYLOAD}"

TICKET_RESPONSE=$(echo "${TICKET_PAYLOAD}" | curl -X POST -H "Authorization: Bearer ${JIRA_API_TOKEN}" \
-H "Content-Type: application/json" \
-d @- \
"https://jira.mongodb.org/rest/api/2/issue/")

TICKET_KEY=$(echo "${TICKET_RESPONSE}" | jq -r '.key')
if [ "${TICKET_KEY}" != "null" ]; then
echo "Jira API response:"
echo "${TICKET_RESPONSE}"

TICKET_KEY=$(echo "${TICKET_RESPONSE}" | jq -r '.key // empty')
if [ -n "${TICKET_KEY}" ] && [ "${TICKET_KEY}" != "null" ]; then
echo "Created Jira ticket: ${TICKET_KEY}."
# Create summary for Slack
echo "Creating Slack Summary with VIOLATION_DETAILS: ${VIOLATION_DETAILS}..."
SLACK_SUMMARY=""
if [ -n "${VIOLATION_DETAILS}" ]; then
SLACK_SUMMARY=$(echo "${VIOLATION_DETAILS}" | head -3)
if [ "$(echo "${VIOLATION_DETAILS}" | wc -l)" -gt 3 ]; then
SLACK_SUMMARY="${SLACK_SUMMARY}\n... and more"
fi
fi

echo "Send Slack notification..."
# Send Slack notification with violation summary
# Send Slack notification with link to Jira ticket for details
SLACK_MESSAGE="Warning-level IPA violations found (${WARNING_COUNT} violations) (${SLACK_ONCALL_USER}).

Jira ticket: https://jira.mongodb.org/browse/${TICKET_KEY}"
curl -X POST -H "Authorization: Bearer ${SLACK_BEARER_TOKEN}" \
See Jira ticket for details: https://jira.mongodb.org/browse/${TICKET_KEY}"

SLACK_RESPONSE=$(curl -X POST -H "Authorization: Bearer ${SLACK_BEARER_TOKEN}" \
-H "Content-type: application/json" \
--data "{\"channel\":\"${SLACK_CHANNEL_ID}\",\"text\":\"${SLACK_MESSAGE}\"}" \
https://slack.com/api/chat.postMessage
https://slack.com/api/chat.postMessage)

echo "Slack API response: ${SLACK_RESPONSE}"

SLACK_OK=$(echo "${SLACK_RESPONSE}" | jq -r '.ok')
if [ "${SLACK_OK}" != "true" ]; then
SLACK_ERROR=$(echo "${SLACK_RESPONSE}" | jq -r '.error')
echo "Warning: Failed to send Slack notification. Error: ${SLACK_ERROR}"

if [ "${SLACK_ERROR}" == "not_in_channel" ]; then
echo "The Slack bot is not a member of channel ${SLACK_CHANNEL_ID}."
echo "Please invite the bot to the channel or update SLACK_CHANNEL_ID."
fi

# Don't fail the script - Jira ticket was created successfully
echo "Continuing despite Slack notification failure..."
else
echo "Slack notification sent successfully."
fi
else
echo "Failed to create Jira ticket"
echo "Response: ${TICKET_RESPONSE}"
ERROR_MESSAGES=$(echo "${TICKET_RESPONSE}" | jq -r '.errorMessages[]? // .errors? // "No error details available"' 2>/dev/null || echo "Could not parse error response")
echo "Error details: ${ERROR_MESSAGES}"
exit 1
fi
9 changes: 8 additions & 1 deletion .github/workflows/release-IPA-metrics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
working-directory: ${{ github.workspace }}

- name: Upload OAS files as artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
name: oas-files
path: |
Expand All @@ -81,6 +81,13 @@ jobs:
node runMetricCollection.js "${{ github.workspace }}/v2-filtered.json"
echo "WARNING_COUNT=$(cat ../outputs/warning-count.txt)" >> "$GITHUB_ENV"

- name: Upload Warning Violations as Artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
name: warning-violations
path: tools/spectral/ipa/metrics/outputs/warning-violations.json
retention-days: 1

- name: aws configure
uses: aws-actions/configure-aws-credentials@v5
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ describe('tools/spectral/ipa/metrics/metricCollection.js runMetricCollectionJob'
const violations = [
{
code: 'xgen-IPA-104-valid-operation-id-warn',
component_id: 'paths./api/atlas/v2/federationSettings/{federationSettingsId}/connectedOrgConfigs/{orgId}.get',
},
];
expect(results.warnings.violations).toEqual(violations);
Expand Down
1 change: 1 addition & 0 deletions tools/spectral/ipa/metrics/metricCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export async function runMetricCollectionJob(

const processedWarnings = warningViolations.map((violation) => ({
code: violation.ipa_rule,
component_id: violation.component_id,
}));

console.log(`Found ${warningViolations.length} warning-level violations`);
Expand Down
Loading