diff --git a/deploy/cr-bot.yaml b/deploy/cr-bot.yaml index 7cfbf18a..ccbaa368 100644 --- a/deploy/cr-bot.yaml +++ b/deploy/cr-bot.yaml @@ -21,21 +21,28 @@ spec: - /cr-bot args: - -log-level=1 - - -access-token=$(GITHUB_ACCESS_TOKEN) - -webhook-secret=$(GITHUB_WEBHOOK_SECRET) - - -config=/etc/config/config.yaml + - -config=/etc/config/config.yaml + - -app-id=$(GITHUB_APP_ID) + - -app-installation-id=$(GITHUB_APP_INSTALLATION_ID) + - -app-private-key=/secrets/github_app_key env: - - name: GITHUB_ACCESS_TOKEN - valueFrom: - secretKeyRef: - key: access-token - name: github - name: GITHUB_WEBHOOK_SECRET valueFrom: secretKeyRef: key: webhook-secret - name: github - image: aslan-spock-register.qiniu.io/qa/cr-bot:v0.2.2 # use your own built image instead + name: github + - name: GITHUB_APP_ID + valueFrom: + secretKeyRef: + key: app-id + name: github-app + - name: GITHUB_APP_INSTALLATION_ID + valueFrom: + secretKeyRef: + key: app-installation-id + name: github-app + image: aslan-spock-register.qiniu.io/qa/cr-bot:v0.2.6 # use your own built image instead imagePullPolicy: Always name: cr-bot ports: @@ -49,7 +56,11 @@ spec: - mountPath: /secrets/github_key subPath: github_key name: ssh-secret - readOnly: true + readOnly: true + - mountPath: /secrets/github_app_key + subPath: github_app_key + name: github-app-secret + readOnly: true volumes: - configMap: defaultMode: 420 @@ -62,6 +73,13 @@ spec: items: - key: ssh-secret path: github_key + - name: github-app-secret + secret: + defaultMode: 256 + secretName: github-app-secret + items: + - key: github-app-secret + path: github_app_key --- apiVersion: v1 kind: Service diff --git a/go.mod b/go.mod index 2a16709a..c80e3723 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,11 @@ module github.com/cr-bot go 1.21.4 require ( + github.com/bradleyfalzon/ghinstallation/v2 v2.8.0 github.com/google/go-github/v57 v57.0.0 + github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 github.com/qiniu/x v1.13.2 + github.com/sirupsen/logrus v1.9.0 k8s.io/test-infra v0.0.0-20231205233654-937dbc605e95 sigs.k8s.io/yaml v1.4.0 ) @@ -12,14 +15,15 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/google/go-github/v56 v56.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/prometheus/client_golang v1.13.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect golang.org/x/sys v0.8.0 // indirect google.golang.org/protobuf v1.30.0 // indirect k8s.io/apimachinery v0.26.5 // indirect diff --git a/go.sum b/go.sum index 7331967d..a4664e45 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bradleyfalzon/ghinstallation/v2 v2.8.0 h1:yUmoVv70H3J4UOqxqsee39+KlXxNEDfTbAp8c/qULKk= +github.com/bradleyfalzon/ghinstallation/v2 v2.8.0/go.mod h1:fmPmvCiBWhJla3zDv9ZTQSZc8AbwyRnGW1yg5ep1Pcs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -72,6 +74,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -116,6 +120,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBWCX3gb4= +github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= github.com/google/go-github/v57 v57.0.0 h1:L+Y3UPTY8ALM8x+TV0lg+IEBI+upibemtBD8Q9u7zHs= github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= @@ -133,6 +139,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= diff --git a/main.go b/main.go index 10833d0d..3148d1ca 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,10 @@ import ( "net/http" "os" + "github.com/bradleyfalzon/ghinstallation/v2" "github.com/cr-bot/config" "github.com/google/go-github/v57/github" + "github.com/gregjones/httpcache" "github.com/qiniu/x/log" "github.com/sirupsen/logrus" gitv2 "k8s.io/test-infra/prow/git/v2" @@ -25,16 +27,26 @@ type options struct { webhookSecret string codeCacheDir string config string + + // support github app + appID int64 + installationID int64 + appPrivateKey string } func (o options) Validate() error { - if o.accessToken == "" { - return errors.New("access-token is required") + if o.accessToken == "" && o.appID == 0 { + return errors.New("either access-token or github app information should be provided") + } + + if o.appID != 0 && o.installationID == 0 { + return errors.New("app-installation-id is required when using github app") } if o.webhookSecret == "" { return errors.New("webhook-secret is required") } + return nil } @@ -48,6 +60,9 @@ func gatherOptions() options { fs.StringVar(&o.webhookSecret, "webhook-secret", "", "webhook secret file") fs.StringVar(&o.codeCacheDir, "code-cache-dir", "/tmp", "code cache dir") fs.StringVar(&o.config, "config", "", "config file") + fs.Int64Var(&o.appID, "app-id", 0, "github app id") + fs.Int64Var(&o.installationID, "app-installation-id", 0, "github app installation id") + fs.StringVar(&o.appPrivateKey, "app-private-key", "", "github app private key") fs.Parse(os.Args[1:]) return o } @@ -61,9 +76,15 @@ func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) log.SetOutputLevel(o.logLevel) - // TODO: support github app - gc := github.NewClient(nil) - if o.accessToken != "" { + var gc *github.Client + if o.appID != 0 { + tr, err := ghinstallation.NewKeyFromFile(httpcache.NewMemoryCacheTransport(), o.appID, o.installationID, o.appPrivateKey) + if err != nil { + log.Fatalf("failed to create github app transport: %v", err) + } + gc = github.NewClient(&http.Client{Transport: tr}) + } else { + gc = github.NewClient(nil) gc.WithAuthToken(o.accessToken) }