From 4321f1de17d1a81cc7df69efaac54c0f780acbbc Mon Sep 17 00:00:00 2001 From: Sascha Grunert Date: Mon, 12 Dec 2022 15:38:32 +0100 Subject: [PATCH] Skip krel fast-forward when release cut issue is open Signed-off-by: Sascha Grunert --- .golangci.yml | 2 + cmd/krel/cmd/ff.go | 5 ++ go.mod | 10 +-- go.sum | 27 ++++--- pkg/fastforward/fastforward.go | 23 +++++- pkg/fastforward/fastforward_test.go | 33 ++++++++- pkg/fastforward/fastforwardfakes/fake_impl.go | 71 +++++++++++++++++++ pkg/fastforward/impl.go | 9 +++ 8 files changed, 158 insertions(+), 22 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 7ef1439d5bc2..a15062466a78 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -110,6 +110,8 @@ linters: # - wrapcheck # - wsl linters-settings: + gocyclo: + min-complexity: 40 godox: keywords: - BUG diff --git a/cmd/krel/cmd/ff.go b/cmd/krel/cmd/ff.go index e1b2aabf9bb4..335678652d19 100644 --- a/cmd/krel/cmd/ff.go +++ b/cmd/krel/cmd/ff.go @@ -50,6 +50,11 @@ verifies that the latest merge base tag is the same for the main and the release branch. This means that only the latest release branch can be fast forwarded. +Additionally, krel lists all k/sig-release issues and searches for the +one with the title "Cut vx.y.0 release". If that exists and is open, then +krel will skip the fast-forward because it may happen that a fast-forward +produces merge conflicts in git when comparing with the already staged sources. + krel merges the provided ref into the release branch and asks for a final confirmation if the push should really happen. The push will only be executed as real push if the '--nomock' flag is specified. diff --git a/go.mod b/go.mod index 697a9f904f31..d6ba33d77aa8 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( sigs.k8s.io/bom v0.4.1 sigs.k8s.io/mdtoc v1.1.0 sigs.k8s.io/promo-tools/v3 v3.4.10 - sigs.k8s.io/release-sdk v0.9.4 + sigs.k8s.io/release-sdk v0.9.5 sigs.k8s.io/release-utils v0.7.3 sigs.k8s.io/yaml v1.3.0 sigs.k8s.io/zeitgeist v0.3.5 @@ -337,12 +337,12 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect helm.sh/helm/v3 v3.10.0 // indirect k8s.io/api v0.25.0 // indirect - k8s.io/apimachinery v0.25.4 // indirect + k8s.io/apimachinery v0.26.0 // indirect k8s.io/cli-runtime v0.25.0 // indirect k8s.io/client-go v0.25.0 // indirect - k8s.io/klog/v2 v2.70.1 // indirect - k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect - k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect + k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect + k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect oras.land/oras-go v1.2.0 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/kustomize/api v0.12.1 // indirect diff --git a/go.sum b/go.sum index 71f2336358fc..6d51b58a38cc 100644 --- a/go.sum +++ b/go.sum @@ -561,7 +561,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= @@ -1159,14 +1158,14 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= +github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= +github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/open-policy-agent/opa v0.45.0 h1:P5nuhVRtR+e58fk3CMMbiqr6ZFyWQPNOC3otsorGsFs= github.com/open-policy-agent/opa v0.45.0/go.mod h1:/OnsYljNEWJ6DXeFOOnoGn8CvwZGMUS4iRqzYdJvmBI= @@ -1371,7 +1370,6 @@ github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= @@ -2385,19 +2383,18 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.25.0 h1:H+Q4ma2U/ww0iGB78ijZx6DRByPz6/733jIuFpX70e0= k8s.io/api v0.25.0/go.mod h1:ttceV1GyV1i1rnmvzT3BST08N6nGt+dudGrquzVQWPk= -k8s.io/apimachinery v0.25.4 h1:CtXsuaitMESSu339tfhVXhQrPET+EiWnIY1rcurKnAc= -k8s.io/apimachinery v0.25.4/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= +k8s.io/apimachinery v0.26.0 h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg= +k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= k8s.io/cli-runtime v0.25.0 h1:XBnTc2Fi+w818jcJGzhiJKQuXl8479sZ4FhtV5hVJ1Q= k8s.io/cli-runtime v0.25.0/go.mod h1:bHOI5ZZInRHhbq12OdUiYZQN8ml8aKZLwQgt9QlLINw= k8s.io/client-go v0.25.0 h1:CVWIaCETLMBNiTUta3d5nzRbXvY5Hy9Dpl+VvREpu5E= k8s.io/client-go v0.25.0/go.mod h1:lxykvypVfKilxhTklov0wz1FoaUZ8X4EwbhS6rpRfN8= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= -k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= -k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4= -k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.0 h1:yoKosVIbsPoFMqAIFHTnrmOuafHal+J/r+I5bdbVWu4= oras.land/oras-go v1.2.0/go.mod h1:pFNs7oHp2dYsYMSS82HaX5l4mpnGO7hbpPN6EWH2ltc= pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4= @@ -2416,8 +2413,8 @@ sigs.k8s.io/mdtoc v1.1.0 h1:q3YtqYzmC2e0hgLXRIOm7/QLuPux1CX3ZHCwlbABxZo= sigs.k8s.io/mdtoc v1.1.0/go.mod h1:QZLVEdHH2iNIR4uHAZyvFRtjloHgVItk8lo/mzCtq3w= sigs.k8s.io/promo-tools/v3 v3.4.10 h1:Nu0LabTLGkRcUjStkdYOtqTk2oOPMwHZdyR4giVMA+E= sigs.k8s.io/promo-tools/v3 v3.4.10/go.mod h1:/m3gcZl8k/qwjGFUPn1Dtw5AGkjtMBtD5W/6TSL9Wmo= -sigs.k8s.io/release-sdk v0.9.4 h1:Ct7Ua6EXOeZ2gIFyhyadoQHOsSHD+gWZ3N17Ub0GF60= -sigs.k8s.io/release-sdk v0.9.4/go.mod h1:q7HBmKxgmM+xTH7X+rdKa7/F/+8f1TnVoDW9RZGJAgk= +sigs.k8s.io/release-sdk v0.9.5 h1:QCMod68Nxpeg46HQWUf7Q32mJCUkTg6OH87vBd6IMnk= +sigs.k8s.io/release-sdk v0.9.5/go.mod h1:I/xiA52I2KKMrhCVCY0AdALTTIf4uf1KpaPl4R3xwDc= sigs.k8s.io/release-utils v0.7.3 h1:6pS8x6c5RmdUgR9qcg1LO6hjUzuE4Yo9TGZ3DemrZdM= sigs.k8s.io/release-utils v0.7.3/go.mod h1:n0mVez/1PZYZaZUTJmxewxH3RJ/Lf7JUDh7TG1CASOE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= diff --git a/pkg/fastforward/fastforward.go b/pkg/fastforward/fastforward.go index 13b00a6cf45a..0a061386d30f 100644 --- a/pkg/fastforward/fastforward.go +++ b/pkg/fastforward/fastforward.go @@ -137,6 +137,23 @@ func (f *FastForward) Run() (err error) { } } + issues, err := f.ListIssues() + if err != nil { + return fmt.Errorf( + "unable to list GitHub issues for %s/%s repo: %w", + git.DefaultGithubOrg, git.DefaultGithubReleaseRepo, err) + } + title := fmt.Sprintf("Cut %s release", f.branchToVersion(branch)) + for _, issue := range issues { + if issue.IsPullRequest() { + continue + } + if issue.GetTitle() == title { + logrus.Infof("Skipping fast forward: release cut issue is open: %s", issue.GetURL()) + return nil + } + } + if f.options.Cleanup { defer func() { if err := f.RepoCleanup(repo); err != nil { @@ -272,7 +289,7 @@ func prepushMessage(gitRoot, branch, ref, releaseRev, headRev string) { } func (f *FastForward) noFastForwardRequired(repo *git.Repo, branch string) (bool, error) { - version := fmt.Sprintf("v%s.0", strings.TrimPrefix(branch, "release-")) + version := f.branchToVersion(branch) tagExists, err := f.RepoHasRemoteTag(repo, version) if err != nil { @@ -282,6 +299,10 @@ func (f *FastForward) noFastForwardRequired(repo *git.Repo, branch string) (bool return tagExists, nil } +func (f *FastForward) branchToVersion(branch string) string { + return fmt.Sprintf("v%s.0", strings.TrimPrefix(branch, "release-")) +} + func (f *FastForward) prepareKubernetesRepo() (*git.Repo, error) { logrus.Infof("Preparing to fast-forward from %s", f.options.MainRef) diff --git a/pkg/fastforward/fastforward_test.go b/pkg/fastforward/fastforward_test.go index 0560e095f78f..d6056b47db83 100644 --- a/pkg/fastforward/fastforward_test.go +++ b/pkg/fastforward/fastforward_test.go @@ -18,8 +18,11 @@ package fastforward import ( "errors" + "fmt" + "strings" "testing" + gogithub "github.com/google/go-github/v47/github" "github.com/stretchr/testify/require" "k8s.io/release/pkg/fastforward/fastforwardfakes" ) @@ -112,6 +115,23 @@ func TestRun(t *testing.T) { require.Nil(t, err) }, }, + { // success release cut issue is open + prepare: func(mock *fastforwardfakes.FakeImpl) *Options { + mock.IsReleaseBranchReturns(true) + mock.RepoHasRemoteBranchReturns(true, nil) + + title := fmt.Sprintf("Cut v%s.0 release", strings.TrimPrefix(branch, "release-")) + mock.ListIssuesReturns([]*gogithub.Issue{{Title: &title}}, nil) + + // never called + mock.AskReturns("", true, errTest) + + return &Options{Branch: branch} + }, + assert: func(err error) { + require.Nil(t, err) + }, + }, { // failure prepare tool repo on Chdir prepare: func(mock *fastforwardfakes.FakeImpl) *Options { mock.ExistsReturns(false) @@ -224,7 +244,7 @@ func TestRun(t *testing.T) { require.NotNil(t, err) }, }, - { // failure not a rrlease branch + { // failure not a release branch prepare: func(mock *fastforwardfakes.FakeImpl) *Options { mock.IsReleaseBranchReturns(false) return &Options{Branch: branch} @@ -253,6 +273,17 @@ func TestRun(t *testing.T) { require.NotNil(t, err) }, }, + { // failure on ListIssues + prepare: func(mock *fastforwardfakes.FakeImpl) *Options { + mock.IsReleaseBranchReturns(true) + mock.RepoHasRemoteBranchReturns(true, nil) + mock.ListIssuesReturns(nil, errTest) + return &Options{Branch: branch} + }, + assert: func(err error) { + require.NotNil(t, err) + }, + }, { // failure on RepoCurrentBranch prepare: func(mock *fastforwardfakes.FakeImpl) *Options { mock.IsReleaseBranchReturns(true) diff --git a/pkg/fastforward/fastforwardfakes/fake_impl.go b/pkg/fastforward/fastforwardfakes/fake_impl.go index 518cde9ae800..f82f97998e6c 100644 --- a/pkg/fastforward/fastforwardfakes/fake_impl.go +++ b/pkg/fastforward/fastforwardfakes/fake_impl.go @@ -20,6 +20,7 @@ package fastforwardfakes import ( "sync" + "github.com/google/go-github/v47/github" "k8s.io/release/pkg/gcp/gcb" "sigs.k8s.io/release-sdk/git" ) @@ -136,6 +137,18 @@ type FakeImpl struct { isReleaseBranchReturnsOnCall map[int]struct { result1 bool } + ListIssuesStub func() ([]*github.Issue, error) + listIssuesMutex sync.RWMutex + listIssuesArgsForCall []struct { + } + listIssuesReturns struct { + result1 []*github.Issue + result2 error + } + listIssuesReturnsOnCall map[int]struct { + result1 []*github.Issue + result2 error + } MkdirTempStub func(string, string) (string, error) mkdirTempMutex sync.RWMutex mkdirTempArgsForCall []struct { @@ -900,6 +913,62 @@ func (fake *FakeImpl) IsReleaseBranchReturnsOnCall(i int, result1 bool) { }{result1} } +func (fake *FakeImpl) ListIssues() ([]*github.Issue, error) { + fake.listIssuesMutex.Lock() + ret, specificReturn := fake.listIssuesReturnsOnCall[len(fake.listIssuesArgsForCall)] + fake.listIssuesArgsForCall = append(fake.listIssuesArgsForCall, struct { + }{}) + stub := fake.ListIssuesStub + fakeReturns := fake.listIssuesReturns + fake.recordInvocation("ListIssues", []interface{}{}) + fake.listIssuesMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeImpl) ListIssuesCallCount() int { + fake.listIssuesMutex.RLock() + defer fake.listIssuesMutex.RUnlock() + return len(fake.listIssuesArgsForCall) +} + +func (fake *FakeImpl) ListIssuesCalls(stub func() ([]*github.Issue, error)) { + fake.listIssuesMutex.Lock() + defer fake.listIssuesMutex.Unlock() + fake.ListIssuesStub = stub +} + +func (fake *FakeImpl) ListIssuesReturns(result1 []*github.Issue, result2 error) { + fake.listIssuesMutex.Lock() + defer fake.listIssuesMutex.Unlock() + fake.ListIssuesStub = nil + fake.listIssuesReturns = struct { + result1 []*github.Issue + result2 error + }{result1, result2} +} + +func (fake *FakeImpl) ListIssuesReturnsOnCall(i int, result1 []*github.Issue, result2 error) { + fake.listIssuesMutex.Lock() + defer fake.listIssuesMutex.Unlock() + fake.ListIssuesStub = nil + if fake.listIssuesReturnsOnCall == nil { + fake.listIssuesReturnsOnCall = make(map[int]struct { + result1 []*github.Issue + result2 error + }) + } + fake.listIssuesReturnsOnCall[i] = struct { + result1 []*github.Issue + result2 error + }{result1, result2} +} + func (fake *FakeImpl) MkdirTemp(arg1 string, arg2 string) (string, error) { fake.mkdirTempMutex.Lock() ret, specificReturn := fake.mkdirTempReturnsOnCall[len(fake.mkdirTempArgsForCall)] @@ -1965,6 +2034,8 @@ func (fake *FakeImpl) Invocations() map[string][][]interface{} { defer fake.isDefaultK8sUpstreamMutex.RUnlock() fake.isReleaseBranchMutex.RLock() defer fake.isReleaseBranchMutex.RUnlock() + fake.listIssuesMutex.RLock() + defer fake.listIssuesMutex.RUnlock() fake.mkdirTempMutex.RLock() defer fake.mkdirTempMutex.RUnlock() fake.removeAllMutex.RLock() diff --git a/pkg/fastforward/impl.go b/pkg/fastforward/impl.go index 8fdb33949b24..a4a55a304074 100644 --- a/pkg/fastforward/impl.go +++ b/pkg/fastforward/impl.go @@ -22,7 +22,9 @@ import ( "k8s.io/release/pkg/gcp/gcb" "k8s.io/release/pkg/release" + gogithub "github.com/google/go-github/v47/github" "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-utils/env" "sigs.k8s.io/release-utils/util" ) @@ -58,6 +60,7 @@ type impl interface { MkdirTemp(string, string) (string, error) Exists(string) bool ConfigureGlobalDefaultUserAndEmail() error + ListIssues() ([]*gogithub.Issue, error) } func (*defaultImpl) CloneOrOpenDefaultGitHubRepoSSH(repo string) (*git.Repo, error) { @@ -163,3 +166,9 @@ func (*defaultImpl) Exists(path string) bool { func (*defaultImpl) ConfigureGlobalDefaultUserAndEmail() error { return git.ConfigureGlobalDefaultUserAndEmail() } + +func (*defaultImpl) ListIssues() ([]*gogithub.Issue, error) { + return github.New().ListIssues( + git.DefaultGithubOrg, git.DefaultGithubReleaseRepo, github.IssueStateOpen, + ) +}