Skip to content

Commit

Permalink
Merge master into prod, release: v1.1.19
Browse files Browse the repository at this point in the history
  • Loading branch information
viktorbenei committed Dec 5, 2016
2 parents f09d461 + 30debf4 commit dcb9524
Show file tree
Hide file tree
Showing 8 changed files with 592 additions and 13 deletions.
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ a [GitHub](https://github.com) *repository*.

1. Open your *repository* on [GitHub.com](https://github.com)
2. Go to `Settings` of the *repository*
3. Select `Webhooks & services`
3. Select `Webhooks`
4. Click on `Add webhook`
5. Specify the `bitrise-webhooks` URL (`.../h/github/BITRISE-APP-SLUG/BITRISE-APP-API-TOKEN`) in the `Payload URL` field
6. Select the *events* you want to trigger a webhook for
Expand Down Expand Up @@ -132,6 +132,21 @@ A short step-by-step guide:
That's all! The next time you __push code__ or __push a new tag__
a build will be triggered (if you have Trigger mapping defined for the event(s) on Bitrise).

### Deveo - setup & usage:

All you have to do is register your `bitrise-webhooks` URL for
a [Deveo](https://deveo.com) *repository*.

1. Open your *repository* on [app.deveo.com](https://app.deveo.com)
2. Go to `Hooks` of the *project*
3. Add new hook to the *repository*
4. Select the hook type as `webhook`
5. Specify the `bitrise-webhooks` URL (`.../h/deveo/BITRISE-APP-SLUG/BITRISE-APP-API-TOKEN`) in the `Url` field
6. Type `json` in the `Content type` field
6. Click `Save hook`

That's all! The next time you __push code__ or __push a new tag__
a build will be triggered (if you have Trigger mapping defined for the event(s) on Bitrise).

### Slack - setup & usage:

Expand Down
2 changes: 1 addition & 1 deletion service/hook/bitbucketv2/bitbucketv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func detectContentTypeAttemptNumberAndEventKey(header http.Header) (string, stri
func transformPushEvent(pushEvent PushEventModel) hookCommon.TransformResultModel {
if len(pushEvent.PushInfo.Changes) < 1 {
return hookCommon.TransformResultModel{
Error: fmt.Errorf("No 'changes' included in the webhook, can't start a build."),
Error: fmt.Errorf("No 'changes' included in the webhook, can't start a build"),
}
}

Expand Down
183 changes: 183 additions & 0 deletions service/hook/deveo/deveo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package deveo

import (
"encoding/json"
"errors"
"fmt"
"net/http"
"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 ---

// CommitModel ...
type CommitModel struct {
Distinct bool `json:"distinct"`
CommitHash string `json:"id"`
CommitMessage string `json:"message"`
}

// PushEventModel ...
type PushEventModel struct {
Ref string `json:"ref"`
Deleted bool `json:"deleted"`
Commits []CommitModel `json:"commits"`
}

// RepoInfoModel ...
type RepoInfoModel struct {
SSHURL string `json:"ssh_url"`
}

// BranchInfoModel ...
type BranchInfoModel struct {
Ref string `json:"ref"`
CommitHash string `json:"sha"`
Repo RepoInfoModel `json:"repo"`
}

// ---------------------------------------
// --- Webhook Provider Implementation ---

// HookProvider ...
type HookProvider struct{}

func transformPushEvent(pushEvent PushEventModel) hookCommon.TransformResultModel {
if pushEvent.Deleted {
return hookCommon.TransformResultModel{
Error: errors.New("This is a 'Deleted' event, no build can be started"),
ShouldSkip: true,
}
}

headCommit := pushEvent.Commits[0]

if strings.HasPrefix(pushEvent.Ref, "refs/heads/") {
// code push
branch := strings.TrimPrefix(pushEvent.Ref, "refs/heads/")

if len(headCommit.CommitHash) == 0 {
return hookCommon.TransformResultModel{
Error: fmt.Errorf("Missing commit hash"),
}
}

return hookCommon.TransformResultModel{
TriggerAPIParams: []bitriseapi.TriggerAPIParamsModel{
{
BuildParams: bitriseapi.BuildParamsModel{
Branch: branch,
CommitHash: headCommit.CommitHash,
CommitMessage: headCommit.CommitMessage,
},
},
},
}
} else if strings.HasPrefix(pushEvent.Ref, "refs/tags/") {
// tag push
tag := strings.TrimPrefix(pushEvent.Ref, "refs/tags/")

if len(headCommit.CommitHash) == 0 {
return hookCommon.TransformResultModel{
Error: fmt.Errorf("Missing commit hash"),
}
}

return hookCommon.TransformResultModel{
TriggerAPIParams: []bitriseapi.TriggerAPIParamsModel{
{
BuildParams: bitriseapi.BuildParamsModel{
Tag: tag,
CommitHash: headCommit.CommitHash,
CommitMessage: headCommit.CommitMessage,
},
},
},
}
}

return hookCommon.TransformResultModel{
Error: fmt.Errorf("Ref (%s) is not a head nor a tag ref", pushEvent.Ref),
ShouldSkip: true,
}
}

func detectContentTypeAndEventID(header http.Header) (string, string, error) {
contentType, err := httputil.GetSingleValueFromHeader("Content-Type", header)
if err != nil {
return "", "", fmt.Errorf("Issue with Content-Type Header: %s", err)
}

deveoEvent, err := httputil.GetSingleValueFromHeader("X-Deveo-Event", header)
if err != nil {
return "", "", fmt.Errorf("Issue with X-Deveo-Event Header: %s", err)
}

return contentType, deveoEvent, nil
}

// TransformRequest ...
func (hp HookProvider) TransformRequest(r *http.Request) hookCommon.TransformResultModel {
contentType, deveoEvent, err := detectContentTypeAndEventID(r.Header)
if err != nil {
return hookCommon.TransformResultModel{
Error: fmt.Errorf("Issue with Headers: %s", err),
}
}

if contentType != hookCommon.ContentTypeApplicationJSON && contentType != hookCommon.ContentTypeApplicationXWWWFormURLEncoded {
return hookCommon.TransformResultModel{
Error: fmt.Errorf("Content-Type is not supported: %s", contentType),
}
}

if deveoEvent != "push" {
// Unsupported Deveo Event
return hookCommon.TransformResultModel{
Error: fmt.Errorf("Unsupported Deveo Webhook event: %s", deveoEvent),
}
}

if r.Body == nil {
return hookCommon.TransformResultModel{
Error: fmt.Errorf("Failed to read content of request body: no or empty request body"),
}
}

if deveoEvent == "push" {
// push (code & tag)
var pushEvent PushEventModel
if contentType == hookCommon.ContentTypeApplicationJSON {
if err := json.NewDecoder(r.Body).Decode(&pushEvent); err != nil {
return hookCommon.TransformResultModel{Error: fmt.Errorf("Failed to parse request body: %s", err)}
}
} else if contentType == hookCommon.ContentTypeApplicationXWWWFormURLEncoded {
payloadValue := r.PostFormValue("payload")
if payloadValue == "" {
return hookCommon.TransformResultModel{Error: fmt.Errorf("Failed to parse request body: empty payload")}
}
if err := json.NewDecoder(strings.NewReader(payloadValue)).Decode(&pushEvent); err != nil {
return hookCommon.TransformResultModel{Error: fmt.Errorf("Failed to parse payload: %s", err)}
}
} else {
return hookCommon.TransformResultModel{
Error: fmt.Errorf("Unsupported Content-Type: %s", contentType),
}
}
return transformPushEvent(pushEvent)
}

return hookCommon.TransformResultModel{
Error: fmt.Errorf("Unsupported Deveo event type: %s", deveoEvent),
}
}

// returns the repository clone URL
func (branchInfoModel BranchInfoModel) getRepositoryURL() string {
return branchInfoModel.Repo.SSHURL
}
Loading

0 comments on commit dcb9524

Please sign in to comment.