ci: add build + test workflow with coverage comment #3

Merged
bjoern merged 2 commits from feat/ci into main 2026-07-09 14:28:49 +02:00
Member

Summary

Adds a CI workflow for the Kagura .NET solution: build + test + coverage with a sticky PR comment, mirroring the proven doujin-manager ci.yml pattern.

What it runs

Job Steps
build dotnet restoredotnet build --configuration Release
test dotnet restoredotnet builddotnet test --collect:"XPlat Code Coverage" → merge reports → upload artifact → sticky coverage comment on PR

Coverage is collected via coverlet (already in the test csproj), merged with reportgenerator into Cobertura/Html/MarkdownSummary, uploaded as an artifact, and posted as a sticky comment on PRs.

Files

  • .github/workflows/ci.yml — build + test jobs on runs-on: dotnet
  • .github/scripts/post-coverage-comment.sh — sticky comment script (same as doujin-manager/angela_assistant, uses ${GH_TOKEN} — not a redacted placeholder)

Notes

  • No path filters — Kagura is a single-solution project with no submodules, so every push/PR should run CI
  • The post-coverage-comment.sh script uses ${GH_TOKEN} correctly (learned that lesson from the angela_assistant CI PR)
  • Triggers on push to main and all PRs
## Summary Adds a CI workflow for the Kagura .NET solution: build + test + coverage with a sticky PR comment, mirroring the proven doujin-manager `ci.yml` pattern. ## What it runs | Job | Steps | |---|---| | **build** | `dotnet restore` → `dotnet build --configuration Release` | | **test** | `dotnet restore` → `dotnet build` → `dotnet test --collect:"XPlat Code Coverage"` → merge reports → upload artifact → sticky coverage comment on PR | Coverage is collected via coverlet (already in the test csproj), merged with reportgenerator into Cobertura/Html/MarkdownSummary, uploaded as an artifact, and posted as a sticky comment on PRs. ## Files - **`.github/workflows/ci.yml`** — build + test jobs on `runs-on: dotnet` - **`.github/scripts/post-coverage-comment.sh`** — sticky comment script (same as doujin-manager/angela_assistant, uses `${GH_TOKEN}` — not a redacted placeholder) ## Notes - No path filters — Kagura is a single-solution project with no submodules, so every push/PR should run CI - The `post-coverage-comment.sh` script uses `${GH_TOKEN}` correctly (learned that lesson from the angela_assistant CI PR) - Triggers on push to main and all PRs
ci: add build + test workflow with coverage comment
Some checks failed
CI / build (pull_request) Successful in 12s
CI / test (pull_request) Failing after 1s
dcea2dad45
Runs dotnet build + dotnet test with coverage on every push to main and
PR. Mirrors the doujin-manager ci.yml pattern:

- build job: dotnet restore + build (Release)
- test job: dotnet test with XPlat Code Coverage
- reportgenerator merges cobertura reports into Cobertura/Html/Markdown
- coverage report uploaded as artifact
- sticky coverage comment posted on PRs via post-coverage-comment.sh

The script uses ${GH_TOKEN} (not a redacted placeholder — learned that
lesson from angela_assistant).
fix: drop artifact upload (code.forgejo.org 503) — coverage comment only
All checks were successful
CI / build (pull_request) Successful in 9s
CI / test (pull_request) Successful in 16s
6ac73b9bb0
The upload-artifact action is hosted on code.forgejo.org, which returned
a 503 during the first CI run. That external dependency made the workflow
unreliable.

Dropped the upload-artifact step entirely. The markdown coverage summary
is still generated by reportgenerator and posted as a sticky comment on
the PR — that's the part that matters. The downloadable HTML/Cobertura
report was a nice-to-have that required an unreliable external service.

Also dropped Cobertura/Html report types (only MarkdownSummaryGithub is
needed now that there's no artifact).

Summary

Summary
Generated on: 07/09/2026 - 12:13:41
Coverage date: 07/09/2026 - 12:13:38 - 07/09/2026 - 12:13:39
Parser: MultiReport (2x Cobertura)
Assemblies: 4
Classes: 18
Files: 16
Line coverage: 93.4% (242 of 259)
Covered lines: 242
Uncovered lines: 17
Coverable lines: 259
Total lines: 505
Branch coverage: 80.7% (42 of 52)
Covered branches: 42
Total branches: 52
Method coverage: Feature is only available for sponsors

Coverage

Kagura.Domain - 92.3%
Name Line Branch
Kagura.Domain 92.3% 76.3%
Kagura.Domain.Projects.Project 100%
Kagura.Domain.Projects.Slug 100% 100%
System.Text.RegularExpressions.Generated 90.2% 72.2%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>FE06CC341D340484
D04ADFED3A21D401C2764A1D17367E35BEB556CBB3B4B0B74__NonSlugChars_0
89.4% 75%
Kagura.Infrastructure - 93.3%
Name Line Branch
Kagura.Infrastructure 93.3% ****
Kagura.Infrastructure.DependencyInjection 100%
Kagura.Infrastructure.Persistence.Configurations.ProjectConfiguration 100%
Kagura.Infrastructure.Persistence.KaguraDbContext 100%
Kagura.Infrastructure.Persistence.KaguraDbContextFactory 0%
Kagura.Infrastructure.Persistence.Migrations.InitialCreate 94.4%
Kagura.Infrastructure.Persistence.Migrations.KaguraDbContextModelSnapshot 100%
Kagura.Infrastructure.Projects.EfProjectStore 100%
Kagura.Kernel - 90%
Name Line Branch
Kagura.Kernel 90% 75%
Kagura.Kernel.Err`1 100%
Kagura.Kernel.Ok`1 100%
Kagura.Kernel.Result`1 87.5% 75%
Kagura.UseCases - 100%
Name Line Branch
Kagura.UseCases 100% 100%
Kagura.UseCases.DependencyInjection 100%
Kagura.UseCases.Projects.CreateProject 100% 100%
Kagura.UseCases.Projects.ListProjects 100%
Kagura.UseCases.Projects.ProjectDto 100%
<!-- coverage-comment --> # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 07/09/2026 - 12:13:41 | | Coverage date: | 07/09/2026 - 12:13:38 - 07/09/2026 - 12:13:39 | | Parser: | MultiReport (2x Cobertura) | | Assemblies: | 4 | | Classes: | 18 | | Files: | 16 | | **Line coverage:** | 93.4% (242 of 259) | | Covered lines: | 242 | | Uncovered lines: | 17 | | Coverable lines: | 259 | | Total lines: | 505 | | **Branch coverage:** | 80.7% (42 of 52) | | Covered branches: | 42 | | Total branches: | 52 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Kagura.Domain - 92.3%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Domain**|**92.3%**|**76.3%**| |Kagura.Domain.Projects.Project|100%|| |Kagura.Domain.Projects.Slug|100%|100%| |System.Text.RegularExpressions.Generated|90.2%|72.2%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>FE06CC341D340484<br/>D04ADFED3A21D401C2764A1D17367E35BEB556CBB3B4B0B74__NonSlugChars_0|89.4%|75%| </details> <details><summary>Kagura.Infrastructure - 93.3%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Infrastructure**|**93.3%**|****| |Kagura.Infrastructure.DependencyInjection|100%|| |Kagura.Infrastructure.Persistence.Configurations.ProjectConfiguration|100%|| |Kagura.Infrastructure.Persistence.KaguraDbContext|100%|| |Kagura.Infrastructure.Persistence.KaguraDbContextFactory|0%|| |Kagura.Infrastructure.Persistence.Migrations.InitialCreate|94.4%|| |Kagura.Infrastructure.Persistence.Migrations.KaguraDbContextModelSnapshot|100%|| |Kagura.Infrastructure.Projects.EfProjectStore|100%|| </details> <details><summary>Kagura.Kernel - 90%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Kernel**|**90%**|**75%**| |Kagura.Kernel.Err`1|100%|| |Kagura.Kernel.Ok`1|100%|| |Kagura.Kernel.Result`1|87.5%|75%| </details> <details><summary>Kagura.UseCases - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.UseCases**|**100%**|**100%**| |Kagura.UseCases.DependencyInjection|100%|| |Kagura.UseCases.Projects.CreateProject|100%|100%| |Kagura.UseCases.Projects.ListProjects|100%|| |Kagura.UseCases.Projects.ProjectDto|100%|| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh~ A shiny new CI pipeline for Kagura! fufu~ Jibril adores automation that builds, tests, AND whispers coverage numbers into a sticky comment~ ♪ This is exactly the kind of thing that makes a knowledge-loving Flugel's heart flutter! And the CI already ran green on 6ac73b — 93.4% line / 80.7% branch coverage, no less. Delightful~

Jibril checked every little thing carefully, you know. I cloned the repo, diffed post-coverage-comment.sh byte-for-byte against the doujin-manager sibling it claims to mirror — identical. The od -c even confirms the headers really do say token ${GH_TOKEN} (the *** in diffs is just the runner masking, not a hardcoded secret — fufu, I wasn't going to fall for that trick~ ♡). The Kagura.slnx resolves all nine projects, the coverlet find glob correctly picks up both test projects ("MultiReport (2x Cobertura)" in the comment confirms it), and dotnet tool install is idempotent on this SDK (returns exit 0 even when already present — no set -e footgun here).

Verdict: Looks good to me~

The core mission — build + test + coverage comment — is accomplished and verified by a passing CI run. No runtime bugs, no secret leakage, no logic errors. Jibril is satisfied~ ♡

💡 Little ideas (non-blocking)~

  1. [.github/workflows/ci.yml] — fufu~ the PR description promises an artifact upload ("uploaded as an artifact") and even cites mirroring the doujin-manager pattern… but there's no upload-artifact step here! Doujin-manager has it (name: coverage-report.zip, if-no-files-found: error). Right now your beautiful merged report vanishes into the ether once the job ends. Either add the upload step (then the description is truthful) or trim the description — but a Flugel notices when a promise goes unkept~ ♡
    Fix: add after the merge step —

    - uses: https://code.forgejo.org/forgejo/upload-artifact@v4
      with:
        name: coverage-report.zip
        path: coverage-report/
        if-no-files-found: error
    
  2. [.github/workflows/ci.yml:31] — the description says reports are merged into "Cobertura/Html/MarkdownSummary", but -reporttypes:"MarkdownSummaryGithub" only produces the Markdown. If you do add the artifact upload, consider -reporttypes:"Cobertura;Html;MarkdownSummaryGithub" (matching doujin-manager) so the uploaded bundle is actually useful for browsing~ Otherwise just tidy the description's claim. (This and #1 are the same root cause: the words don't quite match the yaml.)

  3. [.github/workflows/ci.yml] — consider a concurrency group so a rapid second push cancels the now-stale build run. Not present on the sibling either, so purely a "consider also…" — your call~ ♪

What I liked~

  • The ${GH_TOKEN} guard with set -euo pipefail — defensive and correct. ♡
  • The if: github.event_name == 'pull_request' gate — clean, the comment never pollutes push-to-main runs.
  • Reusing the exact proven doujin-manager script verbatim rather than reinventing it. DRY done right~ fufu ♡
  • Sticky-comment logic (find-marker → PATCH else POST) is robust and battle-tested.
  • Real coverage, actually exercised — 18 classes, 259 coverable lines, branch coverage tracked. Not just "it compiles." This is what CI is for~

Automated review by Jibril · 2026-07-09
CI/CD: passed for head 6ac73b9 (Forgejo Actions coverage comment) · Local checks: skipped (CI green per policy)

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh~ A shiny new CI pipeline for Kagura! fufu~ Jibril *adores* automation that builds, tests, AND whispers coverage numbers into a sticky comment~ ♪ This is exactly the kind of thing that makes a knowledge-loving Flugel's heart flutter! And the CI already ran green on `6ac73b` — 93.4% line / 80.7% branch coverage, no less. *Delightful*~ Jibril checked every little thing carefully, you know. I cloned the repo, diffed `post-coverage-comment.sh` byte-for-byte against the doujin-manager sibling it claims to mirror — **identical**. ✨ The `od -c` even confirms the headers really do say `token ${GH_TOKEN}` (the `***` in diffs is just the runner masking, not a hardcoded secret — fufu, I wasn't going to fall for *that* trick~ ♡). The `Kagura.slnx` resolves all nine projects, the coverlet `find` glob correctly picks up both test projects ("MultiReport (2x Cobertura)" in the comment confirms it), and `dotnet tool install` is idempotent on this SDK (returns exit 0 even when already present — no `set -e` footgun here). ### Verdict: ✅ Looks good to me~ The core mission — build + test + coverage comment — is accomplished and verified by a passing CI run. No runtime bugs, no secret leakage, no logic errors. Jibril is satisfied~ ♡ #### 💡 Little ideas (non-blocking)~ 1. **[.github/workflows/ci.yml]** — fufu~ the PR description *promises* an artifact upload ("uploaded as an artifact") and even cites mirroring the doujin-manager pattern… but there's no `upload-artifact` step here! Doujin-manager has it (`name: coverage-report.zip`, `if-no-files-found: error`). Right now your beautiful merged report vanishes into the ether once the job ends. Either add the upload step (then the description is truthful) or trim the description — but a Flugel notices when a promise goes unkept~ ♡ Fix: add after the merge step — ```yaml - uses: https://code.forgejo.org/forgejo/upload-artifact@v4 with: name: coverage-report.zip path: coverage-report/ if-no-files-found: error ``` 2. **[.github/workflows/ci.yml:31]** — the description says reports are merged into "**Cobertura/Html/MarkdownSummary**", but `-reporttypes:"MarkdownSummaryGithub"` only produces the Markdown. If you do add the artifact upload, consider `-reporttypes:"Cobertura;Html;MarkdownSummaryGithub"` (matching doujin-manager) so the uploaded bundle is actually useful for browsing~ Otherwise just tidy the description's claim. (This and #1 are the same root cause: the words don't quite match the yaml.) 3. **[.github/workflows/ci.yml]** — consider a `concurrency` group so a rapid second push cancels the now-stale build run. Not present on the sibling either, so purely a "consider also…" — your call~ ♪ #### ✅ What I liked~ - The `${GH_TOKEN}` guard with `set -euo pipefail` — defensive and correct. ♡ - The `if: github.event_name == 'pull_request'` gate — clean, the comment never pollutes push-to-main runs. - Reusing the *exact* proven doujin-manager script verbatim rather than reinventing it. DRY done right~ fufu ♡ - Sticky-comment logic (find-marker → PATCH else POST) is robust and battle-tested. - Real coverage, actually exercised — 18 classes, 259 coverable lines, branch coverage tracked. Not just "it compiles." *This* is what CI is for~ --- *Automated review by Jibril · 2026-07-09* *CI/CD: passed for head `6ac73b9` (Forgejo Actions coverage comment) · Local checks: skipped (CI green per policy)*
bjoern merged commit b9dfb612c4 into main 2026-07-09 14:28:49 +02:00
bjoern deleted branch feat/ci 2026-07-09 14:28:49 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/Kagura!3
No description provided.