Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions .github/workflows/backend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ jobs:
runs-on: ubuntu-latest
needs: test
if: always()
outputs:
line_coverage: ${{ steps.coverage-summary.outputs.line_coverage }}
covered_lines: ${{ steps.coverage-summary.outputs.covered_lines }}
total_lines: ${{ steps.coverage-summary.outputs.total_lines }}
coverage_report_outcome: ${{ steps.download-coverage.outcome }}
codecov_outcome: ${{ steps.codecov.outcome }}

steps:
- name: Checkout
Expand All @@ -79,6 +85,42 @@ jobs:
name: backend-coverage-report
path: build/reports/jacoco/test

- name: Calculate line coverage
id: coverage-summary
if: steps.download-coverage.outcome == 'success'
shell: python
run: |
import os
from pathlib import Path
import xml.etree.ElementTree as ET

report = Path("build/reports/jacoco/test/jacocoTestReport.xml")
output = Path(os.environ["GITHUB_OUTPUT"])

line_coverage = "N/A"
covered_lines = "0"
total_lines = "0"

if report.exists():
root = ET.parse(report).getroot()
counter = next(
(item for item in root.findall("counter") if item.get("type") == "LINE"),
None,
)
if counter is not None:
covered = int(counter.get("covered", "0"))
missed = int(counter.get("missed", "0"))
total = covered + missed
covered_lines = str(covered)
total_lines = str(total)
if total > 0:
line_coverage = f"{covered / total * 100:.2f}%"

with output.open("a", encoding="utf-8") as stream:
stream.write(f"line_coverage={line_coverage}\n")
stream.write(f"covered_lines={covered_lines}\n")
stream.write(f"total_lines={total_lines}\n")

- name: Upload coverage to Codecov
id: codecov
if: steps.download-coverage.outcome == 'success'
Expand All @@ -102,3 +144,91 @@ jobs:
echo "| Codecov upload | ${{ steps.codecov.outcome }} |"
echo "| Commit | \`${{ github.sha }}\` |"
} >> "$GITHUB_STEP_SUMMARY"

pr-report:
name: PR report
runs-on: ubuntu-latest
needs:
- test
- coverage
if: >-
always() &&
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository
permissions:
contents: read
pull-requests: write

steps:
- name: Update PR CI report comment
uses: actions/github-script@v9
Comment thread
yong203 marked this conversation as resolved.
env:
TEST_RESULT: ${{ needs.test.result }}
LINE_COVERAGE: ${{ needs.coverage.outputs.line_coverage }}
COVERED_LINES: ${{ needs.coverage.outputs.covered_lines }}
TOTAL_LINES: ${{ needs.coverage.outputs.total_lines }}
COVERAGE_REPORT_OUTCOME: ${{ needs.coverage.outputs.coverage_report_outcome }}
CODECOV_OUTCOME: ${{ needs.coverage.outputs.codecov_outcome }}
WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
CODECOV_PR_URL: https://app.codecov.io/gh/${{ github.repository }}/pull/${{ github.event.pull_request.number }}
with:
script: |
const marker = '<!-- backend-ci-report -->';

const jobResult = (value) => ({
success: 'โœ… Passed',
failure: 'โŒ Failed',
cancelled: 'โšช Cancelled',
skipped: 'โšช Skipped',
})[value] ?? 'โšช Unknown';

const stepResult = (value, successLabel) => ({
success: `โœ… ${successLabel}`,
failure: 'โš ๏ธ Failed',
cancelled: 'โšช Cancelled',
skipped: 'โšช Skipped',
})[value] ?? 'โšช Not available';

const lineCoverage = process.env.LINE_COVERAGE || 'N/A';
const coveredLines = process.env.COVERED_LINES || '0';
const totalLines = process.env.TOTAL_LINES || '0';

const body = [
marker,
'## Backend CI Report',
'',
'| Item | Result |',
'| --- | --- |',
`| Tests | ${jobResult(process.env.TEST_RESULT)} |`,
`| JaCoCo line coverage | ${lineCoverage} (${coveredLines}/${totalLines} lines) |`,
`| Coverage report | ${stepResult(process.env.COVERAGE_REPORT_OUTCOME, 'Generated')} |`,
`| Codecov upload | ${stepResult(process.env.CODECOV_OUTCOME, 'Uploaded')} |`,
'',
`[View workflow run](${process.env.WORKFLOW_URL}) | [View coverage details](${process.env.CODECOV_PR_URL})`,
].join('\n');

const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100,
});
const existing = comments.find((comment) =>
comment.user?.login === 'github-actions[bot]' && comment.body?.includes(marker)
);

if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}
12 changes: 11 additions & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
coverage:
status:
project:
default:
informational: true
patch:
default:
informational: true

comment:
layout: "condensed_header, diff, files"
layout: "condensed_header, condensed_files, condensed_footer"
behavior: default
require_changes: false
require_base: false
require_head: true
hide_project_coverage: false
1 change: 1 addition & 0 deletions docs/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ API ๊ณ„์•ฝ๊ณผ API๋ณ„ ์ƒํƒœ๋Š” `docs/api/README.md`์™€ `docs/api/` ํ•˜์œ„ ๋„๋ฉ”
| Issue | Scope | Status | Notes |
|---|---|---|---|
| [#16](https://github.com/Rewrite-Team/Rewrite-BE/issues/16) | Backend ๋ฌธ์„œ ๊ตฌ์กฐ ๋ฐ ๊ฐœ๋ฐœ ๊ทœ์น™ ์ •๋ฆฌ | Open | ํ˜„์žฌ ๋ฌธ์„œ ๊ตฌ์กฐ์™€ ์ž‘์—… ๊ทœ์น™ ์ •๋ฆฌ ๋ฒ”์œ„ |
| [#46](https://github.com/Rewrite-Team/Rewrite-BE/issues/46) | Codecov ๋ฐ PR CI ๋ฆฌํฌํŠธ ๊ฐœ์„  | Open | Codecov informational status, JaCoCo ์ˆ˜์น˜์™€ Codecov ์ƒ์„ธ ๋งํฌ๋ฅผ ํฌํ•จํ•œ ๊ณ ์ • CI ๋Œ“๊ธ€ ๊ตฌ์„ฑ |

## Current Recommended Next Work

Expand Down
11 changes: 11 additions & 0 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,14 @@ Jacoco๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉฐ, ํ…Œ์ŠคํŠธ ํ›„ `jacocoTestReport`๊ฐ€ ์‹คํ–‰๋œ
build/reports/jacoco/test/html/index.html
build/reports/jacoco/test/jacocoTestReport.xml
```

## Pull Request CI Report

- `test` job ์‹คํŒจ๋Š” ๊ธฐ์กด๊ณผ ๋™์ผํ•˜๊ฒŒ PR check๋ฅผ ์‹คํŒจ ์ฒ˜๋ฆฌํ•œ๋‹ค.
- Codecov project/patch status๋Š” informational๋กœ ์‚ฌ์šฉํ•˜๋ฉฐ ์ปค๋ฒ„๋ฆฌ์ง€ ์ˆ˜์น˜๋งŒ ์ œ๊ณตํ•œ๋‹ค.
- ์ปค๋ฒ„๋ฆฌ์ง€ ๊ฐ์†Œ๋‚˜ Codecov ์—…๋กœ๋“œ ์‹คํŒจ๋งŒ์œผ๋กœ PR ๋ณ‘ํ•ฉ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๋Š”๋‹ค.
- `coverage` job์€ JaCoCo XML์˜ ์ „์ฒด line coverage์™€ Codecov ์—…๋กœ๋“œ ๊ฒฐ๊ณผ๋ฅผ output์œผ๋กœ ์ œ๊ณตํ•œ๋‹ค.
- `pr-report` job์€ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ, line coverage, Codecov ์—…๋กœ๋“œ ์ƒํƒœ์™€ Codecov PR ์ƒ์„ธ ๋งํฌ๋ฅผ ๊ณ ์ • ๋Œ“๊ธ€๋กœ ํ‘œ์‹œํ•œ๋‹ค.
- ๊ณ ์ • ๋Œ“๊ธ€์€ ์ƒˆ workflow ์‹คํ–‰๋งˆ๋‹ค ๊ธฐ์กด `github-actions[bot]` ๋Œ“๊ธ€์„ ๊ฐฑ์‹ ํ•œ๋‹ค.
- PR ์ฝ”๋“œ ์‹คํ–‰ job์—๋Š” ์“ฐ๊ธฐ ๊ถŒํ•œ์„ ์ฃผ์ง€ ์•Š๊ณ , checkout์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š” `pr-report` job์—๋งŒ `pull-requests: write`๋ฅผ ๋ถ€์—ฌํ•œ๋‹ค.
- ์™ธ๋ถ€ fork PR์—์„œ๋Š” ์“ฐ๊ธฐ ํ† ํฐ ์ œํ•œ์„ ๊ณ ๋ คํ•ด ๊ณ ์ • ๋Œ“๊ธ€ ์ž‘์„ฑ์„ ๊ฑด๋„ˆ๋›ด๋‹ค.
Loading