Skip to content

ZXCron: [CITR] Extended Test Suite #4507

ZXCron: [CITR] Extended Test Suite

ZXCron: [CITR] Extended Test Suite #4507

# SPDX-License-Identifier: Apache-2.0
name: "ZXCron: [CITR] Extended Test Suite"
on:
workflow_dispatch:
inputs:
rc-tag:
required: false
description: "Release Candidate Tag:"
type: string
default: ""
enable-promotion:
required: false
description: "Tag with epoch timestamp (enables promotion)"
default: false
type: boolean
schedule:
# Runs Extended Test Suite every three hours Monday to Friday
- cron: "0 */3 * * *"
permissions:
id-token: write
actions: write
pull-requests: write
statuses: write
checks: write
contents: read
defaults:
run:
shell: bash
env:
XTS_CANDIDATE_TAG: "xts-candidate"
XTS_PASS_GREP_PATTERN: "xts-pass-*"
PROMOTED_GREP_PATTERN: "build-.{5}"
BUILD_GREP_PATTERN: "build-*"
jobs:
parameters:
name: Determine Configurable Parameters
runs-on: hl-cn-default-lin-sm
outputs:
solo-ge-0440: ${{ steps.set-parameters.outputs.solo-ge-0440 }}
solo-version: ${{ steps.set-parameters.outputs.solo-version }}
helm-release-name: ${{ steps.set-parameters.outputs.helm-release-name }}
steps:
- name: Initialize GitHub Job
uses: pandaswhocode/initialize-github-job@bfe0b1633012cee3033c757c7095d49c360e23a6 # v1.0.1
- name: Set Parameters
id: set-parameters
run: |
SOLO_GE_0440=$([[ "$(printf '%s\n' "${{vars.CITR_SOLO_VERSION}}" "v0.44.0" | sort -V | head -n1)" == "v0.44.0" ]] && echo "true" || echo "false")
HELM_NAME="mirror"
if [[ "${SOLO_GE_0440}" == "true" ]]; then
HELM_NAME="mirror-1"
fi
echo "::debug::SOLO_GE_0440=${SOLO_GE_0440}"
echo "helm-release-name=${HELM_NAME}" >> "${GITHUB_OUTPUT}"
echo "solo-ge-0440=${SOLO_GE_0440}" >> "${GITHUB_OUTPUT}"
echo "solo-version=${{ vars.CITR_SOLO_VERSION }}" >> "${GITHUB_OUTPUT}"
fetch-xts-candidate:
name: Fetch XTS Candidate Tag
runs-on: hl-cn-default-lin-sm
outputs:
xts-tag-exists: ${{ steps.check-tags-exist.outputs.xts-tag-exists }}
xts-tag-commit: ${{ steps.check-tags-exist.outputs.xts-tag-commit }}
xts-tag-short-commit: ${{ steps.check-tags-exist.outputs.xts-tag-short-commit }}
xts-commit-branch: ${{ steps.check-tags-exist.outputs.xts-commit-branch }}
xts-tag-commit-author: ${{ steps.check-tags-exist.outputs.xts-tag-commit-author }}
xts-tag-commit-email: ${{ steps.check-tags-exist.outputs.xts-tag-commit-email }}
xts-info: ${{ steps.check-tags-exist.outputs.xts-info }}
commit-list: ${{ steps.check-tags-exist.outputs.commit-list }}
steps:
- name: Initialize GitHub Job
uses: pandaswhocode/initialize-github-job@bfe0b1633012cee3033c757c7095d49c360e23a6 # v1.0.1
with:
checkout: "true"
checkout-ref: "main"
checkout-fetch-depth: "0"
checkout-token: "${{ secrets.GH_ACCESS_TOKEN }}"
# Check if the xts-candidate tag exists
# the command git branch --contains xts-tag-commit | grep --quiet <default branch>
# will return an exit code of 1 if the tagged commit is not found on the main
# branch.
- name: Check for tags
id: check-tags-exist
env:
GH_TOKEN: ${{ github.token }}
XTS_PASS_PATTERN: ${{ env.XTS_PASS_GREP_PATTERN }}
BUILD_PROMO_PATTERN: ${{ env.PROMOTED_GREP_PATTERN }}
BUILD_PATTERN: ${{ env.BUILD_GREP_PATTERN }}
RC_TAG: ${{ inputs.rc-tag || '' }}
DEFAULT_BRANCH_NAME: "main"
run: |
# Check if the tag exists and if so grab its commit id
echo "::group::Check for XTS Candidate Tag"
if [[ -n "${RC_TAG}" ]]; then
echo "::group::Use RC Tag"
echo "::debug::Using RC Tag: ${RC_TAG}"
XTS_COMMIT=$(git rev-list -n 1 "${RC_TAG}") >/dev/null 2>&1
XTS_COMMIT_FOUND="${?}"
set -e
# Cancel out if the tag does not exist
if [[ "${XTS_COMMIT_FOUND}" -ne 0 ]]; then
echo "::debug::Tag ${RC_TAG} not found. Cancelling out."
gh run cancel ${{ github.run_id }}
fi
COMMIT_LIST="$(git log -n 1 --pretty=format:"- [%h: %s](https://github.com/${{ github.repository }}/commit/%H)" "${XTS_COMMIT}")"
echo "::endgroup::" # Use RC Tag
else
echo "::group::Use XTS Candidate Tag"
set +e
XTS_COMMIT="$(git rev-list -n 1 "${XTS_CANDIDATE_TAG}")" >/dev/null 2>&1
XTS_COMMIT_FOUND="${?}"
set -e
# Cancel out if the tag does not exist
if [[ "${XTS_COMMIT_FOUND}" -ne 0 ]]; then
echo "::debug::Tag ${XTS_CANDIDATE_TAG} not found. Cancelling out."
gh run cancel ${{ github.run_id }}
fi
# Check if this commit has already been tagged xts-pass-* or build-*
set +e
XTS_PASS_TAGGED="$(git tag --contains "${XTS_COMMIT}" | grep -E "${XTS_PASS_PATTERN}")"
BUILD_PROMOTED_TAGGED="$(git tag --contains "${XTS_COMMIT}" | grep -E "${BUILD_PROMO_PATTERN}")"
set -e
# Use -n; if the BUILD_PROMOTED_TAGGED/XTS_PASS_TAGGED flags are not empty than the commit has been tagged.
if [[ -n "${XTS_PASS_TAGGED}" || -n "${BUILD_PROMOTED_TAGGED}" ]]; then
echo "::debug::Commit ${XTS_COMMIT} has already been tagged as xts-pass or build. Cancelling out."
gh run cancel ${{ github.run_id }}
fi
# Get the list of commits between the previous XTS Pass and the current commit
COMMIT_LIST=""
LATEST_XTS_PASS_TAG="$(git tag --list --sort=-version:refname "${XTS_PASS_PATTERN}" | head --lines 1)"
LATEST_PROMOTED_BUILD_TAG="$(git tag --list --sort=-version:refname "${BUILD_PATTERN}" | head --lines 1)"
if [[ -n "${LATEST_XTS_PASS_TAG}" ]]; then
echo "::debug::Using latest xts-pass tag"
echo "Latest XTS Pass Tag: ${LATEST_XTS_PASS_TAG}"
LATEST_XTS_PASS_COMMIT="$(git rev-list -n 1 "${LATEST_XTS_PASS_TAG}")"
COMMIT_LIST="$(git log --pretty=format:"- [%h: %s](https://github.com/${{ github.repository }}/commit/%H)" "${LATEST_XTS_PASS_COMMIT}..${XTS_COMMIT}")"
elif [[ -n "${LATEST_PROMOTED_BUILD_TAG}" ]]; then
echo "::debug::Using latest promoted build tag as no xts-pass tag found"
echo "Latest Promoted Tag: ${LATEST_PROMOTED_BUILD_TAG}"
LATEST_PROMOTED_BUILD_COMMIT="$(git rev-list -n 1 "${LATEST_PROMOTED_BUILD_TAG}")"
COMMIT_LIST="$(git log --pretty=format:"- [%h: %s](https://github.com/${{ github.repository }}/commit/%H)" "${LATEST_PROMOTED_BUILD_COMMIT}..${XTS_COMMIT}")"
fi
echo "::endgroup::" # Use XTS Candidate Tag
fi
echo "::endgroup::" # Check for XTS Candidate Tag
echo "::group::Check if XTS COMMIT is on default branch"
# Determine which branch the commit belongs to
XTS_COMMIT_BRANCHES="$(git branch -r --contains "${XTS_COMMIT}" | sed 's/^[ *]*//')"
echo "::debug::XTS_COMMIT_BRANCHES=${XTS_COMMIT_BRANCHES}"
XTS_COMMIT_BRANCH="${DEFAULT_BRANCH_NAME}"
COMMIT_ON_DEFAULT_BRANCH=0
# Check if the commit on the default branch
if echo "${XTS_COMMIT_BRANCHES}" | grep -qE "(^|/)${DEFAULT_BRANCH_NAME}$"; then
echo "::debug::Commit ${XTS_COMMIT} found on main branch."
else
echo "::debug::Commit ${XTS_COMMIT} not found on main branch, determining actual branch."
COMMIT_ON_DEFAULT_BRANCH=1
XTS_COMMIT_BRANCH="$(
git name-rev --name-only --refs="refs/remotes/*" "${XTS_COMMIT}" \
| sed 's~^.*origin/~~' \
| sed 's/~.*//'
)"
fi
# Print branch debug info
echo "::debug::XTS_COMMIT_BRANCH=${XTS_COMMIT_BRANCH}"
echo "::debug::COMMIT_ON_DEFAULT_BRANCH=${COMMIT_ON_DEFAULT_BRANCH}"
echo "::endgroup::" # XTS COMMIT is on default branch
echo "::group::Get XTS Commit Information"
# Get the short commit id
XTS_SHORT_COMMIT="$(git rev-parse --short "${XTS_COMMIT}")"
echo "::debug::XTS_SHORT_COMMIT=${XTS_SHORT_COMMIT}"
# Get commit author
AUTHOR_NAME="$(git log -1 --format='%an' "${XTS_COMMIT}")"
AUTHOR_EMAIL="$(git log -1 --format='%ae' "${XTS_COMMIT}")"
echo "::endgroup::" # Get XTS Commit Information
echo "::group::Set Outputs"
# If the tag exists on the Main Branch set the output variables as appropriate
# Otherwise cancel out
if [[ "${COMMIT_ON_DEFAULT_BRANCH}" -eq 0 ]]; then
# GitHub Outputs
echo "xts-tag-exists=true" >> "${GITHUB_OUTPUT}"
echo "xts-tag-commit=${XTS_COMMIT}" >> "${GITHUB_OUTPUT}"
echo "xts-tag-short-commit=${XTS_SHORT_COMMIT}" >> "${GITHUB_OUTPUT}"
echo "xts-tag-commit-author=${AUTHOR_NAME} <${AUTHOR_EMAIL}>" >> "${GITHUB_OUTPUT}"
echo "xts-commit-branch=${XTS_COMMIT_BRANCH}" >> "${GITHUB_OUTPUT}"
echo "xts-tag-commit-email=${AUTHOR_EMAIL}" >> "${GITHUB_OUTPUT}"
echo "xts-info=${XTS_COMMIT_BRANCH} - ${XTS_SHORT_COMMIT}" >> "${GITHUB_OUTPUT}"
COMMIT_COUNT=$(echo "$COMMIT_LIST" | wc -l)
COMMIT_LIST_STR=""
if [[ -z "${COMMIT_LIST//[[:space:]]/}" ]]; then
# should never get here.
echo "::error file=zxcron-extended-test-suite.yaml,line=213::No commits associated with this release; exiting."
exit 1
elif [[ ${COMMIT_COUNT} -gt 15 ]]; then
COMMIT_LIST_STR="Please refer to the workflow summary for the full list of associated commits."
else
PARSED_COMMIT_LIST="${COMMIT_LIST//\`/}"
ESCAPED_COMMIT_LIST=$(jq -Rs . <<< "${PARSED_COMMIT_LIST}")
COMMIT_LIST_STR=${ESCAPED_COMMIT_LIST:1:-1}
fi
echo "commit-list=${COMMIT_LIST_STR}" >> "${GITHUB_OUTPUT}"
# GitHub Step Summary
echo "### XTS-Candidate commit found" >> "${GITHUB_STEP_SUMMARY}"
echo "xts-tag-commit=${XTS_COMMIT}" >> "${GITHUB_STEP_SUMMARY}"
echo "### Commit List" >> "${GITHUB_STEP_SUMMARY}"
echo -e "${COMMIT_LIST}" >> "${GITHUB_STEP_SUMMARY}"
echo "### XTS Information" >> "${GITHUB_STEP_SUMMARY}"
echo "xts-info=${XTS_COMMIT_BRANCH} - ${XTS_SHORT_COMMIT}" >> "${GITHUB_STEP_SUMMARY}"
if [[ -z "${RC_TAG}" ]]; then
echo "::debug::Deleting the XTS candidate tag so we can recreate it later."
git push --delete origin "${XTS_CANDIDATE_TAG}"
git tag -d "${XTS_CANDIDATE_TAG}"
fi
else
echo "::debug::Commit ${XTS_COMMIT} not found on main branch. Cancelling out."
gh run cancel "${{ github.run_id }}"
fi
echo "::endgroup::" # Set Outputs
state-validator-uberjar:
name: Build & Publish Hedera State Validator Uber JAR
needs:
- fetch-xts-candidate
if: ${{ needs.fetch-xts-candidate.result == 'success' && needs.fetch-xts-candidate.outputs.xts-tag-exists == 'true' }}
uses: ./.github/workflows/zxc-build-publish-state-validator.yaml
with:
ref: ${{ needs.fetch-xts-candidate.outputs.xts-tag-commit }}
xts-execution:
name: Execute XTS
needs:
- fetch-xts-candidate
- parameters
- state-validator-uberjar
if: ${{ needs.fetch-xts-candidate.result == 'success' && needs.fetch-xts-candidate.outputs.xts-tag-exists == 'true' }}
uses: ./.github/workflows/zxc-xts-tests.yaml
with:
ref: ${{ needs.fetch-xts-candidate.outputs.xts-tag-commit }}
branch_name: ${{ needs.fetch-xts-candidate.outputs.xts-commit-branch }}
solo-version: ${{ needs.parameters.outputs.solo-version }}
solo-ge-0440: ${{ needs.parameters.outputs.solo-ge-0440 }}
helm-release-name: ${{ needs.parameters.outputs.helm-release-name }}
custom-job-label: "XTS (main):"
enable-timing-sensitive-test-suite: "true"
enable-hammer-test-suite: "true"
enable-hapi-test-suite: "true"
enable-otter-test-suite: "true"
enable-hedera-node-jrs-panel: "true"
enable-sdk-tck-regression-panel: "true"
secrets:
access-token: ${{ secrets.GITHUB_TOKEN }}
platform-access-token: ${{ secrets.PLATFORM_GH_ACCESS_TOKEN }}
regression-access-token: ${{ secrets.GH_ACCESS_TOKEN }}
gcp-project-number: ${{ secrets.PLATFORM_GCP_PROJECT_NUMBER }}
gcp-sa-key-contents: ${{ secrets.PLATFORM_GCP_KEY_FILE }}
gradle-cache-username: ${{ secrets.GRADLE_CACHE_USERNAME }}
gradle-cache-password: ${{ secrets.GRADLE_CACHE_PASSWORD }}
grafana-agent-username: ${{ secrets.GRAFANA_AGENT_USERNAME }}
grafana-agent-password: ${{ secrets.GRAFANA_AGENT_PASSWORD }}
jrs-ssh-user-name: ${{ secrets.PLATFORM_JRS_SSH_USER_NAME }}
jrs-ssh-key-file: ${{ secrets.PLATFORM_JRS_SSH_KEY_FILE }}
slack-api-token: ${{ secrets.PLATFORM_SLACK_API_TOKEN }}
slack-citr-details-token: ${{ secrets.SLACK_CITR_DETAILED_REPORTS_WEBHOOK }}
slack-tck-report-webhook: ${{ secrets.SLACK_TCK_MONITOR_WEBHOOK }}
xts-optional-execution:
name: Execute Optional XTS Tests
needs:
- fetch-xts-candidate
- parameters
- state-validator-uberjar
if: ${{ needs.fetch-xts-candidate.result == 'success' && needs.fetch-xts-candidate.outputs.xts-tag-exists == 'true' }}
uses: ./.github/workflows/zxc-xts-tests.yaml
with:
ref: ${{ needs.fetch-xts-candidate.outputs.xts-tag-commit }}
branch_name: ${{ needs.fetch-xts-candidate.outputs.xts-commit-branch }}
solo-version: ${{ needs.parameters.outputs.solo-version }}
solo-ge-0440: ${{ needs.parameters.outputs.solo-ge-0440 }}
helm-release-name: ${{ needs.parameters.outputs.helm-release-name }}
mirror-node-version: ${{ vars.CITR_MIRROR_NODE_VERSION }}
custom-job-label: "XTS (Optional):"
enable-mirror-node-regression-panel: "true"
enable-rpc-relay-regression-panel: "true"
enable-block-node-regression-panel: "true"
enable-chaos-otter-test-suite: "true"
secrets:
access-token: ${{ secrets.GH_ACCESS_TOKEN }}
slack-citr-details-token: ${{ secrets.SLACK_CITR_DETAILED_REPORTS_WEBHOOK }}
tag-for-promotion:
name: Tag as XTS-Passing
runs-on: hl-cn-default-lin-sm
needs:
- fetch-xts-candidate
- xts-execution
if: ${{ needs.xts-execution.result == 'success' }}
steps:
- name: Initialize GitHub Job
uses: pandaswhocode/initialize-github-job@bfe0b1633012cee3033c757c7095d49c360e23a6 # v1.0.1
with:
checkout: "true"
checkout-ref: ${{ needs.fetch-xts-candidate.outputs.xts-tag-commit }}
checkout-fetch-depth: "0"
checkout-token: ${{ secrets.GH_ACCESS_TOKEN }}
- name: Import GPG Key
id: gpg_importer
uses: step-security/ghaction-import-gpg@c86c374c0659a6c2d1284bccf8af889e73ce8fe0 # v6.3.0
with:
git_commit_gpgsign: true
git_tag_gpgsign: true
git_user_signingkey: true
gpg_private_key: ${{ secrets.SVCS_GPG_KEY_CONTENTS }}
passphrase: ${{ secrets.SVCS_GPG_KEY_PASSPHRASE }}
# Now that the XTS suite has run we should be able to tag for promotion
- name: Tag for XTS promotion
env:
RC_TAG: ${{ inputs.rc-tag || '' }}
TAG_WITH_EPOCH: ${{ inputs.enable-promotion || 'false' }}
run: |
if [[ -n "${RC_TAG}" ]] && [[ "${TAG_WITH_EPOCH}" == "false" ]]; then
echo "::debug::Tagging adhoc commit as XTS passing"
TAG="adhoc-xts-pass-${RC_TAG}"
set +e
TAG_COMMIT="$(git rev-list -n 1 "${TAG}")" >/dev/null 2>&1
TAG_EXISTS="${?}"
set -e
if [[ "${TAG_EXISTS}" -eq 0 ]]; then
echo "::debug::Tag exists, recreate it"
echo "Tag ${TAG} already exists. Deleting."
git push --delete origin "${TAG}"
git tag -d "${TAG}"
fi
echo "::debug::Push the new tag ${TAG}"
git tag --annotate "${TAG}" --message "chore: tagging release candidate as XTS passing"
git push --set-upstream origin "${TAG}"
echo "### Commit Tagged as XTS-Passing" >> "${GITHUB_STEP_SUMMARY}"
echo "xts-pass-tag=${TAG}" >> "${GITHUB_STEP_SUMMARY}"
else
echo "::debug::Tagging commit with epoch timestamp as XTS passing"
EPOCH_TIME="$(date +%s)"
TAG="xts-pass-${EPOCH_TIME}"
git tag --annotate "${TAG}" --message "chore: tagging commit for build candidate promotion"
git push --set-upstream origin --tags
echo "### Commit Tagged for Promotion" >> "${GITHUB_STEP_SUMMARY}"
echo "promotion-tag=${TAG}" >> "${GITHUB_STEP_SUMMARY}"
fi
report-success:
name: Report XTS execution success
runs-on: hl-cn-default-lin-sm
needs:
- fetch-xts-candidate
- xts-execution
- tag-for-promotion
if: ${{ (needs.fetch-xts-candidate.result == 'success' &&
needs.xts-execution.result == 'success' &&
needs.tag-for-promotion.result == 'success') &&
!cancelled() }}
steps:
- name: Initialize GitHub Job
uses: pandaswhocode/initialize-github-job@bfe0b1633012cee3033c757c7095d49c360e23a6 # v1.0.1
- name: Report Success (slack)
uses: slackapi/slack-github-action@b0fa283ad8fea605de13dc3f449259339835fc52 # v2.1.0
with:
webhook: ${{ secrets.SLACK_CITR_OPERATIONS_WEBHOOK }}
webhook-type: incoming-webhook
payload-templated: true
payload: |
{
"attachments": [
{
"color": "#00FF00",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": ":tada: XTS - eXtended Test Suite Passing Report (${{ needs.fetch-xts-candidate.outputs.xts-info }}) Passed",
"emoji": true
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*XTS Job Succeeded. Test panel status below*"
},
"fields": [
{
"type": "plain_text",
"text": "Fetch XTS Candidate Tag: ${{ needs.fetch-xts-candidate.result }}"
},
{
"type": "plain_text",
"text": "XTS Execution: ${{ needs.xts-execution.result }}"
},
{
"type": "plain_text",
"text": "Tag as XTS-Passing: ${{ needs.tag-for-promotion.result }}"
}
]
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Workflow and Commit Information*\nFor a full list of executed tests see `Workflow run URL` below"
},
"fields": [
{
"type": "mrkdwn",
"text": "*Source Commit*:"
},
{
"type": "mrkdwn",
"text": "<${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.fetch-xts-candidate.outputs.xts-tag-commit }}>"
},
{
"type": "mrkdwn",
"text": "*Commit author*:"
},
{
"type": "mrkdwn",
"text": "${{ needs.fetch-xts-candidate.outputs.xts-tag-commit-author }}"
},
{
"type": "mrkdwn",
"text": "*Workflow run ID*:"
},
{
"type": "mrkdwn",
"text": " ${{ github.run_id }}"
},
{
"type": "mrkdwn",
"text": "*Workflow run URL*:"
},
{
"type": "mrkdwn",
"text": "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>"
}
]
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Commit List*:"
},
"fields": [
{
"type": "mrkdwn",
"text": "${{ needs.fetch-xts-candidate.outputs.commit-list }}"
}
]
}
]
}
]
}
report-failure:
name: Report XTS execution failure
runs-on: hl-cn-default-lin-sm
needs:
- fetch-xts-candidate
- xts-execution
- tag-for-promotion
if: ${{ (needs.fetch-xts-candidate.result != 'success' ||
needs.xts-execution.result != 'success' ||
needs.tag-for-promotion.result != 'success') &&
!cancelled() && always() }}
steps:
- name: Initialize GitHub Job
uses: pandaswhocode/initialize-github-job@bfe0b1633012cee3033c757c7095d49c360e23a6 # v1.0.1
with:
checkout: "true"
checkout-ref: main
checkout-fetch-depth: "0"
checkout-token: ${{ secrets.GH_ACCESS_TOKEN }}
- name: Collect run logs in a log file
env:
GH_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }}
continue-on-error: true
run: |
for job_id in "$(gh run view "${{ github.run_id }}" --json jobs --jq '.jobs | map(.databaseId) | .[0:-1] | .[]')"; do
echo "Fetching logs for job $job_id..."
current_job_name="$(gh run view ${{ github.run_id }} --json jobs | jq --argjson job_id "$job_id" -r '.jobs[] | select(.databaseId == $job_id) | .name')"
echo "Logs for job $current_job_name :" >> run.log
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/hiero-ledger/hiero-consensus-node/actions/jobs/$job_id/logs >> run.log
done
- name: Upload log as artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
continue-on-error: true
with:
path: run.log
- name: Find Commit Author in Slack
id: find-commit-author-slack
continue-on-error: true
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_CITR_BOT_TOKEN }}
EMAIL: ${{ needs.fetch-xts-candidate.outputs.xts-tag-commit-email }}
run: |
SLACK_USER_ID=$(curl -s -X GET "https://slack.com/api/users.list" \
-H "Authorization: Bearer ${SLACK_BOT_TOKEN}" | jq -r --arg email "${EMAIL}" \
'.members[] | select((.profile.email // "" | ascii_downcase) == ($email | ascii_downcase)) | .name')
if [[ -z "${SLACK_USER_ID}" || "${SLACK_USER_ID}" == "null" ]]; then
echo "No Slack user found for email: ${EMAIL}"
SLACK_USER_ID="No matching slack user found"
else
echo "Found slack user for email: ${EMAIL}"
SLACK_USER_ID="<@${SLACK_USER_ID}>"
fi
echo "slack-user-id=${SLACK_USER_ID}" >> "${GITHUB_OUTPUT}"
- name: Determine failure mode
id: extended-test-suite-failure
if: ${{ needs.xts-execution.result != 'success' }}
run: |
failure_mode="${{ needs.xts-execution.outputs.failure-mode || 'general' }}"
echo "mode=${failure_mode}" >> "${GITHUB_OUTPUT}"
- name: Set Rootly Service Name
id: set-rootly-service
run: |
ROOTLY_SERVICE_NAME="CITR General"
if [[ "${{ needs.fetch-xts-candidate.result }}" =~ ^(cancelled|failure)$ ]] \
|| [[ "${{ needs.tag-for-promotion.result }}" =~ ^(cancelled|failure)$ ]] \
|| [[ "${{ steps.extended-test-suite-failure.outputs.mode || 'general' }}" == "workflow" ]]; then
ROOTLY_SERVICE_NAME="CI/CD Workflows"
fi
echo "service=${ROOTLY_SERVICE_NAME}" >> "${GITHUB_OUTPUT}"
- name: Build Rootly Summary
id: rootly-summary
env:
PRINT_FAILED_TESTS_SCRIPT: ".github/workflows/support/scripts/print-failed-tests.sh"
run: |
title="The eXtended Test Suite job failed (${{ needs.fetch-xts-candidate.outputs.xts-info }})."
echo "title=${title}" >> "${GITHUB_OUTPUT}"
{
echo 'summary<<EOF'
echo "------------------------------------"
echo "Status of each jobs:"
echo "- Execute XTS: ${{ needs.xts-execution.result }}"
echo "- Tag for Promotion: ${{ needs.tag-for-promotion.result }}"
echo "------------------------------------"
if [[ "${{ needs.xts-execution.result }}" != "success" ]]; then
echo "XTS tests failed due to a ${{ needs.xts-execution.outputs.failure-mode }} error."
echo "Failing Test(s):"
bash "${{ github.workspace }}/${{ env.PRINT_FAILED_TESTS_SCRIPT }}" "${{ needs.xts-execution.outputs.failed-tests }}"
echo "------------------------------------"
fi
echo "Commit information:"
echo "- Author: ${{ needs.fetch-xts-candidate.outputs.xts-tag-commit-author }}"
echo "- Commit: <${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.fetch-xts-candidate.outputs.xts-tag-commit }}>"
echo "- Workflow: <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>"
echo "------------------------------------"
echo "Commit List:"
echo -e "${{ needs.fetch-xts-candidate.outputs.commit-list }}"
echo EOF
} >> "${GITHUB_OUTPUT}"
- name: Log Rootly Summary
run: |
echo "## Rootly Summary:"
echo "### Title: ${{ steps.rootly-summary.outputs.title }}" >> "${GITHUB_STEP_SUMMARY}"
echo "${{ steps.rootly-summary.outputs.summary }}" >> "${GITHUB_STEP_SUMMARY}"
echo "### Rootly Service" >> "${GITHUB_STEP_SUMMARY}"
echo "${{ steps.set-rootly-service.outputs.service }}" >> "${GITHUB_STEP_SUMMARY}"
- name: Create Rootly Alert
id: create-rootly-alert
uses: pandaswhocode/rootly-alert-action@fdae1529e5aed62040016accf719a0ceb7dae57f # v1.0.0
continue-on-error: true
with:
api_key: ${{ secrets.ROOTLY_API_TOKEN }}
summary: "${{ steps.rootly-summary.outputs.title }}"
details: "${{ steps.rootly-summary.outputs.summary }}"
notification_target_type: "Service"
notification_target: ${{ steps.set-rootly-service.outputs.service }}
set_as_noise: "false"
alert_urgency: "High"
external_id: ${{ github.run_id }}
external_url: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
environments: "CITR"
- name: Build Slack Payload Message
id: payload
run: |
cat <<EOF > slack_payload.json
{
"attachments": [
{
"color": "#FF0000",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": ":grey_exclamation: XTS - eXtended Test Suite Failure Report (${{ needs.fetch-xts-candidate.outputs.xts-info }}) Failed",
"emoji": true
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*XTS Job Resulted in failure. See status below.*"
},
"fields": [
{
"type": "plain_text",
"text": "Fetch XTS Candidate Tag: ${{ needs.fetch-xts-candidate.result }}"
},
{
"type": "plain_text",
"text": "XTS Execution: ${{ needs.xts-execution.result }}"
},
{
"type": "plain_text",
"text": "Tag as XTS-Passing: ${{ needs.tag-for-promotion.result }}"
}
]
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Workflow and Commit Information*"
},
"fields": [
{
"type": "mrkdwn",
"text": "*Source Commit*:"
},
{
"type": "mrkdwn",
"text": "<${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.fetch-xts-candidate.outputs.xts-tag-commit }}>"
},
{
"type": "mrkdwn",
"text": "*Commit author*:"
},
{
"type": "mrkdwn",
"text": "${{ needs.fetch-xts-candidate.outputs.xts-tag-commit-author }}"
},
{
"type": "mrkdwn",
"text": "*Slack user*:"
},
{
"type": "mrkdwn",
"text": "${{ steps.find-commit-author-slack.outputs.slack-user-id }}"
},
{
"type": "mrkdwn",
"text": "*Workflow run ID*:"
},
{
"type": "mrkdwn",
"text": " ${{ github.run_id }}"
},
{
"type": "mrkdwn",
"text": "*Workflow run URL*:"
},
{
"type": "mrkdwn",
"text": "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>"
}
]
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Commit List*:"
},
"fields": [
{
"type": "mrkdwn",
"text": "${{ needs.fetch-xts-candidate.outputs.commit-list }}"
}
]
}
]
}
]
}
EOF
- name: Report failure (slack citr-operations)
if: ${{ steps.set-rootly-service.outputs.service != 'CI/CD Workflows' }}
uses: slackapi/slack-github-action@b0fa283ad8fea605de13dc3f449259339835fc52 # v2.1.0
with:
webhook: ${{ secrets.SLACK_CITR_OPERATIONS_WEBHOOK }}
webhook-type: incoming-webhook
payload-templated: true
payload-file-path: slack_payload.json
- name: Report failure (slack citr-failures)
if: ${{ steps.set-rootly-service.outputs.service == 'CI/CD Workflows' }}
uses: slackapi/slack-github-action@b0fa283ad8fea605de13dc3f449259339835fc52 # v2.1.0
with:
webhook: ${{ secrets.SLACK_CITR_FAILURES_WEBHOOK }}
webhook-type: incoming-webhook
payload-templated: true
payload-file-path: slack_payload.json