Skip to content

feat(do-plugin): expose http_port_protocol for gRPC services (F5)#34

Merged
intel352 merged 3 commits intomainfrom
feat/http-port-protocol
Apr 28, 2026
Merged

feat(do-plugin): expose http_port_protocol for gRPC services (F5)#34
intel352 merged 3 commits intomainfrom
feat/http-port-protocol

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

Implements P-2.F5 from the IaC DO staging plan. Adds the canonical http_port_protocol config key for infra.container_service (App Platform services) and teaches the historic protocol shorthand a grpc alias.

  • Both keys flow into godo.AppServiceSpec.Protocol (ServingProtocol enum) — see godo v1.178.0 apps.gen.go:568 and the constant block at lines 1553-1554.
  • HTTP2 and grpc (case-insensitive) both resolve to godo.SERVINGPROTOCOL_HTTP2. gRPC is served as HTTP/2 with prior knowledge per the godo ServingProtocol doc comment.
  • When both keys are set, the explicit http_port_protocol wins (precedence test included).
  • Empty / HTTP / unset → empty string (DO defaults to HTTP). Unknown values pass through as godo.ServingProtocol(strings.ToUpper(...)) for forward compatibility.

Branch / SHAs

  • Branch: feat/http-port-protocol
  • Base SHA: 2a26a08865af2fe83f0f315b4a8d9a5ea3c2993a (origin/main)
  • Head SHA: a4212d302097ede9cdeab961325f8979d6f881b9

Files

  • internal/drivers/app_platform_buildspec.go — rename servingProtocolFromConfighttpPortProtocolFromConfig, accept both keys, add grpc alias.
  • internal/drivers/app_platform_buildspec_test.go — three new tests (see below).
  • CHANGELOG.md — Unreleased entry.

Test output

$ GOWORK=off go test -race -run 'TestBuildAppSpec_HTTPPortProtocol|TestBuildAppSpec_Protocol' -v ./internal/drivers/...
=== RUN   TestBuildAppSpec_Protocol_HTTP2
--- PASS: TestBuildAppSpec_Protocol_HTTP2 (0.00s)
=== RUN   TestBuildAppSpec_Protocol_Default
--- PASS: TestBuildAppSpec_Protocol_Default (0.00s)
=== RUN   TestBuildAppSpec_HTTPPortProtocol_HTTP2
--- PASS: TestBuildAppSpec_HTTPPortProtocol_HTTP2 (0.00s)
=== RUN   TestBuildAppSpec_Protocol_GRPC_AliasesHTTP2
--- PASS: TestBuildAppSpec_Protocol_GRPC_AliasesHTTP2 (0.00s)
=== RUN   TestBuildAppSpec_HTTPPortProtocol_OverridesProtocol
--- PASS: TestBuildAppSpec_HTTPPortProtocol_OverridesProtocol (0.00s)
PASS
ok  	github.com/GoCodeAlone/workflow-plugin-digitalocean/internal/drivers	1.471s

Full repo: GOWORK=off go test -race ./... → all packages pass.

Self-review checklist

  • TDD: RED (3 new tests fail with expected mismatch) → GREEN → regression invariant verified (full driver suite + full repo green).
  • PR scope matches task "Files" section: only app_platform_buildspec.go, app_platform_buildspec_test.go, CHANGELOG.md modified.
  • Existing TestBuildAppSpec_Protocol_HTTP2 and TestBuildAppSpec_Protocol_Default still pass — no regression on the original protocol: HTTP2 path.
  • go test -race clean.
  • golangci-lint run reports only pre-existing issues in database.go / app_platform_migration_repair_test.go — unrelated to this PR.
  • Both http_port_protocol: HTTP2 AND protocol: grpc (alias) exercised, plus precedence test.
  • Branched off origin/main (2a26a08), git pull --ff-only origin main before push, no other tasks pre-baked.

🤖 Generated with Claude Code

Add the canonical `http_port_protocol` config key for App Platform
services and teach the historic `protocol` shorthand a `grpc` alias.
Both flow into `godo.AppServiceSpec.Protocol` (godo v1.178.0
apps.gen.go:568) — `HTTP2` and `grpc` resolve to
`SERVINGPROTOCOL_HTTP2`. When both keys are set, `http_port_protocol`
wins.

Co-authored-by: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 28, 2026 02:37
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for configuring DigitalOcean App Platform service port protocol via a canonical http_port_protocol key, while preserving backward compatibility with the historic protocol shorthand (including a grpc alias).

Changes:

  • Rename and extend protocol parsing to accept http_port_protocol with precedence over protocol, and map grpc → HTTP2.
  • Add unit tests covering http_port_protocol, grpc alias behavior, and key precedence.
  • Document the new config behavior in CHANGELOG.md.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
internal/drivers/app_platform_buildspec.go Implements http_port_protocol parsing + grpc alias and wires it into AppServiceSpec.Protocol.
internal/drivers/app_platform_buildspec_test.go Adds tests for canonical key, aliasing, and precedence.
CHANGELOG.md Adds Unreleased entry describing the new keys/behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +127 to +136
// name. Takes precedence when both keys are set.
// - "protocol" — historic shorthand. Recognized aliases: "grpc" → HTTP2
// (gRPC requires HTTP/2 with prior knowledge per DO docs).
//
// DO recognizes HTTP and HTTP2; unknown values pass through for forward
// compatibility with future godo releases.
func httpPortProtocolFromConfig(cfg map[string]any) godo.ServingProtocol {
// Explicit canonical key wins over the shorthand.
raw := strFromConfig(cfg, "http_port_protocol", "")
if raw == "" {
Decide precedence by KEY PRESENCE, not value emptiness, so an explicit
`http_port_protocol: ""` is an opt-out instead of a silent fallthrough
to the `protocol` shorthand. Previously `strFromConfig` collapsed empty
to default and the function would proceed to read `protocol`, surfacing
HTTP2 from a `protocol: grpc` shorthand the user thought they had
overridden.

New test (TDD, RED→GREEN):
TestBuildAppSpec_HTTPPortProtocol_ExplicitEmpty_DoesNotFallThrough.

Addresses code-review Finding #3 / Copilot inline comment, F5 round 2.

Co-authored-by: Claude <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for configuring App Platform service port protocol using the canonical http_port_protocol key while preserving the legacy protocol key (including a grpc alias that maps to HTTP/2), ensuring the desired value reaches godo.AppServiceSpec.Protocol.

Changes:

  • Renamed and expanded protocol mapping helper to prefer http_port_protocol (by key presence) and support protocol: grpc → HTTP2.
  • Added tests covering canonical key usage, gRPC aliasing, and key-precedence (including explicit-empty behavior).
  • Documented the new behavior in the Unreleased changelog.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
internal/drivers/app_platform_buildspec.go Implements http_port_protocol precedence and grpc alias mapping into AppServiceSpec.Protocol.
internal/drivers/app_platform_buildspec_test.go Adds test coverage for canonical key, aliasing, and precedence semantics.
CHANGELOG.md Notes the new config key + alias behavior under Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +208 to +211
// Without the key-presence check, `strFromConfig("http_port_protocol", "")`
// would return the empty default and the function would proceed to read
// `protocol`, surfacing HTTP2 — surprising and contrary to the documented
// precedence. (Code-review Finding #3 / Copilot inline comment, F5 round 2.)
Comment on lines +124 to +133
// Two canonical keys are accepted:
//
// - "http_port_protocol" — explicit, mirrors the DO App Platform API field
// name. Takes precedence by KEY PRESENCE: if the key is set in cfg (even
// to an empty string), its value is honored and the shorthand is NOT
// consulted. This makes `http_port_protocol: ""` an explicit opt-out
// rather than a silent fallthrough.
// - "protocol" — historic shorthand. Consulted only when
// "http_port_protocol" is absent. Recognized aliases: "grpc" → HTTP2
// (gRPC requires HTTP/2 with prior knowledge per DO docs).
Pure docstring cleanup. No code, no test logic.

- httpPortProtocolFromConfig: change "Two canonical keys" → "Two config
  keys" since `protocol` is a historic shorthand, not canonical. Mark
  http_port_protocol explicitly as the canonical key in its bullet.

- TestBuildAppSpec_HTTPPortProtocol_ExplicitEmpty_DoesNotFallThrough:
  fix the strFromConfig signature reference (it takes cfg as first arg,
  not just key + default), and drop internal-process language from the
  trailing parenthetical per public-repo team conventions.

Co-authored-by: Claude <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for configuring DigitalOcean App Platform service serving protocol via the canonical http_port_protocol key (including precedence over the legacy protocol key) and introduces a grpc alias that resolves to HTTP/2, aligning infra.container_service config with DO App Platform API semantics.

Changes:

  • Renamed and expanded protocol parsing to accept http_port_protocol (canonical) with key-presence precedence over protocol, and added grpc → HTTP2 aliasing.
  • Added unit tests covering canonical key behavior, grpc aliasing, and precedence (including explicit-empty semantics).
  • Documented the new config behavior in the changelog under Unreleased.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
internal/drivers/app_platform_buildspec.go Implements canonical http_port_protocol handling, precedence rules, and grpc aliasing into godo.AppServiceSpec.Protocol.
internal/drivers/app_platform_buildspec_test.go Adds focused tests for canonical key, grpc aliasing, and precedence/explicit-empty behavior.
CHANGELOG.md Notes the new http_port_protocol key and protocol: grpc alias under Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@intel352 intel352 merged commit e1014e8 into main Apr 28, 2026
7 checks passed
@intel352 intel352 deleted the feat/http-port-protocol branch April 28, 2026 03:44
intel352 added a commit that referenced this pull request Apr 28, 2026
…ll target enforcement (#38)

P-2 staging IaC alignment. Bumps plugin.json:
- version: 0.6.2 → 0.8.0
- minEngineVersion: 0.3.51 → 0.20.1 (matches workflow v0.20.1 fixtures
  used by alignment + align/security-check integration tests).

Consolidates the [Unreleased] block under [v0.8.0] - 2026-04-28 with
preamble describing the three F-track features:

- F4 expose: internal (PR #35) — App Platform services may opt out of
  the public edge route. Five validation guards reject misconfiguration
  at apply time. Diff cascade derives expose + image from the live
  AppSpec so in-place toggles produce Plan actions.
- F5 http_port_protocol + protocol: grpc alias (PR #34) — explicit
  canonical key for HTTP/2 plus gRPC shorthand.
- F7 firewall droplet_ids + tags target enforcement (PR #36) —
  firewalls now require at least one target; Diff detects in-place
  target/rule changes; Outputs round-trip through structpb cleanly.

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants