[CMPT-5389] feat(pipelines): add dr pipeline command behind feature gate with shared infrastructure - #517
Conversation
ajalon1
left a comment
There was a problem hiding this comment.
General questions about internal/pipelines. It's a style thing mostly, but you should rename the package internal/drapi/pipelines since almost all of this has to do with API handling.
I'm also wondering about the overall architecture. This feels like there will be a level of strong coupling between the command code and the API code in internal/pipelines. The Workload API folks settled on a filesapi Client interface that hides all of this detail from the command code. I'd suggest looking at that.
Requesting changes for:
- command name
- hiding docs from mkdocs TOC
- removing getToken memoization
- dealing w. resolveToken refactor
| } | ||
|
|
||
| return config.GetAPIKey(context.Background()) | ||
| } |
There was a problem hiding this comment.
Unlike the change to getToken(), I think this one is worth doing, but this is not a complete refactor; drapi.post, .delete, .patch should use it.
You can either make those changes here, or add a TODO and pull everything out into a separate PR.
There was a problem hiding this comment.
I'll do the refactor on post/delete/patch and move this function into auth.go since that would seem more natural place for it after the refactors
|
I like the direction you're going with token memoization -- I think it will clean up some small bits of our auth story -- but you either need to complete the refactors here or do them separately. Also, scope.go took me a while to parse, but it actually seems pretty clear and clean. Hopefully easy for your team to manage going forward. :) |
|
I just realized that #493 already tackles the getToken memoization issues. Definitely pull out getToken() refactors. :) |
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit dc1d016. Configure here.
ajalon1
left a comment
There was a problem hiding this comment.
LGTM once PR checks are green
|
🔐 Fork smoke tests started by maintainer ⏳ Security scans passed. Running smoke tests... Commit: |
|
✅ All smoke tests passed! (Fork PR) ✅ Security Scan: success |
…rastructure
Registers the `pipelines` command group (feature-gated behind
DATAROBOT_CLI_FEATURE_PIPELINES=true) and introduces the shared transport
layer used by all subsequent subcommand PRs:
- cmd/root.go: wire pipelines.Cmd() into the CLI root via CommandAdder
- cmd/pipelines/cmd.go: parent command with features.SetGate("pipelines")
- internal/drapi/client.go: NewHTTPClient, AuthorizeRequest helpers
- internal/drapi/get.go: resolveToken with viperx (replaces raw viper)
- internal/pipelines/transport.go: doJSON, doDelete, decodeHTTPError
- internal/pipelines/scope.go: draft/locked URL resolution
- internal/pipelines/time.go: custom Time for naive UTC datetime parsing
- docs: add pipelines entry to README.md command table and mkdocs nav
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… docs, auth refactor
- Rename internal/pipelines → internal/drapi/pipelines (reviewer: treat as
drapi sub-package consistent with internal/drapi/filesapi)
- transport.go: replace drapi.AuthorizeRequest with drapi.SetAuthHeaders
(the pre-existing canonical helper); inline &http.Client{Timeout: 30s}
directly, matching the pattern used by post.go/get.go/patch.go/delete.go;
remove internal/drapi/client.go as it is no longer needed
- internal/drapi/auth.go: route SetAuthHeaders through resolveToken() so
--skip-auth is honoured consistently across all API paths
- cmd/pipelines/cmd.go: Use "pipeline" (singular per project convention),
Aliases: ["pipelines"] for backward compat
- docs/mkdocs.yml: remove pipelines nav entry until feature is GA
- scope.go: use url.PathEscape on pipelineID to prevent path injection
- time_test.go: add unit tests for Time.UnmarshalJSON
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… auth.go Move var token, GetToken/SetToken, and resolveToken from get.go into auth.go so all token-related logic lives in one place. Update post.go, delete.go, and patch.go to call resolveToken() instead of config.GetAPIKey() directly, making --skip-auth work consistently for every outbound API verb. Use url.PathEscape on pipelineID in scope.go with a failing test first to guard against path injection. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nd docs - Rename cmd/pipelines/ → cmd/pipeline/ (Use: "pipeline", alias "pipelines") - Rename internal/drapi/pipelines/ → internal/drapi/pipeline/ (API URLs unchanged) - Change feature gate annotation to singular "pipeline" (env: DATAROBOT_CLI_FEATURE_PIPELINE) - Add url.PathEscape for pipelineID in scope.go; add failing+passing path-escape tests - Add unit tests for time.go (7 cases + struct unmarshal) - Update docs to reference DATAROBOT_CLI_FEATURE_PIPELINE Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…EADME Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…es scope Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
scope.go and scope_test.go are first used by the graph command (crud branch), not by the base infrastructure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Follows singular-name convention from CLAUDE.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
570b6f7 to
b9b4326
Compare
|
🔐 Fork smoke tests started by maintainer ⏳ Security scans passed. Running smoke tests... Commit: |
|
✅ All smoke tests passed! (Fork PR) ✅ Security Scan: success |
|
🔐 Fork smoke tests started by maintainer ⏳ Security scans passed. Running smoke tests... Commit: |
|
✅ All smoke tests passed! (Fork PR) ✅ Security Scan: success |
The double WaitFor pattern called tm.Output() twice; the second call saw
an empty buffer because both strings render on the same Bubble Tea frame.
The original single WaitFor("Variables found in") is sufficient — it only
resolves after dotenvFileUpdatedMsg is processed, meaning the save is done.
Also harden FinalModel() with Require so the real failure surfaces first.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66e5164 to
94a6c60
Compare
|
🔐 Fork smoke tests started by maintainer ⏳ Security scans passed. Running smoke tests... Commit: |
|
✅ All smoke tests passed! (Fork PR) ✅ Security Scan: success |

Summary
dr pipelineinto the CLI root command behind theDATAROBOT_CLI_FEATURE_PIPELINEfeature gate — the command is hidden unlessDATAROBOT_CLI_FEATURE_PIPELINE=trueis exportedinternal/pipeline/shared infrastructure:transport.go(HTTP client helpers,decodeHTTPError,doJSON,doDelete),scope.go(draft/locked scope resolution +--scope/--versionflag semantics), andtime.go(RFC3339 formatting utilities)internal/drapi/client.goand fixes rawviperimports ininternal/drapi/get.goandinternal/drapi/client_test.goto useinternal/config/viperx(required bydepguard)This is PR 1 of 6 in a stacked series:
cmpt-5391/pipelines-basecmpt-5391/pipelines-crudcreate/list/get/update/delete/lock/version/graphcmpt-5391/pipelines-runsrunsubcommand groupcmpt-5391/pipelines-inputsinputsubcommand groupcmpt-5391/pipelines-schedulesschedulesubcommand groupcmpt-5391/pipelines-environmentsenvironmentsubcommand groupTest plan
go build ./...— compiles cleanlygo test ./cmd/pipeline/... ./internal/pipeline/... ./internal/drapi/...— all passgolangci-lint run ./cmd/pipeline/... ./internal/pipeline/...— zero issuesDATAROBOT_CLI_FEATURE_PIPELINE=false go run main.go pipeline— command hidden (unknown command error)DATAROBOT_CLI_FEATURE_PIPELINE=true go run main.go pipeline --help— command visible, no subcommands listed🤖 Generated with Claude Code
Note
Medium Risk
Medium risk because it refactors shared
internal/drapitoken resolution used by all HTTP helpers (including--skip-authbehavior), which could impact authentication/header injection across commands.Overview
Introduces a new feature-gated top-level
dr pipeline/dr pipelinescommand (no subcommands yet), wires it into the root command, and documents it in the command reference.Adds shared pipelines API infrastructure under
internal/drapi/pipelinefor draft vs locked scope URL construction (ResolveScope/PipelinePath), parsing pipelines-api naive UTC timestamps (Time), and lightweight JSON request/DELETE helpers with improved FastAPI-style error detail extraction.Refactors
internal/drapiauth handling by centralizing the memoized token inauth.goand addingresolveToken()so--skip-authcan source the token from viper config without network verification; updatesGet/Post/Patch/Deleteto use this resolver.Reviewed by Cursor Bugbot for commit dc1d016. Configure here.