Skip to content

Commit

Permalink
Merge master into prod, release: v1.1.4
Browse files Browse the repository at this point in the history
  • Loading branch information
viktorbenei committed Apr 27, 2016
2 parents 41bbe94 + 99d35c6 commit 0e63677
Show file tree
Hide file tree
Showing 6 changed files with 385 additions and 4 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ For more information check the *How to add support for a new Provider* section.
* handled on the path: `/h/visualstudio/BITRISE-APP-SLUG/BITRISE-APP-API-TOKEN`
* [GitLab](https://gitlab.com)
* handled on the path: `/h/gitlab/BITRISE-APP-SLUG/BITRISE-APP-API-TOKEN`
* [Gogs](https://gogs.io)
* handled on the path: `/h/gogs/BITRISE-APP-SLUG/BITRISE-APP-API-TOKEN`


### GitHub - setup & usage:
Expand Down Expand Up @@ -78,6 +80,22 @@ a [GitLab](https://gitlab.com) *project*.
That's all, the next time you push code (into your repository) a build will be triggered.


### Gogs - setup & usage:

All you have to do is register your `bitrise-webhooks` URL as a Webhook in your [Gogs](https://gogs.io) repository.

1. Open your *project* on your repository's hosting URL.
1. Go to `Settings` of the *project*
1. Select `Webhooks`, `Add Webhook`, then `Gogs`.
1. Specify the `bitrise-webhooks` URL (`.../h/gogs/BITRISE-APP-SLUG/BITRISE-APP-API-TOKEN`) in the `Payload URL` field.
1. Set the `Content Type` to `application/json`.
1. A Secret is not required at this time.
1. Set the trigger to be fired on `Just the push event`
1. Save the Webhook.

That's all, the next time you push code (into your repository) a build will be triggered.


### Visual Studio Online / Visual Studio Team Services - setup & usage:

All you have to do is register your `bitrise-webhooks` URL for
Expand Down Expand Up @@ -331,5 +349,11 @@ response provider will be used.
## TODO

* Re-try handling
* Docker image: auto-create & publish a Docker Image for the webhooks server, to make it easy to run it on your own server
* Bitbucket V1 (aka "Services" on the Bitbucket web UI) - not sure whether we should support this,
it's already kind of deprecated, and we already support the newer, V2 webhooks.

## Contributors

* [The Bitrise Team](https://github.com/bitrise-io)
* [Chad Robinson](https://github.com/crrobinson14)
3 changes: 0 additions & 3 deletions bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ workflows:
# Go lint
go get -u github.com/golang/lint/golint
# Go Vet
go get -u golang.org/x/tools/cmd/vet
test:
before_run:
- _install_test_tools
Expand Down
2 changes: 2 additions & 0 deletions service/hook/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
hookCommon "github.com/bitrise-io/bitrise-webhooks/service/hook/common"
"github.com/bitrise-io/bitrise-webhooks/service/hook/github"
"github.com/bitrise-io/bitrise-webhooks/service/hook/gitlab"
"github.com/bitrise-io/bitrise-webhooks/service/hook/gogs"
"github.com/bitrise-io/bitrise-webhooks/service/hook/slack"
"github.com/bitrise-io/bitrise-webhooks/service/hook/visualstudioteamservices"
"github.com/gorilla/mux"
Expand All @@ -26,6 +27,7 @@ func supportedProviders() map[string]hookCommon.Provider {
"slack": slack.HookProvider{},
"visualstudio": visualstudioteamservices.HookProvider{},
"gitlab": gitlab.HookProvider{},
"gogs": gogs.HookProvider{},
}
}

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

// # Infos / notes:
//
// ## Webhook calls
//
// Official API docs: https://gogs.io/docs/features/webhook
//
// This module works very similarly to the Gitlab processor.
// Please look there for more discussion of its operation.

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 ---

const (
pushEventID = "push"
)

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

// CodePushEventModel ...
type CodePushEventModel struct {
Secret string `json:"secret"`
Ref string `json:"ref"`
CheckoutSHA string `json:"after"`
Commits []CommitModel `json:"commits"`
}

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

// HookProvider ...
type HookProvider struct{}

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)
}

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

return contentType, eventID, nil
}

func transformCodePushEvent(codePushEvent CodePushEventModel) hookCommon.TransformResultModel {
if !strings.HasPrefix(codePushEvent.Ref, "refs/heads/") {
return hookCommon.TransformResultModel{
Error: fmt.Errorf("Ref (%s) is not a head ref", codePushEvent.Ref),
ShouldSkip: true,
}
}
branch := strings.TrimPrefix(codePushEvent.Ref, "refs/heads/")

lastCommit := CommitModel{}
isLastCommitFound := false
for _, aCommit := range codePushEvent.Commits {
if aCommit.CommitHash == codePushEvent.CheckoutSHA {
isLastCommitFound = true
lastCommit = aCommit
break
}
}

if !isLastCommitFound {
return hookCommon.TransformResultModel{
Error: errors.New("The commit specified by 'after' was not included in the 'commits' array - no match found"),
}
}

return hookCommon.TransformResultModel{
TriggerAPIParams: []bitriseapi.TriggerAPIParamsModel{
{
BuildParams: bitriseapi.BuildParamsModel{
CommitHash: lastCommit.CommitHash,
CommitMessage: lastCommit.CommitMessage,
Branch: branch,
},
},
},
}
}

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

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

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

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

// code push
var codePushEvent CodePushEventModel
if contentType == "application/json" {
if err := json.NewDecoder(r.Body).Decode(&codePushEvent); err != nil {
return hookCommon.TransformResultModel{Error: fmt.Errorf("Failed to parse request body: %s", err)}
}
}
return transformCodePushEvent(codePushEvent)
}
Loading

0 comments on commit 0e63677

Please sign in to comment.