Skip to content

feat: auto-generate --allow-host-service-ports from services: port mappings#23760

Merged
pelikhan merged 12 commits intomainfrom
feat/service-ports-23756
Apr 1, 2026
Merged

feat: auto-generate --allow-host-service-ports from services: port mappings#23760
pelikhan merged 12 commits intomainfrom
feat/service-ports-23756

Conversation

@Mossaka
Copy link
Copy Markdown
Collaborator

@Mossaka Mossaka commented Mar 31, 2026

Summary

Closes #23756

  • Adds automatic detection of service port mappings from services: configuration and generates ${{ job.services['<id>'].ports['<port>'] }} expressions for AWF's --allow-host-service-ports flag
  • Uses bracket notation for all service IDs (e.g. job.services['my-postgres']) with single-quote escaping, ensuring correctness for hyphenated names and other non-identifier characters
  • Parses all port spec formats: explicit mappings (5432:5432), dynamic host ports (5432), remapped ports (49152:5432), TCP protocol suffix, port ranges with expansion cap, and integer values
  • Emits compile-time warnings (to stderr, incrementing the compiler warning counter) for services without ports (unreachable from sandbox), invalid ports format, and UDP-only ports (unsupported)
  • Services YAML is parsed via typed structs (servicesYAMLWrapper / serviceContainerConfig) with yaml: field annotations rather than map[string]any type assertions

Files changed

File Change
pkg/workflow/service_ports.go New: typed YAML structs, port spec parsing, and expression generation logic
pkg/workflow/service_ports_test.go New: comprehensive unit tests for all port syntaxes, edge cases, hyphenated IDs, and deterministic ordering
pkg/workflow/compiler_types.go Added ServicePortExpressions field to WorkflowData
pkg/workflow/compiler_orchestrator_workflow.go Call port extraction after services merge; emit warnings to stderr with IncrementWarningCount()
pkg/workflow/awf_helpers.go Emit --allow-host-service-ports as raw arg in AWF command
pkg/cli/workflows/test-service-ports.md New: test workflow fixture with postgres and redis services
pkg/cli/compile_service_ports_integration_test.go New: integration tests verifying compiled lock file output
.github/workflows/smoke-service-ports.md New: smoke test workflow (runs on daily schedule)

Example

Input services:

services:
  postgres:
    image: postgres:15
    ports:
      - 5432:5432
  redis:
    image: redis:7
    ports:
      - 6379:6379

Compiled AWF command includes:

--allow-host-service-ports "${{ job.services['postgres'].ports['5432'] }},${{ job.services['redis'].ports['6379'] }}"

Test plan

  • Unit tests: port spec parsing for all syntaxes (explicit, dynamic, remapped, TCP, UDP, range, integer, float64)
  • Unit tests: expression generation for single/multi service+port combinations, hyphenated service IDs, invalid ports format
  • Negative tests: services without ports emit warnings, UDP ports skipped, invalid ranges rejected
  • Deterministic ordering test: alphabetical by service ID
  • Integration tests (pkg/cli/compile_service_ports_integration_test.go): multi-service lock file output, no-services case, hyphenated ID bracket notation
  • Smoke test workflow (smoke-service-ports.md) runs daily against a live Redis service container
  • make build passes
  • make test-unit passes
  • make fmt passes
  • make lint passes for changed files

…ppings (#23756)

When a workflow uses GitHub Actions services: with port mappings, the agent
running inside AWF's isolated network cannot reach service containers without
explicit port configuration. The compiler now automatically detects service
ports and emits ${{ job.services.<id>.ports['<port>'] }} expressions as
--allow-host-service-ports in the AWF command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 31, 2026 18:37
Copy link
Copy Markdown
Contributor

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 compiler support to auto-generate AWF --allow-host-service-ports arguments from services:<id>.ports mappings by parsing port specs and emitting GitHub Actions runtime expressions.

Changes:

  • Introduces service port parsing + expression generation (${{ job.services.<id>.ports['<containerPort>'] }}) with range expansion and UDP warnings.
  • Plumbs generated expressions through WorkflowData and service-merge compilation flow.
  • Emits the generated --allow-host-service-ports argument into the AWF command as a raw (non-shell-escaped) argument.

Reviewed changes

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

Show a summary per file
File Description
pkg/workflow/service_ports.go New parsing/extraction logic for services ports and expression generation.
pkg/workflow/service_ports_test.go New unit tests covering port syntax variants and ordering behavior.
pkg/workflow/compiler_types.go Adds ServicePortExpressions to WorkflowData.
pkg/workflow/compiler_orchestrator_workflow.go Extracts/records service port expressions after services merge.
pkg/workflow/awf_helpers.go Appends --allow-host-service-ports to the AWF command when expressions exist.
Comments suppressed due to low confidence (3)

pkg/workflow/service_ports.go:100

  • The expression uses dot-notation with the raw service ID (job.services....). GitHub Actions expression dot access breaks for IDs containing characters like '-' and can also become unsafe if IDs contain characters that interfere with quoting. Consider generating bracket-notation for non-identifier service IDs (job.services['']) and validating/escaping IDs before embedding them into the command string.
		for _, portSpec := range portsList {
			containerPorts, portWarnings := parsePortSpec(portSpec)
			for _, w := range portWarnings {
				warnings = append(warnings, fmt.Sprintf("service %q: %s", serviceID, w))
			}
			for _, cp := range containerPorts {
				expr := fmt.Sprintf("${{ job.services.%s.ports['%d'] }}", serviceID, cp)
				expressions = append(expressions, expr)
			}

pkg/workflow/service_ports.go:133

  • Numeric port specs: float64 is truncated to int without checking that it’s an integer value, and no range validation is performed. This can silently accept invalid YAML like 5432.5 or ports outside 1-65535. Consider rejecting non-integer floats and validating the port range; also consider handling other numeric types (int64/uint64) that YAML decoders commonly produce.
func parsePortSpec(spec any) ([]int, []string) {
	var portStr string
	switch v := spec.(type) {
	case int:
		return []int{v}, nil
	case float64:
		// YAML may parse unquoted numbers as float64
		return []int{int(v)}, nil
	case string:

pkg/workflow/service_ports.go:153

  • Protocol parsing only treats "udp" specially; any other suffix (e.g., "sctp") will be treated as TCP, which conflicts with the stated "AWF only supports TCP" behavior. Consider warning+skipping any protocol that isn’t empty/"tcp".
	// Check for protocol suffix
	protocol := "tcp"
	if idx := strings.LastIndex(portStr, "/"); idx != -1 {
		protocol = strings.ToLower(portStr[idx+1:])
		portStr = portStr[:idx]
	}

	if protocol == "udp" {
		return nil, []string{fmt.Sprintf("UDP port %q skipped; AWF only supports TCP", portStr)}
	}

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

"strings"

"github.com/github/gh-aw/pkg/logger"
goyaml "gopkg.in/yaml.v3"
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

This file uses gopkg.in/yaml.v3 for parsing, but the rest of pkg/workflow consistently uses github.com/goccy/go-yaml for YAML (e.g., pkg/workflow/frontmatter_extraction_yaml.go:11). Mixing YAML implementations can lead to different decoded Go types (e.g., int vs int64/uint64) and inconsistent behavior; consider switching this to goccy/go-yaml for consistency.

Suggested change
goyaml "gopkg.in/yaml.v3"
goyaml "github.com/goccy/go-yaml"

Copilot uses AI. Check for mistakes.
Comment on lines +519 to +525
// Extract service port expressions for AWF --allow-host-service-ports
if workflowData.Services != "" {
expressions, warnings := ExtractServicePortExpressions(workflowData.Services)
workflowData.ServicePortExpressions = expressions
for _, w := range warnings {
orchestratorWorkflowLog.Printf("Warning: %s", w)
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

These are meant to be compile-time warnings, but they’re currently only emitted via the debug logger (visible only when DEBUG/ACTIONS_RUNNER_DEBUG is enabled). To match existing warning behavior in this package (e.g., pkg/workflow/action_pins.go prints console-formatted warnings to stderr), consider emitting these warnings through the same user-visible warning mechanism instead of (or in addition to) debug logs.

Copilot uses AI. Check for mistakes.
Comment on lines +134 to +170
func TestExtractServicePortExpressions(t *testing.T) {
tests := []struct {
name string
servicesYAML string
expectedResult string
expectedWarnings []string
}{
{
name: "empty services YAML",
servicesYAML: "",
expectedResult: "",
},
{
name: "single service with single port",
servicesYAML: `services:
postgres:
image: postgres:15
ports:
- 5432:5432
`,
expectedResult: "${{ job.services.postgres.ports['5432'] }}",
},
{
name: "multiple services with ports",
servicesYAML: `services:
postgres:
image: postgres:15
ports:
- 5432:5432
redis:
image: redis:7
ports:
- 6379:6379
`,
expectedResult: "${{ job.services.postgres.ports['5432'] }},${{ job.services.redis.ports['6379'] }}",
},
{
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

Consider adding a test case for service IDs that require bracket-notation in GitHub Actions expressions (e.g., a service named "my-postgres"), since the generated expression differs from the simple dot-notation cases covered here.

Copilot uses AI. Check for mistakes.
Comment on lines +121 to +132
func servicePortsContains(s, substr string) bool {
return len(s) >= len(substr) && servicePortsSearchSubstring(s, substr)
}

func servicePortsSearchSubstring(s, substr string) bool {
for i := 0; i <= len(s)-len(substr); i++ {
if s[i:i+len(substr)] == substr {
return true
}
}
return false
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The helper functions servicePortsContains/servicePortsSearchSubstring reimplement substring search; using strings.Contains would be simpler and less error-prone. This would also let you remove a small amount of custom code from the test file.

Copilot uses AI. Check for mistakes.
Mossaka and others added 2 commits March 31, 2026 19:19
- Switch from gopkg.in/yaml.v3 to goccy/go-yaml for consistency with the
  rest of pkg/workflow, adding uint64/int64 type cases for goccy's integer
  decoding behavior
- Replace strings.Index with strings.Cut to satisfy the modernize linter
- Surface invalid ports format as a user-visible warning instead of only
  logging at debug level
- Replace custom substring search helpers with strings.Contains
- Add test cases for hyphenated service IDs and invalid ports format

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Emit service port warnings through console.FormatWarningMessage to
stderr, matching the existing warning pattern used by action_pins.go
and other compilation warnings in the package.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a smoke-service-ports workflow that validates the --allow-host-service-ports
feature end-to-end. The workflow declares a Redis service container and instructs
the agent to connect to Redis on localhost:6379, verifying PING/PONG, SET/GET
round-trip, and INFO server queries.

Closes part of #23756 (smoke test validation).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

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

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

Comments suppressed due to low confidence (3)

pkg/workflow/service_ports.go:159

  • Protocol parsing currently treats any unknown suffix as supported (e.g. "5432/sctp" will be accepted as TCP). GitHub Actions only supports tcp/udp here; please validate the suffix and emit a warning + skip (or default explicitly to tcp only when suffix is empty or "tcp").
	// Check for protocol suffix
	protocol := "tcp"
	if idx := strings.LastIndex(portStr, "/"); idx != -1 {
		protocol = strings.ToLower(portStr[idx+1:])
		portStr = portStr[:idx]
	}

	if protocol == "udp" {
		return nil, []string{fmt.Sprintf("UDP port %q skipped; AWF only supports TCP", portStr)}
	}

pkg/workflow/service_ports.go:139

  • Numeric port specs are cast to int without validating range or type-safety. This can silently accept invalid values (e.g. float64(5432.9) truncates to 5432) or overflow when converting uint64/int64 to int. Consider validating the value is an integer and within 1-65535 (and rejecting negatives/zero) before returning it as a port.
	switch v := spec.(type) {
	case int:
		return []int{v}, nil
	case uint64:
		// goccy/go-yaml decodes unquoted integers as uint64
		return []int{int(v)}, nil
	case int64:
		return []int{int(v)}, nil
	case float64:
		// Some YAML libraries parse unquoted numbers as float64
		return []int{int(v)}, nil
	case string:

pkg/workflow/service_ports.go:199

  • String port parsing doesn’t validate the resulting port numbers are within the valid TCP/UDP range (1-65535). As written, specs like "0", "70000", or negative ranges will produce expressions that can’t resolve correctly at runtime. Add bounds checks for both single ports and each expanded range value, and return a warning when out of range.
	// Check for port range (e.g., "6000-6010")
	if startStr, endStr, found := strings.Cut(containerPart, "-"); found {
		start, err1 := strconv.Atoi(startStr)
		end, err2 := strconv.Atoi(endStr)
		if err1 != nil || err2 != nil {
			return nil, []string{fmt.Sprintf("invalid port range %q", containerPart)}
		}

		if end < start {
			return nil, []string{fmt.Sprintf("invalid port range %q: end < start", containerPart)}
		}

		count := end - start + 1
		if count > maxPortRangeExpansion {
			return nil, []string{fmt.Sprintf("port range %q expands to %d ports, exceeding cap of %d", containerPart, count, maxPortRangeExpansion)}
		}

		ports := make([]int, 0, count)
		for p := start; p <= end; p++ {
			ports = append(ports, p)
		}
		return ports, nil
	}

	// Single port
	port, err := strconv.Atoi(containerPart)
	if err != nil {
		return nil, []string{fmt.Sprintf("invalid port number %q", containerPart)}
	}

	return []int{port}, nil

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

warnings = append(warnings, fmt.Sprintf("service %q: %s", serviceID, w))
}
for _, cp := range containerPorts {
expr := fmt.Sprintf("${{ job.services.%s.ports['%d'] }}", serviceID, cp)
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

GitHub Actions expression dot-notation will break for service IDs that aren’t valid identifiers (e.g. IDs containing '-' or starting with a digit). The generated expression should use bracket notation for the service key (and escape any embedded single quotes) so it works for all valid workflow service IDs: ${{ job.services['<id>'].ports['<port>'] }}.

This issue also appears in the following locations of the same file:

  • line 128
  • line 150
  • line 169
Suggested change
expr := fmt.Sprintf("${{ job.services.%s.ports['%d'] }}", serviceID, cp)
escapedServiceID := strings.ReplaceAll(serviceID, "'", "''")
expr := fmt.Sprintf("${{ job.services['%s'].ports['%d'] }}", escapedServiceID, cp)

Copilot uses AI. Check for mistakes.
ports:
- 5432:5432
`,
expectedResult: "${{ job.services.my-postgres.ports['5432'] }}",
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

This test codifies dot-notation for a hyphenated service ID, but GitHub Actions expressions require bracket notation for keys containing '-' (e.g. job.services['my-postgres']...). Update the expected expression (and the generator) so service IDs with '-' are handled correctly.

Suggested change
expectedResult: "${{ job.services.my-postgres.ports['5432'] }}",
expectedResult: "${{ job.services['my-postgres'].ports['5432'] }}",

Copilot uses AI. Check for mistakes.
workflowData.ServicePortExpressions = expressions
for _, w := range warnings {
orchestratorWorkflowLog.Printf("Warning: %s", w)
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(w))
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

Warnings are emitted to stderr here but the compiler’s warning counter isn’t incremented. To keep summary/exit behavior consistent with other warnings (e.g. pkg/workflow/compiler.go), call c.IncrementWarningCount() for each emitted warning.

Suggested change
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(w))
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(w))
c.IncrementWarningCount()

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Agreed — incrementing c.IncrementWarningCount() is important for consistent warning summary behavior across the compiler. Good catch! 🔍

📰 BREAKING: Report filed by Smoke Copilot

@Mossaka Mossaka added the smoke label Mar 31, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

❌ Service ports validation failed! Smoke Service Ports could not reach Redis: failed

@github-actions
Copy link
Copy Markdown
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions github-actions bot removed the smoke label Mar 31, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

🌑 The shadows whisper... Smoke Codex failed. The oracle requires further meditation...

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

✅ All tools validated successfully! Agent Container Smoke Test confirms agent container is ready.

@github-actions

This comment has been minimized.

…ning count

- Use bracket notation (job.services['id']) for all service IDs to handle
  hyphens and other special characters in GitHub Actions expressions
- Add port range validation (1-65535) for all port spec types
- Reject non-integer float64 values and unknown protocols (not just UDP)
- Increment compiler warning count for service port warnings
- Add test cases for out-of-range ports, unknown protocols, non-integer floats
- Recompile smoke-service-ports lock file with updated expression format

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test 23817988098@Mossaka

Test Result
GitHub MCP
MCP Scripts GH CLI
Serena MCP
Playwright
Web Fetch
File Writing
Bash Tool
Discussion Interaction
Build gh-aw
Discussion Creation
Workflow Dispatch
PR Review

Overall: ⚠️ PARTIAL PASS (11/12) — Serena MCP tools unavailable

📰 BREAKING: Report filed by Smoke Copilot ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Smoke test review of PR #23760. Key observations: service IDs with hyphens need bracket notation in expressions, and warning counter should be incremented when warnings are emitted to stderr.

📰 BREAKING: Report filed by Smoke Copilot

warnings = append(warnings, fmt.Sprintf("service %q: %s", serviceID, w))
}
for _, cp := range containerPorts {
expr := fmt.Sprintf("${{ job.services.%s.ports['%d'] }}", serviceID, cp)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Service IDs containing hyphens or other non-identifier characters (e.g., my-postgres) will produce invalid GitHub Actions expressions with dot notation. Consider using bracket notation: $\{\{ job.services['id'].ports['port'] }} for all service IDs to ensure correctness.

workflowData.ServicePortExpressions = expressions
for _, w := range warnings {
orchestratorWorkflowLog.Printf("Warning: %s", w)
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(w))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warnings emitted here should also call c.IncrementWarningCount() to keep the warning counter consistent with the rest of the compiler's warning tracking behavior.

@github-actions
Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

💥 Automated smoke test review - all systems nominal!

💥 [THE END] — Illustrated by Smoke Claude

continue
}

ports, hasPorts := svcMap["ports"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 Smoke test review comment #1: The silent skip on invalid ports mapping is a good candidate for a user-visible warning. The warnings slice is already in scope — appending a message here would surface this misconfiguration during gh aw compile.

for _, w := range warnings {
orchestratorWorkflowLog.Printf("Warning: %s", w)
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(w))
c.IncrementWarningCount()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 Smoke test review comment #2: Debug-only log here means users won't see the warning unless ACTIONS_RUNNER_DEBUG is set. Consider also emitting to stderr so this is visible during normal compilation, consistent with other warnings in this package.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Agreed — incrementing c.IncrementWarningCount() is important for consistent warning summary behavior across the compiler. Good catch! 🔍

📰 BREAKING: Report filed by Smoke Copilot

The --allow-host-service-ports flag was added to AWF's main branch but
not yet released in v0.25.1. The smoke test needs AWF built from source
to validate this feature. Replaces install_awf_binary.sh with a
checkout-and-build step, and locally builds container images tagged as
0.25.1 so --skip-pull uses them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Mossaka Mossaka added the smoke label Mar 31, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

✅ All tools validated successfully! Agent Container Smoke Test confirms agent container is ready.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

Hey @Mossaka 👋 — great work on the automatic --allow-host-service-ports generation! The implementation is clean, the issue (#23756) was filed first with a thorough spec, and the PR follows it faithfully using a coding agent.

This PR looks ready for maintainer review. 🎉


Contribution check: 🟢 Aligned · tests ✅ · description ✅ · focused ✅ · no new deps

Generated by Contribution Check ·

@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented Apr 1, 2026

@copilot review changes, review comments

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 1, 2026

@copilot review changes, review comments

All review comments have been addressed across commits 51a51ae, 4ed5092, and 7aa6405:

  • goccy/go-yaml used throughout (not gopkg.in/yaml.v3)
  • Invalid ports-format errors surfaced in the warnings slice (not just debug-logged)
  • Warnings emitted to stderr via console.FormatWarningMessage with c.IncrementWarningCount() per warning
  • Bracket notation used for all service IDs: ${{ job.services['my-postgres'].ports['5432'] }} with single-quote escaping
  • Test for hyphenated service ID added with correct bracket-notation expectation
  • Tests use strings.Contains directly (no custom helper functions)

CI is passing on the latest commit.

…7-438a-9fa7-b3a86d41180a

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Comment on lines +5 to +8
schedule: every 12h
pull_request:
types: [labeled]
names: ["smoke"]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot run daily, not on pull requests

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Done in 816a57a — removed pull_request trigger and changed the schedule to daily.

Copilot AI requested a review from pelikhan April 1, 2026 03:36
@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented Apr 1, 2026

@copilot review comments

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 1, 2026

@copilot review comments

All review comments are addressed. Here's the current state:

  • goccy/go-yaml used throughout service_ports.go (not gopkg.in/yaml.v3)
  • Invalid ports format surfaces a warning in the warnings slice (line 98), not just debug-logged
  • Warnings emitted to stderr via console.FormatWarningMessage with c.IncrementWarningCount() per warning (orchestrator line 527–528)
  • Bracket notation for all service IDs: ${{ job.services['my-postgres'].ports['5432'] }} with single-quote escaping (line 108–109)
  • Hyphenated service ID test added with correct bracket-notation expectation
  • Tests use strings.Contains directly (no custom helper functions)
  • Smoke test runs daily only (no pull_request trigger), schedule changed to daily (commit 816a57a)

All 33 unit tests pass.

@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented Apr 1, 2026

@copilot

  • add Go type with yaml annotations to parse the yaml
  • add tests and integration tests in pkg/cli/workflows

…or service ports

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/1a8413b1-7fb1-4e16-ba81-98cae2550ebb

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 1, 2026

@copilot

  • add Go type with yaml annotations to parse the yaml
  • add tests and integration tests in pkg/cli/workflows

Done in fc65fca:

Typed structs (service_ports.go): replaced map[string]any parsing with servicesYAMLWrapper and serviceContainerConfig structs carrying yaml: field annotations. Ports stays any to handle both string specs and bare integers at the YAML list level; everything above that is now fully typed.

Test fixture (pkg/cli/workflows/test-service-ports.md): a workflow with two services (postgres:5432, redis:6379).

Integration tests (pkg/cli/compile_service_ports_integration_test.go, //go:build integration):

  • TestCompileServicePortsWorkflow — compiles the fixture and asserts both job.services['postgres'].ports['5432'] and job.services['redis'].ports['6379'] appear in the lock file under --allow-host-service-ports
  • TestCompileServicePorts_NoServices — no services → flag absent from lock file
  • TestCompileServicePorts_HyphenatedServiceIDmy-postgres emits bracket notation, not dot notation

@pelikhan pelikhan merged commit 74416d9 into main Apr 1, 2026
2 checks passed
@pelikhan pelikhan deleted the feat/service-ports-23756 branch April 1, 2026 04:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: auto-generate --allow-host-service-ports from services: port mappings

4 participants