Skip to content

Commit

Permalink
Implement CodePipelineEvent (#247)
Browse files Browse the repository at this point in the history
* [BREAKING CHANGE] Clean up CodePipeline Job Implementation

* Incorrectly used "CodePipelineEvent"

* Fix original typo missed when moving to job

* Implement CodePipeline Events

* Reference docs: https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html#codepipeline_event_type
* Test json from Reference Docs
* Fix data issues from live testing vs real events

* Fix up detail types

* Allow for floats

* Add "CloudWatch" to maintain backwards compatability

* go fmt

* Change tests to CloudWatch rename also

* Remove Job

* Fix explicit type constants

* Fix merge issue

* Add missed CloudWatch change

* Codereview fixes

* Change tests to match the ExecutionId -> ID change

* Again missed the test change to match with int64

* String to Int change to match code change

Co-authored-by: Bryan Moffatt <[email protected]>
  • Loading branch information
whithajess and bmoffatt authored Sep 18, 2021
1 parent d64324e commit 250c0d5
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 0 deletions.
107 changes: 107 additions & 0 deletions events/codepipeline_cloudwatch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package events

import (
"time"
)

const (
CodePipelineEventSource = "aws.codepipeline"
CodePipelineExecutionEventDetailType = "CodePipeline Pipeline Execution State Change"
CodePipelineActionEventDetailType = "CodePipeline Action Execution State Change"
CodePipelineStageEventDetailType = "CodePipeline Stage Execution State Change"
)

type CodePipelineStageState string

const (
CodePipelineStageStateStarted CodePipelineStageState = "STARTED"
CodePipelineStageStateSucceeded CodePipelineStageState = "SUCCEEDED"
CodePipelineStageStateResumed CodePipelineStageState = "RESUMED"
CodePipelineStageStateFailed CodePipelineStageState = "FAILED"
CodePipelineStageStateCanceled CodePipelineStageState = "CANCELED"
)

type CodePipelineState string

const (
CodePipelineStateStarted CodePipelineState = "STARTED"
CodePipelineStateSucceeded CodePipelineState = "SUCCEEDED"
CodePipelineStateResumed CodePipelineState = "RESUMED"
CodePipelineStateFailed CodePipelineState = "FAILED"
CodePipelineStateCanceled CodePipelineState = "CANCELED"
CodePipelineStateSuperseded CodePipelineState = "SUPERSEDED"
)

type CodePipelineActionState string

const (
CodePipelineActionStateStarted CodePipelineActionState = "STARTED"
CodePipelineActionStateSucceeded CodePipelineActionState = "SUCCEEDED"
CodePipelineActionStateFailed CodePipelineActionState = "FAILED"
CodePipelineActionStateCanceled CodePipelineActionState = "CANCELED"
)

// CodePipelineEvent is documented at:
// https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html#codepipeline_event_type
type CodePipelineCloudWatchEvent struct {
// Version is the version of the event's schema.
Version string `json:"version"`

// ID is the GUID of this event.
ID string `json:"id"`

// DetailType informs the schema of the Detail field. For deployment state-change
// events, the value should be equal to CodePipelineDeploymentEventDetailType.
// For instance state-change events, the value should be equal to
// CodePipelineInstanceEventDetailType.
DetailType string `json:"detail-type"`

// Source should be equal to CodePipelineEventSource.
Source string `json:"source"`

// AccountID is the id of the AWS account from which the event originated.
AccountID string `json:"account"`

// Time is the event's timestamp.
Time time.Time `json:"time"`

// Region is the AWS region from which the event originated.
Region string `json:"region"`

// Resources is a list of ARNs of CodePipeline applications and deployment
// groups that this event pertains to.
Resources []string `json:"resources"`

// Detail contains information specific to a deployment event.
Detail CodePipelineEventDetail `json:"detail"`
}

type CodePipelineEventDetail struct {
Pipeline string `json:"pipeline"`

// From live testing this is always int64 not string as documented
Version int64 `json:"version"`

ExecutionID string `json:"execution-id"`

Stage string `json:"stage"`

Action string `json:"action"`

State CodePipelineState `json:"state"`

Region string `json:"region"`

Type CodePipelineEventDetailType `json:"type"`
}

type CodePipelineEventDetailType struct {
Owner string `json:"owner"`

Category string `json:"category"`

Provider string `json:"provider"`

// From published EventBridge schema registry this is always int64 not string as documented
Version int64 `json:"version"`
}
99 changes: 99 additions & 0 deletions events/codepipeline_cloudwatch_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package events

import (
"encoding/json"
"github.com/stretchr/testify/require"
"io/ioutil"
"testing"
"time"
)

func TestUnmarshalCodePipelineEvent(t *testing.T) {
tests := []struct {
input string
expect CodePipelineCloudWatchEvent
}{
{
input: "testdata/codepipeline-action-execution-stage-change-event.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: 1,
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,
},
},
},
},
{
input: "testdata/codepipeline-execution-stage-change-event.json",
expect: CodePipelineCloudWatchEvent{
Version: "0",
ID: "CWE-event-id",
DetailType: "CodePipeline Stage 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: 1,
ExecutionID: "01234567-0123-0123-0123-012345678901",
State: "STARTED",
},
},
},
{
input: "testdata/codepipeline-execution-state-change-event.json",
expect: CodePipelineCloudWatchEvent{
Version: "0",
ID: "CWE-event-id",
DetailType: "CodePipeline Pipeline 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: 1,
ExecutionID: "01234567-0123-0123-0123-012345678901",
State: "STARTED",
},
},
},
}

for _, testcase := range tests {
data, err := ioutil.ReadFile(testcase.input)
require.NoError(t, err)

var actual CodePipelineCloudWatchEvent
require.NoError(t, json.Unmarshal(data, &actual))

require.Equal(t, testcase.expect, actual)
}
}
Original file line number Diff line number Diff line change
@@ -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": 1,
"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
}
}
}
18 changes: 18 additions & 0 deletions events/testdata/codepipeline-execution-stage-change-event.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": "0",
"id": "CWE-event-id",
"detail-type": "CodePipeline Stage 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": 1,
"state": "STARTED",
"execution-id": "01234567-0123-0123-0123-012345678901"
}
}
18 changes: 18 additions & 0 deletions events/testdata/codepipeline-execution-state-change-event.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": "0",
"id": "CWE-event-id",
"detail-type": "CodePipeline Pipeline 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": 1,
"state": "STARTED",
"execution-id": "01234567-0123-0123-0123-012345678901"
}
}

0 comments on commit 250c0d5

Please sign in to comment.