From 17230eec8b2377d65e8202db977e0785b25a12ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ngh=C4=A9a=20Nguy=E1=BB=85n=20Ng=E1=BB=8Dc?= Date: Sat, 9 May 2026 07:41:04 +0700 Subject: [PATCH 1/2] fix(events): correct CodePipelineEventBridge version field types The AWS service team confirmed the correct types for version fields in CodePipelineCloudWatchEvent (issue #552): - .version (top level): string -- already correct - .detail.version: numeric -- was int64, now json.Number - .detail.type.version: string -- was int64, now string The previous int64 types caused UnmarshalTypeError at runtime when AWS sent detail.version as a float (e.g. 2.0) or detail.type.version as a quoted string (e.g. "1"). json.Number is used for detail.version to handle both integer and float representations without losing the raw value. Test fixture updated to reflect real AWS payload format, and a new fixture added to cover the float version regression case. Fixes #552 --- events/codepipeline_cloudwatch.go | 10 +++-- events/codepipeline_cloudwatch_test.go | 40 +++++++++++++++++-- ...tion-stage-change-event-float-version.json | 27 +++++++++++++ ...e-action-execution-stage-change-event.json | 2 +- 4 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 events/testdata/codepipeline-action-execution-stage-change-event-float-version.json diff --git a/events/codepipeline_cloudwatch.go b/events/codepipeline_cloudwatch.go index 41340c4e..3ab21ea0 100644 --- a/events/codepipeline_cloudwatch.go +++ b/events/codepipeline_cloudwatch.go @@ -1,6 +1,7 @@ package events import ( + "encoding/json" "time" ) @@ -79,8 +80,9 @@ type CodePipelineEventBridgeEvent = CodePipelineCloudWatchEvent type CodePipelineEventDetail struct { Pipeline string `json:"pipeline"` - // From live testing this is always int64 not string as documented - Version int64 `json:"version"` + // Version is numeric. AWS may send integer (1) or float (2.0) depending on the event. + // json.Number preserves the raw value and allows callers to convert as needed. + Version json.Number `json:"version"` ExecutionID string `json:"execution-id"` @@ -104,8 +106,8 @@ type CodePipelineEventDetailType struct { Provider string `json:"provider"` - // From published EventBridge schema registry this is always int64 not string as documented - Version int64 `json:"version"` + // Version is a string per the AWS EventBridge schema registry and confirmed by the service team. + Version string `json:"version"` } type CodePipelineEventDetailExecutionResult struct { diff --git a/events/codepipeline_cloudwatch_test.go b/events/codepipeline_cloudwatch_test.go index 13321980..fbd7002c 100644 --- a/events/codepipeline_cloudwatch_test.go +++ b/events/codepipeline_cloudwatch_test.go @@ -29,7 +29,7 @@ func TestUnmarshalCodePipelineEvent(t *testing.T) { }, Detail: CodePipelineEventDetail{ Pipeline: "myPipeline", - Version: 1, + Version: "1", ExecutionID: "01234567-0123-0123-0123-012345678901", Stage: "Prod", Action: "myAction", @@ -39,7 +39,7 @@ func TestUnmarshalCodePipelineEvent(t *testing.T) { Owner: "AWS", Category: "Deploy", Provider: "CodeDeploy", - Version: 1, + Version: "1", }, }, }, @@ -59,7 +59,7 @@ func TestUnmarshalCodePipelineEvent(t *testing.T) { }, Detail: CodePipelineEventDetail{ Pipeline: "myPipeline", - Version: 1, + Version: "1", ExecutionID: "01234567-0123-0123-0123-012345678901", State: "STARTED", }, @@ -80,12 +80,44 @@ func TestUnmarshalCodePipelineEvent(t *testing.T) { }, Detail: CodePipelineEventDetail{ Pipeline: "myPipeline", - Version: 1, + Version: "1", ExecutionID: "01234567-0123-0123-0123-012345678901", State: "STARTED", }, }, }, + { + // AWS may send detail.version as a float (e.g. 2.0) rather than an integer. + // Regression test for https://github.com/aws/aws-lambda-go/issues/552 + input: "testdata/codepipeline-action-execution-stage-change-event-float-version.json", + expect: CodePipelineCloudWatchEvent{ + Version: "0", + ID: "CWE-event-id", + DetailType: "CodePipeline Action Execution State Change", + Source: "aws.codepipeline", + AccountID: "123456789012", + Time: time.Date(2017, 04, 22, 3, 31, 47, 0, time.UTC), + Region: "us-east-1", + Resources: []string{ + "arn:aws:codepipeline:us-east-1:123456789012:pipeline:myPipeline", + }, + Detail: CodePipelineEventDetail{ + Pipeline: "myPipeline", + Version: "2.0", + ExecutionID: "01234567-0123-0123-0123-012345678901", + Stage: "Prod", + Action: "myAction", + State: "STARTED", + Region: "us-west-2", + Type: CodePipelineEventDetailType{ + Owner: "AWS", + Category: "Deploy", + Provider: "CodeDeploy", + Version: "1", + }, + }, + }, + }, } for _, testcase := range tests { diff --git a/events/testdata/codepipeline-action-execution-stage-change-event-float-version.json b/events/testdata/codepipeline-action-execution-stage-change-event-float-version.json new file mode 100644 index 00000000..4a60fb65 --- /dev/null +++ b/events/testdata/codepipeline-action-execution-stage-change-event-float-version.json @@ -0,0 +1,27 @@ +{ + "version": "0", + "id": "CWE-event-id", + "detail-type": "CodePipeline Action Execution State Change", + "source": "aws.codepipeline", + "account": "123456789012", + "time": "2017-04-22T03:31:47Z", + "region": "us-east-1", + "resources": [ + "arn:aws:codepipeline:us-east-1:123456789012:pipeline:myPipeline" + ], + "detail": { + "pipeline": "myPipeline", + "version": 2.0, + "execution-id": "01234567-0123-0123-0123-012345678901", + "stage": "Prod", + "action": "myAction", + "state": "STARTED", + "region":"us-west-2", + "type": { + "owner": "AWS", + "category": "Deploy", + "provider": "CodeDeploy", + "version": "1" + } + } +} diff --git a/events/testdata/codepipeline-action-execution-stage-change-event.json b/events/testdata/codepipeline-action-execution-stage-change-event.json index 826fa77a..9d41990f 100644 --- a/events/testdata/codepipeline-action-execution-stage-change-event.json +++ b/events/testdata/codepipeline-action-execution-stage-change-event.json @@ -21,7 +21,7 @@ "owner": "AWS", "category": "Deploy", "provider": "CodeDeploy", - "version": 1 + "version": "1" } } } \ No newline at end of file From e573267c8b1da6326628ab1681c2d5cfce1dd63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ngh=C4=A9a=20Nguy=E1=BB=85n=20Ng=E1=BB=8Dc?= Date: Sat, 9 May 2026 07:42:35 +0700 Subject: [PATCH 2/2] docs: improve Version field comment in CodePipelineEventDetail --- events/codepipeline_cloudwatch.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/events/codepipeline_cloudwatch.go b/events/codepipeline_cloudwatch.go index 3ab21ea0..24d4a342 100644 --- a/events/codepipeline_cloudwatch.go +++ b/events/codepipeline_cloudwatch.go @@ -80,8 +80,8 @@ type CodePipelineEventBridgeEvent = CodePipelineCloudWatchEvent type CodePipelineEventDetail struct { Pipeline string `json:"pipeline"` - // Version is numeric. AWS may send integer (1) or float (2.0) depending on the event. - // json.Number preserves the raw value and allows callers to convert as needed. + // Version is the pipeline version number. AWS may send this as an integer (e.g. 1) + // or a float (e.g. 2.0). Use Version.Int64() or Version.Float64() to extract the value. Version json.Number `json:"version"` ExecutionID string `json:"execution-id"`