LoginSignup
6
5

More than 5 years have passed since last update.

GitHubのPull Requestが作成されたら自動でレビューアをアサインする

Posted at

WebHookから呼ばれることが前提

roulette.go
package main

import (
    "encoding/json"
    "io"
    "log"
    "math/rand"
    "net/http"
    "os"
    "strings"
)

var (
    githubToken = os.Getenv("GITHUB_TOKEN")
    githubUsers = strings.Split(os.Getenv("GITHUB_REVIEWERS"), ",")
)

// assign reviewer
func assign(url string, user string) error {
    assignBody := "{\"assignee\":\"" + user + "\"}"

    // update state
    r, _ := http.NewRequest("PATCH", url, strings.NewReader(assignBody))
    r.Header.Add("Authorization", "token "+githubToken)
    r.Header.Add("Content-Type", "application/json")
    client := &http.Client{}
    resp, err := client.Do(r)
    defer resp.Body.Close()
    if err != nil {
        log.Print(err)
        return err
    }
    return nil
}

func comment(url string, user string) error {
    body := "{\"body\":\"@" + user + "please review\"}"
    r, _ := http.NewRequest("POST", url, strings.NewReader(body))
    r.Header.Add("Authorization", "token "+githubToken)
    r.Header.Add("Content-Type", "application/json")
    client := &http.Client{}
    resp, err := client.Do(r)
    defer resp.Body.Close()
    if err != nil {
        log.Print(err)
        return err
    }
    return nil
}

func Hook(w http.ResponseWriter, req *http.Request) {
    err := req.ParseForm()
    if err != nil {
        log.Print(err)
        // TODO: 500 error
        return
    }

    v := req.FormValue("payload")
    var m map[string]interface{}
    err = json.Unmarshal([]byte(v), &m)
    if err != nil {
        log.Print(err)
        // TODO: 500 error
        return
    }

    if m["action"] != "opened" {
        return
    }

    links := m["pull_request"].(map[string]interface{})["_links"].(map[string]interface{})
    assignUrl := links["issue"].(map[string]interface{})["href"].(string)
    commentUrl := links["comments"].(map[string]interface{})["href"].(string)
    reviewer := githubUsers[rand.Intn(len(githubUsers))]
    assign(assignUrl, reviewer)
    comment(commentUrl, reviewer)
}

func ping(w http.ResponseWriter, req *http.Request) {
    io.WriteString(w, "pong\n")
}

func main() {
    log.Printf("reviewer candidates are %v", githubUsers)
    port := os.Getenv("PORT")
    if len(port) == 0 {
        port = "8000"
    }
    http.HandleFunc("/", Hook)
    http.HandleFunc("/ping", ping)
    log.Printf("start server. port: %v", port)
    err := http.ListenAndServe(":"+port, nil)

    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5