This repository has been archived by the owner on Oct 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27
/
main.go
123 lines (103 loc) · 3.08 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"os"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/codepipeline"
"github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
"github.com/google/go-github/github"
)
var githubOAuthToken = ""
var codepipelineTemplate = ""
func pipelineExists(target string) bool {
sess := session.Must(session.NewSession())
svc := codepipeline.New(sess)
resp, _ := svc.GetPipeline(&codepipeline.GetPipelineInput{
Name: &target,
})
return resp.Pipeline != nil
}
func clonePipeline(source, target, branch string) error {
sess := session.Must(session.NewSession())
svc := codepipeline.New(sess)
resp, err := svc.GetPipeline(&codepipeline.GetPipelineInput{
Name: &source,
})
if err != nil {
return err
}
pipeline := &codepipeline.PipelineDeclaration{
Name: &target,
RoleArn: resp.Pipeline.RoleArn,
ArtifactStore: resp.Pipeline.ArtifactStore,
Stages: resp.Pipeline.Stages,
}
oauth_token := os.Getenv("GITHUB_OAUTH_TOKEN")
if oauth_token == "" {
oauth_token = githubOAuthToken
}
pipeline.Stages[0].Actions[0].Configuration["OAuthToken"] = &oauth_token
pipeline.Stages[0].Actions[0].Configuration["Branch"] = &branch
_, err = svc.CreatePipeline(&codepipeline.CreatePipelineInput{
Pipeline: pipeline,
})
return err
}
func destroyPipeline(target string) error {
sess := session.Must(session.NewSession())
svc := codepipeline.New(sess)
_, err := svc.DeletePipeline(&codepipeline.DeletePipelineInput{
Name: &target,
})
return err
}
type evtStructure struct {
Header map[string]string `json:"header"`
Body json.RawMessage `json:"body"`
}
type response struct {
Header map[string]string `json:"header"`
Error string `json:",omitempty"`
Status string `json:"status"`
HTTPStatus int `json:"httpStatus"`
RequestID string `json:"requestId"`
}
func Handle(evt json.RawMessage, ctx *runtime.Context) (string, error) {
var payload evtStructure
json.Unmarshal(evt, &payload)
var rsp = response{
Header: make(map[string]string),
RequestID: ctx.AWSRequestID,
}
if payload.Header["X-GitHub-Event"] == "pull_request" {
prEvt := new(github.PullRequestEvent)
json.Unmarshal(payload.Body, prEvt)
prName := fmt.Sprintf("pr-%d", *prEvt.PullRequest.Number)
if *prEvt.PullRequest.State == "open" {
if !pipelineExists(prName) {
err := clonePipeline(codepipelineTemplate, prName, *prEvt.PullRequest.Head.Ref)
if v, ok := err.(awserr.Error); ok {
log.Printf("failed: %#v %#v\n", v.Message(), v.OrigErr())
}
}
} else if *prEvt.PullRequest.State == "closed" {
if pipelineExists(prName) {
err := destroyPipeline(prName)
}
}
rsp.Header["X-GitHub-Delivery"] = payload.Header["X-GitHub-Delivery"]
rsp.Status = "ok"
rsp.HTTPStatus = 200
} else {
rsp.Error = fmt.Sprintf("unhandled %s", payload.Header["X-GitHub-Event"])
rsp.Status = "error"
rsp.HTTPStatus = 200
}
var b = bytes.Buffer{}
json.NewEncoder(&b).Encode(rsp)
return b.String(), nil
}