Skip to content

CodeBuild event streaming#1809

Merged
jordanstephens merged 6 commits intomainfrom
jordan/codebuild-events
Feb 6, 2026
Merged

CodeBuild event streaming#1809
jordanstephens merged 6 commits intomainfrom
jordan/codebuild-events

Conversation

@jordanstephens
Copy link
Copy Markdown
Member

@jordanstephens jordanstephens commented Jan 19, 2026

Description

This PR implements CodeBuild Event streaming by parsing CodeBuild log messages and emitting events on the subscribe stream (just like we do for ecs events).

Linked Issues

Checklist

  • I have performed a self-review of my code
  • I have added appropriate tests
  • I have updated the Defang CLI docs and/or README to reflect my changes, if necessary

Summary by CodeRabbit

  • Documentation

    • Updated Samples reference to DefangLabs/samples with examples for Golang, Python, and Node.js.
  • New Features

    • Added AWS CodeBuild event handling and streaming support for build/deploy status updates.
  • Tests

    • Added tests validating CodeBuild log parsing and state mapping.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 19, 2026

📝 Walkthrough

Walkthrough

Adds AWS CodeBuild event parsing and dispatch into the BYOC AWS log streaming pipeline, introduces a CodebuildEvent type and Event interface, updates stream constructors/subscriptions and ByocAws to register/dispatch CodeBuild handlers, and updates README sample links.

Changes

Cohort / File(s) Summary
Documentation Updates
pkgs/npm/README.md, src/README.md
Updated Samples link targets to DefangLabs/samples and expanded descriptions to mention Golang, Python, and Node.js deployment/task examples.
BYOC AWS client & stream
src/pkg/cli/client/byoc/aws/byoc.go, src/pkg/cli/client/byoc/aws/stream.go, src/pkg/cli/client/byoc/aws/stream_test.go, src/pkg/cli/client/byoc/aws/subscribe.go
Added CodebuildEventHandler interface and registration; extended ByocAws struct to store CodeBuild handlers and register them in Subscribe; updated newByocServerStream signature to accept a CodeBuild handler and added nil-safety checks; integrated CodeBuild parsing/dispatch into event loop; added HandleCodebuildEvent on subscribe stream; tests adjusted to new constructor signature.
CodeBuild parsing module & tests
src/pkg/clouds/aws/codebuild/event.go, src/pkg/clouds/aws/codebuild/event_test.go
New codebuild package: Event interface and CodebuildEvent type with accessors (Service, Etag, Host, State, Status); ParseCodebuildEvent and parseCodebuildMessage map log messages to defangv1.ServiceState; comprehensive unit tests added for state mapping and parsing.

Sequence Diagram

sequenceDiagram
    participant LogStream as CloudWatch Log Stream
    participant Parser as byocServerStream
    participant CBHandler as CodebuildEventHandler
    participant Subscriber as byocSubscribeServerStream
    participant Client as CLI Client

    LogStream->>Parser: deliver log entries
    activate Parser
    Parser->>Parser: parse entries (ECS / Firelens / CodeBuild)
    Parser->>Parser: ParseCodebuildEvent(entry)
    alt CodeBuild handler registered
        Parser->>CBHandler: HandleCodebuildEvent(evt)
        activate CBHandler
        CBHandler->>Subscriber: build SubscribeResponse
        Subscriber->>Client: stream SubscribeResponse
        deactivate CBHandler
    else No handler
        Parser->>Subscriber: skip CodeBuild dispatch
        Subscriber->>Client: continue other events
    end
    deactivate Parser
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • edwardrf
  • lionello

Poem

🐰 I hopped through logs both near and wide,

Trimmed a tail and let CodeBuild ride,
Events now scurry to handlers with cheer,
Streams sing back responses for all to hear,
Little paws clap — new parsing is here! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'CodeBuild event streaming' directly matches the main objective: implementing CodeBuild event streaming by parsing logs and emitting events.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jordan/codebuild-events

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.5.0)

level=warning msg="[linters_context] running gomodguard failed: unable to read module file go.mod: current working directory must have a go.mod file: if you are not using go modules it is suggested to disable this linter"
level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Comment @coderabbitai help to get the list of available commands and usage tips.

@jordanstephens jordanstephens force-pushed the jordan/codebuild-events branch from 9e00e22 to 6f0e03c Compare February 5, 2026 23:33
@jordanstephens jordanstephens changed the title sketch out codebuild events CodeBuild event streaming Feb 5, 2026
@jordanstephens jordanstephens marked this pull request as ready for review February 5, 2026 23:36
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pkg/cli/client/byoc/aws/stream.go (1)

102-113: ⚠️ Potential issue | 🟠 Major

CodeBuild service filtering currently drops all build logs when services is set.
response.Service remains <service>-image, while CodeBuild entries use the trimmed <service>. The pre-filter checks <service>-image and the per-entry filter checks <service>, so any non-empty services filter will exclude CodeBuild logs unless the client supplies both names.

🛠️ Suggested fix (use a single canonical service name for filtering)
 	// Client-side filtering on etag and service (if provided)
+	serviceForFilter := response.GetService()
+	if parseCodeBuildRecords {
+		serviceForFilter = strings.TrimSuffix(serviceForFilter, "-image")
+	}
 	if response.Etag != "" && bs.etag != "" && bs.etag != response.Etag {
 		return nil // TODO: filter these out using the AWS StartLiveTail API
 	}
-	if len(bs.services) > 0 && !slices.Contains(bs.services, response.GetService()) {
+	if len(bs.services) > 0 && !slices.Contains(bs.services, serviceForFilter) {
 		return nil // TODO: filter these out using the AWS StartLiveTail API
 	}
@@
 	} else if parseCodeBuildRecords {
-		entry.Service = strings.TrimSuffix(response.Service, "-image")
+		entry.Service = serviceForFilter
 		entry.Etag = response.Etag
 		entry.Host = response.Host
 		evt := codebuild.ParseCodebuildEvent(entry)

Also applies to: 144-150, 184-199

🤖 Fix all issues with AI agents
In `@src/pkg/cli/client/byoc/aws/subscribe.go`:
- Around line 22-31: HandleCodebuildEvent on byocSubscribeServerStream currently
forwards every CodeBuild event to s.ch; apply the same etag/service filtering
used for ECS events by early-returning when the event doesn't match the
subscriber's filters (e.g., check s.etag and s.service or call an existing
s.matchesFilter(evt) before building resp). Only construct and send
defangv1.SubscribeResponse if the event passes the filter, otherwise return;
preserve the select on s.ch and s.done for sending when matched.

Comment thread src/pkg/cli/client/byoc/aws/subscribe.go
Comment thread src/pkg/cli/client/byoc/aws/stream.go Outdated
Comment thread src/pkg/cli/client/byoc/aws/subscribe.go Outdated
Comment thread src/pkg/clouds/aws/codebuild/event.go Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pkg/cli/client/byoc/aws/stream.go (1)

94-199: ⚠️ Potential issue | 🟠 Major

CodeBuild events get dropped when services filtering is enabled.
response.Service / entry.Service are set to <service>-image, so the Line 145 and Line 197 filters reject typical <service> names. Normalize to the trimmed service for filtering (without changing the emitted service if you still want -image in logs).

🛠️ Suggested fix
-	if len(bs.services) > 0 && !slices.Contains(bs.services, response.GetService()) {
+	filterService := response.GetService()
+	if parseCodeBuildRecords {
+		filterService = strings.TrimSuffix(filterService, "-image")
+	}
+	if len(bs.services) > 0 && !slices.Contains(bs.services, filterService) {
 		return nil // TODO: filter these out using the AWS StartLiveTail API
 	}
...
-		if entry.Service != "" && len(bs.services) > 0 && !slices.Contains(bs.services, entry.Service) {
+		entryService := entry.Service
+		if parseCodeBuildRecords {
+			entryService = strings.TrimSuffix(entryService, "-image")
+		}
+		if entryService != "" && len(bs.services) > 0 && !slices.Contains(bs.services, entryService) {
 			continue
 		}
🤖 Fix all issues with AI agents
In `@src/pkg/clouds/aws/codebuild/event.go`:
- Around line 63-65: The Host() method on CodebuildEvent currently returns the
literal "codebuild" which discards the parsed host/build id set during
ParseCodebuildEvent (entry.Host); update CodebuildEvent.Host() to return the
stored field (e.host) and use "codebuild" only as a fallback when e.host is
empty so downstream consumers get the actual build id when available; locate the
Host() method on the CodebuildEvent type and change its return to e.host (with a
conditional fallback).
- Around line 67-68: The Status() method on CodebuildEvent currently returns an
empty string causing SubscribeResponse.Status to be blank; implement Status() to
return a meaningful value by extracting a status from the event payload (e.g.,
return a dedicated field like e.Status or e.BuildStatus if present, otherwise
fall back to the raw message string such as e.RawMessage or the JSON
"detail"->"build-status" value), so subscribers receive a non-empty status;
update the CodebuildEvent.Status() implementation to check and return these
fields in priority order.
🧹 Nitpick comments (1)
src/pkg/cli/client/byoc/aws/subscribe.go (1)

23-35: Consider emitting the trimmed service name in responses.
You filter with strings.TrimSuffix(..., "-image") but still emit Name: evt.Service(). If you want output to match what users subscribe to, consider using the trimmed value.

♻️ Suggested refactor
-	service := strings.TrimSuffix(evt.Service(), "-image")
+	service := strings.TrimSuffix(evt.Service(), "-image")
 	if len(s.services) > 0 && !slices.Contains(s.services, service) {
 		return
 	}
 	resp := defangv1.SubscribeResponse{
-		Name:   evt.Service(),
+		Name:   service,
 		Status: evt.Status(),
 		State:  evt.State(),
 	}

Comment thread src/pkg/clouds/aws/codebuild/event.go
Comment thread src/pkg/clouds/aws/codebuild/event.go
@jordanstephens jordanstephens merged commit f2f6133 into main Feb 6, 2026
14 checks passed
@jordanstephens jordanstephens deleted the jordan/codebuild-events branch February 6, 2026 23:19
@coderabbitai coderabbitai Bot mentioned this pull request Mar 6, 2026
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