From eb3dd5bb27734a6e9428840a1045abd3061b4eae Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets <70503964+oleksiikolomiietssnapp@users.noreply.github.com> Date: Tue, 25 Feb 2025 08:49:44 +0100 Subject: [PATCH 01/13] Create run_tests.yml --- .github/workflows/run_tests.yml | 79 +++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .github/workflows/run_tests.yml diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml new file mode 100644 index 0000000..9e90855 --- /dev/null +++ b/.github/workflows/run_tests.yml @@ -0,0 +1,79 @@ +# This workflow will test a Swift project + # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift + + name: Package Test + env: + DESTINATION: 'platform=macOS,variant=Mac Catalyst,name=My Mac' + SCHEME: 'SnappThemingSVGSupport' + WORKSPACE_PATH: '.swiftpm/xcode/package.xcworkspace' + COVERAGE_REPORT_PATH: './coverage/coverage.xcresult' + on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + + jobs: + build: + + runs-on: macos-latest + + steps: + - uses: actions/checkout@v4 + - name: List Xcode installations + run: sudo ls -1 /Applications | grep "Xcode" + - name: Select Xcode 16.2 + run: sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer + + - name: Run Swift Tests with Coverage + run: | + swift test --enable-swift-testing --enable-code-coverage + CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) + echo $CODECOV_PATH + + - name: Run Coverage Extraction Script + run: bash .github/scripts/extract_coverage.sh + + - name: Comment on Pull Request + if: github.event_name == 'pull_request' + uses: actions/github-script@v6 + with: + script: | + const fs = require('fs'); + const coverageOutput = fs.readFileSync('pr_coverage_summary.txt', 'utf8'); + + const newComment = ` + ### 🛡️ Code Coverage Report + + ${coverageOutput} + + _Generated by GitHub Actions._ + `; + + // Fetch existing comments + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + }); + + // Identify and delete previous bot comments + const botComments = comments.data.filter(comment => + comment.body.includes("### 🛡️ Code Coverage Report") + ); + + for (const botComment of botComments) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + }); + } + + // Create a comment on the pull request + await github.rest.issues.createComment({ + issue_number: context.payload.pull_request.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: newComment, + }); From fa09db897e73e2b0e20f38b0cc70b0e81b5bce70 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 08:53:59 +0100 Subject: [PATCH 02/13] add extract_coverage.sh --- .github/scripts/extract_coverage.sh | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/scripts/extract_coverage.sh diff --git a/.github/scripts/extract_coverage.sh b/.github/scripts/extract_coverage.sh new file mode 100644 index 0000000..d945845 --- /dev/null +++ b/.github/scripts/extract_coverage.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) + +# Extract all line coverage data for files containing 'SnappTheming/Sources' +FILES_LINE_COUNTS=$(jq -r '.data[0].files[] | select(.filename | contains("SnappThemingSVGSupport/Sources")) | .summary.lines' "$CODECOV_PATH") + +total_lines=0 +covered_lines=0 + +# Loop through each file's line count data (FILES_LINE_COUNTS) +for lines_data in $(echo "$FILES_LINE_COUNTS" | jq -c '.'); do + # Extract total and covered lines for each file + total=$(echo "$lines_data" | jq '.count') + covered=$(echo "$lines_data" | jq '.covered') + + # Add to the total lines and covered lines + total_lines=$((total_lines + total)) + covered_lines=$((covered_lines + covered)) +done + +# Calculate the average line coverage percentage +if [ $total_lines -gt 0 ]; then + average_coverage=$(echo "scale=6; $covered_lines * 100 / $total_lines" | bc) # Keep 6 decimal places +else + average_coverage=0 +fi + +average_coverage_rounded=$(echo "$average_coverage" | awk '{print int($1 * 100 + 0.5) / 100}') +average_coverage_with_percentage="${average_coverage_rounded}%" + +# Save to pr_coverage_summary.txt +cat < pr_coverage_summary.txt +| ID | Name | Executable Lines | Coverage | +|----|------|-----------------:|---------:| +| 0 | SnappTheming | $total_lines | **$average_coverage_with_percentage** | +EOF From 60864ea706036ca13026673c04438e466d1c4175 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:06:13 +0100 Subject: [PATCH 03/13] update script and add test plan --- .github/workflows/run_tests.yml | 27 +++++++++++++++----------- SnappThemingSVGSupport.xctestplan | 32 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 SnappThemingSVGSupport.xctestplan diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 9e90855..b4797d7 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -3,10 +3,13 @@ name: Package Test env: - DESTINATION: 'platform=macOS,variant=Mac Catalyst,name=My Mac' - SCHEME: 'SnappThemingSVGSupport' - WORKSPACE_PATH: '.swiftpm/xcode/package.xcworkspace' + EXTRACT_COVERAGE: '.github/scripts/extract_coverage.sh' COVERAGE_REPORT_PATH: './coverage/coverage.xcresult' + XCODE_VERSION: 'Xcode_16.2.app' + XCODE_PATH: '/Applications/Xcode_16.2.app/Contents/Developer' + COVERAGE_SUMMARY_FILE: 'pr_coverage_summary.txt' + BOT_COMMENT_HEADER: '### 🛡️ Code Coverage Report' + on: push: branches: [ "main" ] @@ -20,19 +23,21 @@ steps: - uses: actions/checkout@v4 - - name: List Xcode installations + + - name: List Xcode Installations run: sudo ls -1 /Applications | grep "Xcode" - - name: Select Xcode 16.2 - run: sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer + + - name: Select Xcode + run: sudo xcode-select -s ${{ env.XCODE_PATH }} - name: Run Swift Tests with Coverage run: | swift test --enable-swift-testing --enable-code-coverage CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) - echo $CODECOV_PATH + echo "CODECOV_PATH=${CODECOV_PATH}" >> $GITHUB_ENV - name: Run Coverage Extraction Script - run: bash .github/scripts/extract_coverage.sh + run: bash ${{ env.EXTRACT_COVERAGE }} - name: Comment on Pull Request if: github.event_name == 'pull_request' @@ -40,10 +45,10 @@ with: script: | const fs = require('fs'); - const coverageOutput = fs.readFileSync('pr_coverage_summary.txt', 'utf8'); + const coverageOutput = fs.readFileSync('${{ env.COVERAGE_SUMMARY_FILE }}', 'utf8'); const newComment = ` - ### 🛡️ Code Coverage Report + ${{ env.BOT_COMMENT_HEADER }} ${coverageOutput} @@ -59,7 +64,7 @@ // Identify and delete previous bot comments const botComments = comments.data.filter(comment => - comment.body.includes("### 🛡️ Code Coverage Report") + comment.body.includes("${{ env.BOT_COMMENT_HEADER }}") ); for (const botComment of botComments) { diff --git a/SnappThemingSVGSupport.xctestplan b/SnappThemingSVGSupport.xctestplan new file mode 100644 index 0000000..5dc1df6 --- /dev/null +++ b/SnappThemingSVGSupport.xctestplan @@ -0,0 +1,32 @@ +{ + "configurations" : [ + { + "id" : "A7A2AE7E-6FA3-49EF-A068-BB0BC519E557", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + "codeCoverage" : { + "targets" : [ + { + "containerPath" : "container:", + "identifier" : "SnappThemingSVGSupport", + "name" : "SnappThemingSVGSupport" + } + ] + } + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:", + "identifier" : "SnappThemingSVGSupportTests", + "name" : "SnappThemingSVGSupportTests" + } + } + ], + "version" : 1 +} From 273258d6b88e62fa6a25d181e36ed48951c9d1d6 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:12:53 +0100 Subject: [PATCH 04/13] improve extract_coverage.sh --- .github/scripts/extract_coverage.sh | 58 ++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/.github/scripts/extract_coverage.sh b/.github/scripts/extract_coverage.sh index d945845..5dc3f6d 100644 --- a/.github/scripts/extract_coverage.sh +++ b/.github/scripts/extract_coverage.sh @@ -1,37 +1,69 @@ #!/bin/bash +set -e # Exit immediately if a command exits with a non-zero status +set -u # Treat unset variables as an error and exit immediately +# Define environment variables +PACKAGE_NAME="SnappThemingSVGSupport" +SOURCE_PATH="$PACKAGE_NAME/Sources" +OUTPUT_FILE="pr_coverage_summary.txt" +DECIMAL_PRECISION=6 +DISPLAY_PRECISION=2 + +# Get the path to the coverage report CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) +echo "Using coverage report at: $CODECOV_PATH" -# Extract all line coverage data for files containing 'SnappTheming/Sources' -FILES_LINE_COUNTS=$(jq -r '.data[0].files[] | select(.filename | contains("SnappThemingSVGSupport/Sources")) | .summary.lines' "$CODECOV_PATH") +# Extract all line coverage data for files containing the specified source path +# Use a temporary file for the extracted data to avoid command substitution issues +TMP_DATA_FILE=$(mktemp) +jq -r --arg source_path "$SOURCE_PATH" '.data[0].files[] | select(.filename | contains($source_path)) | .summary.lines' "$CODECOV_PATH" > "$TMP_DATA_FILE" total_lines=0 covered_lines=0 -# Loop through each file's line count data (FILES_LINE_COUNTS) -for lines_data in $(echo "$FILES_LINE_COUNTS" | jq -c '.'); do - # Extract total and covered lines for each file - total=$(echo "$lines_data" | jq '.count') - covered=$(echo "$lines_data" | jq '.covered') +# Process each line of the data file +while IFS= read -r line_data || [[ -n "$line_data" ]]; do + # Skip empty lines + [[ -z "$line_data" ]] && continue + + # Extract total and covered lines + total=$(echo "$line_data" | jq -r '.count') + covered=$(echo "$line_data" | jq -r '.covered') + + # Validate numbers before adding them + if ! [[ "$total" =~ ^[0-9]+$ ]] || ! [[ "$covered" =~ ^[0-9]+$ ]]; then + echo "Error: Invalid line count data found" + exit 1 + fi # Add to the total lines and covered lines total_lines=$((total_lines + total)) covered_lines=$((covered_lines + covered)) -done +done < "$TMP_DATA_FILE" # Calculate the average line coverage percentage if [ $total_lines -gt 0 ]; then - average_coverage=$(echo "scale=6; $covered_lines * 100 / $total_lines" | bc) # Keep 6 decimal places + average_coverage=$(bc <<< "scale=$DECIMAL_PRECISION; $covered_lines * 100 / $total_lines") else average_coverage=0 fi -average_coverage_rounded=$(echo "$average_coverage" | awk '{print int($1 * 100 + 0.5) / 100}') +# Format the coverage percentage with proper rounding +average_coverage_rounded=$(printf "%.*f" $DISPLAY_PRECISION "$average_coverage") average_coverage_with_percentage="${average_coverage_rounded}%" -# Save to pr_coverage_summary.txt -cat < pr_coverage_summary.txt +echo "Total executable lines: $total_lines" +echo "Covered lines: $covered_lines" +echo "Coverage: $average_coverage_with_percentage" + +# Save to output file +cat > "$OUTPUT_FILE" << EOF | ID | Name | Executable Lines | Coverage | |----|------|-----------------:|---------:| -| 0 | SnappTheming | $total_lines | **$average_coverage_with_percentage** | +| 0 | ${PACKAGE_NAME%SVGSupport} | $total_lines | **$average_coverage_with_percentage** | EOF + +echo "Coverage summary saved to $OUTPUT_FILE" + +# Clean up temporary files +rm -f "$TMP_DATA_FILE" From 49e66999da9535695f11a7b803004e7b40e3cc9a Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:16:08 +0100 Subject: [PATCH 05/13] update extract_coverage.sh --- .github/scripts/extract_coverage.sh | 62 ++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/.github/scripts/extract_coverage.sh b/.github/scripts/extract_coverage.sh index 5dc3f6d..f5fa3c2 100644 --- a/.github/scripts/extract_coverage.sh +++ b/.github/scripts/extract_coverage.sh @@ -13,10 +13,62 @@ DISPLAY_PRECISION=2 CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) echo "Using coverage report at: $CODECOV_PATH" +# Check if the file exists +if [ ! -f "$CODECOV_PATH" ]; then + echo "Error: Coverage report not found at $CODECOV_PATH" + exit 1 +fi + +# Check if the file is a valid JSON file +if ! jq empty "$CODECOV_PATH" 2>/dev/null; then + echo "Error: Invalid JSON format in $CODECOV_PATH" + echo "First 100 bytes of file content:" + head -c 100 "$CODECOV_PATH" | hexdump -C + + # Create a minimal coverage report + cat > "$OUTPUT_FILE" << EOF +| ID | Name | Executable Lines | Coverage | +|----|------|-----------------:|---------:| +| 0 | ${PACKAGE_NAME%SVGSupport} | 0 | **0.00%** | +EOF + echo "Created a minimal coverage report due to JSON parsing failure" + exit 0 +fi + # Extract all line coverage data for files containing the specified source path # Use a temporary file for the extracted data to avoid command substitution issues TMP_DATA_FILE=$(mktemp) -jq -r --arg source_path "$SOURCE_PATH" '.data[0].files[] | select(.filename | contains($source_path)) | .summary.lines' "$CODECOV_PATH" > "$TMP_DATA_FILE" +jq -r --arg source_path "$SOURCE_PATH" '.data[0].files[] | select(.filename | contains($source_path)) | .summary.lines' "$CODECOV_PATH" > "$TMP_DATA_FILE" || { + echo "Error: Failed to extract coverage data" + echo "JSON structure may be different than expected" + + # Create a minimal coverage report + cat > "$OUTPUT_FILE" << EOF +| ID | Name | Executable Lines | Coverage | +|----|------|-----------------:|---------:| +| 0 | ${PACKAGE_NAME%SVGSupport} | 0 | **0.00%** | +EOF + echo "Created a minimal coverage report due to data extraction failure" + # Clean up temporary file + rm -f "$TMP_DATA_FILE" + exit 0 +} + +# Check if we actually got any data +if [ ! -s "$TMP_DATA_FILE" ]; then + echo "Warning: No coverage data found for files in $SOURCE_PATH" + + # Create a minimal coverage report + cat > "$OUTPUT_FILE" << EOF +| ID | Name | Executable Lines | Coverage | +|----|------|-----------------:|---------:| +| 0 | ${PACKAGE_NAME%SVGSupport} | 0 | **0.00%** | +EOF + echo "Created a minimal coverage report with 0% coverage" + # Clean up temporary file + rm -f "$TMP_DATA_FILE" + exit 0 +fi total_lines=0 covered_lines=0 @@ -27,13 +79,13 @@ while IFS= read -r line_data || [[ -n "$line_data" ]]; do [[ -z "$line_data" ]] && continue # Extract total and covered lines - total=$(echo "$line_data" | jq -r '.count') - covered=$(echo "$line_data" | jq -r '.covered') + total=$(echo "$line_data" | jq -r '.count' 2>/dev/null) + covered=$(echo "$line_data" | jq -r '.covered' 2>/dev/null) # Validate numbers before adding them if ! [[ "$total" =~ ^[0-9]+$ ]] || ! [[ "$covered" =~ ^[0-9]+$ ]]; then - echo "Error: Invalid line count data found" - exit 1 + echo "Warning: Invalid line count data found, skipping: $line_data" + continue fi # Add to the total lines and covered lines From 5627abfec64600245d8ef45c9886c96b61a70ff0 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:20:18 +0100 Subject: [PATCH 06/13] update extract_coverage.sh --- .github/scripts/extract_coverage.sh | 290 ++++++++++++++++++++++------ 1 file changed, 226 insertions(+), 64 deletions(-) diff --git a/.github/scripts/extract_coverage.sh b/.github/scripts/extract_coverage.sh index f5fa3c2..d375c52 100644 --- a/.github/scripts/extract_coverage.sh +++ b/.github/scripts/extract_coverage.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -e # Exit immediately if a command exits with a non-zero status -set -u # Treat unset variables as an error and exit immediately +# Turn off automatic exit on error for more controlled debugging +set -u # Treat unset variables as an error # Define environment variables PACKAGE_NAME="SnappThemingSVGSupport" @@ -8,98 +8,254 @@ SOURCE_PATH="$PACKAGE_NAME/Sources" OUTPUT_FILE="pr_coverage_summary.txt" DECIMAL_PRECISION=6 DISPLAY_PRECISION=2 +DEBUG_LOG="coverage_debug.log" -# Get the path to the coverage report -CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) +# Start debug log +{ + echo "====== DEBUG LOG ======" + echo "Date: $(date)" + echo "Script started" + echo "Package: $PACKAGE_NAME" + echo "Source path: $SOURCE_PATH" + echo "Environment variables:" + env | sort + echo "Current directory: $(pwd)" + echo "Directory contents:" + ls -la + echo "========================" +} > "$DEBUG_LOG" + +# Function to log debug information +log_debug() { + echo "$(date +%H:%M:%S) - $1" >> "$DEBUG_LOG" +} + +# Function to examine a file +examine_file() { + local file="$1" + log_debug "Examining file: $file" + + if [ -f "$file" ]; then + log_debug "File exists and size is: $(wc -c < "$file") bytes" + log_debug "File type: $(file -b "$file")" + log_debug "First 500 bytes:" + head -c 500 "$file" | hexdump -C >> "$DEBUG_LOG" + log_debug "File stats: $(stat "$file" 2>/dev/null || ls -la "$file")" + else + log_debug "File does not exist" + fi +} + +# Create a fallback coverage report +create_fallback_report() { + local reason="$1" + log_debug "Creating fallback report due to: $reason" + + cat > "$OUTPUT_FILE" << EOF + | ID | Name | Executable Lines | Coverage | + |----|------|-----------------:|---------:| + | 0 | ${PACKAGE_NAME%SVGSupport} | 0 | **0.00%** | + EOF + echo "Created a minimal coverage report due to: $reason" + log_debug "Fallback report created" +} + +log_debug "Obtaining coverage path from Swift" +echo "Running Swift test to get coverage path..." + +# Get the path to the coverage report - capture both stdout and stderr +CODECOV_OUTPUT=$(swift test --enable-code-coverage --show-codecov-path 2>&1) +EXIT_CODE=$? + +# Log the command output +log_debug "Swift test exit code: $EXIT_CODE" +log_debug "Swift test output: $CODECOV_OUTPUT" + +# Check if the command succeeded +if [ $EXIT_CODE -ne 0 ]; then +echo "Error: Failed to get coverage path. Exit code: $EXIT_CODE" +log_debug "Error: Swift test command failed with exit code $EXIT_CODE" +create_fallback_report "swift test command failed" + +echo "Debug log written to $DEBUG_LOG" +exit 0 +fi + +# Extract the path from the output +CODECOV_PATH=$(echo "$CODECOV_OUTPUT" | tail -n 1) echo "Using coverage report at: $CODECOV_PATH" +log_debug "Coverage path: $CODECOV_PATH" # Check if the file exists if [ ! -f "$CODECOV_PATH" ]; then - echo "Error: Coverage report not found at $CODECOV_PATH" - exit 1 +echo "Error: Coverage report not found at $CODECOV_PATH" +log_debug "Coverage file does not exist" + +# Check if the directory exists +CODECOV_DIR=$(dirname "$CODECOV_PATH") +if [ -d "$CODECOV_DIR" ]; then +log_debug "Parent directory exists, contents:" +ls -la "$CODECOV_DIR" >> "$DEBUG_LOG" +else +log_debug "Parent directory does not exist" fi -# Check if the file is a valid JSON file -if ! jq empty "$CODECOV_PATH" 2>/dev/null; then - echo "Error: Invalid JSON format in $CODECOV_PATH" - echo "First 100 bytes of file content:" - head -c 100 "$CODECOV_PATH" | hexdump -C +create_fallback_report "coverage file not found" +echo "Debug log written to $DEBUG_LOG" +exit 0 +fi - # Create a minimal coverage report - cat > "$OUTPUT_FILE" << EOF -| ID | Name | Executable Lines | Coverage | -|----|------|-----------------:|---------:| -| 0 | ${PACKAGE_NAME%SVGSupport} | 0 | **0.00%** | -EOF - echo "Created a minimal coverage report due to JSON parsing failure" - exit 0 +# Examine the coverage file +examine_file "$CODECOV_PATH" + +# Try to validate the JSON file +log_debug "Validating JSON format" +JSON_CHECK=$(jq empty "$CODECOV_PATH" 2>&1) +JSON_EXIT_CODE=$? + +log_debug "JSON validation exit code: $JSON_EXIT_CODE" +log_debug "JSON validation output: $JSON_CHECK" + +if [ $JSON_EXIT_CODE -ne 0 ]; then +echo "Error: Invalid JSON format in $CODECOV_PATH" +echo "JSON validation error: $JSON_CHECK" + +# Try to determine the file format and size +FILE_TYPE=$(file -b "$CODECOV_PATH") +FILE_SIZE=$(wc -c < "$CODECOV_PATH") +echo "File appears to be: $FILE_TYPE (Size: $FILE_SIZE bytes)" + +log_debug "Trying to parse as xcresult instead" +if [[ "$CODECOV_PATH" == *".xcresult"* ]]; then +echo "Detected .xcresult format, trying xcresulttool..." +if command -v xcrun &> /dev/null; then +log_debug "xcrun is available, trying to extract coverage data" +XCRUN_OUTPUT=$(xcrun xcresulttool get --format json --path "$CODECOV_PATH" 2>&1) +log_debug "xcrun output: $XCRUN_OUTPUT" +else +log_debug "xcrun not available" +fi fi -# Extract all line coverage data for files containing the specified source path -# Use a temporary file for the extracted data to avoid command substitution issues +create_fallback_report "invalid JSON format" +echo "Debug log written to $DEBUG_LOG" +exit 0 +fi + +# Try to extract coverage data +log_debug "Extracting coverage data" TMP_DATA_FILE=$(mktemp) -jq -r --arg source_path "$SOURCE_PATH" '.data[0].files[] | select(.filename | contains($source_path)) | .summary.lines' "$CODECOV_PATH" > "$TMP_DATA_FILE" || { - echo "Error: Failed to extract coverage data" - echo "JSON structure may be different than expected" +JQ_CMD="jq -r --arg source_path \"$SOURCE_PATH\" '.data[0].files[] | select(.filename | contains(\$source_path)) | .summary.lines' \"$CODECOV_PATH\"" +log_debug "JQ command: $JQ_CMD" - # Create a minimal coverage report - cat > "$OUTPUT_FILE" << EOF -| ID | Name | Executable Lines | Coverage | -|----|------|-----------------:|---------:| -| 0 | ${PACKAGE_NAME%SVGSupport} | 0 | **0.00%** | -EOF - echo "Created a minimal coverage report due to data extraction failure" - # Clean up temporary file - rm -f "$TMP_DATA_FILE" - exit 0 +# First, check the structure of the JSON to see what we're working with +log_debug "Examining JSON structure" +JSON_KEYS=$(jq -r 'keys' "$CODECOV_PATH" 2>&1) +log_debug "Top-level JSON keys: $JSON_KEYS" + +# Try to extract data with different queries to see what works +log_debug "Trying different JSON paths" + +# Try the original path +JQ_RESULT=$(jq -r '.data[0].files[] | select(.filename | contains("'"$SOURCE_PATH"'")) | .summary.lines' "$CODECOV_PATH" 2>&1) +JQ_EXIT_CODE=$? +log_debug "Original JQ path exit code: $JQ_EXIT_CODE" +log_debug "Original JQ path result: $JQ_RESULT" + +# Try alternative paths +log_debug "Trying alternative JSON paths" +ALT_PATHS=( +'.data[].files[].summary.lines' +'.files[].summary.lines' +'.targets[].files[].summary.lines' +'.' +) + +for path in "${ALT_PATHS[@]}"; do +log_debug "Trying path: $path" +ALT_RESULT=$(jq -r "$path" "$CODECOV_PATH" 2>&1) +ALT_EXIT_CODE=$? +log_debug " Exit code: $ALT_EXIT_CODE" +if [ $ALT_EXIT_CODE -eq 0 ] && [ -n "$ALT_RESULT" ] && [ "$ALT_RESULT" != "null" ]; then +log_debug " Found data with path: $path" +log_debug " Data sample: $(echo "$ALT_RESULT" | head -n 5)" +else +log_debug " No data found with this path" +fi +done + +# Try our best to extract some meaningful data +echo "Attempting to extract coverage data..." +jq -r '.data[0].files[] | select(.filename | contains("'"$SOURCE_PATH"'")) | .summary.lines' "$CODECOV_PATH" > "$TMP_DATA_FILE" 2>> "$DEBUG_LOG" || { + log_debug "Failed with original path, trying alternatives" + + # Try the first alternative that might work + for path in "${ALT_PATHS[@]}"; do + log_debug "Extracting with alternative path: $path" + jq -r "$path" "$CODECOV_PATH" > "$TMP_DATA_FILE" 2>> "$DEBUG_LOG" + if [ -s "$TMP_DATA_FILE" ]; then + log_debug "Found data with path: $path" + break + else + log_debug "No data found with path: $path" + fi + done } -# Check if we actually got any data +# Check if we got any data if [ ! -s "$TMP_DATA_FILE" ]; then - echo "Warning: No coverage data found for files in $SOURCE_PATH" +echo "Warning: No coverage data extracted using any known JSON path" +log_debug "No coverage data could be extracted" +create_fallback_report "no coverage data found" - # Create a minimal coverage report - cat > "$OUTPUT_FILE" << EOF -| ID | Name | Executable Lines | Coverage | -|----|------|-----------------:|---------:| -| 0 | ${PACKAGE_NAME%SVGSupport} | 0 | **0.00%** | -EOF - echo "Created a minimal coverage report with 0% coverage" - # Clean up temporary file - rm -f "$TMP_DATA_FILE" - exit 0 +# Clean up temporary file +rm -f "$TMP_DATA_FILE" +echo "Debug log written to $DEBUG_LOG" +exit 0 fi +log_debug "Extracted data file size: $(wc -c < "$TMP_DATA_FILE") bytes" +log_debug "Extracted data sample: $(head -n 5 "$TMP_DATA_FILE")" + total_lines=0 covered_lines=0 +log_debug "Processing coverage data" # Process each line of the data file while IFS= read -r line_data || [[ -n "$line_data" ]]; do - # Skip empty lines - [[ -z "$line_data" ]] && continue - - # Extract total and covered lines - total=$(echo "$line_data" | jq -r '.count' 2>/dev/null) - covered=$(echo "$line_data" | jq -r '.covered' 2>/dev/null) - - # Validate numbers before adding them - if ! [[ "$total" =~ ^[0-9]+$ ]] || ! [[ "$covered" =~ ^[0-9]+$ ]]; then - echo "Warning: Invalid line count data found, skipping: $line_data" - continue - fi - - # Add to the total lines and covered lines - total_lines=$((total_lines + total)) - covered_lines=$((covered_lines + covered)) +# Skip empty lines +[[ -z "$line_data" ]] && continue + +log_debug "Processing line data: $line_data" +# Extract total and covered lines +total=$(echo "$line_data" | jq -r '.count' 2>/dev/null) +covered=$(echo "$line_data" | jq -r '.covered' 2>/dev/null) + +log_debug "Extracted: total=$total, covered=$covered" + +# Validate numbers before adding them +if ! [[ "$total" =~ ^[0-9]+$ ]] || ! [[ "$covered" =~ ^[0-9]+$ ]]; then +log_debug "Invalid data: $line_data" +echo "Warning: Invalid line count data found, skipping: $line_data" +continue +fi + +# Add to the total lines and covered lines +total_lines=$((total_lines + total)) +covered_lines=$((covered_lines + covered)) done < "$TMP_DATA_FILE" +log_debug "Final counts: total_lines=$total_lines, covered_lines=$covered_lines" + # Calculate the average line coverage percentage if [ $total_lines -gt 0 ]; then - average_coverage=$(bc <<< "scale=$DECIMAL_PRECISION; $covered_lines * 100 / $total_lines") +average_coverage=$(bc <<< "scale=$DECIMAL_PRECISION; $covered_lines * 100 / $total_lines") else - average_coverage=0 +average_coverage=0 fi +log_debug "Calculated coverage: $average_coverage" + # Format the coverage percentage with proper rounding average_coverage_rounded=$(printf "%.*f" $DISPLAY_PRECISION "$average_coverage") average_coverage_with_percentage="${average_coverage_rounded}%" @@ -108,6 +264,7 @@ echo "Total executable lines: $total_lines" echo "Covered lines: $covered_lines" echo "Coverage: $average_coverage_with_percentage" +log_debug "Creating final report" # Save to output file cat > "$OUTPUT_FILE" << EOF | ID | Name | Executable Lines | Coverage | @@ -115,7 +272,12 @@ cat > "$OUTPUT_FILE" << EOF | 0 | ${PACKAGE_NAME%SVGSupport} | $total_lines | **$average_coverage_with_percentage** | EOF +log_debug "Report created successfully" echo "Coverage summary saved to $OUTPUT_FILE" # Clean up temporary files rm -f "$TMP_DATA_FILE" +log_debug "Temporary files cleaned up" +log_debug "Script completed successfully" + +echo "Debug log written to $DEBUG_LOG" From e09e7bacb8fc85e9e3a51d34d54f60b81af79f3c Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:23:56 +0100 Subject: [PATCH 07/13] update extract_coverage.sh --- .github/scripts/extract_coverage.sh | 283 +++------------------------- 1 file changed, 24 insertions(+), 259 deletions(-) diff --git a/.github/scripts/extract_coverage.sh b/.github/scripts/extract_coverage.sh index d375c52..79b1fbb 100644 --- a/.github/scripts/extract_coverage.sh +++ b/.github/scripts/extract_coverage.sh @@ -1,283 +1,48 @@ #!/bin/bash -# Turn off automatic exit on error for more controlled debugging -set -u # Treat unset variables as an error -# Define environment variables -PACKAGE_NAME="SnappThemingSVGSupport" +# Environment variables +PACKAGE_NAME="SnappThemingSVGSpport" SOURCE_PATH="$PACKAGE_NAME/Sources" OUTPUT_FILE="pr_coverage_summary.txt" -DECIMAL_PRECISION=6 -DISPLAY_PRECISION=2 -DEBUG_LOG="coverage_debug.log" +DECIMAL_PLACES=6 +DISPLAY_PLACES=2 -# Start debug log -{ - echo "====== DEBUG LOG ======" - echo "Date: $(date)" - echo "Script started" - echo "Package: $PACKAGE_NAME" - echo "Source path: $SOURCE_PATH" - echo "Environment variables:" - env | sort - echo "Current directory: $(pwd)" - echo "Directory contents:" - ls -la - echo "========================" -} > "$DEBUG_LOG" - -# Function to log debug information -log_debug() { - echo "$(date +%H:%M:%S) - $1" >> "$DEBUG_LOG" -} - -# Function to examine a file -examine_file() { - local file="$1" - log_debug "Examining file: $file" - - if [ -f "$file" ]; then - log_debug "File exists and size is: $(wc -c < "$file") bytes" - log_debug "File type: $(file -b "$file")" - log_debug "First 500 bytes:" - head -c 500 "$file" | hexdump -C >> "$DEBUG_LOG" - log_debug "File stats: $(stat "$file" 2>/dev/null || ls -la "$file")" - else - log_debug "File does not exist" - fi -} - -# Create a fallback coverage report -create_fallback_report() { - local reason="$1" - log_debug "Creating fallback report due to: $reason" - - cat > "$OUTPUT_FILE" << EOF - | ID | Name | Executable Lines | Coverage | - |----|------|-----------------:|---------:| - | 0 | ${PACKAGE_NAME%SVGSupport} | 0 | **0.00%** | - EOF - echo "Created a minimal coverage report due to: $reason" - log_debug "Fallback report created" -} - -log_debug "Obtaining coverage path from Swift" -echo "Running Swift test to get coverage path..." - -# Get the path to the coverage report - capture both stdout and stderr -CODECOV_OUTPUT=$(swift test --enable-code-coverage --show-codecov-path 2>&1) -EXIT_CODE=$? - -# Log the command output -log_debug "Swift test exit code: $EXIT_CODE" -log_debug "Swift test output: $CODECOV_OUTPUT" - -# Check if the command succeeded -if [ $EXIT_CODE -ne 0 ]; then -echo "Error: Failed to get coverage path. Exit code: $EXIT_CODE" -log_debug "Error: Swift test command failed with exit code $EXIT_CODE" -create_fallback_report "swift test command failed" - -echo "Debug log written to $DEBUG_LOG" -exit 0 -fi - -# Extract the path from the output -CODECOV_PATH=$(echo "$CODECOV_OUTPUT" | tail -n 1) +# Get the path to the coverage report +CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) echo "Using coverage report at: $CODECOV_PATH" -log_debug "Coverage path: $CODECOV_PATH" - -# Check if the file exists -if [ ! -f "$CODECOV_PATH" ]; then -echo "Error: Coverage report not found at $CODECOV_PATH" -log_debug "Coverage file does not exist" - -# Check if the directory exists -CODECOV_DIR=$(dirname "$CODECOV_PATH") -if [ -d "$CODECOV_DIR" ]; then -log_debug "Parent directory exists, contents:" -ls -la "$CODECOV_DIR" >> "$DEBUG_LOG" -else -log_debug "Parent directory does not exist" -fi - -create_fallback_report "coverage file not found" -echo "Debug log written to $DEBUG_LOG" -exit 0 -fi - -# Examine the coverage file -examine_file "$CODECOV_PATH" - -# Try to validate the JSON file -log_debug "Validating JSON format" -JSON_CHECK=$(jq empty "$CODECOV_PATH" 2>&1) -JSON_EXIT_CODE=$? - -log_debug "JSON validation exit code: $JSON_EXIT_CODE" -log_debug "JSON validation output: $JSON_CHECK" - -if [ $JSON_EXIT_CODE -ne 0 ]; then -echo "Error: Invalid JSON format in $CODECOV_PATH" -echo "JSON validation error: $JSON_CHECK" - -# Try to determine the file format and size -FILE_TYPE=$(file -b "$CODECOV_PATH") -FILE_SIZE=$(wc -c < "$CODECOV_PATH") -echo "File appears to be: $FILE_TYPE (Size: $FILE_SIZE bytes)" - -log_debug "Trying to parse as xcresult instead" -if [[ "$CODECOV_PATH" == *".xcresult"* ]]; then -echo "Detected .xcresult format, trying xcresulttool..." -if command -v xcrun &> /dev/null; then -log_debug "xcrun is available, trying to extract coverage data" -XCRUN_OUTPUT=$(xcrun xcresulttool get --format json --path "$CODECOV_PATH" 2>&1) -log_debug "xcrun output: $XCRUN_OUTPUT" -else -log_debug "xcrun not available" -fi -fi -create_fallback_report "invalid JSON format" -echo "Debug log written to $DEBUG_LOG" -exit 0 -fi - -# Try to extract coverage data -log_debug "Extracting coverage data" -TMP_DATA_FILE=$(mktemp) -JQ_CMD="jq -r --arg source_path \"$SOURCE_PATH\" '.data[0].files[] | select(.filename | contains(\$source_path)) | .summary.lines' \"$CODECOV_PATH\"" -log_debug "JQ command: $JQ_CMD" - -# First, check the structure of the JSON to see what we're working with -log_debug "Examining JSON structure" -JSON_KEYS=$(jq -r 'keys' "$CODECOV_PATH" 2>&1) -log_debug "Top-level JSON keys: $JSON_KEYS" - -# Try to extract data with different queries to see what works -log_debug "Trying different JSON paths" - -# Try the original path -JQ_RESULT=$(jq -r '.data[0].files[] | select(.filename | contains("'"$SOURCE_PATH"'")) | .summary.lines' "$CODECOV_PATH" 2>&1) -JQ_EXIT_CODE=$? -log_debug "Original JQ path exit code: $JQ_EXIT_CODE" -log_debug "Original JQ path result: $JQ_RESULT" - -# Try alternative paths -log_debug "Trying alternative JSON paths" -ALT_PATHS=( -'.data[].files[].summary.lines' -'.files[].summary.lines' -'.targets[].files[].summary.lines' -'.' -) - -for path in "${ALT_PATHS[@]}"; do -log_debug "Trying path: $path" -ALT_RESULT=$(jq -r "$path" "$CODECOV_PATH" 2>&1) -ALT_EXIT_CODE=$? -log_debug " Exit code: $ALT_EXIT_CODE" -if [ $ALT_EXIT_CODE -eq 0 ] && [ -n "$ALT_RESULT" ] && [ "$ALT_RESULT" != "null" ]; then -log_debug " Found data with path: $path" -log_debug " Data sample: $(echo "$ALT_RESULT" | head -n 5)" -else -log_debug " No data found with this path" -fi -done - -# Try our best to extract some meaningful data -echo "Attempting to extract coverage data..." -jq -r '.data[0].files[] | select(.filename | contains("'"$SOURCE_PATH"'")) | .summary.lines' "$CODECOV_PATH" > "$TMP_DATA_FILE" 2>> "$DEBUG_LOG" || { - log_debug "Failed with original path, trying alternatives" - - # Try the first alternative that might work - for path in "${ALT_PATHS[@]}"; do - log_debug "Extracting with alternative path: $path" - jq -r "$path" "$CODECOV_PATH" > "$TMP_DATA_FILE" 2>> "$DEBUG_LOG" - if [ -s "$TMP_DATA_FILE" ]; then - log_debug "Found data with path: $path" - break - else - log_debug "No data found with path: $path" - fi - done -} - -# Check if we got any data -if [ ! -s "$TMP_DATA_FILE" ]; then -echo "Warning: No coverage data extracted using any known JSON path" -log_debug "No coverage data could be extracted" -create_fallback_report "no coverage data found" - -# Clean up temporary file -rm -f "$TMP_DATA_FILE" -echo "Debug log written to $DEBUG_LOG" -exit 0 -fi - -log_debug "Extracted data file size: $(wc -c < "$TMP_DATA_FILE") bytes" -log_debug "Extracted data sample: $(head -n 5 "$TMP_DATA_FILE")" +# Extract all line coverage data for files containing SOURCE_PATH +FILES_LINE_COUNTS=$(jq -r --arg path "$SOURCE_PATH" '.data[0].files[] | select(.filename | contains($path)) | .summary.lines' "$CODECOV_PATH") total_lines=0 covered_lines=0 -log_debug "Processing coverage data" -# Process each line of the data file -while IFS= read -r line_data || [[ -n "$line_data" ]]; do -# Skip empty lines -[[ -z "$line_data" ]] && continue - -log_debug "Processing line data: $line_data" -# Extract total and covered lines -total=$(echo "$line_data" | jq -r '.count' 2>/dev/null) -covered=$(echo "$line_data" | jq -r '.covered' 2>/dev/null) - -log_debug "Extracted: total=$total, covered=$covered" - -# Validate numbers before adding them -if ! [[ "$total" =~ ^[0-9]+$ ]] || ! [[ "$covered" =~ ^[0-9]+$ ]]; then -log_debug "Invalid data: $line_data" -echo "Warning: Invalid line count data found, skipping: $line_data" -continue -fi - -# Add to the total lines and covered lines -total_lines=$((total_lines + total)) -covered_lines=$((covered_lines + covered)) -done < "$TMP_DATA_FILE" +# Loop through each file's line count data +for lines_data in $(echo "$FILES_LINE_COUNTS" | jq -c '.'); do + # Extract total and covered lines for each file + total=$(echo "$lines_data" | jq '.count') + covered=$(echo "$lines_data" | jq '.covered') -log_debug "Final counts: total_lines=$total_lines, covered_lines=$covered_lines" + # Add to the total lines and covered lines + total_lines=$((total_lines + total)) + covered_lines=$((covered_lines + covered)) +done # Calculate the average line coverage percentage if [ $total_lines -gt 0 ]; then -average_coverage=$(bc <<< "scale=$DECIMAL_PRECISION; $covered_lines * 100 / $total_lines") + average_coverage=$(echo "scale=$DECIMAL_PLACES; $covered_lines * 100 / $total_lines" | bc) else -average_coverage=0 + average_coverage=0 fi -log_debug "Calculated coverage: $average_coverage" - -# Format the coverage percentage with proper rounding -average_coverage_rounded=$(printf "%.*f" $DISPLAY_PRECISION "$average_coverage") +average_coverage_rounded=$(echo "$average_coverage" | awk '{print int($1 * 100 + 0.5) / 100}') average_coverage_with_percentage="${average_coverage_rounded}%" -echo "Total executable lines: $total_lines" -echo "Covered lines: $covered_lines" -echo "Coverage: $average_coverage_with_percentage" - -log_debug "Creating final report" -# Save to output file -cat > "$OUTPUT_FILE" << EOF +# Save to pr_coverage_summary.txt +cat < "$OUTPUT_FILE" | ID | Name | Executable Lines | Coverage | |----|------|-----------------:|---------:| -| 0 | ${PACKAGE_NAME%SVGSupport} | $total_lines | **$average_coverage_with_percentage** | +| 0 | $PACKAGE_NAME | $total_lines | **$average_coverage_with_percentage** | EOF -log_debug "Report created successfully" -echo "Coverage summary saved to $OUTPUT_FILE" - -# Clean up temporary files -rm -f "$TMP_DATA_FILE" -log_debug "Temporary files cleaned up" -log_debug "Script completed successfully" - -echo "Debug log written to $DEBUG_LOG" +echo "Coverage report generated with $average_coverage_with_percentage coverage" From 04a1309a81d9811c865e206e304dd938c73c9335 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:29:43 +0100 Subject: [PATCH 08/13] update extract_coverage.sh --- .github/scripts/extract_coverage.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/scripts/extract_coverage.sh b/.github/scripts/extract_coverage.sh index 79b1fbb..bf5d7e9 100644 --- a/.github/scripts/extract_coverage.sh +++ b/.github/scripts/extract_coverage.sh @@ -1,11 +1,10 @@ #!/bin/bash # Environment variables -PACKAGE_NAME="SnappThemingSVGSpport" +PACKAGE_NAME="SnappThemingSVGSupport" SOURCE_PATH="$PACKAGE_NAME/Sources" OUTPUT_FILE="pr_coverage_summary.txt" DECIMAL_PLACES=6 -DISPLAY_PLACES=2 # Get the path to the coverage report CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) From 8d03f75851a31f7f222cc3894ad063a7e1eb2481 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:40:30 +0100 Subject: [PATCH 09/13] updated run_tests.yml, extract_coverage.sh and added create_comment.js --- .github/scripts/create_comment.js | 58 +++++++++++++ .github/scripts/extract_coverage.sh | 14 +-- .github/workflows/run_tests.yml | 128 ++++++++++------------------ 3 files changed, 111 insertions(+), 89 deletions(-) create mode 100644 .github/scripts/create_comment.js diff --git a/.github/scripts/create_comment.js b/.github/scripts/create_comment.js new file mode 100644 index 0000000..2591955 --- /dev/null +++ b/.github/scripts/create_comment.js @@ -0,0 +1,58 @@ +// Script to create a PR comment with code coverage results +const fs = require('fs'); + +// Get environment variables +const commentHeader = process.env.BOT_COMMENT_HEADER || '### 🛡️ Code Coverage Report'; +const coverageSummaryFile = process.env.COVERAGE_SUMMARY_FILE || 'pr_coverage_summary.txt'; + +async function run() { + try { + // Read the coverage output + const coverageOutput = fs.readFileSync(coverageSummaryFile, 'utf8'); + + // Create the comment content + const newComment = ` +${commentHeader} + +${coverageOutput} + +_Generated by GitHub Actions._ +`; + + // Fetch existing comments + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + }); + + // Identify and delete previous bot comments + const botComments = comments.data.filter(comment => + comment.body.includes(commentHeader) + ); + + for (const botComment of botComments) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + }); + } + + // Create a comment on the pull request + await github.rest.issues.createComment({ + issue_number: context.payload.pull_request.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: newComment, + }); + + console.log('PR comment created successfully!'); + } catch (error) { + console.error('Error creating PR comment:', error); + process.exit(1); + } +} + +// Execute the function +run(); diff --git a/.github/scripts/extract_coverage.sh b/.github/scripts/extract_coverage.sh index bf5d7e9..1611c30 100644 --- a/.github/scripts/extract_coverage.sh +++ b/.github/scripts/extract_coverage.sh @@ -1,13 +1,15 @@ #!/bin/bash # Environment variables -PACKAGE_NAME="SnappThemingSVGSupport" -SOURCE_PATH="$PACKAGE_NAME/Sources" -OUTPUT_FILE="pr_coverage_summary.txt" +PACKAGE_NAME=${PACKAGE_NAME:-"SnappThemingSVGSupport"} +SOURCE_PATH=${SOURCE_PATH:-"$PACKAGE_NAME/Sources"} +OUTPUT_FILE=${COVERAGE_SUMMARY_FILE:-"pr_coverage_summary.txt"} DECIMAL_PLACES=6 -# Get the path to the coverage report -CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) +# Use CODECOV_PATH from environment if provided, otherwise get it +if [ -z "$CODECOV_PATH" ]; then + CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) +fi echo "Using coverage report at: $CODECOV_PATH" # Extract all line coverage data for files containing SOURCE_PATH @@ -37,7 +39,7 @@ fi average_coverage_rounded=$(echo "$average_coverage" | awk '{print int($1 * 100 + 0.5) / 100}') average_coverage_with_percentage="${average_coverage_rounded}%" -# Save to pr_coverage_summary.txt +# Save to output file cat < "$OUTPUT_FILE" | ID | Name | Executable Lines | Coverage | |----|------|-----------------:|---------:| diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index b4797d7..4076504 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -1,84 +1,46 @@ # This workflow will test a Swift project - # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift - - name: Package Test - env: - EXTRACT_COVERAGE: '.github/scripts/extract_coverage.sh' - COVERAGE_REPORT_PATH: './coverage/coverage.xcresult' - XCODE_VERSION: 'Xcode_16.2.app' - XCODE_PATH: '/Applications/Xcode_16.2.app/Contents/Developer' - COVERAGE_SUMMARY_FILE: 'pr_coverage_summary.txt' - BOT_COMMENT_HEADER: '### 🛡️ Code Coverage Report' - - on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - - jobs: - build: - - runs-on: macos-latest - - steps: - - uses: actions/checkout@v4 - - - name: List Xcode Installations - run: sudo ls -1 /Applications | grep "Xcode" - - - name: Select Xcode - run: sudo xcode-select -s ${{ env.XCODE_PATH }} - - - name: Run Swift Tests with Coverage - run: | - swift test --enable-swift-testing --enable-code-coverage - CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) - echo "CODECOV_PATH=${CODECOV_PATH}" >> $GITHUB_ENV - - - name: Run Coverage Extraction Script - run: bash ${{ env.EXTRACT_COVERAGE }} - - - name: Comment on Pull Request - if: github.event_name == 'pull_request' - uses: actions/github-script@v6 - with: - script: | - const fs = require('fs'); - const coverageOutput = fs.readFileSync('${{ env.COVERAGE_SUMMARY_FILE }}', 'utf8'); - - const newComment = ` - ${{ env.BOT_COMMENT_HEADER }} - - ${coverageOutput} - - _Generated by GitHub Actions._ - `; - - // Fetch existing comments - const comments = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.payload.pull_request.number, - }); - - // Identify and delete previous bot comments - const botComments = comments.data.filter(comment => - comment.body.includes("${{ env.BOT_COMMENT_HEADER }}") - ); - - for (const botComment of botComments) { - await github.rest.issues.deleteComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: botComment.id, - }); - } - - // Create a comment on the pull request - await github.rest.issues.createComment({ - issue_number: context.payload.pull_request.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: newComment, - }); +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift + +name: Package Test +env: + EXTRACT_COVERAGE: '.github/scripts/extract_coverage.sh' + CREATE_COMMENT: '.github/scripts/create_pr_comment.js' + COVERAGE_REPORT_PATH: './coverage/coverage.xcresult' + XCODE_VERSION: 'Xcode_16.2.app' + XCODE_PATH: '/Applications/Xcode_16.2.app/Contents/Developer' + COVERAGE_SUMMARY_FILE: 'pr_coverage_summary.txt' + BOT_COMMENT_HEADER: '### 🛡️ Code Coverage Report' + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v4 + + - name: List Xcode Installations + run: sudo ls -1 /Applications | grep "Xcode" + + - name: Select Xcode + run: sudo xcode-select -s ${{ env.XCODE_PATH }} + + - name: Run Swift Tests with Coverage + run: | + swift test --enable-swift-testing --enable-code-coverage + CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) + echo "CODECOV_PATH=${CODECOV_PATH}" >> $GITHUB_ENV + + - name: Run Coverage Extraction Script + run: bash ${{ env.EXTRACT_COVERAGE }} + + - name: Comment on Pull Request + if: github.event_name == 'pull_request' + uses: actions/github-script@v6 + with: + script-path: ${{ env.CREATE_COMMENT }} From 4aff2e6599360df777f7efb563af87905cc78cc8 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:42:14 +0100 Subject: [PATCH 10/13] fix run_tests.yml --- .github/workflows/run_tests.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 4076504..23de803 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -20,27 +20,27 @@ on: jobs: build: runs-on: macos-latest - + steps: - uses: actions/checkout@v4 - + - name: List Xcode Installations - run: sudo ls -1 /Applications | grep "Xcode" - + run: sudo ls -1 /Applications | grep "Xcode" + - name: Select Xcode - run: sudo xcode-select -s ${{ env.XCODE_PATH }} - + run: sudo xcode-select -s ${{ env.XCODE_PATH }} + - name: Run Swift Tests with Coverage - run: | + run: | swift test --enable-swift-testing --enable-code-coverage CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) echo "CODECOV_PATH=${CODECOV_PATH}" >> $GITHUB_ENV - + - name: Run Coverage Extraction Script - run: bash ${{ env.EXTRACT_COVERAGE }} - + run: bash ${{ env.EXTRACT_COVERAGE }} + - name: Comment on Pull Request - if: github.event_name == 'pull_request' - uses: actions/github-script@v6 - with: + if: github.event_name == 'pull_request' + uses: actions/github-script@v6 + with: script-path: ${{ env.CREATE_COMMENT }} From 55275db61a1939242e7375c1cab0155968a2e3e8 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:43:46 +0100 Subject: [PATCH 11/13] fix run_tests.yml --- .github/workflows/run_tests.yml | 44 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 23de803..a5112f9 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -13,34 +13,34 @@ env: on: push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] + branches: [ "main" ] + pull_request: + branches: [ "main" ] jobs: build: - runs-on: macos-latest + runs-on: macos-latest - steps: - - uses: actions/checkout@v4 + steps: + - uses: actions/checkout@v4 - - name: List Xcode Installations - run: sudo ls -1 /Applications | grep "Xcode" + - name: List Xcode Installations + run: sudo ls -1 /Applications | grep "Xcode" - - name: Select Xcode - run: sudo xcode-select -s ${{ env.XCODE_PATH }} + - name: Select Xcode + run: sudo xcode-select -s ${{ env.XCODE_PATH }} - - name: Run Swift Tests with Coverage - run: | - swift test --enable-swift-testing --enable-code-coverage - CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) - echo "CODECOV_PATH=${CODECOV_PATH}" >> $GITHUB_ENV + - name: Run Swift Tests with Coverage + run: | + swift test --enable-swift-testing --enable-code-coverage + CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) + echo "CODECOV_PATH=${CODECOV_PATH}" >> $GITHUB_ENV - - name: Run Coverage Extraction Script - run: bash ${{ env.EXTRACT_COVERAGE }} + - name: Run Coverage Extraction Script + run: bash ${{ env.EXTRACT_COVERAGE }} - - name: Comment on Pull Request - if: github.event_name == 'pull_request' - uses: actions/github-script@v6 - with: - script-path: ${{ env.CREATE_COMMENT }} + - name: Comment on Pull Request + if: github.event_name == 'pull_request' + uses: actions/github-script@v6 + with: + script-path: ${{ env.CREATE_COMMENT }} From e2aab7c143de7e9148050338215e290710f0fa20 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:45:22 +0100 Subject: [PATCH 12/13] fix run_tests.yml --- .github/workflows/run_tests.yml | 49 +++++++++++++++++---------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index a5112f9..d9f8f75 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -2,6 +2,7 @@ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift name: Package Test + env: EXTRACT_COVERAGE: '.github/scripts/extract_coverage.sh' CREATE_COMMENT: '.github/scripts/create_pr_comment.js' @@ -12,35 +13,35 @@ env: BOT_COMMENT_HEADER: '### 🛡️ Code Coverage Report' on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] jobs: - build: - runs-on: macos-latest + build: + runs-on: macos-latest - steps: - - uses: actions/checkout@v4 + steps: + - uses: actions/checkout@v4 - - name: List Xcode Installations - run: sudo ls -1 /Applications | grep "Xcode" + - name: List Xcode Installations + run: sudo ls -1 /Applications | grep "Xcode" - - name: Select Xcode - run: sudo xcode-select -s ${{ env.XCODE_PATH }} + - name: Select Xcode + run: sudo xcode-select -s ${{ env.XCODE_PATH }} - - name: Run Swift Tests with Coverage - run: | - swift test --enable-swift-testing --enable-code-coverage - CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) - echo "CODECOV_PATH=${CODECOV_PATH}" >> $GITHUB_ENV + - name: Run Swift Tests with Coverage + run: | + swift test --enable-swift-testing --enable-code-coverage + CODECOV_PATH=$(swift test --enable-code-coverage --show-codecov-path) + echo "CODECOV_PATH=${CODECOV_PATH}" >> $GITHUB_ENV - - name: Run Coverage Extraction Script - run: bash ${{ env.EXTRACT_COVERAGE }} + - name: Run Coverage Extraction Script + run: bash ${{ env.EXTRACT_COVERAGE }} - - name: Comment on Pull Request - if: github.event_name == 'pull_request' - uses: actions/github-script@v6 - with: - script-path: ${{ env.CREATE_COMMENT }} + - name: Comment on Pull Request + if: github.event_name == 'pull_request' + uses: actions/github-script@v6 + with: + script-path: ${{ env.CREATE_COMMENT }} From 4b75d4b9e5b4e23bd21950a428dee9c2249848b4 Mon Sep 17 00:00:00 2001 From: Oleksii Kolomiiets Date: Tue, 25 Feb 2025 09:51:04 +0100 Subject: [PATCH 13/13] update run_tests.yml and remove create_comment.js --- .github/scripts/create_comment.js | 58 ------------------------------- .github/workflows/run_tests.yml | 40 ++++++++++++++++++++- 2 files changed, 39 insertions(+), 59 deletions(-) delete mode 100644 .github/scripts/create_comment.js diff --git a/.github/scripts/create_comment.js b/.github/scripts/create_comment.js deleted file mode 100644 index 2591955..0000000 --- a/.github/scripts/create_comment.js +++ /dev/null @@ -1,58 +0,0 @@ -// Script to create a PR comment with code coverage results -const fs = require('fs'); - -// Get environment variables -const commentHeader = process.env.BOT_COMMENT_HEADER || '### 🛡️ Code Coverage Report'; -const coverageSummaryFile = process.env.COVERAGE_SUMMARY_FILE || 'pr_coverage_summary.txt'; - -async function run() { - try { - // Read the coverage output - const coverageOutput = fs.readFileSync(coverageSummaryFile, 'utf8'); - - // Create the comment content - const newComment = ` -${commentHeader} - -${coverageOutput} - -_Generated by GitHub Actions._ -`; - - // Fetch existing comments - const comments = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.payload.pull_request.number, - }); - - // Identify and delete previous bot comments - const botComments = comments.data.filter(comment => - comment.body.includes(commentHeader) - ); - - for (const botComment of botComments) { - await github.rest.issues.deleteComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: botComment.id, - }); - } - - // Create a comment on the pull request - await github.rest.issues.createComment({ - issue_number: context.payload.pull_request.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: newComment, - }); - - console.log('PR comment created successfully!'); - } catch (error) { - console.error('Error creating PR comment:', error); - process.exit(1); - } -} - -// Execute the function -run(); diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index d9f8f75..73182a0 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -44,4 +44,42 @@ jobs: if: github.event_name == 'pull_request' uses: actions/github-script@v6 with: - script-path: ${{ env.CREATE_COMMENT }} + script: | + const fs = require('fs'); + const coverageOutput = fs.readFileSync('${{ env.COVERAGE_SUMMARY_FILE }}', 'utf8'); + + const newComment = ` + ${{ env.BOT_COMMENT_HEADER }} + + ${coverageOutput} + + _Generated by GitHub Actions._ + `; + + // Fetch existing comments + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + }); + + // Identify and delete previous bot comments + const botComments = comments.data.filter(comment => + comment.body.includes("${{ env.BOT_COMMENT_HEADER }}") + ); + + for (const botComment of botComments) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + }); + } + + // Create a comment on the pull request + await github.rest.issues.createComment({ + issue_number: context.payload.pull_request.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: newComment, + });