#!/bin/bash # Exit on any error set -e # Get the number of shards (default to 10 if not provided) NUM_SHARDS=${1:-10} # Convert to 0-based index for internal calculations SHARD_INDEX_ZERO_BASED=$((${2:-1} - 1)) SHARD_INDEX=${2:-1} # Keep original 1-based index for output # Directory containing feature files FEATURES_DIR="fineract-e2e-tests-runner/src/test/resources/features" TEMP_FILE="/tmp/feature_scenarios_$(date +%s).txt" # Check if features directory exists if [ ! -d "$FEATURES_DIR" ]; then echo "Error: Features directory not found at $FEATURES_DIR" exit 1 fi # Function to count scenarios in a feature file count_scenarios() { local file="$1" # Count scenario and scenario outline keywords, excluding commented lines grep -v '^[[:space:]]*#' "$file" | grep -c 'Scenario\( Outline\)\?:' || echo "0" } # Process each feature file and count scenarios echo "Analyzing feature files to count scenarios..." > "$TEMP_FILE" while IFS= read -r -d $'\0' file; do # Remove the 'fineract-e2e-tests-runner/' prefix rel_path="${file#fineract-e2e-tests-runner/}" scenario_count=$(count_scenarios "$file") echo "$scenario_count $rel_path" done < <(find "$FEATURES_DIR" -type f -name '*.feature' -print0) | sort -nr > "$TEMP_FILE" # Read the sorted list of features SORTED_FEATURES=() while IFS= read -r line; do # Extract just the file path (removing the scenario count) path=$(echo "$line" | awk '{$1=""; print $0}' | sed 's/^ //') [ -n "$path" ] && SORTED_FEATURES+=("$path") done < "$TEMP_FILE" TOTAL_FEATURES=${#SORTED_FEATURES[@]} # Check if any feature files were found if [ $TOTAL_FEATURES -eq 0 ]; then echo "Warning: No feature files found in $FEATURES_DIR" # Create an empty feature list file FEATURE_LIST_FILE="feature_shard_${SHARD_INDEX}.txt" > "$FEATURE_LIST_FILE" echo "Created empty feature list file: $FEATURE_LIST_FILE" rm -f "$TEMP_FILE" exit 0 fi # Create a file to store the feature file paths # Use the 1-based index for the filename FEATURE_LIST_FILE="feature_shard_${SHARD_INDEX}.txt" > "$FEATURE_LIST_FILE" # First, distribute features to shards in a round-robin fashion to balance scenario counts for ((i=0; i> "$FEATURE_LIST_FILE.tmp" fi done # Sort the feature files in this shard by name (with 0_* files first) # First, extract just the filenames and prepend a sort key while IFS= read -r line; do # Get just the filename part filename=$(basename "$line") # Create a sort key: 0 for files starting with 0_, 1 otherwise if [[ "$filename" == 0_* ]]; then sort_key="0_$filename" else sort_key="1_$filename" fi echo "$sort_key|$line" done < "$FEATURE_LIST_FILE.tmp" | \ # Sort by the sort key and filename sort -t'|' -k1,1 -k2,2 | \ # Remove the sort key cut -d'|' -f2- > "$FEATURE_LIST_FILE" # Clean up temporary file rm -f "$FEATURE_LIST_FILE.tmp" # Count scenarios in this shard SHARD_SCENARIOS=0 while IFS= read -r line; do [ -z "$line" ] && continue count=$(grep -m 1 -F "$line" "$TEMP_FILE" | awk '{print $1}') SHARD_SCENARIOS=$((SHARD_SCENARIOS + count)) done < "$FEATURE_LIST_FILE" # Get the list of features in this shard for output SHARD_FEATURES=() while IFS= read -r line; do [ -n "$line" ] && SHARD_FEATURES+=("$line") done < "$FEATURE_LIST_FILE" NUM_FEATURES=${#SHARD_FEATURES[@]} # Output the shard information echo "Shard $SHARD_INDEX (1-based): $NUM_FEATURES features with $SHARD_SCENARIOS total scenarios" if [ $NUM_FEATURES -gt 0 ]; then echo "First feature: ${SHARD_FEATURES[0]}" if [ $NUM_FEATURES -gt 1 ]; then echo "Last feature: ${SHARD_FEATURES[$((NUM_FEATURES-1))]}" fi echo "Features in this shard (scenario count):" while IFS= read -r line; do [ -z "$line" ] && continue count=$(grep -m 1 -F "$line" "$TEMP_FILE" | awk '{print $1}') echo " - $line ($count scenarios)" done < "$FEATURE_LIST_FILE" fi echo "Feature list written to $FEATURE_LIST_FILE" # Clean up temp file rm -f "$TEMP_FILE" # Set output for GitHub Actions if [ -n "$GITHUB_OUTPUT" ]; then echo "FEATURE_LIST_FILE=$FEATURE_LIST_FILE" >> $GITHUB_OUTPUT fi