Add CI/CD badge and testing #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Python Module Tests | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Python version to test (e.g., 3.13.5, 3.12.9)' | |
| required: false | |
| type: string | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| jobs: | |
| detect-versions: | |
| name: Detect Python Versions to Test | |
| runs-on: ubuntu-latest | |
| outputs: | |
| versions: ${{ steps.detect.outputs.versions }} | |
| has-changes: ${{ steps.detect.outputs.has-changes }} | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect Versions to Test | |
| id: detect | |
| run: | | |
| echo "=== Detecting Python Versions to Test ===" | |
| # Initialize versions array | |
| VERSIONS="[]" | |
| HAS_CHANGES="false" | |
| # Check if manual dispatch with specific version | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ github.event.inputs.version }}" ]; then | |
| echo "Manual workflow dispatch with version: ${{ github.event.inputs.version }}" | |
| VERSIONS='["${{ github.event.inputs.version }}"]' | |
| HAS_CHANGES="true" | |
| echo "versions=$VERSIONS" >> $GITHUB_OUTPUT | |
| echo "has-changes=$HAS_CHANGES" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # For pull requests, detect versions from pre-release files | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| echo "Pull request detected, checking for pre-release files..." | |
| # Get changed files in the PR | |
| CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) | |
| echo "Changed files:" | |
| echo "$CHANGED_FILES" | |
| # Look for pre-release files (e.g., bearsampp-python-3.13.5-2025.8.21.7z) | |
| PRERELEASE_FILES=$(echo "$CHANGED_FILES" | grep -E 'bearsampp-python-[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?(-[a-z0-9]+)?-[0-9]+\.[0-9]+\.[0-9]+\.7z' || true) | |
| if [ -n "$PRERELEASE_FILES" ]; then | |
| echo "✅ Found pre-release files:" | |
| echo "$PRERELEASE_FILES" | |
| # Extract version numbers from pre-release filenames | |
| DETECTED_VERSIONS="" | |
| while IFS= read -r file; do | |
| # Extract version from filename (e.g., bearsampp-python-3.13.5-2025.8.21.7z -> 3.13.5) | |
| VERSION=$(echo "$file" | grep -oE 'python-[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?(-[a-z0-9]+)?' | sed 's/python-//') | |
| if [ -n "$VERSION" ]; then | |
| echo " Detected version: $VERSION from $file" | |
| DETECTED_VERSIONS="$DETECTED_VERSIONS $VERSION" | |
| fi | |
| done <<< "$PRERELEASE_FILES" | |
| # Verify these versions exist in releases.properties | |
| VALID_VERSIONS="" | |
| for version in $DETECTED_VERSIONS; do | |
| if grep -q "^${version}" releases.properties; then | |
| echo "✅ Version $version exists in releases.properties" | |
| VALID_VERSIONS="$VALID_VERSIONS $version" | |
| HAS_CHANGES="true" | |
| else | |
| echo "⚠️ Version $version not found in releases.properties" | |
| fi | |
| done | |
| if [ -n "$VALID_VERSIONS" ]; then | |
| VERSIONS=$(echo "$VALID_VERSIONS" | tr ' ' '\n' | grep -v '^$' | sort -u | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| echo "Valid versions to test from pre-release files: $VERSIONS" | |
| fi | |
| else | |
| echo "ℹ️ No pre-release files found in PR" | |
| fi | |
| # Fallback: Check PR title for version numbers if no pre-release files found | |
| if [ "$HAS_CHANGES" = "false" ]; then | |
| echo "Checking PR title for version numbers as fallback..." | |
| PR_TITLE="${{ github.event.pull_request.title }}" | |
| echo "PR Title: $PR_TITLE" | |
| # Extract version numbers from PR title (e.g., 3.13.5, 3.12.9) | |
| TITLE_VERSIONS=$(echo "$PR_TITLE" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?(-[a-z0-9]+)?' || true) | |
| if [ -n "$TITLE_VERSIONS" ]; then | |
| echo "Found versions in PR title: $TITLE_VERSIONS" | |
| # Verify these versions exist in releases.properties | |
| VALID_VERSIONS="" | |
| for version in $TITLE_VERSIONS; do | |
| if grep -q "^${version}" releases.properties; then | |
| echo "✅ Version $version exists in releases.properties" | |
| VALID_VERSIONS="$VALID_VERSIONS $version" | |
| HAS_CHANGES="true" | |
| else | |
| echo "⚠️ Version $version not found in releases.properties" | |
| fi | |
| done | |
| if [ -n "$VALID_VERSIONS" ]; then | |
| VERSIONS=$(echo "$VALID_VERSIONS" | tr ' ' '\n' | grep -v '^$' | sort -u | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| echo "Valid versions to test from PR title: $VERSIONS" | |
| fi | |
| else | |
| echo "ℹ️ No version numbers found in PR title" | |
| fi | |
| fi | |
| else | |
| # For push events, test only the latest version (first line in releases.properties) | |
| echo "Push event detected, testing latest version only" | |
| HAS_CHANGES="true" | |
| LATEST_VERSION=$(grep -E "^[0-9]" releases.properties | cut -d'=' -f1 | tr -d ' ' | head -n 1) | |
| if [ -n "$LATEST_VERSION" ]; then | |
| VERSIONS=$(echo "$LATEST_VERSION" | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| echo "Latest version to test: $VERSIONS" | |
| else | |
| echo "⚠️ No versions found in releases.properties" | |
| VERSIONS="[]" | |
| HAS_CHANGES="false" | |
| fi | |
| fi | |
| echo "Final versions to test: $VERSIONS" | |
| echo "Has changes: $HAS_CHANGES" | |
| echo "versions=$VERSIONS" >> $GITHUB_OUTPUT | |
| echo "has-changes=$HAS_CHANGES" >> $GITHUB_OUTPUT | |
| test-python: | |
| name: Test Python ${{ matrix.version }} | |
| needs: detect-versions | |
| if: needs.detect-versions.outputs.has-changes == 'true' | |
| runs-on: windows-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| version: ${{ fromJson(needs.detect-versions.outputs.versions) }} | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@v4 | |
| - name: Create Test Results Directory | |
| run: | | |
| New-Item -ItemType Directory -Force -Path "test-results" | |
| Write-Host "✅ Created test-results directory" | |
| - name: Phase 1.1 - Download and Extract Python | |
| id: download-python | |
| continue-on-error: true | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $version = "${{ matrix.version }}" | |
| Write-Host "=== Phase 1.1: Download and Extract Python $version ===" | |
| # Create test directory | |
| New-Item -ItemType Directory -Force -Path "test-python" | Out-Null | |
| # Read releases.properties | |
| $releasesFile = "releases.properties" | |
| if (-not (Test-Path $releasesFile)) { | |
| Write-Host "❌ ERROR: releases.properties not found" | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=releases.properties not found" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| # Parse releases.properties to find download URL | |
| $downloadUrl = $null | |
| Get-Content $releasesFile | ForEach-Object { | |
| $line = $_.Trim() | |
| if ($line -match "^$version\s*=\s*(.+)$") { | |
| $downloadUrl = $matches[1].Trim() | |
| } | |
| } | |
| if (-not $downloadUrl) { | |
| Write-Host "❌ ERROR: Version $version not found in releases.properties" | |
| Write-Host "Available versions in releases.properties:" | |
| Get-Content $releasesFile | Select-String "^[0-9]" | ForEach-Object { Write-Host " - $($_.Line.Split('=')[0].Trim())" } | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=Version $version not found in releases.properties" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| Write-Host "Download URL: $downloadUrl" | |
| try { | |
| $fileName = [System.IO.Path]::GetFileName($downloadUrl) | |
| $downloadPath = Join-Path "test-python" $fileName | |
| Write-Host "Downloading Python $version..." | |
| Write-Host "Target file: $downloadPath" | |
| try { | |
| Invoke-WebRequest -Uri $downloadUrl -OutFile $downloadPath -UseBasicParsing -TimeoutSec 300 | |
| } catch { | |
| Write-Host "❌ ERROR: Download failed!" | |
| Write-Host "Error details: $($_.Exception.Message)" | |
| Write-Host "Status Code: $($_.Exception.Response.StatusCode.value__)" | |
| Write-Host "URL attempted: $downloadUrl" | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=Download failed: $($_.Exception.Message)" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| if (Test-Path $downloadPath) { | |
| $fileSize = (Get-Item $downloadPath).Length / 1MB | |
| Write-Host "✅ Downloaded: $fileName ($([math]::Round($fileSize, 2)) MB)" | |
| # Verify file is not empty or too small | |
| if ($fileSize -lt 0.1) { | |
| Write-Host "❌ ERROR: Downloaded file is too small ($([math]::Round($fileSize, 2)) MB), likely corrupted" | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=Downloaded file is too small or corrupted" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| # Extract the archive | |
| Write-Host "Extracting archive..." | |
| $extractOutput = & 7z x $downloadPath -o"test-python" -y 2>&1 | |
| if ($LASTEXITCODE -eq 0) { | |
| Write-Host "✅ Extraction successful" | |
| # List extracted contents | |
| Write-Host "Extracted contents:" | |
| Get-ChildItem -Path "test-python" -Directory | ForEach-Object { Write-Host " - $($_.Name)" } | |
| # Find the python directory | |
| $pythonDir = Get-ChildItem -Path "test-python" -Directory | Where-Object { $_.Name -match "^python" } | Select-Object -First 1 | |
| if ($pythonDir) { | |
| $pythonPath = $pythonDir.FullName | |
| Write-Host "✅ Python directory found: $pythonPath" | |
| # Verify python.exe exists | |
| $pythonExe = Join-Path $pythonPath "python.exe" | |
| if (Test-Path $pythonExe) { | |
| Write-Host "✅ python.exe exists" | |
| echo "python-path=$pythonPath" >> $env:GITHUB_OUTPUT | |
| echo "success=true" >> $env:GITHUB_OUTPUT | |
| } else { | |
| Write-Host "❌ ERROR: python.exe not found in $pythonPath" | |
| Write-Host "Directory structure:" | |
| Get-ChildItem -Path $pythonPath | ForEach-Object { Write-Host " - $($_.Name)" } | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=python.exe not found in extracted archive" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| } else { | |
| Write-Host "❌ ERROR: Python directory not found after extraction" | |
| Write-Host "Expected directory pattern: python*" | |
| Write-Host "Found directories:" | |
| Get-ChildItem -Path "test-python" -Directory | ForEach-Object { Write-Host " - $($_.Name)" } | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=Python directory not found after extraction" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| } else { | |
| Write-Host "❌ ERROR: Extraction failed with exit code: $LASTEXITCODE" | |
| Write-Host "7z output:" | |
| Write-Host $extractOutput | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=Extraction failed with exit code $LASTEXITCODE" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| } else { | |
| Write-Host "❌ ERROR: Download file not found at expected path: $downloadPath" | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=Download file not found after download attempt" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| } catch { | |
| Write-Host "❌ ERROR: Unexpected error occurred" | |
| Write-Host "Error message: $($_.Exception.Message)" | |
| Write-Host "Stack trace: $($_.ScriptStackTrace)" | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=$($_.Exception.Message)" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| - name: Phase 1.2 - Verify Python Installation | |
| id: verify-python | |
| if: steps.download-python.outputs.success == 'true' | |
| continue-on-error: true | |
| run: | | |
| $ErrorActionPreference = "Continue" | |
| $pythonPath = "${{ steps.download-python.outputs.python-path }}" | |
| Write-Host "=== Phase 1.2: Verify Python Installation ===" | |
| # Check for required executables | |
| $requiredExes = @("python.exe", "pip.exe") | |
| $allFound = $true | |
| $verifyResults = @{} | |
| foreach ($exe in $requiredExes) { | |
| $exePath = Join-Path $pythonPath $exe | |
| if (Test-Path $exePath) { | |
| Write-Host "✅ Found: $exe" | |
| $verifyResults[$exe] = @{ found = $true; path = $exePath } | |
| } else { | |
| # pip might be in Scripts directory | |
| $scriptsPath = Join-Path $pythonPath "Scripts" | |
| $exePath = Join-Path $scriptsPath $exe | |
| if (Test-Path $exePath) { | |
| Write-Host "✅ Found: $exe (in Scripts)" | |
| $verifyResults[$exe] = @{ found = $true; path = $exePath } | |
| } else { | |
| Write-Host "❌ Missing: $exe" | |
| $verifyResults[$exe] = @{ found = $false } | |
| if ($exe -ne "pip.exe") { | |
| $allFound = $false | |
| } | |
| } | |
| } | |
| } | |
| # Test python version | |
| if ($allFound) { | |
| try { | |
| $pythonExe = Join-Path $pythonPath "python.exe" | |
| $versionOutput = & $pythonExe --version 2>&1 | Out-String | |
| Write-Host "Version: $versionOutput" | |
| $verifyResults["version"] = $versionOutput.Trim() | |
| } catch { | |
| Write-Host "⚠️ Could not get version: $_" | |
| } | |
| } | |
| $verifyResults | ConvertTo-Json -Depth 10 | Out-File "test-results/verify.json" | |
| if ($allFound) { | |
| echo "success=true" >> $env:GITHUB_OUTPUT | |
| echo "python-exe=$pythonExe" >> $env:GITHUB_OUTPUT | |
| } else { | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| - name: Phase 2 - Test Basic Functionality | |
| id: test-basic | |
| if: steps.verify-python.outputs.success == 'true' | |
| continue-on-error: true | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $pythonExe = "${{ steps.verify-python.outputs.python-exe }}" | |
| Write-Host "=== Phase 2: Test Basic Functionality ===" | |
| try { | |
| $allFunctional = $true | |
| $testResults = @() | |
| Write-Host "`nTesting python.exe --version..." | |
| try { | |
| $pythonVersion = & $pythonExe --version 2>&1 | |
| Write-Host $pythonVersion | |
| if ($LASTEXITCODE -eq 0) { | |
| Write-Host "✅ python.exe is functional" | |
| $testResults += "python: PASS" | |
| } else { | |
| Write-Host "❌ python.exe failed with exit code: $LASTEXITCODE" | |
| $allFunctional = $false | |
| $testResults += "python: FAIL" | |
| } | |
| } catch { | |
| Write-Host "❌ python.exe error: $_" | |
| $allFunctional = $false | |
| $testResults += "python: ERROR" | |
| } | |
| Write-Host "`nTesting pip..." | |
| try { | |
| $pipVersion = & $pythonExe -m pip --version 2>&1 | |
| Write-Host $pipVersion | |
| if ($LASTEXITCODE -eq 0) { | |
| Write-Host "✅ pip is functional" | |
| $testResults += "pip: PASS" | |
| } else { | |
| Write-Host "⚠️ pip failed with exit code: $LASTEXITCODE" | |
| $testResults += "pip: WARN" | |
| } | |
| } catch { | |
| Write-Host "⚠️ pip error: $_" | |
| $testResults += "pip: WARN" | |
| } | |
| Write-Host "`nTesting Python import system..." | |
| try { | |
| $importTest = & $pythonExe -c "import sys; print(f'Python {sys.version}')" 2>&1 | |
| Write-Host $importTest | |
| if ($LASTEXITCODE -eq 0) { | |
| Write-Host "✅ Python import system is functional" | |
| $testResults += "import: PASS" | |
| } else { | |
| Write-Host "❌ Python import failed with exit code: $LASTEXITCODE" | |
| $allFunctional = $false | |
| $testResults += "import: FAIL" | |
| } | |
| } catch { | |
| Write-Host "❌ Python import error: $_" | |
| $allFunctional = $false | |
| $testResults += "import: ERROR" | |
| } | |
| Write-Host "`nTest Results:" | |
| $testResults | ForEach-Object { Write-Host " $_" } | |
| if ($allFunctional) { | |
| Write-Host "`n✅ All critical tests passed" | |
| echo "success=true" >> $env:GITHUB_OUTPUT | |
| } else { | |
| Write-Host "`n❌ Some critical tests failed" | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=One or more critical tests failed" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| } catch { | |
| Write-Host "❌ Error testing Python: $_" | |
| echo "success=false" >> $env:GITHUB_OUTPUT | |
| echo "error=$($_.Exception.Message)" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| - name: Generate Test Summary | |
| if: always() | |
| run: | | |
| $version = "${{ matrix.version }}" | |
| Write-Host "`n=== Test Summary for Python $version ===" | |
| $phase1_1 = "${{ steps.download-python.outputs.success }}" -eq "true" | |
| $phase1_2 = "${{ steps.verify-python.outputs.success }}" -eq "true" | |
| $phase2 = "${{ steps.test-basic.outputs.success }}" -eq "true" | |
| # Get error messages if any | |
| $error1_1 = "${{ steps.download-python.outputs.error }}" | |
| $error2 = "${{ steps.test-basic.outputs.error }}" | |
| $summary = "### Python $version`n`n" | |
| $summary += "**Phase 1: Installation Validation**`n" | |
| $summary += "- Download & Extract: $(if ($phase1_1) { '✅ PASS' } else { '❌ FAIL' })`n" | |
| if (-not $phase1_1 -and $error1_1) { | |
| $summary += " - Error: $error1_1`n" | |
| } | |
| $summary += "- Verify Executables: $(if ($phase1_2) { '✅ PASS' } else { '❌ FAIL' })`n`n" | |
| if ($phase1_2) { | |
| $summary += "**Phase 2: Basic Functionality**`n" | |
| $summary += "- Test Executables: $(if ($phase2) { '✅ PASS' } else { '❌ FAIL' })`n" | |
| if (-not $phase2 -and $error2) { | |
| $summary += " - Error: $error2`n" | |
| } | |
| $summary += "`n" | |
| } | |
| # Overall status | |
| $allPassed = $phase1_1 -and $phase1_2 -and $phase2 | |
| if ($allPassed) { | |
| $summary += "**Overall Status:** ✅ ALL TESTS PASSED`n" | |
| } else { | |
| $summary += "**Overall Status:** ❌ SOME TESTS FAILED`n" | |
| $summary += "`n" | |
| $summary += "<details>`n" | |
| $summary += "<summary>💡 Click here for troubleshooting tips</summary>`n`n" | |
| $summary += "- Check the workflow logs for detailed error messages`n" | |
| $summary += "- Download the test artifacts for complete logs`n" | |
| $summary += "- Verify the .7z archive structure matches expected format`n" | |
| $summary += "- Ensure all required DLL dependencies are included`n" | |
| $summary += "</details>`n" | |
| } | |
| Write-Host $summary | |
| $summary | Out-File "test-results/summary.md" | |
| # Set job outcome based on test results | |
| if (-not $allPassed) { | |
| Write-Host "##[error]Tests failed for Python $version" | |
| exit 1 | |
| } | |
| - name: Upload Test Results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-results-python-${{ matrix.version }} | |
| path: test-results/ | |
| retention-days: 30 | |
| report-results: | |
| name: Report Test Results | |
| needs: [detect-versions, test-python] | |
| if: always() && needs.detect-versions.outputs.has-changes == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download all test results | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: all-results | |
| continue-on-error: true | |
| - name: Generate PR Comment | |
| run: | | |
| echo "## 🐍 Python Module Tests - Results" > comment.md | |
| echo "" >> comment.md | |
| echo "**Test Date:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> comment.md | |
| # Determine overall test status | |
| TEST_STATUS="${{ needs.test-python.result }}" | |
| VERSIONS='${{ needs.detect-versions.outputs.versions }}' | |
| if [ "$TEST_STATUS" = "skipped" ] || [ "$VERSIONS" = "[]" ]; then | |
| echo "**Status:** ⏭️ Tests skipped - no versions to test" >> comment.md | |
| echo "" >> comment.md | |
| echo "ℹ️ **Why were tests skipped?**" >> comment.md | |
| echo "" >> comment.md | |
| echo "Tests are only run when:" >> comment.md | |
| echo "- PR includes pre-release files (e.g., \`bearsampp-python-3.13.5-2025.8.21.7z\`), OR" >> comment.md | |
| echo "- PR title contains version numbers (e.g., \"3.13.5\", \"3.12.9\") as fallback" >> comment.md | |
| echo "" >> comment.md | |
| echo "**To trigger tests:**" >> comment.md | |
| echo "1. Add pre-release .7z files to your PR, OR" >> comment.md | |
| echo "2. Add version numbers to your PR title (e.g., \"Update Python 3.13.5\"), OR" >> comment.md | |
| echo "3. Manually trigger the workflow from the Actions tab" >> comment.md | |
| elif [ "$TEST_STATUS" = "success" ]; then | |
| echo "**Status:** ✅ All tests passed" >> comment.md | |
| elif [ "$TEST_STATUS" = "failure" ]; then | |
| echo "**Status:** ❌ Some tests failed" >> comment.md | |
| else | |
| echo "**Status:** ⚠️ Tests completed with issues" >> comment.md | |
| fi | |
| echo "" >> comment.md | |
| # Generate badges for each version | |
| if [ "$TEST_STATUS" != "skipped" ] && [ "$VERSIONS" != "[]" ]; then | |
| echo "### 📊 Test Results by Version" >> comment.md | |
| echo "" >> comment.md | |
| # Parse versions and check results | |
| VERSION_LIST=$(echo '${{ needs.detect-versions.outputs.versions }}' | jq -r '.[]') | |
| for version in $VERSION_LIST; do | |
| # Check if summary file exists for this version | |
| SUMMARY_FILE="all-results/test-results-python-${version}/summary.md" | |
| if [ -f "$SUMMARY_FILE" ]; then | |
| # Check if tests passed by looking for "ALL TESTS PASSED" in summary | |
| if grep -q "ALL TESTS PASSED" "$SUMMARY_FILE"; then | |
| # Success badge (green) | |
| echo "" >> comment.md | |
| else | |
| # Failure badge (red) | |
| echo "" >> comment.md | |
| fi | |
| else | |
| # No results badge (gray) | |
| echo "" >> comment.md | |
| fi | |
| done | |
| echo "" >> comment.md | |
| fi | |
| echo "" >> comment.md | |
| # Check if artifacts exist | |
| if [ -d "all-results" ]; then | |
| # Count expected vs actual results | |
| EXPECTED_COUNT=$(echo '${{ needs.detect-versions.outputs.versions }}' | jq '. | length') | |
| ACTUAL_COUNT=$(find all-results -name "summary.md" 2>/dev/null | wc -l) | |
| echo "**Results:** $ACTUAL_COUNT of $EXPECTED_COUNT versions tested" >> comment.md | |
| echo "" >> comment.md | |
| # Check if there are any failures | |
| HAS_FAILURES=false | |
| for version_dir in all-results/test-results-python-*; do | |
| if [ -d "$version_dir" ]; then | |
| for summary_file in "$version_dir"/summary.md; do | |
| if [ -f "$summary_file" ]; then | |
| if ! grep -q "ALL TESTS PASSED" "$summary_file"; then | |
| HAS_FAILURES=true | |
| break 2 | |
| fi | |
| fi | |
| done | |
| fi | |
| done | |
| # Only show detailed results if there are failures | |
| if [ "$HAS_FAILURES" = true ]; then | |
| echo "### 📋 Detailed Test Results" >> comment.md | |
| echo "" >> comment.md | |
| for version_dir in all-results/test-results-python-*; do | |
| if [ -d "$version_dir" ]; then | |
| for summary_file in "$version_dir"/summary.md; do | |
| if [ -f "$summary_file" ]; then | |
| cat "$summary_file" >> comment.md | |
| echo "" >> comment.md | |
| fi | |
| done | |
| fi | |
| done | |
| else | |
| echo "_All tests passed successfully! ✨_" >> comment.md | |
| echo "" >> comment.md | |
| fi | |
| elif [ "$TEST_STATUS" != "skipped" ] && [ "$VERSIONS" != "[]" ]; then | |
| echo "⚠️ No test results available" >> comment.md | |
| echo "" >> comment.md | |
| fi | |
| if [ "$TEST_STATUS" != "skipped" ] && [ "$VERSIONS" != "[]" ]; then | |
| echo "---" >> comment.md | |
| echo "" >> comment.md | |
| echo "### 📋 Test Phases" >> comment.md | |
| echo "" >> comment.md | |
| echo "Each version is tested through the following phases:" >> comment.md | |
| echo "- **Phase 1:** Installation Validation (Download, Extract, Verify Executables)" >> comment.md | |
| echo "- **Phase 2:** Basic Functionality (Test Python Version, pip, Import System)" >> comment.md | |
| echo "" >> comment.md | |
| echo "_Check artifacts for detailed logs._" >> comment.md | |
| fi | |
| cat comment.md | |
| - name: Comment on PR | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const comment = fs.readFileSync('comment.md', 'utf8'); | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const botComment = comments.find(comment => | |
| comment.user.type === 'Bot' && | |
| comment.body.includes('🐍 Python Module Tests') | |
| ); | |
| if (botComment) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: botComment.id, | |
| body: comment | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: comment | |
| }); | |
| } | |
| - name: Display Results Summary (Manual Run) | |
| if: github.event_name == 'workflow_dispatch' | |
| run: | | |
| echo "## 🐍 Python Module Tests - Manual Run Results" | |
| echo "" | |
| cat comment.md |