Skip to content

Instantly share code, notes, and snippets.

@vnadgir
Created December 6, 2019 15:50
Show Gist options
  • Save vnadgir/7fe629fa2a19d355851e51c0fd5b1b29 to your computer and use it in GitHub Desktop.
Save vnadgir/7fe629fa2a19d355851e51c0fd5b1b29 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"github.com/google/go-github/github"
cli "github.com/jawher/mow.cli"
log "github.com/sirupsen/logrus"
"golang.org/x/oauth2"
)
var httpClient = http.Client{}
func main() {
app := cli.App("git-police", "Github policy enforcer")
verbose := app.BoolOpt("v verbose", false, "enable verbose logging")
app.Command("branch", "enforce branch protection", enforceBranchProtection)
app.Before = func() {
log.SetOutput(os.Stderr)
if *verbose {
log.SetLevel(log.DebugLevel)
} else {
log.SetLevel(log.ErrorLevel)
}
}
app.Run(os.Args)
}
func enforceBranchProtection(cmd *cli.Cmd) {
token := cmd.StringOpt("t token", os.Getenv("TOKEN"), "Github Token")
org := cmd.StringOpt("o org", os.Getenv("ORG"), "The Github Organisation")
repo := cmd.StringsOpt("r repos", []string{""}, "The Github repos")
cmd.Before = func() {
if len(*token) == 0 {
log.Panic("token is a required arg")
}
if len(*org) == 0 {
log.Panic("org is a required arg")
}
if len(*repo) == 0 {
log.Panic("repo is a required arg")
}
}
cmd.Action = func() {
ctx, cancel := context.WithCancel(context.Background())
token := oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: *token,
})
tokenClient := oauth2.NewClient(ctx, token)
client := github.NewClient(tokenClient)
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
doneChan := make(chan struct{})
go func() {
doEnforce(ctx, client, *org, "master", *repo)
doneChan <- struct{}{}
}()
select {
case <-sigChan:
log.Info("sigterm received, exiting")
cancel()
case <-doneChan:
log.Info("finished, exiting")
}
}
}
func doEnforce(ctx context.Context, client *github.Client, org, branch string, repo []string) {
for _, r := range repo {
_, res, err := client.Repositories.UpdateBranchProtection(ctx, org, r, branch, &github.ProtectionRequest{
EnforceAdmins: true,
RequiredPullRequestReviews: &github.PullRequestReviewsEnforcementRequest{
DismissStaleReviews: true,
RequireCodeOwnerReviews: true,
RequiredApprovingReviewCount: 1,
},
})
if err != nil {
fmt.Println("ignoring " + r + " because of err " + err.Error())
} else {
fmt.Println("Branch protection request returned with status " + res.Status)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment