-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge master into prod, release: v1.1
- Loading branch information
Showing
6 changed files
with
595 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
149 changes: 149 additions & 0 deletions
149
service/hook/visualstudioteamservices/visualstudioteamservices.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package visualstudioteamservices | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"regexp" | ||
"strings" | ||
|
||
"github.com/bitrise-io/bitrise-webhooks/bitriseapi" | ||
hookCommon "github.com/bitrise-io/bitrise-webhooks/service/hook/common" | ||
"github.com/bitrise-io/go-utils/httputil" | ||
) | ||
|
||
// -------------------------- | ||
// --- Webhook Data Model --- | ||
|
||
// CommitsModel ... | ||
type CommitsModel struct { | ||
CommitID string `json:"commitId"` | ||
Comment string `json:"comment"` | ||
} | ||
|
||
// RefUpdatesModel ... | ||
type RefUpdatesModel struct { | ||
Name string `json:"name"` | ||
} | ||
|
||
// ResourceModel ... | ||
type ResourceModel struct { | ||
Commits []CommitsModel `json:"commits"` | ||
RefUpdates []RefUpdatesModel `json:"refUpdates"` | ||
} | ||
|
||
// CodePushEventModel ... | ||
type CodePushEventModel struct { | ||
SubscriptionID string `json:"subscriptionId"` | ||
EventType string `json:"eventType"` | ||
PublisherID string `json:"publisherId"` | ||
Resource ResourceModel `json:"resource"` | ||
} | ||
|
||
// --------------------------------------- | ||
// --- Webhook Provider Implementation --- | ||
|
||
// HookProvider ... | ||
type HookProvider struct{} | ||
|
||
func detectContentType(header http.Header) (string, error) { | ||
contentType, err := httputil.GetSingleValueFromHeader("Content-Type", header) | ||
if err != nil { | ||
return "", fmt.Errorf("Issue with Content-Type Header: %s", err) | ||
} | ||
|
||
return contentType, nil | ||
} | ||
|
||
// transformCodePushEvent ... | ||
func transformCodePushEvent(codePushEvent CodePushEventModel) hookCommon.TransformResultModel { | ||
if codePushEvent.PublisherID != "tfs" { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("Not a Team Foundation Server notification, can't start a build."), | ||
} | ||
} | ||
|
||
if codePushEvent.EventType != "git.push" { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("Not a code push event, can't start a build."), | ||
} | ||
} | ||
|
||
if codePushEvent.SubscriptionID == "00000000-0000-0000-0000-000000000000" { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("Initial (test) event detected, skipping."), | ||
ShouldSkip: true, | ||
} | ||
} | ||
|
||
if len(codePushEvent.Resource.RefUpdates) != 1 { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("Can't detect branch information (resource.refUpdates is empty), can't start a build."), | ||
} | ||
} | ||
|
||
if !strings.HasPrefix(codePushEvent.Resource.RefUpdates[0].Name, "refs/heads/") { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("Badly formatted branch detected, can't start a build."), | ||
} | ||
} | ||
branch := strings.TrimPrefix(codePushEvent.Resource.RefUpdates[0].Name, "refs/heads/") | ||
|
||
if len(codePushEvent.Resource.Commits) < 1 { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("No 'commits' included in the webhook, can't start a build."), | ||
} | ||
} | ||
// VSO sends separate events for separate branches, | ||
// and commits are in ascending order, by commit date-time | ||
aCommit := codePushEvent.Resource.Commits[0] | ||
|
||
return hookCommon.TransformResultModel{ | ||
TriggerAPIParams: []bitriseapi.TriggerAPIParamsModel{ | ||
{ | ||
BuildParams: bitriseapi.BuildParamsModel{ | ||
CommitHash: aCommit.CommitID, | ||
CommitMessage: aCommit.Comment, | ||
Branch: branch, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
// TransformRequest ... | ||
func (hp HookProvider) TransformRequest(r *http.Request) hookCommon.TransformResultModel { | ||
contentType, err := detectContentType(r.Header) | ||
if err != nil { | ||
return hookCommon.TransformResultModel{ | ||
Error: err, | ||
} | ||
} | ||
matched, err := regexp.MatchString("application/json", contentType) | ||
if err != nil { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("Issue with Header checking: %s", err), | ||
} | ||
} | ||
|
||
if matched != true { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("Content-Type is not supported: %s", contentType), | ||
} | ||
} | ||
|
||
if r.Body == nil { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("Failed to read content of request body: no or empty request body"), | ||
} | ||
} | ||
|
||
var codePushEvent CodePushEventModel | ||
if err := json.NewDecoder(r.Body).Decode(&codePushEvent); err != nil { | ||
return hookCommon.TransformResultModel{ | ||
Error: fmt.Errorf("Failed to parse request body as JSON: %s", err), | ||
} | ||
} | ||
|
||
return transformCodePushEvent(codePushEvent) | ||
} |
Oops, something went wrong.