Skip to content

fix(clients): add idempotent replay logic and handle malformed UUID #253

fix(clients): add idempotent replay logic and handle malformed UUID

fix(clients): add idempotent replay logic and handle malformed UUID #253

Workflow file for this run

name: CI
on:
push:
branches: ["**"]
pull_request:
permissions:
contents: read
actions: read
jobs:
backend:
name: Backend (Maven)
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up JDK 25
uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0
with:
distribution: temurin
java-version: 25
cache: maven
- name: Run backend tests
run: mvn -B -ntp verify
- name: Upload backend JaCoCo report
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: backend-jacoco-report
path: |
target/site/jacoco/jacoco.xml
target/site/jacoco-it/jacoco.xml
if-no-files-found: warn
retention-days: 7
sonar-backend:
name: SonarQube - backend
runs-on: ubuntu-latest
needs: [backend]
if: >
((github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) ||
(github.event_name == 'pull_request' && github.actor != 'dependabot[bot]'))
outputs:
sonar_skipped: ${{ steps.sonar-check.outputs.sonar_skipped }}
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
SONAR_ORGANIZATION: ${{ vars.SONAR_ORGANIZATION }}
SONAR_PROJECT_KEY: ${{ vars.SONAR_PROJECT_KEY }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Check Sonar configuration
id: sonar-check
run: |
if [ -z "$SONAR_TOKEN" ]; then
echo "sonar_skipped=true" >> "$GITHUB_OUTPUT"
echo "SONAR_TOKEN not set; skipping backend analysis"
exit 0
fi
host_url="${SONAR_HOST_URL:-https://sonarcloud.io}"
host_url="${host_url%/}"
if [ "$host_url" = "https://sonarcloud.io" ] && [ -z "$SONAR_ORGANIZATION" ]; then
echo "sonar_skipped=true" >> "$GITHUB_OUTPUT"
echo "SONAR_ORGANIZATION not set for SonarCloud; skipping backend analysis"
exit 0
fi
echo "sonar_skipped=false" >> "$GITHUB_OUTPUT"
echo "sonar_enabled=true" >> "$GITHUB_OUTPUT"
- name: Set up JDK 25
if: steps.sonar-check.outputs.sonar_enabled == 'true'
uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0
with:
distribution: temurin
java-version: 25
cache: maven
- name: Download backend JaCoCo report
if: steps.sonar-check.outputs.sonar_enabled == 'true'
continue-on-error: true
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: backend-jacoco-report
path: coverage
- name: Run SonarQube analysis (backend)
if: steps.sonar-check.outputs.sonar_enabled == 'true'
shell: bash
env:
REPO_NAME: ${{ github.event.repository.name }}
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_HEAD_REF: ${{ github.head_ref }}
PR_BASE_REF: ${{ github.base_ref }}
run: |
host_url="${SONAR_HOST_URL:-https://sonarcloud.io}"
sonar_project_key="${SONAR_PROJECT_KEY:-$REPO_NAME}"
report_paths=""
if [ -d "coverage" ]; then
report_paths=$(find coverage -type f -name "jacoco.xml" | paste -sd "," - || true)
fi
cmd=(
mvn -B -ntp
-Djacoco.skip=true
-DskipTests
verify
sonar:sonar
"-Dsonar.host.url=${host_url}"
"-Dsonar.projectKey=${sonar_project_key}"
"-Dsonar.token=${SONAR_TOKEN}"
)
if [ -n "${report_paths}" ]; then
cmd+=("-Dsonar.coverage.jacoco.xmlReportPaths=${report_paths}")
else
echo "JaCoCo XML report not found; Sonar will run without coverage input"
fi
if [ -n "${SONAR_ORGANIZATION}" ]; then
cmd+=("-Dsonar.organization=${SONAR_ORGANIZATION}")
fi
if [ "${EVENT_NAME}" = "pull_request" ] && [ -n "${PR_NUMBER}" ] && [ -n "${PR_HEAD_REF}" ] && [ -n "${PR_BASE_REF}" ]; then
cmd+=("-Dsonar.pullrequest.key=${PR_NUMBER}")
cmd+=("-Dsonar.pullrequest.branch=${PR_HEAD_REF}")
cmd+=("-Dsonar.pullrequest.base=${PR_BASE_REF}")
fi
"${cmd[@]}"
- name: Locate backend Sonar report-task
if: steps.sonar-check.outputs.sonar_enabled == 'true'
id: report-task
shell: bash
run: |
report_task=$(find . -type f \( -path "*/target/sonar/report-task.txt" -o -path "*/.scannerwork/report-task.txt" \) | head -1)
if [ -z "$report_task" ]; then
echo "Unable to find Sonar report-task.txt" >&2
exit 1
fi
echo "path=${report_task}" >> "$GITHUB_OUTPUT"
- name: Wait for Quality Gate and publish backend Sonar summary
if: steps.sonar-check.outputs.sonar_enabled == 'true'
shell: bash
env:
REPO_NAME: ${{ github.event.repository.name }}
run: |
sonar_project_key="${SONAR_PROJECT_KEY:-$REPO_NAME}"
extra_args=()
if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then
extra_args+=("--allow-missing-new-code-metrics")
fi
python3 .github/scripts/sonar_quality_gate_report.py \
--component-name "backend" \
--project-key "${sonar_project_key}" \
--report-task-file "${{ steps.report-task.outputs.path }}" \
--timeout-seconds 900 \
"${extra_args[@]}"
notify-telegram:
name: Notify Telegram
runs-on: ubuntu-latest
needs: [backend, sonar-backend]
if: ${{ always() }}
permissions:
contents: read
env:
TELEGRAM_TO: ${{ secrets.TELEGRAM_TO }}
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Compose Telegram message
id: compose
run: python3 .github/scripts/compose_telegram_message.py
env:
BACKEND_RESULT: ${{ needs.backend.result }}
SONAR_BACKEND_RESULT: ${{ needs.sonar-backend.result }}
SONAR_BACKEND_SKIPPED: ${{ needs.sonar-backend.outputs.sonar_skipped }}
- name: Notify Telegram
if: ${{ env.TELEGRAM_TO != '' && env.TELEGRAM_TOKEN != '' }}
uses: appleboy/telegram-action@221e6b684967abe813051ee4a37dd61770a83ad3 # v1.0.1
with:
to: ${{ secrets.TELEGRAM_TO }}
token: ${{ secrets.TELEGRAM_TOKEN }}
message: ${{ steps.compose.outputs.message }}
format: html
- name: Telegram skipped (missing secrets)
if: ${{ env.TELEGRAM_TO == '' || env.TELEGRAM_TOKEN == '' }}
run: echo "TELEGRAM_TO and/or TELEGRAM_TOKEN are not set. Skipping Telegram notification."