#!/bin/bash # CI script to update coverage badge in README.md # Usage: scripts/ci-update-coverage-badge.sh [badge_type] [flags] # badge_type can be "bdd", "unit", or empty for combined coverage # flags: --no-commit (skip git commit), --no-push (skip git push) set -e if [ -z "$1" ]; then echo "Error: Coverage percentage not provided" exit 1 fi COVERAGE=$1 BADGE_TYPE=${2:-"combined"} # Parse flags NO_COMMIT=false NO_PUSH=false for arg in "$@"; do if [ "$arg" = "--no-commit" ]; then NO_COMMIT=true elif [ "$arg" = "--no-push" ]; then NO_PUSH=true fi done # Determine badge color if (( $(echo "$COVERAGE >= 80" | bc -l) )); then COLOR="brightgreen" elif (( $(echo "$COVERAGE >= 50" | bc -l) )); then COLOR="yellow" else COLOR="red" fi # Create different badge URLs and markdown format based on type if [ "$BADGE_TYPE" = "bdd" ]; then BADGE_URL="https://img.shields.io/badge/BDD_Coverage-${COVERAGE}%-${COLOR}?style=flat-square" BADGE_MARKDOWN="[![BDD Coverage](${BADGE_URL})](https://gitea.arcodange.lab/arcodange/dance-lessons-coach)" SEARCH_PATTERN="BDD_Coverage-.*-.*?style=flat-square" elif [ "$BADGE_TYPE" = "unit" ]; then BADGE_URL="https://img.shields.io/badge/Unit_Coverage-${COVERAGE}%-${COLOR}?style=flat-square" BADGE_MARKDOWN="[![Unit Coverage](${BADGE_URL})](https://gitea.arcodange.lab/arcodange/dance-lessons-coach)" SEARCH_PATTERN="Unit_Coverage-.*-.*?style=flat-square" else BADGE_URL="https://img.shields.io/badge/coverage-${COVERAGE}%-${COLOR}?style=flat-square" BADGE_MARKDOWN="[![Coverage](${BADGE_URL})](https://gitea.arcodange.lab/arcodange/dance-lessons-coach)" SEARCH_PATTERN="coverage-.*-.*?style=flat-square" fi # Clean up any malformed badge lines from previous runs # Remove lines starting with "nhttps://" or "https://" that aren't proper markdown sed -i.bak '/^nhttps:\/\/.*img.shields.io.*Coverage/d' README.md 2>/dev/null || true sed -i.bak '/^https:\/\/.*img.shields.io.*Coverage/d' README.md 2>/dev/null || true # Remove old duplicate badges for the specific type being updated if [ "$BADGE_TYPE" = "bdd" ] || [ "$BADGE_TYPE" = "unit" ]; then # Remove all existing badges of this type before adding new one sed -i.bak "/${BADGE_TYPE}_Coverage/d" README.md 2>/dev/null || true fi rm -f README.md.bak # Only update if coverage has actually changed if grep -q "${BADGE_TYPE}_Coverage-${COVERAGE}%" README.md || grep -q "coverage-${COVERAGE}%" README.md; then echo "Coverage badge already up to date at ${COVERAGE}%" exit 0 fi # Also check if badge already exists with this coverage (more flexible pattern) if [ "$BADGE_TYPE" = "bdd" ] || [ "$BADGE_TYPE" = "unit" ]; then # Capitalize first letter for badge name if [ "$BADGE_TYPE" = "unit" ]; then BADGE_NAME="Unit" else BADGE_NAME="BDD" fi if grep -q "\[!\[${BADGE_NAME} Coverage\].*${COVERAGE}%" README.md; then echo "Coverage badge already exists at ${COVERAGE}%" exit 0 fi fi # Cross-platform sed command # Detect if we're on macOS (BSD sed) or Linux (GNU sed) SED_CMD="" if [[ "$(uname)" == "Darwin" ]]; then # macOS - requires empty string after -i SED_CMD="sed -i ''" else # Linux - standard GNU sed SED_CMD="sed -i" fi # Update README - handle both old and new badge formats if [ "$BADGE_TYPE" = "bdd" ] || [ "$BADGE_TYPE" = "unit" ]; then # For BDD/Unit badges, add them if they don't exist, or update if they do if grep -q "${BADGE_TYPE}_Coverage" README.md; then # Update existing badge with proper markdown format $SED_CMD "s|^\[!\[${BADGE_TYPE} Coverage\].*|"${BADGE_MARKDOWN}"|" README.md else # Add new badge line after the License badge (more reliable reference) # Use a more reliable approach with temporary file for cross-platform compatibility TEMP_FILE=$(mktemp) awk -v new_badge="${BADGE_MARKDOWN}" '{ if ($0 ~ /\[!\[License\].*license-MIT-green/) { print $0 print new_badge } else { print $0 } }' README.md > "$TEMP_FILE" mv "$TEMP_FILE" README.md fi else # For combined coverage, use the original logic $SED_CMD "s|^\[!\[Coverage\].*|"${BADGE_MARKDOWN}"|" README.md fi # Set up git git config --global user.name "CI Bot" git config --global user.email "ci@arcodange.fr" # Set up credentials using Gitea token if [ -n "$PACKAGES_TOKEN" ]; then git config --global credential.helper store echo "https://${PACKAGES_TOKEN}@gitea.arcodange.lab" > ~/.git-credentials fi git add README.md # Skip commit if --no-commit flag is set if [ "$NO_COMMIT" = true ]; then echo "Skipping git commit due to --no-commit flag" echo "Coverage badge updated to ${COVERAGE}% in README.md (not committed)" exit 0 fi if git commit -m "🤖 chore: update coverage badge to ${COVERAGE}% [skip ci]"; then # Skip push if --no-push flag is set if [ "$NO_PUSH" = true ]; then echo "Skipping git push due to --no-push flag" echo "Coverage badge updated to ${COVERAGE}% and committed locally" exit 0 fi # Try push with retry logic for race conditions for i in 1 2 3; do if git push; then echo "Successfully updated coverage badge to ${COVERAGE}%" # Update local repo to the new HEAD after successful push git fetch origin git reset --hard origin/${GITHUB_REF_NAME:-${CI_COMMIT_REF_NAME:-main}} exit 0 else echo "Push attempt $i failed, retrying..." if [ $i -eq 3 ]; then echo "Final push attempt failed - another job may have updated the badge" git pull --rebase || true git push || echo "Recovery push also failed" # Ensure we're on the latest commit even if push failed git fetch origin git reset --hard origin/${GITHUB_REF_NAME:-${CI_COMMIT_REF_NAME:-main}} fi sleep 2 fi done else echo "No coverage change to commit" fi