mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-07 05:22:56 +00:00
## Problem `benchmarking` job fails because `aws-oicd-role-arn` input is not set ## Summary of changes: - Set `aws-oicd-role-arn` for `benchmarking job - Always require `aws-oicd-role-arn` to be set - Rename `aws_oicd_role_arn` to `aws-oicd-role-arn` for consistency
248 lines
9.7 KiB
YAML
248 lines
9.7 KiB
YAML
name: 'Create Allure report'
|
|
description: 'Generate Allure report from uploaded by actions/allure-report-store tests results'
|
|
|
|
inputs:
|
|
store-test-results-into-db:
|
|
description: 'Whether to store test results into the database. TEST_RESULT_CONNSTR/TEST_RESULT_CONNSTR_NEW should be set'
|
|
type: boolean
|
|
required: false
|
|
default: false
|
|
aws-oicd-role-arn:
|
|
description: 'OIDC role arn to interract with S3'
|
|
required: true
|
|
|
|
outputs:
|
|
base-url:
|
|
description: 'Base URL for Allure report'
|
|
value: ${{ steps.generate-report.outputs.base-url }}
|
|
base-s3-url:
|
|
description: 'Base S3 URL for Allure report'
|
|
value: ${{ steps.generate-report.outputs.base-s3-url }}
|
|
report-url:
|
|
description: 'Allure report URL'
|
|
value: ${{ steps.generate-report.outputs.report-url }}
|
|
report-json-url:
|
|
description: 'Allure report JSON URL'
|
|
value: ${{ steps.generate-report.outputs.report-json-url }}
|
|
|
|
runs:
|
|
using: "composite"
|
|
|
|
steps:
|
|
# We're using some of env variables quite offen, so let's set them once.
|
|
#
|
|
# It would be nice to have them set in common runs.env[0] section, but it doesn't work[1]
|
|
#
|
|
# - [0] https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runsenv
|
|
# - [1] https://github.com/neondatabase/neon/pull/3907#discussion_r1154703456
|
|
#
|
|
- name: Set variables
|
|
shell: bash -euxo pipefail {0}
|
|
run: |
|
|
PR_NUMBER=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH" || true)
|
|
if [ "${PR_NUMBER}" != "null" ]; then
|
|
BRANCH_OR_PR=pr-${PR_NUMBER}
|
|
elif [ "${GITHUB_REF_NAME}" = "main" ] || [ "${GITHUB_REF_NAME}" = "release" ] || \
|
|
[ "${GITHUB_REF_NAME}" = "release-proxy" ] || [ "${GITHUB_REF_NAME}" = "release-compute" ]; then
|
|
# Shortcut for special branches
|
|
BRANCH_OR_PR=${GITHUB_REF_NAME}
|
|
else
|
|
BRANCH_OR_PR=branch-$(printf "${GITHUB_REF_NAME}" | tr -c "[:alnum:]._-" "-")
|
|
fi
|
|
|
|
LOCK_FILE=reports/${BRANCH_OR_PR}/lock.txt
|
|
|
|
WORKDIR=/tmp/${BRANCH_OR_PR}-$(date +%s)
|
|
mkdir -p ${WORKDIR}
|
|
|
|
echo "BRANCH_OR_PR=${BRANCH_OR_PR}" >> $GITHUB_ENV
|
|
echo "LOCK_FILE=${LOCK_FILE}" >> $GITHUB_ENV
|
|
echo "WORKDIR=${WORKDIR}" >> $GITHUB_ENV
|
|
echo "BUCKET=${BUCKET}" >> $GITHUB_ENV
|
|
env:
|
|
BUCKET: neon-github-public-dev
|
|
|
|
# TODO: We can replace with a special docker image with Java and Allure pre-installed
|
|
- uses: actions/setup-java@v4
|
|
with:
|
|
distribution: 'temurin'
|
|
java-version: '17'
|
|
|
|
- name: Install Allure
|
|
shell: bash -euxo pipefail {0}
|
|
run: |
|
|
if ! which allure; then
|
|
ALLURE_ZIP=allure-${ALLURE_VERSION}.zip
|
|
wget -q https://github.com/allure-framework/allure2/releases/download/${ALLURE_VERSION}/${ALLURE_ZIP}
|
|
echo "${ALLURE_ZIP_SHA256} ${ALLURE_ZIP}" | sha256sum --check
|
|
unzip -q ${ALLURE_ZIP}
|
|
echo "$(pwd)/allure-${ALLURE_VERSION}/bin" >> $GITHUB_PATH
|
|
rm -f ${ALLURE_ZIP}
|
|
fi
|
|
env:
|
|
ALLURE_VERSION: 2.27.0
|
|
ALLURE_ZIP_SHA256: b071858fb2fa542c65d8f152c5c40d26267b2dfb74df1f1608a589ecca38e777
|
|
|
|
- uses: aws-actions/configure-aws-credentials@v4
|
|
if: ${{ !cancelled() }}
|
|
with:
|
|
aws-region: eu-central-1
|
|
role-to-assume: ${{ inputs.aws-oicd-role-arn }}
|
|
role-duration-seconds: 3600 # 1 hour should be more than enough to upload report
|
|
|
|
# Potentially we could have several running build for the same key (for example, for the main branch), so we use improvised lock for this
|
|
- name: Acquire lock
|
|
shell: bash -euxo pipefail {0}
|
|
run: |
|
|
LOCK_TIMEOUT=300 # seconds
|
|
|
|
LOCK_CONTENT="${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
|
echo ${LOCK_CONTENT} > ${WORKDIR}/lock.txt
|
|
|
|
# Do it up to 5 times to avoid race condition
|
|
for _ in $(seq 1 5); do
|
|
for i in $(seq 1 ${LOCK_TIMEOUT}); do
|
|
LOCK_ACQUIRED=$(aws s3api head-object --bucket neon-github-public-dev --key ${LOCK_FILE} | jq --raw-output '.LastModified' || true)
|
|
# `date --date="..."` is supported only by gnu date (i.e. it doesn't work on BSD/macOS)
|
|
if [ -z "${LOCK_ACQUIRED}" ] || [ "$(( $(date +%s) - $(date --date="${LOCK_ACQUIRED}" +%s) ))" -gt "${LOCK_TIMEOUT}" ]; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
aws s3 mv --only-show-errors ${WORKDIR}/lock.txt "s3://${BUCKET}/${LOCK_FILE}"
|
|
|
|
# Double-check that exactly THIS run has acquired the lock
|
|
aws s3 cp --only-show-errors "s3://${BUCKET}/${LOCK_FILE}" ./lock.txt
|
|
if [ "$(cat lock.txt)" = "${LOCK_CONTENT}" ]; then
|
|
break
|
|
fi
|
|
done
|
|
|
|
- name: Generate and publish final Allure report
|
|
id: generate-report
|
|
shell: bash -euxo pipefail {0}
|
|
run: |
|
|
REPORT_PREFIX=reports/${BRANCH_OR_PR}
|
|
RAW_PREFIX=reports-raw/${BRANCH_OR_PR}/${GITHUB_RUN_ID}
|
|
|
|
BASE_URL=https://${BUCKET}.s3.amazonaws.com/${REPORT_PREFIX}/${GITHUB_RUN_ID}
|
|
BASE_S3_URL=s3://${BUCKET}/${REPORT_PREFIX}/${GITHUB_RUN_ID}
|
|
REPORT_URL=${BASE_URL}/index.html
|
|
REPORT_JSON_URL=${BASE_URL}/data/suites.json
|
|
|
|
# Get previously uploaded data for this run
|
|
ZSTD_NBTHREADS=0
|
|
|
|
S3_FILEPATHS=$(aws s3api list-objects-v2 --bucket ${BUCKET} --prefix ${RAW_PREFIX}/ | jq --raw-output '.Contents[]?.Key')
|
|
if [ -z "$S3_FILEPATHS" ]; then
|
|
# There's no previously uploaded data for this $GITHUB_RUN_ID
|
|
exit 0
|
|
fi
|
|
|
|
time aws s3 cp --recursive --only-show-errors "s3://${BUCKET}/${RAW_PREFIX}/" "${WORKDIR}/"
|
|
for archive in $(find ${WORKDIR} -name "*.tar.zst"); do
|
|
mkdir -p ${archive%.tar.zst}
|
|
time tar -xf ${archive} -C ${archive%.tar.zst}
|
|
rm -f ${archive}
|
|
done
|
|
|
|
# Get history trend
|
|
time aws s3 cp --recursive --only-show-errors "s3://${BUCKET}/${REPORT_PREFIX}/latest/history" "${WORKDIR}/latest/history" || true
|
|
|
|
# Generate report
|
|
time allure generate --clean --output ${WORKDIR}/report ${WORKDIR}/*
|
|
|
|
# Replace a logo link with a redirect to the latest version of the report
|
|
sed -i 's|<a href="." class=|<a href="https://'${BUCKET}'.s3.amazonaws.com/'${REPORT_PREFIX}'/latest/index.html?nocache='"'+Date.now()+'"'" class=|g' ${WORKDIR}/report/app.js
|
|
|
|
# Upload a history and the final report (in this particular order to not to have duplicated history in 2 places)
|
|
time aws s3 mv --recursive --only-show-errors "${WORKDIR}/report/history" "s3://${BUCKET}/${REPORT_PREFIX}/latest/history"
|
|
|
|
# Use aws s3 cp (instead of aws s3 sync) to keep files from previous runs to make old URLs work,
|
|
# and to keep files on the host to upload them to the database
|
|
time s5cmd --log error cp "${WORKDIR}/report/*" "s3://${BUCKET}/${REPORT_PREFIX}/${GITHUB_RUN_ID}/"
|
|
|
|
# Generate redirect
|
|
cat <<EOF > ${WORKDIR}/index.html
|
|
<!DOCTYPE html>
|
|
|
|
<meta charset="utf-8">
|
|
<title>Redirecting to ${REPORT_URL}</title>
|
|
<meta http-equiv="refresh" content="0; URL=${REPORT_URL}">
|
|
EOF
|
|
time aws s3 cp --only-show-errors ${WORKDIR}/index.html "s3://${BUCKET}/${REPORT_PREFIX}/latest/index.html"
|
|
|
|
echo "base-url=${BASE_URL}" >> $GITHUB_OUTPUT
|
|
echo "base-s3-url=${BASE_S3_URL}" >> $GITHUB_OUTPUT
|
|
echo "report-url=${REPORT_URL}" >> $GITHUB_OUTPUT
|
|
echo "report-json-url=${REPORT_JSON_URL}" >> $GITHUB_OUTPUT
|
|
|
|
echo "[Allure Report](${REPORT_URL})" >> ${GITHUB_STEP_SUMMARY}
|
|
|
|
- name: Release lock
|
|
if: always()
|
|
shell: bash -euxo pipefail {0}
|
|
run: |
|
|
aws s3 cp --only-show-errors "s3://${BUCKET}/${LOCK_FILE}" ./lock.txt || exit 0
|
|
|
|
if [ "$(cat lock.txt)" = "${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" ]; then
|
|
aws s3 rm "s3://${BUCKET}/${LOCK_FILE}"
|
|
fi
|
|
|
|
- name: Cache poetry deps
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.cache/pypoetry/virtualenvs
|
|
key: v2-${{ runner.os }}-${{ runner.arch }}-python-deps-bookworm-${{ hashFiles('poetry.lock') }}
|
|
|
|
- name: Store Allure test stat in the DB (new)
|
|
if: ${{ !cancelled() && inputs.store-test-results-into-db == 'true' }}
|
|
shell: bash -euxo pipefail {0}
|
|
env:
|
|
COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
BASE_S3_URL: ${{ steps.generate-report.outputs.base-s3-url }}
|
|
run: |
|
|
if [ ! -d "${WORKDIR}/report/data/test-cases" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
export DATABASE_URL=${REGRESS_TEST_RESULT_CONNSTR_NEW}
|
|
|
|
./scripts/pysync
|
|
|
|
poetry run python3 scripts/ingest_regress_test_result-new-format.py \
|
|
--reference ${GITHUB_REF} \
|
|
--revision ${COMMIT_SHA} \
|
|
--run-id ${GITHUB_RUN_ID} \
|
|
--run-attempt ${GITHUB_RUN_ATTEMPT} \
|
|
--test-cases-dir ${WORKDIR}/report/data/test-cases
|
|
|
|
- name: Cleanup
|
|
if: always()
|
|
shell: bash -euxo pipefail {0}
|
|
run: |
|
|
if [ -d "${WORKDIR}" ]; then
|
|
rm -rf ${WORKDIR}
|
|
fi
|
|
|
|
- uses: actions/github-script@v7
|
|
if: always()
|
|
env:
|
|
REPORT_URL: ${{ steps.generate-report.outputs.report-url }}
|
|
COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
with:
|
|
# Retry script for 5XX server errors: https://github.com/actions/github-script#retries
|
|
retries: 5
|
|
script: |
|
|
const { REPORT_URL, COMMIT_SHA } = process.env
|
|
|
|
await github.rest.repos.createCommitStatus({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
sha: `${COMMIT_SHA}`,
|
|
state: 'success',
|
|
target_url: `${REPORT_URL}`,
|
|
context: 'Allure report',
|
|
})
|