agola/cmd/agola-git-hook/main.go
2019-02-22 10:46:48 +01:00

166 lines
4.1 KiB
Go

// Copyright 2019 Sorint.lab
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"bytes"
"context"
"encoding/json"
"log"
"net/http"
"os"
"strings"
"github.com/sorintlab/agola/internal/util"
)
const (
emptySHA = "0000000000000000000000000000000000000000"
)
type Hook struct {
Sha string `json:"sha"`
Ref string `json:"ref"`
Before string `json:"before"`
After string `json:"after"`
Compare string `json:"compare_url"`
RefType string `json:"ref_type"`
Pusher struct {
Name string `json:"name"`
Email string `json:"email"`
Login string `json:"login"`
Username string `json:"username"`
} `json:"pusher"`
Repo struct {
ID int64 `json:"id"`
Name string `json:"name"`
FullName string `json:"full_name"`
URL string `json:"html_url"`
Private bool `json:"private"`
Owner struct {
Name string `json:"name"`
Email string `json:"email"`
Username string `json:"username"`
} `json:"owner"`
} `json:"repository"`
Commits []Commit `json:"commits"`
Sender struct {
ID int64 `json:"id"`
Login string `json:"login"`
Username string `json:"username"`
Email string `json:"email"`
Avatar string `json:"avatar_url"`
} `json:"sender"`
}
type Commit struct {
ID string `json:"id"`
Message string `json:"message"`
URL string `json:"url"`
}
func isBareRepository(path string) (bool, error) {
git := &util.Git{}
out, err := git.Output(context.Background(), nil, "rev-parse", "--is-bare-repository")
if err != nil {
return false, err
}
return string(out) == "true", nil
}
func commitMessage(sha string) (string, error) {
git := &util.Git{}
out, err := git.Output(context.Background(), nil, "show", "-s", "--format=%B", sha)
return strings.TrimSpace(string(out)), err
}
func genHook(oldCommit, newCommit, ref string) (*Hook, error) {
hook := &Hook{}
hook.Before = oldCommit
hook.After = newCommit
hook.Ref = ref
hook.Commits = make([]Commit, 2)
hook.Commits[0].ID = newCommit
hook.Commits[1].ID = oldCommit
newCommitMessage, err := commitMessage(newCommit)
if err != nil {
return nil, err
}
hook.Commits[0].Message = newCommitMessage
if oldCommit != emptySHA {
oldCommitMessage, err := commitMessage(oldCommit)
if err != nil {
return nil, err
}
hook.Commits[1].Message = oldCommitMessage
}
git := &util.Git{}
repo, _ := git.ConfigGet(context.Background(), "agola.repo")
log.Printf("repo: %s", repo)
parts := strings.Split(string(repo), "/")
hook.Repo.Owner.Username = parts[0]
hook.Repo.Name = parts[1]
return hook, nil
}
func main() {
log.Printf("post receice hook")
//data, _ := ioutil.ReadAll(os.Stdin)
//parts := strings.Split(string(data), " ")
//if len(parts) != 3 {
// log.Fatalf("not enought parts. data: %s", data)
//}
//oldCommit := parts[0]
//newCommit := parts[1]
//ref := parts[2]
oldCommit := os.Args[1]
newCommit := os.Args[2]
ref := os.Args[3]
log.Printf("oldcommit: %s, newcommit: %s, ref: %s", oldCommit, newCommit, ref)
git := &util.Git{}
repo, _ := git.ConfigGet(context.Background(), "agola.repo")
webhookURL, _ := git.ConfigGet(context.Background(), "agola.webhookURL")
log.Printf("repo: %s", repo)
log.Printf("webhookURL: %s", webhookURL)
hook, _ := genHook(oldCommit, newCommit, ref)
hookj, _ := json.Marshal(hook)
req, err := http.NewRequest("POST", webhookURL, bytes.NewReader(hookj))
if err != nil {
log.Fatalf("err: %v", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Gitea-Event", "push")
if _, err := http.DefaultClient.Do(req); err != nil {
log.Fatalf("err: %v", err)
}
}