[FEATURE] 리팩터링 챕터 8 작성 완료 #23
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: PR Test & Coverage Report | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| jobs: | |
| test: | |
| name: Run Tests & Coverage | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12.6' | |
| - name: Install Poetry | |
| run: | | |
| pipx install poetry | |
| - name: Install Dependencies | |
| run: | | |
| poetry install --no-root | |
| - name: Run Tests (by Makefile) | |
| run: | | |
| poetry run make test | |
| - name: Combine Coverage Report (XML) | |
| run: | | |
| poetry run coverage xml -o coverage.xml | |
| - name: Parse Coverage for Comment | |
| id: coverage-comment | |
| run: | | |
| percentage=$(poetry run python -c " | |
| import xml.etree.ElementTree as ET | |
| tree = ET.parse('coverage.xml') | |
| root = tree.getroot() | |
| line_rate = float(root.attrib['line-rate']) | |
| print(f'{line_rate * 100:.2f}') | |
| ") | |
| echo "COVERAGE_PERCENT=$percentage" >> "$GITHUB_OUTPUT" | |
| - name: Parse Merged JUnit Results for Summary (only merged-results.xml) | |
| id: junit-summary | |
| run: | | |
| summary=$(poetry run python -c " | |
| import xml.etree.ElementTree as ET | |
| tree = ET.parse('test-results/merged-results.xml') | |
| root = tree.getroot() | |
| # 'testsuites' 또는 'testsuite'에 따라 동작 다름 (방어코드) | |
| if root.tag == 'testsuites': | |
| suites = root.findall('testsuite') | |
| elif root.tag == 'testsuite': | |
| suites = [root] | |
| else: | |
| raise ValueError(f'Unexpected root tag: {root.tag}') | |
| total_tests = 0 | |
| total_failures = 0 | |
| total_skipped = 0 | |
| total_errors = 0 | |
| total_time = 0.0 | |
| for suite in suites: | |
| total_tests += int(suite.attrib.get('tests', 0)) | |
| total_failures += int(suite.attrib.get('failures', 0)) | |
| total_skipped += int(suite.attrib.get('skipped', 0)) | |
| total_errors += int(suite.attrib.get('errors', 0)) | |
| total_time += float(suite.attrib.get('time', 0)) | |
| passed = total_tests - total_failures - total_skipped | |
| print(f'PASSED={passed}') | |
| print(f'FAILED={total_failures}') | |
| print(f'SKIPPED={total_skipped}') | |
| print(f'TIME={total_time:.2f}') | |
| ") | |
| echo "$summary" >> "$GITHUB_OUTPUT" | |
| - name: Publish Merged Test Results Summary | |
| uses: test-summary/action@v2 | |
| with: | |
| paths: "test-results/merged-results.xml" | |
| if: always() | |
| - name: Upload Coverage HTML Report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-html | |
| path: htmlcov/ | |
| - name: Upload All JUnit XML Files (for archive) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: junit-xml-reports | |
| path: test-results/ | |
| - name: Add Test & Coverage Summary Comment to PR | |
| uses: peter-evans/create-or-update-comment@v4 | |
| with: | |
| issue-number: ${{ github.event.pull_request.number }} | |
| body: | | |
| ## 📝 Test & Coverage Report | |
| | Metric | Value | | |
| |--------|-----| | |
| | ✅ Passed | ${{ steps.junit-summary.outputs.PASSED }} | | |
| | ❌ Failed | ${{ steps.junit-summary.outputs.FAILED }} | | |
| | ⏩ Skipped | ${{ steps.junit-summary.outputs.SKIPPED }} | | |
| | ⏱️ Time | ${{ steps.junit-summary.outputs.TIME }}s | | |
| | 📊 Line Coverage | ${{ steps.coverage-comment.outputs.COVERAGE_PERCENT }}% | | |
| token: ${{ secrets.PAT_TOKEN }} |