Enhance modes #26
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: Tests | |
on: | |
push: | |
branches: [ "main", "develop" ] | |
pull_request: | |
branches: [ "main", "develop" ] | |
permissions: | |
contents: read | |
pull-requests: write | |
issues: write | |
jobs: | |
tests: | |
name: Tests (PHP ${{ matrix.php }}) | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
php: ['8.4'] | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Setup PHP | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: ${{ matrix.php }} | |
extensions: mbstring, hash, sodium | |
coverage: xdebug | |
- name: Install dependencies | |
uses: ramsey/composer-install@v3 | |
- name: Check code style | |
run: composer lint | |
continue-on-error: true | |
id: lint | |
- name: Run tests with coverage | |
run: ./vendor/bin/phpunit --coverage-clover=coverage/clover.xml --coverage-html=coverage/html --coverage-text | |
continue-on-error: true | |
id: tests | |
- name: Check coverage percentage | |
id: coverage | |
run: | | |
if [ -f coverage/clover.xml ]; then | |
COVERAGE=$(php -r " | |
\$xml = simplexml_load_file('coverage/clover.xml'); | |
\$metrics = \$xml->project->metrics; | |
\$statements = (float)\$metrics['statements']; | |
\$coveredstatements = (float)\$metrics['coveredstatements']; | |
if (\$statements > 0) { | |
\$percentage = (\$coveredstatements / \$statements) * 100; | |
echo round(\$percentage, 2); | |
} else { | |
echo '0'; | |
} | |
") | |
echo "percentage=$COVERAGE" >> $GITHUB_OUTPUT | |
echo "Coverage: $COVERAGE%" | |
if (( $(echo "$COVERAGE < 100" | bc -l) )); then | |
echo "coverage_failed=true" >> $GITHUB_OUTPUT | |
echo "❌ Coverage requirement not met: $COVERAGE% (required: 100%)" | |
exit 1 | |
else | |
echo "coverage_failed=false" >> $GITHUB_OUTPUT | |
echo "✅ Coverage requirement met: $COVERAGE%" | |
fi | |
else | |
echo "percentage=0" >> $GITHUB_OUTPUT | |
echo "coverage_failed=true" >> $GITHUB_OUTPUT | |
echo "❌ Coverage report not found" | |
exit 1 | |
fi | |
- name: Comment on PR (Failure) | |
if: (steps.lint.outcome == 'failure' || steps.coverage.outputs.coverage_failed == 'true') && github.event_name == 'pull_request' | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const fs = require('fs'); | |
let lintStatus = '${{ steps.lint.outcome }}'; | |
let testStatus = '${{ steps.tests.outcome }}'; | |
let coveragePercentage = '${{ steps.coverage.outputs.percentage }}'; | |
let coverageFailed = '${{ steps.coverage.outputs.coverage_failed }}'; | |
let message = `## 🔍 Test Results - PHP ${{ matrix.php }}\n\n`; | |
if (lintStatus === 'failure') { | |
message += `❌ **Code Style Check Failed**\n\n`; | |
message += `Code style violations found. Please run \`composer fix\` to automatically fix them.\n\n`; | |
} else { | |
message += `✅ **Code Style Check Passed**\n\n`; | |
} | |
if (testStatus === 'failure') { | |
message += `❌ **Tests Failed**\n\n`; | |
message += `Some tests are failing. Please check the [workflow run](${context.payload.pull_request.html_url}/checks) for details.\n\n`; | |
} else { | |
message += `✅ **Tests Passed**\n\n`; | |
} | |
if (coverageFailed === 'true') { | |
message += `❌ **Code Coverage: ${coveragePercentage}%** (Required: 100%)\n\n`; | |
message += `Code coverage requirement not met. Please add tests to achieve 100% coverage.\n\n`; | |
} else { | |
message += `✅ **Code Coverage: ${coveragePercentage}%**\n\n`; | |
} | |
message += `---\n*This comment was automatically generated by the test workflow.*`; | |
// Check if we already commented on this PR | |
const comments = await github.rest.issues.listComments({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
}); | |
const botComment = comments.data.find(comment => | |
comment.user.login === 'github-actions[bot]' && | |
comment.body.includes('Test Results - PHP ${{ matrix.php }}') | |
); | |
if (botComment) { | |
// Update existing comment | |
await github.rest.issues.updateComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
comment_id: botComment.id, | |
body: message | |
}); | |
} else { | |
// Create new comment | |
await github.rest.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
body: message | |
}); | |
} | |
- name: Upload coverage reports | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: coverage-reports-php${{ matrix.php }} | |
path: coverage/ | |
retention-days: 30 | |
- name: Fail on lint errors | |
if: steps.lint.outcome == 'failure' | |
run: | | |
echo "❌ Build failed due to code style violations" | |
exit 1 | |
- name: Fail on coverage < 100% | |
if: steps.coverage.outputs.coverage_failed == 'true' | |
run: | | |
echo "❌ Build failed due to insufficient code coverage: ${{ steps.coverage.outputs.percentage }}%" | |
exit 1 |