refactor(forge)!: prepare interface for GitLab support#3194
Conversation
|
🤖 Finished Review · ✅ Success · Started 12:01 AM UTC · Completed 12:19 AM UTC |
PR Summary by Qodoforge: evolve Client interface for multi-forge + GitLab URL parsing
AI Description
Diagram
High-Level Assessment
Files changed (9)
|
Site previewPreview: https://00f1afb5-site.fullsend-ai.workers.dev Commit: |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Code Review by Qodo
1.
|
ReviewClean Phase 0 forge interface preparation — the only changes since the prior review at All type-assertion patterns across FindingsMedium
Low
Prior review resolution
Previous runReviewClean Phase 0 forge interface preparation — the only change since the prior review at All type-assertion patterns across FindingsMedium
Low
Prior review resolution
Previous run (2)ReviewClean Phase 0 forge interface preparation — the method rename from All type-assertion patterns across FindingsMedium
Low
Prior review resolution
Previous run (3)ReviewClean Phase 0 forge interface preparation — the prior review's actionable consumer-completeness finding has been fixed. Both All type-assertion patterns across FindingsMedium
Low
Prior review resolution
Previous run (4)ReviewClean Phase 0 forge interface preparation. All prior review findings persist with no regressions. The type-assertion patterns across FindingsMedium
Low
Prior review resolution
Previous run (5)ReviewClean Phase 0 forge interface preparation. All prior review findings persist with no regressions. The type-assertion patterns across FindingsMedium
Low
Prior review resolution
Labels: PR modifies forge abstraction layer and Go source exclusively Previous run (6)ReviewFindingsMedium
Low
Previous run (7)ReviewFindingsMedium
Low
Previous run (8)ReviewFindingsMedium
Low
Prior review resolution
Previous run (9)ReviewFindingsMedium
Low
Prior review resolution
Previous run (10)ReviewClean Phase 0 forge interface preparation. All actionable feedback from the prior review at FindingsMedium
Low
Prior review resolution
Previous run (11)ReviewFindingsMedium
Low
Previous run (12)ReviewMedium
Low
Previous run (13)ReviewMedium
Low
Previous run (14)ReviewHigh
Medium
Previous run (15)ReviewClean Phase 0 forge interface preparation. All actionable feedback from the prior review at FindingsMedium
Low
Prior review resolution
Previous run (16)ReviewFindingsMedium
Low
Prior review resolution
Previous run (17)ReviewVerdict: comment Solid Phase 0 forge interface preparation. The breaking change is correctly marked ( FindingsMedium
Low
Prior review resolutionAll findings from prior reviews have been evaluated:
Previous run (18)ReviewVerdict: comment Well-structured Phase 0 forge interface preparation. The breaking change is properly marked ( FindingsMedium
Low
Prior review resolutionAll findings from the prior review at SHA
Labels: PR modifies forge abstraction layer (internal/forge/) and Go source exclusively Previous run (19)ReviewVerdict: comment Well-structured Phase 0 forge interface preparation. The breaking change is properly marked ( FindingsMedium
Low
Prior review resolutionAll findings from the prior review at SHA
Labels: PR modifies forge abstraction layer (internal/forge/) and Go source exclusively Previous run (20)ReviewFindingsHigh
Medium
Low
|
3aaf789 to
5eb7fbb
Compare
|
🤖 Finished Review · ✅ Success · Started 11:31 AM UTC · Completed 11:45 AM UTC |
5eb7fbb to
c826375
Compare
|
🤖 Finished Review · ✅ Success · Started 11:53 AM UTC · Completed 12:05 PM UTC |
c826375 to
723b228
Compare
|
🤖 Finished Review · ✅ Success · Started 12:11 PM UTC · Completed 12:30 PM UTC |
723b228 to
0dd5ad9
Compare
|
🤖 Finished Review · ✅ Success · Started 12:36 PM UTC · Completed 12:47 PM UTC |
c5cb18f to
5fa1dbf
Compare
|
🤖 Finished Review · ✅ Success · Started 12:48 PM UTC · Completed 1:01 PM UTC |
5fa1dbf to
3c1558b
Compare
|
🤖 Finished Review · ✅ Success · Started 1:09 PM UTC · Completed 1:20 PM UTC |
Evolve the forge.Client interface for multi-forge support: - Add ErrNotSupported sentinel for operations not available on a forge, with IsNotSupported() helper matching the existing pattern - Add 6 new methods to Client: IsProtectedBranch, Create/Delete/List PipelineSchedule, UpdateCIVariable, CreateProtectedCIVariable - Add PipelineSchedule type with CronTimezone field - CreatePipelineSchedule accepts variables map[string]string parameter for setting schedule variables at creation time - Extract ListOrgInstallations and GetAppClientID into a new GitHubExtensions interface (breaking: callers must type-assert) - Update all callers in appsetup and cli packages to use type assertion, with proper ErrNotSupported handling to skip GitHub-specific flows on non-GitHub forges - Return ErrNotSupported early in appsetup when forge lacks GitHubExtensions instead of falling through to manifest flow - Implement IsProtectedBranch on GitHub via branch protection API with URL-escaped path segments; distinguish "not protected" 404 from genuine not-found 404 by inspecting APIError.Message; close resp.Body on the success path - Stub pipeline/variable methods on GitHub with ErrNotSupported - Support gitlab.com URL parsing in ParseForgeURL (including nested groups via /-/ separator); IsSupportedForge remains github.com-only until fetch support lands — an internal isRecognizedForge helper gates URL parsing - Add FakeClient implementations with round-trip fidelity for pipeline schedules and initialized maps in NewFakeClient - Update harness validation to reject gitlab.com skill URLs with a clear "fetch support has not landed yet" message - Add forge guards in resolve, fetchsvc, and parseAgentSourceURL callers of ParseForgeURL to reject non-GitHub URLs at runtime - Name CI/CD variable methods UpdateCIVariable/CreateProtectedCIVariable to distinguish from the existing RepoVariable family (GitHub Actions variables); use name parameter for consistency - Add godoc explaining RepoVariable vs CIVariable method families and why pipeline schedules live on Client vs GitHubExtensions - Add CreateProtectedCIVariable godoc clarifying unmasked, branch-restricted semantics vs CreateRepoSecret for credentials - Remove dead-code ghOK re-check in admin.go runUninstall verification path (unreachable when existingSlugs is non-empty) - Add tests for IsProtectedBranch (including branch names with / and genuine 404 errors), ErrNotSupported stubs, FakeClient schedule round-trip, GitLab URL parsing, GitLab URL rejection in resolve, fetchsvc, and agent CLI, and non-GitHub forge fallback paths in appsetup and cli BREAKING CHANGE: ListOrgInstallations and GetAppClientID are removed from forge.Client. Callers must type-assert to forge.GitHubExtensions. Signed-off-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
3c1558b to
0c7da2f
Compare
|
🤖 Finished Review · ✅ Success · Started 1:25 PM UTC · Completed 1:36 PM UTC |
waynesun09
left a comment
There was a problem hiding this comment.
Approved — review-squad round 5 (fix verification + ADR review).
All three medium findings from round 4 are verified fixed at 0c7da2f3: the GitLab guard in parseAgentSourceURL (with rejection test), the appsetup non-GitHub test now reaching the type-assertion path, and the CI-variable rename (UpdateCIVariable/CreateProtectedCIVariable with name params and corrected godoc). internal/forge, internal/forge/github, and internal/appsetup test suites pass; the TestRunAgent_* failures in internal/cli are environmental and unrelated to this diff.
Outstanding, non-blocking:
-
PipelineSchedule.CronTimezoneis unsettable through the Client API — see the existing thread. Dead surface with no callers yet; fine as a follow-up when the GitLab implementation lands. -
ADR 0067 convention issues (per
skills/writing-adrs), non-blocking but worth a follow-up PR:- Size: ~483 content lines vs the documented <80 target (>100 is the repo's own red-flag threshold). Most Decision subsections (credential model, cron poller mechanics, tier tables, security comparison) duplicate material that lives in the 1,916-line companion plan — they could compress to 1–2 sentences plus a link.
- One decision per ADR: the credential model (bot PAT, WIF vs protected-variable modes, auto-selection) is an independent decision bundled into the event-dispatch ADR —
architecture.mdalready cites it as answering the per-role identity question, which suggests it deserves its own ADR. The forge-abstraction section likewise restates this PR's interface changes and could shrink to a cross-reference. - Consequences format: 15 bullets + 5-item risk list + comparison table vs the 3–5 one-sentence-bullet target; the risk list and comparison table fit better in the plan or problem docs.
- Minor: the forge-method list in the ADR omits
ListPipelineSchedulesandCreateProtectedCIVariable.
Convention checks that pass for ADR 0067: template compliance (frontmatter, status match, no leading zeros, valid relates_to), cross-references (ADR 0028 already deprecated with a forward link), and living-doc updates (architecture.md and the gitlab-implementation problem doc are already annotated).
|
🤖 Retro · ❌ Terminated · Started 2:30 PM UTC · Ended 2:39 PM UTC |
|
PR #3194 is a large Go interface refactoring (840+/86-, 27 files) to prepare the forge package for GitLab support. The automated review agent ran 12 times across 3 days but its initial pass only found procedural/medium-low issues. The human reviewer (waynesun09, operating as a review-squad with 4-8 LLM agents) found 10+ medium/high-severity correctness findings across 4 rounds that the automated review agent never independently discovered — most critically, a resource leak that 4/8 review-squad agents caught independently. Qodo also found 4 bugs in its first pass that the review agent missed. Three proposals target the correctness sub-agent's Go-specific analysis capabilities:
Proposals filed
|
ralphbean
left a comment
There was a problem hiding this comment.
LGTM. One non-blocking note inline.
| @@ -1881,7 +1898,7 @@ func runUninstall(ctx context.Context, client forge.Client, printer *ui.Printer, | |||
| printer.Blank() | |||
There was a problem hiding this comment.
[non-blocking] ghExt here is only non-nil when ghOK is true, and this line is only reachable when listErr == nil, which requires ghOK. So it's safe today — but the invariant is implicit and spread across ~30 lines of branching. Could we guard this with if !ghOK { ... } or restructure so ghExt stays in scope only where it's valid? Mostly thinking about a future editor who changes the branching above and gets a nil deref.
|
This is marked as a breaking change, so we will be broken on our org? |
Summary
ErrNotSupportedsentinel andPipelineScheduletype to the forge packageforge.Client:IsProtectedBranch,CreatePipelineSchedule,DeletePipelineSchedule,ListPipelineSchedules,UpdateVariable,CreateProtectedVariableListOrgInstallationsandGetAppClientIDfromforge.Clientinto a newGitHubExtensionsinterface, updating all callers (appsetup, cli) to use type-assertionIsProtectedBranchon GitHub via the branch protection API; stubs pipeline/variable methods withErrNotSupportedgitlab.cominIsSupportedForgeandParseForgeURL(including nested groups via/-/separator)FakeClientimplementations for all new methods with configurable fields and call recordersIsProtectedBranch,ErrNotSupportedstubs, and GitLab URL parsingThis is Phase 0 of GitLab forge support: pure refactoring + interface evolution with no behavioral changes to existing functionality.
Test plan
go build ./...passesgo vet ./...passesgo test ./internal/forge/... ./internal/appsetup/... ./internal/cli/...all passmake lintpassesBreaking changes
ListOrgInstallationsandGetAppClientIDare removed fromforge.Clientand moved to the newGitHubExtensionsinterface. All in-tree callers are updated. Out-of-tree callers (if any) must type-assert toforge.GitHubExtensions.🤖 Generated with Claude Code