refactor: Phase C core deletion — drop GCP SDKs + arm asymmetric CI gate (cloud-SDK extraction COMPLETE)#688
Conversation
…netes_gke — now plugin-served via workflow-plugin-gcp v1.1.0
…te (allowlist OAuth2 ADC compute/metadata) + wfctl gcs actionable error + replace stylistic google.Endpoint in auth_oauth2.go
…traction complete
There was a problem hiding this comment.
Pull request overview
Plan-2 Phase C core deletion: removes in-core GCP/GKE/GCS implementations now served by workflow-plugin-gcp, drops GCP SDK dependencies from the core module graph, and adds a permanent CI/audit gate to prevent reintroducing forbidden cloud SDK deps (except the allowlisted cloud.google.com/go/compute/metadata ADC helper).
Changes:
- Deleted in-core GCS state/storage modules and the GKE Kubernetes backend; updated core/plugin registrations and documentation to reflect plugin ownership.
- Removed
cloud.google.com/go/storage,google.golang.org/api, and related GCP/OpenTelemetry deps fromgo.mod/go.sum; refactored OAuth2 Google provider to avoid importinggolang.org/x/oauth2/google. - Added Phase C enforcement to
scripts/audit-cloud-symbols.shand mirrored the dependency-graph gate in CI.
Reviewed changes
Copilot reviewed 15 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/audit-cloud-symbols.sh | Adds Phase C invariants: module/ import ban and asymmetric build-graph allowlist gate. |
| plugins/storage/plugin.go | Removes storage.gcs module registration and schema from core storage plugin. |
| plugins/storage/plugin_test.go | Updates storage plugin tests to reflect removed storage.gcs. |
| module/storage_gcs.go | Deletes in-core GCS storage module implementation. |
| module/storage_gcs_test.go | Deletes in-core GCS storage module tests. |
| module/platform_kubernetes_gke.go | Deletes in-core GKE backend (Container API) implementation. |
| module/iac_state_gcs.go | Deletes in-core GCS IaC state store implementation. |
| module/iac_state_gcs_test.go | Deletes in-core GCS IaC state store tests. |
| module/iac_module.go | Removes gcs backend from in-core iac.state backends; updates error messaging. |
| module/auth_oauth2.go | Removes oauth2/google import by hardcoding Google OAuth2 endpoints to reduce transitive deps. |
| go.mod | Drops GCP SDK and related transitive dependencies. |
| go.sum | Removes sums for deleted GCP/OpenTelemetry/API deps (post-tidy). |
| DOCUMENTATION.md | Updates module tables to remove storage.gcs and clarify plugin-served state backends. |
| docs/migrations/2026-05-15-plugin-modules-on-iac.md | Extends migration guide to cover Phase C (GCS/GKE) cutover and allowlist rationale. |
| cmd/wfctl/infra_state_store.go | Changes gcs backend handling to an actionable “plugin required” error (matching spaces/s3 pattern). |
| .phase-c-complete | Arms Phase C enforcement mode for the audit script. |
| .github/workflows/ci.yml | Extends cloud-sdk-audit job with setup/go-list based asymmetric dependency gate. |
Comments suppressed due to low confidence (1)
plugins/storage/plugin.go:44
Capabilities()still describes storage as including “S3, GCS” even though this plugin’s manifest/module registrations no longer include any S3/GCS module types (those are now plugin-served). Please update the capability description to match the current in-core surface to prevent misleading capability docs/UI output.
Author: "GoCodeAlone",
Description: "Storage, database, persistence, and cache modules with DB pipeline steps",
Tier: plugin.TierCore,
ModuleTypes: []string{
"storage.local",
"storage.sqlite",
"storage.artifact",
"database.workflow",
"database.partitioned",
"persistence.store",
"cache.redis",
},
| DEPS=$(GOWORK=off go list -deps ./... 2>/dev/null || true) | ||
| AZURE_UNEXPECTED=$(echo "$DEPS" | grep -F 'github.com/Azure/azure-sdk-for-go' || true) | ||
| API_UNEXPECTED=$(echo "$DEPS" | grep '^google\.golang\.org/api' || true) | ||
| GCP_UNEXPECTED=$(echo "$DEPS" \ | ||
| | grep '^cloud\.google\.com/go' \ | ||
| | grep -v '^cloud\.google\.com/go/compute/metadata$' \ | ||
| || true) | ||
| if [[ -n "$AZURE_UNEXPECTED" ]]; then | ||
| echo " FAIL: azure-sdk-for-go transitive deps in core build graph:" | ||
| printf ' %s\n' $AZURE_UNEXPECTED | ||
| FAIL=1 | ||
| fi | ||
| if [[ -n "$API_UNEXPECTED" ]]; then | ||
| echo " FAIL: google.golang.org/api transitive deps in core build graph:" | ||
| printf ' %s\n' $API_UNEXPECTED | ||
| FAIL=1 | ||
| fi | ||
| if [[ -n "$GCP_UNEXPECTED" ]]; then | ||
| echo " FAIL: unexpected cloud.google.com/go transitive deps in core build graph:" | ||
| printf ' %s\n' $GCP_UNEXPECTED | ||
| echo | ||
| echo " Only cloud.google.com/go/compute/metadata is allowlisted (OAuth2 ADC helper" | ||
| echo " pulled by provider/gcp's service-account auth). If you need a new GCP SDK" | ||
| echo " package, factor it into a plugin instead — workflow core is gcp-SDK-free" | ||
| echo " per Phase C (plan 2026-05-15-plugin-modules-on-iac.md Task 18)." | ||
| FAIL=1 | ||
| fi | ||
| if [[ -z "$AZURE_UNEXPECTED$API_UNEXPECTED$GCP_UNEXPECTED" ]]; then | ||
| echo " build graph: clean (compute/metadata allowlisted)" | ||
| fi |
| // transitively pulls `cloud.google.com/go/compute/metadata` (an ADC helper | ||
| // for GCE/GKE workload identity) — and Phase C's permanent asymmetric CI | ||
| // gate (decisions/0034 + plan 2026-05-15-plugin-modules-on-iac.md Task 18) | ||
| // asserts zero `cloud.google.com/go/*` packages in core's build graph. |
| env: | ||
| GOWORK: "off" | ||
| run: | | ||
| UNEXPECTED=$(go list -deps ./... \ |
⏱ Benchmark Results✅ No significant performance regressions detected. benchstat comparison (baseline → PR)
|
… list exit code in audit script + CI gate + correct stale auth_oauth2 comment
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
| while IFS= read -r f; do | ||
| [[ -z "$f" ]] && continue | ||
| for sdk in 'cloud.google.com/go' 'google.golang.org/api' 'github.com/Azure/azure-sdk-for-go'; do | ||
| if real_import "$f" "$sdk"; then | ||
| MOD_FORBIDDEN+=("$f -> $sdk") | ||
| fi | ||
| done |
| fi | ||
| # `|| true` on each grep is fine: grep returning 1 means "no matches" = | ||
| # success case. Only the outer `go list` exit code matters for gate sanity. | ||
| AZURE_UNEXPECTED=$(echo "$DEPS" | grep -F 'github.com/Azure/azure-sdk-for-go' || true) |
…ort grep -F, anchor azure prefix to ^)
… struct-literal fields
| # Extract just the Go import block of a file (handles single `import (...)`). | ||
| import_block() { | ||
| awk '/^import \(/{f=1} f{print} /^\)/{if(f)exit}' "$1" | ||
| } | ||
|
|
||
| real_import() { # file, sdk → 0 if sdk appears in a real import (block OR single-line) | ||
| # `|| true` on the inner grep: a no-match exit 1 must not poison the pipe | ||
| # under `set -o pipefail`. | ||
| # Single-line form matches plain, aliased, dot, and blank imports: | ||
| # import "pkg" / import foo "pkg" / import . "pkg" / import _ "pkg" | ||
| { import_block "$1"; grep -E '^import +([A-Za-z_.][A-Za-z0-9_]* +)?"' "$1" 2>/dev/null || true; } | grep -q "$2" | ||
| # Match the SDK string with `-F` (fixed string): SDK prefixes contain `.` | ||
| # which would otherwise be regex metachars matching any character. | ||
| { import_block "$1"; grep -E '^import +([A-Za-z_.][A-Za-z0-9_]* +)?"' "$1" 2>/dev/null || true; } | grep -qF "$2" | ||
| } |
| MOD_FORBIDDEN+=("$f -> $sdk") | ||
| fi | ||
| done | ||
| done < <(grep -rl 'cloud\.google\.com/go\|google\.golang\.org/api\|github\.com/Azure/azure-sdk-for-go' module/ --include='*.go' 2>/dev/null | grep -v '_test\.go' | sort) |
Summary
Plan-2 Phase C core deletion: removes in-core GCP duplicates of code now plugin-served by workflow-plugin-gcp v1.1.0; arms the permanent asymmetric CI gate that prevents future
cloud.google.com/go/*deps (beyond OAuth2 ADC'scompute/metadata) from leaking back into workflow core. Closes the cloud-SDK extraction project.3 commits, one per task:
cd93ad40): deletemodule/iac_state_gcs.go+module/storage_gcs.go+module/platform_kubernetes_gke.go+ stripcase "gcs":fromiac_module.go+ dropstorage.gcsfromplugins/storage/plugin.go+ DOCUMENTATION.md update. gcs / GKE / storage.gcs now plugin-served via workflow-plugin-gcp v1.1.0 (gke per ADR 0037 — ResourceDriver fold underinfra.k8s_cluster).4a80f71b): dropcloud.google.com/go/storage+google.golang.org/api+ OpenTelemetry GCP fromgo.mod(post-tidy); replace stylisticgoogle.Endpointinmodule/auth_oauth2.gowith literaloauth2.Endpoint{}(drops the unnecessary OAuth2 IdP login transitive); updatecmd/wfctl/infra_state_store.gocase "gcs":to actionable plugin-required error (matches PR 4's spaces/s3 pattern); arm.phase-c-completemarker; extendscripts/audit-cloud-symbols.sh --checkwith 2 new invariants (zero unexpected gcp deps + zero azure deps in module/) using comment-immunereal_importhelper; extendcloud-sdk-auditjob in.github/workflows/ci.ymlwith belt-and-suspendersgo list -depsgate. Asymmetric design (aws stays in forprovider/aws/etc., gcp out,compute/metadataallowlisted as the OAuth2 ADC helper) structurally enforced.470de848): Phase C migration doc + final cross-phase verification atdocs/migrations/2026-05-15-plugin-modules-on-iac.md— gcs/storage.gcs/gke operator-facing migration steps + OAuth2 ADC allowlist disclosure paragraph + Phase A/B/C × PRs × ADRs recap table + final invariant re-check evidence. DOCUMENTATION.mdiac.staterow reflects post-PR-5 reality.Final invariant verification (project-level)
Breaking change
Workflow ≥ v0.53.0. Operators using
iac.state backend: gcs,storage.gcs, orplatform.kubernetes(type:gke)MUST install workflow-plugin-gcp v1.1.0. See migration doc for full instructions.Rollback
Revert PR 5 → in-core gcs/storage.gcs/platform_kubernetes_gke restore + GCP SDKs return + asymmetric CI gate disarms. gcs clean-break + workflow-plugin-gcp v1.1.0 release roll back as MATCHED PAIR.
Cloud-SDK extraction project — final state
Future PRs accidentally pulling
cloud.google.com/go/*(beyondcompute/metadata) orgoogle.golang.org/apiorgithub.com/Azure/azure-sdk-for-gowill fail thecloud-sdk-auditCI job automatically.Test plan
.phase-c-complete)GOWORK=off go build ./... && GOWORK=off go test ./...PASS on every commitcloud.google.com/go/compute/metadata🤖 Generated with Claude Code