fix(ci): Make perf-report job safer and more robust

- Add input validation for tag format
- Check for required tools (curl, jq, bc)
- Skip if report already exists (idempotent)
- Add colored logging for better visibility
- Handle push failures gracefully
- Use 'rules' instead of 'only' for modern GitLab CI
- Add GIT_DEPTH: 0 for full history access
This commit is contained in:
russell@unturf.com 2026-01-18 14:12:53 -05:00
parent 88a3a6718c
commit 9ecc93a75f
2 changed files with 96 additions and 21 deletions

View file

@ -235,28 +235,67 @@ perf-report:
stage: report
needs:
- trigger-test-matrix
variables:
GIT_STRATEGY: clone
GIT_DEPTH: 0
script:
- echo "Generating performance report for $CI_COMMIT_TAG..."
- bash scripts/generate-perf-report.sh "$CI_COMMIT_TAG"
- echo "========================================"
- echo "Performance Report Generator"
- echo "Tag: $CI_COMMIT_TAG"
- echo "========================================"
- |
echo "Generating performance charts..."
build/un -a -f "reports/$CI_COMMIT_TAG/perf.json" scripts/generate-perf-charts.py || echo "Charts generation requires unsandbox"
mv -f *.png "reports/$CI_COMMIT_TAG/" 2>/dev/null || true
- ls -la "reports/$CI_COMMIT_TAG/"
# Validate tag format
if ! echo "$CI_COMMIT_TAG" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "ERROR: Invalid tag format: $CI_COMMIT_TAG"
exit 1
fi
- |
echo "Committing performance report to main..."
git config user.email "ci@unturf.com"
git config user.name "GitLab CI"
git remote set-url origin "https://gitlab-ci-token:${CI_JOB_TOKEN}@git.unturf.com/${CI_PROJECT_PATH}.git"
git fetch origin main
git checkout main
git add reports/
git commit -m "perf: Add performance report for $CI_COMMIT_TAG" || echo "No changes to commit"
git push origin main || echo "Push failed - may need deploy key"
# Generate performance report (fetches CI timing data)
echo "Step 1: Generating performance report..."
bash scripts/generate-perf-report.sh "$CI_COMMIT_TAG" || {
echo "WARN: Report generation failed, continuing..."
}
- |
# Generate charts via unsandbox (optional - may fail without API keys)
echo "Step 2: Generating performance charts..."
if [ -f "reports/$CI_COMMIT_TAG/perf.json" ]; then
build/un -a -f "reports/$CI_COMMIT_TAG/perf.json" scripts/generate-perf-charts.py && \
mv -f *.png "reports/$CI_COMMIT_TAG/" 2>/dev/null || \
echo "WARN: Chart generation skipped (unsandbox unavailable)"
else
echo "WARN: No perf.json found, skipping charts"
fi
- |
# Show what was generated
echo "Step 3: Report contents..."
ls -la "reports/$CI_COMMIT_TAG/" 2>/dev/null || echo "No report directory"
- |
# Commit back to main (requires write access)
echo "Step 4: Committing to main..."
if [ -d "reports/$CI_COMMIT_TAG" ]; then
git config user.email "ci@unturf.com"
git config user.name "GitLab CI"
git remote set-url origin "https://gitlab-ci-token:${CI_JOB_TOKEN}@git.unturf.com/${CI_PROJECT_PATH}.git"
git fetch origin main
git checkout main
git pull origin main
git add reports/
git diff --cached --quiet || {
git commit -m "perf: Add performance report for $CI_COMMIT_TAG
Generated automatically by CI after tagged release.
Pipeline: $CI_PIPELINE_URL"
git push origin main && echo "SUCCESS: Report committed to main" || \
echo "WARN: Push failed - CI_JOB_TOKEN may lack write access"
}
else
echo "WARN: No report to commit"
fi
artifacts:
paths:
- reports/
expire_in: 90 days
only:
- /^\d+\.\d+\.\d+$/
when: always
rules:
- if: '$CI_COMMIT_TAG =~ /^\d+\.\d+\.\d+$/'
allow_failure: true

View file

@ -5,10 +5,22 @@
# Usage: scripts/generate-perf-report.sh [TAG]
# Example: scripts/generate-perf-report.sh 4.2.0
#
# Output: reports/perf-{TAG}.md and reports/perf-{TAG}.json
# Output: reports/{TAG}/perf.json and reports/{TAG}/perf.md
#
# Safe for automation - idempotent and validates inputs
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
TAG="${1:-}"
GITLAB_URL="https://git.unturf.com"
PROJECT_PATH="engineering/unturf/un-inception"
@ -17,19 +29,43 @@ if [ -z "$TAG" ]; then
# Default to current VERSION
if [ -f VERSION ]; then
TAG=$(cat VERSION)
log_info "Using version from VERSION file: $TAG"
else
echo "Usage: $0 <tag>"
log_error "Usage: $0 <tag>"
echo "Example: $0 4.2.0"
exit 1
fi
fi
echo "Generating performance report for tag: $TAG"
# Validate tag format
if ! echo "$TAG" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
log_error "Invalid tag format: $TAG (expected X.Y.Z)"
exit 1
fi
# Check for required tools
for cmd in curl jq bc; do
if ! command -v $cmd &> /dev/null; then
log_error "Required command not found: $cmd"
exit 1
fi
done
log_info "Generating performance report for tag: $TAG"
# Create versioned reports directory
REPORT_DIR="reports/$TAG"
mkdir -p "$REPORT_DIR"
echo "Output directory: $REPORT_DIR"
log_info "Output directory: $REPORT_DIR"
# Check if report already exists (idempotent - skip if complete)
if [ -f "$REPORT_DIR/perf.json" ] && [ -f "$REPORT_DIR/perf.md" ]; then
log_warn "Report already exists for $TAG"
log_info "To regenerate, delete: rm -rf $REPORT_DIR"
echo ""
ls -la "$REPORT_DIR/"
exit 0
fi
# Find pipeline for this tag (prefer passing pipelines)
echo "Finding pipeline for tag $TAG..."