Conversation
Initialize previously discarded its caller-supplied ctx and constructed the oauth2 client with context.Background(), silently dropping any oauth2.HTTPClient injected via the provided ctx (tests, custom transports, proxy configurations). Now the ctx is forwarded to oauth2.NewClient, and a nil-ctx guard returns a typed error instead of panicking inside the oauth2 stack. Tests: nil-ctx guard + a capturing-transport regression test that verifies a custom http.Client injected via oauth2.HTTPClient observes a real outbound godo request. Refs: workflow-plugin-digitalocean#62
The hand-rolled Plan body duplicated logic that already lives in
platform.ComputePlan and silently dropped two correctness paths the
canonical helper enforces:
1. ForceNew → replace promotion: ComputePlan upgrades update→replace
when any FieldChange has ForceNew=true; the prior body only
honored DiffResult.NeedsReplace, so any driver that returned
ForceNew=true on a per-field basis (without setting NeedsReplace)
emitted update actions that would later fail at Apply time.
2. DependsOn-ordered dispatch: ComputePlan parallelises Diff with an
errgroup worker pool and topologically sorts the resulting actions
so the Apply stage sees creates-before-replaces-before-deletes
order. The previous body iterated desired in input order with no
ordering guarantee.
The 2-statement (call + pointer-bridge return) shape matches the
W-Refactor / iac-codemod canonical target asserted by
cmd/iac-codemod AssertPlanDelegatesToHelper. Lint reports 0 findings on
internal/provider.go after this change.
Test impact:
- planDiffFakeDriver gains a sync.Mutex around its observable state
(Diff is dispatched in parallel by ComputePlan).
- TestMain sets WFCTL_DIFFCACHE=disabled so per-test Diff dispatches
are reproducible (the filesystem cache is global per UID and would
otherwise let one test poison another).
- TestDOProvider_Plan_KeepsDistinctCurrentStatePerConfigHashAction
retired and replaced by TestDOProvider_Plan_RejectsUnregisteredDriverType
— the configHash-fallback semantic it pinned no longer applies, since
ComputePlan surfaces the missing-driver error rather than masking it.
Refs: workflow-plugin-digitalocean#63
There was a problem hiding this comment.
Pull request overview
This PR closes two correctness gaps in DOProvider by (1) properly threading the caller’s context.Context into the DigitalOcean client initialization path, and (2) delegating planning to the workflow platform’s canonical platform.ComputePlan helper to restore replace/ordering semantics.
Changes:
- Update
DOProvider.Initializeto require a non-nil ctx and pass it tooauth2.NewClient, ensuring ctx-injectedoauth2.HTTPClientis honored end-to-end. - Collapse
DOProvider.Planto the canonical 2-statement delegation toplatform.ComputePlan, restoring ForceNew→replace promotion and dependency-correct action ordering. - Adjust tests to disable the diffcache backend, add Initialize ctx coverage, and make the plan Diff fake concurrency-safe.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| internal/provider.go | Thread ctx into oauth2 client creation; delegate Plan to platform.ComputePlan and remove the now-unneeded local helper logic. |
| internal/provider_test.go | Disable diffcache for reproducible tests; add Initialize ctx tests; mutex-protect fake driver state; update Plan contract test expectations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+115
to
+121
| // Return a minimal 200 with empty JSON body so godo doesn't choke. | ||
| return &http.Response{ | ||
| StatusCode: http.StatusOK, | ||
| Body: http.NoBody, | ||
| Header: make(http.Header), | ||
| Request: req, | ||
| }, nil |
Contributor
Author
There was a problem hiding this comment.
Fixed in 48b380e — capturing transport now returns a minimal valid JSON object body ({}) with a Content-Type header, and the comment is updated to match.
Copilot review #68: the capturing transport returned http.NoBody, which godo's response decoder can error on (EOF / invalid JSON), making the test more brittle than necessary and rendering the inline comment about "empty JSON body" misleading. Return a minimal valid JSON object body ("{}") with a Content-Type header instead — the test still only cares that the transport observed the request, but the path is robust against godo's decode-on-success behavior on pointer-to-struct destinations.
This was referenced May 7, 2026
Copilot AI
added a commit
that referenced
this pull request
May 7, 2026
…already fixed in PR #68) Agent-Logs-Url: https://github.com/GoCodeAlone/workflow-plugin-digitalocean/sessions/962a09f7-575b-460c-85b7-d4de08c75f7b Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
intel352
added a commit
that referenced
this pull request
May 7, 2026
* Initial plan * fix: update stale comment in provider_conformance_test.go (issue #62 already fixed in PR #68) Agent-Logs-Url: https://github.com/GoCodeAlone/workflow-plugin-digitalocean/sessions/962a09f7-575b-460c-85b7-d4de08c75f7b Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> * docs: clarify initialize context behavior --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: intel352 <77607+intel352@users.noreply.github.com> Co-authored-by: Jon Langevin <codingsloth@pm.me>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes two correctness gaps in
DOProvider:Initializenow threads its caller-suppliedctxintooauth2.NewClientinstead of constructing the godo client withcontext.Background(). Operators who inject a custom*http.Clientviaoauth2.HTTPClient(tests, custom transports, proxy configurations) now have that client honored end-to-end.Planis collapsed to the canonical 2-statement bridge overplatform.ComputePlan. The hand-rolled body silently dropped (a) theForceNew → replaceupgrade and (b)DependsOnordering, both of which the canonical helper enforces.Reference: iac-deferred-cleanup plan rev10 §PR 6.
This PR is scoped to
#62 + #63only. TheEnumeratorinterface implementation lives in the follow-up PR 6b (feat/do-enumerator-impl), which blocks on workflow PR 4 reachingmain.Changes
internal/provider.goInitializeacceptsctx(was_), forwards tooauth2.NewClient, rejectsnil.Planbecomesplan, err := platform.ComputePlan(ctx, p, desired, current); return &plan, err.resourceOutputFromStatehelper.internal/provider_test.goTestMainsetsWFCTL_DIFFCACHE=disabledso the platform diff cache cannot poison test runs.planDiffFakeDrivergains async.Mutexaround its observable state (ComputePlan dispatchesDiffin parallel viaerrgroup).TestDOProvider_Initialize_NilCtxRejectedandTestDOProvider_Initialize_ThreadsCtxToGodoClientpin DOProvider.Initialize ignores ctx parameter — godo client uses context.Background() #62.TestDOProvider_Plan_KeepsDistinctCurrentStatePerConfigHashAction(legacyconfigHash-fallback) replaced withTestDOProvider_Plan_RejectsUnregisteredDriverTypematching the new contract.Test plan
GOWORK=off go test -race -count=1 ./...(all green: internal + drivers + root)iac-codemod lint -dry-run internal/provider.goreports 0 findings (Plan canonical pattern recognized)Out of scope
Enumeratorimpl — separate PR 6b (feat/do-enumerator-impl); blocks on workflow PR 4 (Enumerator interface) reachingmain.v0.10.1tag — cut after PR 6b merges (not after this PR), per plan rev10 §Coordination.🤖 Generated with Claude Code