mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 15:08:47 -07:00
feat: link QA test cases to GitHub issues
File a GitHub issue from a failing test case, and let the case follow the
issue afterwards.
POST api/testcasemanagement/v1/testcase/{id}/issue file + link
DELETE api/testcasemanagement/v1/testcase/{id}/issue unlink
POST api/testcasemanagement/v1/issues/sync reconcile now
plus TestCaseIssueReconciler, a background sweep on the same code path as the
manual endpoint so the two cannot drift. Admin-gated: these are not part of the
2023 client's surface, unlike the existing test-case routes which are open
because the watch gates that tab client-side.
The link lives in TestCaseEntity.JiraBugUrl — the field Rec Room's own tooling
used for the bug filed against a failing case. That avoids a migration, which
matters more here than the name: the Postgres path is EnsureCreated-only and
never replays migrations, so a new column has to be added twice or it is missing
in production. A leftover genuine Jira link is ignored rather than misparsed,
since the issue number is only read from a GitHub-shaped URL.
Filing is idempotent — a case already carrying a live issue returns it instead
of filing again, so sweeping a failing pass repeatedly does not spam duplicates.
Unlinking leaves the issue alone; closing someone's issue as a side effect of
tidying a QA link would be the wrong call.
Reconcile moves a case only between the two states it owns: closed+Failed goes
to NotYetTested, open+NotYetTested goes back to Failed. A closed issue is NOT
marked Passed — closing is a developer's claim that the fix landed, not a
tester's observation that the case passes, so the case goes back in the queue.
The first draft flipped any non-Failed case to Failed on an open issue, which
contradicted its own doc comment and yanked a case out from under a tester
mid-claim; the test for that caught it.
Everything degrades rather than fails when unconfigured: IsConfigured is false
without a token, endpoints answer 503 with the reason, and the reconciler logs
once and idles. GitHub is faked in the tests, which cover idempotency, both
state transitions, the mid-claim case, and the unconfigured path.
This commit is contained in:
@@ -179,6 +179,59 @@ Enforcement caveat carried over from `RoomEntity.MaxCapacity`: this is the
|
||||
advertised cap. The client never sets Photon `RoomOptions.MaxPlayers`, so
|
||||
hard enforcement still needs a ClientMod Photon patch.
|
||||
|
||||
## Test cases ↔ GitHub issues
|
||||
|
||||
QA test cases can file and track GitHub issues. Configure with:
|
||||
|
||||
| Key | Meaning |
|
||||
| --- | --- |
|
||||
| `GitHub:Token` | PAT with `issues:write` on the target repo |
|
||||
| `GitHub:Repository` | `owner/name`, e.g. `DorkSquadRR/DorkNet` |
|
||||
| `GitHub:ReconcileIntervalMinutes` | Sweep interval, default 15; `0` disables sweeps but leaves the manual endpoint working |
|
||||
|
||||
**Without a token nothing breaks.** `IGitHubIssues.IsConfigured` is false, the
|
||||
endpoints answer `503` with the reason, and the background reconciler logs once
|
||||
and idles. A server with no GitHub credentials is a normal deployment.
|
||||
|
||||
Endpoints (admin-gated — these are not part of the 2023 client's surface):
|
||||
|
||||
- `POST api/testcasemanagement/v1/testcase/{id}/issue` — file and link.
|
||||
**Idempotent**: a case already carrying a live issue returns that issue
|
||||
instead of filing a duplicate, so sweeping a failing pass repeatedly is safe.
|
||||
The issue body carries the description, key, room, test pass and tester
|
||||
comments; labels are `qa` plus the case's own tags.
|
||||
- `DELETE api/testcasemanagement/v1/testcase/{id}/issue` — unlink only. The
|
||||
issue itself is left alone; closing someone's issue as a side effect of
|
||||
tidying a QA link would be the wrong call.
|
||||
- `POST api/testcasemanagement/v1/issues/sync` — reconcile now. The background
|
||||
service runs the same code path on its interval, so manual and automatic
|
||||
cannot drift.
|
||||
|
||||
### Where the link is stored
|
||||
|
||||
In `TestCaseEntity.JiraBugUrl` — the field Rec Room's own QA tooling used for
|
||||
the bug filed against a failing case. Reusing it means **no migration**, which
|
||||
matters more here than the name: the Postgres path is `EnsureCreated`-only and
|
||||
never replays migrations, so a new column has to be added twice (migration *and*
|
||||
an idempotent `Ensure*` patch) or it is simply missing in production. A field
|
||||
that already exists everywhere has neither problem, and the admin UI renders it
|
||||
already. A leftover genuine Jira link is ignored rather than misparsed — the
|
||||
issue number is only read from a URL matching the GitHub issue shape.
|
||||
|
||||
### What the reconciler will and won't change
|
||||
|
||||
| Issue | Case status | Result |
|
||||
| --- | --- | --- |
|
||||
| Closed | Failed | → NotYetTested |
|
||||
| Open | NotYetTested | → Failed |
|
||||
| anything | Claimed / Passed | untouched |
|
||||
|
||||
A closed issue does **not** mark the case Passed: closing is a developer's claim
|
||||
that the fix landed, not a tester's observation that the case passes, so it goes
|
||||
back in the queue for another run. And only those two states are the
|
||||
reconciler's to move — a case a tester has Claimed, or marked Passed after
|
||||
verifying the fix, is never dragged back underneath them.
|
||||
|
||||
## Build And Deploy
|
||||
|
||||
The service Dockerfile builds the admin SPA for service images that need
|
||||
|
||||
Reference in New Issue
Block a user