Add pending status on PR synchronize event

Signed-off-by: Steven Kriegler <61625851+justusbunsi@users.noreply.github.com>
This commit is contained in:
justusbunsi 2021-10-10 17:59:28 +02:00
parent 56f7a1081b
commit 895dfe92e0
No known key found for this signature in database
GPG key ID: 990B348ECAC9C7DB
4 changed files with 111 additions and 8 deletions

View file

@ -37,13 +37,28 @@ func (h *GiteaWebhookHandler) parseBody(rw http.ResponseWriter, r *http.Request)
func (h *GiteaWebhookHandler) HandleSynchronize(rw http.ResponseWriter, r *http.Request) { func (h *GiteaWebhookHandler) HandleSynchronize(rw http.ResponseWriter, r *http.Request) {
rw.Header().Set("Content-Type", "application/json") rw.Header().Set("Content-Type", "application/json")
_, err := h.parseBody(rw, r) raw, err := h.parseBody(rw, r)
if err != nil { if err != nil {
return return
} }
w, ok := webhook.NewPullWebhook(raw)
if !ok {
rw.WriteHeader(http.StatusUnprocessableEntity)
io.WriteString(rw, `{"message": "Error parsing POST body."}`)
return
}
if err := w.Validate(); err != nil {
rw.WriteHeader(http.StatusOK)
io.WriteString(rw, fmt.Sprintf(`{"message": "%s"}`, err.Error()))
return
}
rw.WriteHeader(http.StatusOK) rw.WriteHeader(http.StatusOK)
io.WriteString(rw, `{"message": "Processing data. See bot logs for details."}`) io.WriteString(rw, `{"message": "Processing data. See bot logs for details."}`)
w.ProcessData(h.giteaSdk, h.sqSdk)
} }
func (h *GiteaWebhookHandler) HandleComment(rw http.ResponseWriter, r *http.Request) { func (h *GiteaWebhookHandler) HandleComment(rw http.ResponseWriter, r *http.Request) {
@ -54,7 +69,7 @@ func (h *GiteaWebhookHandler) HandleComment(rw http.ResponseWriter, r *http.Requ
return return
} }
w, ok := webhook.New(raw) w, ok := webhook.NewCommentWebhook(raw)
if !ok { if !ok {
rw.WriteHeader(http.StatusUnprocessableEntity) rw.WriteHeader(http.StatusUnprocessableEntity)
io.WriteString(rw, `{"message": "Error parsing POST body."}`) io.WriteString(rw, `{"message": "Error parsing POST body."}`)

View file

@ -6,6 +6,7 @@ type State gitea.StatusState
const ( const (
StatusOK State = State(gitea.StatusSuccess) StatusOK State = State(gitea.StatusSuccess)
StatusPending State = State(gitea.StatusPending)
StatusFailure State = State(gitea.StatusFailure) StatusFailure State = State(gitea.StatusFailure)
) )

View file

@ -21,7 +21,7 @@ type comment struct {
Body string `json:"body"` Body string `json:"body"`
} }
type Webhook struct { type CommentWebhook struct {
Action string `json:"action"` Action string `json:"action"`
IsPR bool `json:"is_pull"` IsPR bool `json:"is_pull"`
Issue issue `json:"issue"` Issue issue `json:"issue"`
@ -29,7 +29,7 @@ type Webhook struct {
ConfiguredProject settings.Project ConfiguredProject settings.Project
} }
func (w *Webhook) inProjectsMapping(p []settings.Project) (bool, int) { func (w *CommentWebhook) inProjectsMapping(p []settings.Project) (bool, int) {
owner := w.Issue.Repository.Owner owner := w.Issue.Repository.Owner
name := w.Issue.Repository.Name name := w.Issue.Repository.Name
for idx, proj := range p { for idx, proj := range p {
@ -41,7 +41,7 @@ func (w *Webhook) inProjectsMapping(p []settings.Project) (bool, int) {
return false, 0 return false, 0
} }
func (w *Webhook) Validate() error { func (w *CommentWebhook) Validate() error {
if !w.IsPR { if !w.IsPR {
return fmt.Errorf("ignore non-PR hook") return fmt.Errorf("ignore non-PR hook")
} }
@ -64,7 +64,7 @@ func (w *Webhook) Validate() error {
return nil return nil
} }
func (w *Webhook) ProcessData(gSDK giteaSdk.GiteaSdkInterface, sqSDK sqSdk.SonarQubeSdkInterface) { func (w *CommentWebhook) ProcessData(gSDK giteaSdk.GiteaSdkInterface, sqSDK sqSdk.SonarQubeSdkInterface) {
headRef, err := gSDK.DetermineHEAD(w.ConfiguredProject.Gitea, w.Issue.Number) headRef, err := gSDK.DetermineHEAD(w.ConfiguredProject.Gitea, w.Issue.Number)
if err != nil { if err != nil {
log.Printf("Error retrieving HEAD ref: %s", err.Error()) log.Printf("Error retrieving HEAD ref: %s", err.Error())
@ -79,8 +79,8 @@ func (w *Webhook) ProcessData(gSDK giteaSdk.GiteaSdkInterface, sqSDK sqSdk.Sonar
}) })
} }
func New(raw []byte) (*Webhook, bool) { func NewCommentWebhook(raw []byte) (*CommentWebhook, bool) {
w := &Webhook{} w := &CommentWebhook{}
err := json.Unmarshal(raw, &w) err := json.Unmarshal(raw, &w)
if err != nil { if err != nil {
log.Printf("Error parsing Gitea webhook: %s", err.Error()) log.Printf("Error parsing Gitea webhook: %s", err.Error())

View file

@ -0,0 +1,87 @@
package gitea
import (
"encoding/json"
"fmt"
"log"
giteaSdk "gitea-sonarqube-pr-bot/internal/clients/gitea"
sqSdk "gitea-sonarqube-pr-bot/internal/clients/sonarqube"
"gitea-sonarqube-pr-bot/internal/settings"
)
type pullRequest struct {
Number int64 `json:"number"`
Head struct {
Sha string `json:"sha"`
} `json:"head"`
}
type repoOwner struct {
Login string `json:"login"`
}
type rawRepository struct {
Name string `json:"name"`
Owner repoOwner `json:"owner"`
}
type PullWebhook struct {
Action string `json:"action"`
PullRequest pullRequest `json:"pull_request"`
RawRepository rawRepository `json:"repository"`
Repository settings.GiteaRepository
ConfiguredProject settings.Project
}
func (w *PullWebhook) inProjectsMapping(p []settings.Project) (bool, int) {
owner := w.RawRepository.Owner.Login
name := w.RawRepository.Name
for idx, proj := range p {
if proj.Gitea.Owner == owner && proj.Gitea.Name == name {
return true, idx
}
}
return false, 0
}
func (w *PullWebhook) Validate() error {
found, pIdx := w.inProjectsMapping(settings.Projects)
owner := w.RawRepository.Owner.Login
name := w.RawRepository.Name
if !found {
return fmt.Errorf("ignore hook for non-configured project '%s/%s'", owner, name)
}
if w.Action != "synchronized" {
return fmt.Errorf("ignore hook for action others than synchronized")
}
w.Repository = settings.GiteaRepository{
Owner: owner,
Name: name,
}
w.ConfiguredProject = settings.Projects[pIdx]
return nil
}
func (w *PullWebhook) ProcessData(gSDK giteaSdk.GiteaSdkInterface, sqSDK sqSdk.SonarQubeSdkInterface) {
_ = gSDK.UpdateStatus(w.ConfiguredProject.Gitea, w.PullRequest.Head.Sha, giteaSdk.StatusDetails{
Url: "",
Message: "Analysis pending...",
State: giteaSdk.StatusPending,
})
}
func NewPullWebhook(raw []byte) (*PullWebhook, bool) {
w := &PullWebhook{}
err := json.Unmarshal(raw, &w)
if err != nil {
log.Printf("Error parsing Gitea webhook: %s", err.Error())
return w, false
}
return w, true
}