Commit 67eccb86 authored by Andreas Wagner's avatar Andreas Wagner
Browse files

Add github routines.

parent 5e8b6246
// Package github processes webhook posts, retrieves files and pipes them to zenodo processing
package github
import (
"encoding/json"
"fmt"
"io"
"log"
"gitlab.gwdg.de/rg-mpg-de/tei2zenodo"
)
// 0. decide where trigger keywords can be stored - in commit messages?
// 1. parse github push request -> get commits
// 2. retrieve commits -> get files
// 3. retrieve files -> pipe to zenodo
// PushHook stores the payload of a github push webhook event
type PushHook struct {
Ref string
Head string
Before string
After string
Size int
Created bool
Deleted bool
Forced bool
Compare string
Sender User
Pusher User
Organization Org
Repository Repo
Commits []Commit
}
// ReleaseHook stores the payload of a github release webhook event
type ReleaseHook struct {
Action string
Release Release
Repository Repo
Sender User
}
// Release stores the details of a github release
type Release struct {
ID int64
NodeID string
TagName string
TargetCommitish string
Name string
Draft bool
Prerelease bool
Author User
CreatedAt string
PublishedAt string
URL string
AssetsURL string
UploadURL string
HTMLURL string
TarballURL string
ZipballURL string
Body string
}
// Commit stores info about a single commit
type Commit struct {
SHA string
Message string
URL string
Author User
}
// CommitDetails stores more detailed information about a single commit
type CommitDetails struct {
SHA string
NodeID string
Author User
Committer User
Commit CommitMeta
Files []File
Stats Stats
URL string
HTMLURL string
CommentsURL string
}
// CommitMeta stores information about committer, tree etc
type CommitMeta struct {
URL string
Author User
Committer User
Message string
CommentCount int
Tree Commit
Parents []Commit
Verification Verification
}
// Verification stores information about a commit's verification
type Verification struct {
Verified bool
Reason string
Signature string
Payload string
}
// Stats stores information about a commit's stats
type Stats struct {
Additions int
Deletions int
Changes int
Total int
}
// File stores information about a file concerned by a commit
type File struct {
Filename string
Additions int
Deletions int
Changes int
Status string
Patch string
RawURL string
BlobURL string
}
// User stores information about a person
type User struct {
Name string
Login string
EMail string
ID int64
NodeID string
Type string
GravatarID string
Date string
SideAdmin bool
URL string
HTMLURL string
AvatarURL string
FollowersURL string
FollowingURL string
GistsURL string
StarredURL string
SubscriptionsURL string
OrganizationsURL string
ReposURL string
EventsURL string
ReceivedEventsURL string
}
// Org stores information about a github organization
type Org struct {
Login string
ID int64
NodeID string
Description string
URL string
ReposURL string
EventsURL string
HooksURL string
IssuesURL string
MembersURL string
PublicMembersURL string
AvatarURL string
}
// Repo stores information about a github repository
type Repo struct {
ID int64
NodeID string
Name string
FullName string
Description string
License string
Owner User
Language string
DefaultBranch string
MasterBranch string
CreatedAt string
UpdatedAt string
PushedAt string
Size int
ForksCount int
Forks int
OpenIssuesCount int
OpenIssues int
WatchersCount int
Watchers int
StargazersCount int
Stargazers int
Private bool
Form bool
Archived bool
Disabled bool
HasIssues bool
HasProjects bool
HasDownloads bool
HasWiki bool
HasPages bool
Homepage string
URL string
HTMLURL string
ForksURL string
KeysURL string
CollaboratorsURL string
TeamsURL string
HooksURL string
IssueEventsURL string
EventsURL string
AssigneesURL string
BranchesURL string
TagsURL string
BlobsURL string
GitTagsURL string
GitRegsURL string
TreesURL string
StatusesURL string
LanguagesURL string
StargazersURL string
ContributorsURL string
SubscribersURL string
SubscriptionURL string
CommitsURL string
GitCommitsURL string
CommentsURL string
IssueCommentsURL string
ContentsURL string
CompareURL string
MergesURL string
ArchiveURL string
DownloadsURL string
IssuesURL string
PullsURL string
MilestonesURL string
NotificationsURL string
LabelsURL string
ReleasesURL string
DeploymentsURL string
GitURL string
SSHURL string
CloneURL string
SVNURL string
MirrorURL string
}
// ProcessHook processes a Webhook's payload
// it returns a (boolean) doPublish value, a slice of readers with all concerned files, and an error value
func ProcessHook(hookType string, r io.Reader, conf *tei2zenodo.Config) (bool, []io.ReadSeeker, error) {
doPublish := false
switch hookType {
case "push":
{
var payload PushHook
err := json.NewDecoder(r).Decode(&payload)
if err != nil {
log.Printf("Error processing push hook: %+v", err)
return false, nil, fmt.Errorf("error processing push hook: %s", err)
}
log.Printf("Parsed hook: %+v", payload)
log.Printf("%+d Commits: %+v", len(payload.Commits), payload.Commits)
}
case "ping":
{
return false, nil, nil
}
default:
{
log.Printf("Unknown hook type %s", hookType)
return false, nil, fmt.Errorf("unknown hook type %s", hookType)
}
}
return doPublish, nil, nil
}
......@@ -2,15 +2,18 @@ package routing
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
"strconv"
"strings"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/stephenmuss/ginerus"
"gitlab.gwdg.de/rg-mpg-de/tei2zenodo"
"gitlab.gwdg.de/rg-mpg-de/tei2zenodo/internal/pkg/github"
"gitlab.gwdg.de/rg-mpg-de/tei2zenodo/internal/pkg/t2zxml"
"gitlab.gwdg.de/rg-mpg-de/tei2zenodo/internal/pkg/zenodo"
)
......@@ -70,7 +73,43 @@ func SetupRoutes(conf tei2zenodo.Config) *gin.Engine {
})
}
if conf.WebhookAPI != "" {
APIv1.GET(conf.WebhookAPI, func(c *gin.Context) {
APIv1.POST(conf.WebhookAPI, func(c *gin.Context) {
var r io.ReadSeeker
// Read hook type from header
hookType := c.Request.Header.Get("X-GitHub-Event")
// Read payload from Request body
buf := new(bytes.Buffer)
buf.ReadFrom(c.Request.Body)
file := buf.String()
r = strings.NewReader(file)
// Process Hook to extract files
doPublish, files, err := github.ProcessHook(hookType, r, &conf)
if err != nil {
log.Printf("Error parsing webhook event: %v", err)
AbortMsg(500, fmt.Errorf("problem parsing webhook event: %s", err), c)
}
if len(files) == 0 {
log.Printf("No files returned")
}
log.Printf("doPublish: %s", strconv.FormatBool(doPublish))
// Send each file to processing
for i, f := range files {
var myDeposit tei2zenodo.Deposit
log.Printf("Processing file %d", i)
err := zenodo.ProcessFile(&conf, &myDeposit, f, doPublish)
if err != nil {
AbortMsg(500, err, c)
return
}
}
log.Printf("=== All done ===")
c.JSON(200, "processed hook successfully")
})
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment