diff --git a/README.md b/README.md index dcb379cd0b1..4159f292ef5 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Status: In Progress Details: [Documentation](https://sigs.k8s.io/k8s-container-image-promoter/cmd/cip-mm/README.md) -### [`gh2gcs`](/cmd/gh2gcs) +### [`gh2gcs`](https://sigs.k8s.io/k8s-container-image-promoter/cmd/gh2gcs) Upload GitHub release assets to Google Cloud Storage. @@ -95,7 +95,7 @@ Status: In Progress Audience: [Release Managers][release-managers] and subproject maintainers responsible for promoting container artifacts -Details: [Documentation](/cmd/gh2gcs/README.md) +Details: [Documentation](https://sigs.k8s.io/k8s-container-image-promoter/cmd/gh2gcs/README.md) ## End User diff --git a/cmd/gh2gcs/README.md b/cmd/gh2gcs/README.md deleted file mode 100644 index 5c2a718397a..00000000000 --- a/cmd/gh2gcs/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# GitHub Releases to Google Cloud Storage - -This directory contains a tool called `gh2gcs` that downloads a release published in GitHub to a Google Cloud Storage Bucket. - -## Requirements - -This tool directly depends on `gcloud` and `gsutil` to be installed on the system. - -Google Cloud has [documentation on installing and configuring the Google Cloud SDK CLI tools](https://cloud.google.com/sdk/docs/quickstarts). - -## Install - -The simplest way to install the `gh2gcs` CLI is via `go get`: - -``` -$ go get k8s.io/release/cmd/gh2gcs -``` - -This will install `gh2gcs` to `$(go env GOPATH)/bin/gh2gcs`. - -## Usage - -To use this tool to copy a release to a Google Cloud Storage, run: - -```bash -$ gh2gcs \ - --org kubernetes --repo kubernetes --bucket my-test-bucket \ - --release-dir release --tags v1.18.0 - -INFO Validating gh2gcs options... -INFO Downloading assets for the following kubernetes/kubernetes release tags: v1.18.0 -INFO Download assets for kubernetes/kubernetes@v1.18.0 -INFO Writing assets to /tmp/test/kubernetes/kubernetes/v1.18.0 -... - -``` - -## Use case - -GitHub has a rate limit on downloading release artifacts. The artifacts that are often used (e.g. in CI) are uploaded to Google Cloud Storage, as GCS doesn't have read rate limits. This improves test stability as flakes related to hitting rate limits are avoided. - -## SIG Release managed buckets - -The following GCS buckets are managed by SIG Release: - -- k8s-artifacts-cni - contains [CNI plugins](https://github.com/containernetworking/plugins) artifacts -- k8s-artifacts-cri-tools - contains [CRI tools](https://github.com/kubernetes-sigs/cri-tools) artifacts (`crictl` and `critest`) - -The artifacts are pushed to GCS by [Release Managers](https://github.com/kubernetes/sig-release/blob/master/release-managers.md). The pushing is done manually by running the appropriate `gh2gcs` command. It's recommended for Release Managers to watch the appropriate repositories for new releases. diff --git a/cmd/gh2gcs/cmd/root.go b/cmd/gh2gcs/cmd/root.go deleted file mode 100644 index a55a4a6fbea..00000000000 --- a/cmd/gh2gcs/cmd/root.go +++ /dev/null @@ -1,279 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cmd - -import ( - "fmt" - "os" - "strings" - - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "gopkg.in/yaml.v2" - - "k8s.io/release/pkg/gh2gcs" - "k8s.io/release/pkg/github" - "sigs.k8s.io/release-sdk/gcli" - "sigs.k8s.io/release-utils/log" -) - -// rootCmd represents the base command when called without any subcommands -var rootCmd = &cobra.Command{ - Use: "gh2gcs --org kubernetes --repo release --bucket --release-dir [--tags v0.0.0] [--include-prereleases] [--output-dir ] [--download-only] [--config ]", - Short: "gh2gcs uploads GitHub releases to Google Cloud Storage", - Example: "gh2gcs --org kubernetes --repo release --bucket k8s-staging-release-test --release-dir release --tags v0.0.0,v0.0.1", - SilenceUsage: true, - SilenceErrors: true, - PersistentPreRunE: initLogging, - PreRunE: func(cmd *cobra.Command, args []string) error { - return checkRequiredFlags(cmd.Flags()) - }, - RunE: func(*cobra.Command, []string) error { - return run(opts) - }, -} - -type options struct { - downloadOnly bool - includePrereleases bool - org string - repo string - bucket string - releaseDir string - outputDir string - logLevel string - tags []string - configFilePath string -} - -var opts = &options{} - -var ( - orgFlag = "org" - repoFlag = "repo" - tagsFlag = "tags" - configFlag = "config" - includePrereleasesFlag = "include-prereleases" - bucketFlag = "bucket" - releaseDirFlag = "release-dir" - outputDirFlag = "output-dir" - downloadOnlyFlag = "download-only" - - // requiredFlags only if the config flag is not set - requiredFlags = []string{ - orgFlag, - repoFlag, - bucketFlag, - releaseDirFlag, - } -) - -// Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { - if err := rootCmd.Execute(); err != nil { - logrus.Fatal(err) - } - - if !rootCmd.Flags().Changed(outputDirFlag) { - logrus.Infof("Cleaning temporary directory %s", opts.outputDir) - os.RemoveAll(opts.outputDir) - } -} - -func init() { - rootCmd.PersistentFlags().StringVar( - &opts.org, - orgFlag, - "", - "GitHub org/user", - ) - - rootCmd.PersistentFlags().StringVar( - &opts.repo, - repoFlag, - "", - "GitHub repo", - ) - - rootCmd.PersistentFlags().StringSliceVar( - &opts.tags, - tagsFlag, - []string{}, - "release tags to upload to GCS", - ) - - rootCmd.PersistentFlags().BoolVar( - &opts.includePrereleases, - includePrereleasesFlag, - false, - "specifies whether prerelease assets should be uploaded to GCS", - ) - - rootCmd.PersistentFlags().StringVar( - &opts.bucket, - bucketFlag, - "", - "GCS bucket to upload to", - ) - - rootCmd.PersistentFlags().StringVar( - &opts.releaseDir, - releaseDirFlag, - "", - "directory to upload to within the specified GCS bucket", - ) - - rootCmd.PersistentFlags().StringVar( - &opts.outputDir, - outputDirFlag, - "", - "local directory for releases to be downloaded to", - ) - - rootCmd.PersistentFlags().BoolVar( - &opts.downloadOnly, - downloadOnlyFlag, - false, - "only download the releases, do not push them to GCS. Requires the output-dir flag to also be set", - ) - - rootCmd.PersistentFlags().StringVar( - &opts.logLevel, - "log-level", - "info", - fmt.Sprintf("the logging verbosity, either %s", log.LevelNames()), - ) - - rootCmd.PersistentFlags().StringVar( - &opts.configFilePath, - configFlag, - "", - "config file to set all the branch/repositories the user wants to", - ) -} - -func initLogging(*cobra.Command, []string) error { - return log.SetupGlobalLogger(opts.logLevel) -} - -func checkRequiredFlags(flags *pflag.FlagSet) error { - if flags.Lookup(configFlag).Changed { - return nil - } - - checkRequiredFlags := []string{} - flags.VisitAll(func(flag *pflag.Flag) { - for _, requiredflag := range requiredFlags { - if requiredflag == flag.Name && !flag.Changed { - checkRequiredFlags = append(checkRequiredFlags, requiredflag) - } - } - }) - - if len(checkRequiredFlags) != 0 { - return errors.New("Required flag(s) `" + strings.Join(checkRequiredFlags, ", ") + "` not set") - } - - return nil -} - -func run(opts *options) error { - if err := opts.SetAndValidate(); err != nil { - return errors.Wrap(err, "validating gh2gcs options") - } - - if err := gcli.PreCheck(); err != nil { - return errors.Wrap(err, "pre-checking for GCP package usage") - } - - releaseCfgs := &gh2gcs.Config{} - if opts.configFilePath != "" { - logrus.Infof("Reading the config file %s...", opts.configFilePath) - data, err := os.ReadFile(opts.configFilePath) - if err != nil { - return errors.Wrap(err, "failed to read the file") - } - - logrus.Info("Parsing the config...") - err = yaml.UnmarshalStrict(data, &releaseCfgs) - if err != nil { - return errors.Wrap(err, "failed to decode the file") - } - } else { - // TODO: Expose certain GCSCopyOptions for user configuration - newReleaseCfg := &gh2gcs.ReleaseConfig{ - Org: opts.org, - Repo: opts.repo, - Tags: opts.tags, - IncludePrereleases: opts.includePrereleases, - GCSBucket: opts.bucket, - ReleaseDir: opts.releaseDir, - } - - releaseCfgs.ReleaseConfigs = append(releaseCfgs.ReleaseConfigs, *newReleaseCfg) - } - - // Create a real GitHub API client - gh := github.New() - - for _, releaseCfg := range releaseCfgs.ReleaseConfigs { - if len(releaseCfg.Tags) == 0 { - releaseTags, err := gh.GetReleaseTags(releaseCfg.Org, releaseCfg.Repo, releaseCfg.IncludePrereleases) - if err != nil { - return errors.Wrap(err, "getting release tags") - } - - releaseCfg.Tags = releaseTags - } - - if err := gh2gcs.DownloadReleases(&releaseCfg, gh, opts.outputDir); err != nil { - return errors.Wrap(err, "downloading release assets") - } - logrus.Infof("Files downloaded to %s directory", opts.outputDir) - - if !opts.downloadOnly { - if err := gh2gcs.Upload(&releaseCfg, gh, opts.outputDir); err != nil { - return errors.Wrap(err, "uploading release assets to GCS") - } - } - } - - return nil -} - -// SetAndValidate sets some default options and verifies if options are valid -func (o *options) SetAndValidate() error { - logrus.Info("Validating gh2gcs options...") - - if o.outputDir == "" { - if opts.downloadOnly { - return errors.Errorf("when %s flag is set you need to specify the %s", downloadOnlyFlag, outputDirFlag) - } - - tmpDir, err := os.MkdirTemp("", "gh2gcs") - if err != nil { - return errors.Wrap(err, "creating temp directory") - } - - o.outputDir = tmpDir - } - - return nil -} diff --git a/cmd/gh2gcs/main.go b/cmd/gh2gcs/main.go deleted file mode 100644 index 216c8135a27..00000000000 --- a/cmd/gh2gcs/main.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import "k8s.io/release/cmd/gh2gcs/cmd" - -func main() { - cmd.Execute() -} diff --git a/cmd/krel/cmd/changelog.go b/cmd/krel/cmd/changelog.go index 76cb247a02f..0c23ca5c523 100644 --- a/cmd/krel/cmd/changelog.go +++ b/cmd/krel/cmd/changelog.go @@ -25,7 +25,7 @@ import ( "github.com/spf13/cobra" "k8s.io/release/pkg/changelog" - "k8s.io/release/pkg/github" + "sigs.k8s.io/release-sdk/github" ) // changelogCmd represents the subcommand for `krel changelog` diff --git a/cmd/krel/cmd/changelog_test.go b/cmd/krel/cmd/changelog_test.go index 8efd3546fa7..993ca7e0927 100644 --- a/cmd/krel/cmd/changelog_test.go +++ b/cmd/krel/cmd/changelog_test.go @@ -25,7 +25,7 @@ import ( "github.com/stretchr/testify/require" "k8s.io/release/pkg/changelog" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" ) func (s *sut) getChangelogOptions(tag string) *changelog.Options { diff --git a/cmd/krel/cmd/ff.go b/cmd/krel/cmd/ff.go index 149b0e26087..adf734edab5 100644 --- a/cmd/krel/cmd/ff.go +++ b/cmd/krel/cmd/ff.go @@ -24,7 +24,7 @@ import ( "github.com/spf13/cobra" "k8s.io/release/pkg/fastforward" - kgit "k8s.io/release/pkg/git" + kgit "sigs.k8s.io/release-sdk/git" ) var ffOpts = &fastforward.Options{} diff --git a/cmd/krel/cmd/ff_test.go b/cmd/krel/cmd/ff_test.go index 384978af2ff..84a4f85af0e 100644 --- a/cmd/krel/cmd/ff_test.go +++ b/cmd/krel/cmd/ff_test.go @@ -22,7 +22,7 @@ import ( "github.com/stretchr/testify/require" "k8s.io/release/pkg/fastforward" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" ) func (s *sut) getFfOptions() *fastforward.Options { diff --git a/cmd/krel/cmd/promote-images.go b/cmd/krel/cmd/promote-images.go index 6f041c055ca..5de2ed51c12 100644 --- a/cmd/krel/cmd/promote-images.go +++ b/cmd/krel/cmd/promote-images.go @@ -27,10 +27,10 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/release" reg "sigs.k8s.io/k8s-container-image-promoter/legacy/dockerregistry" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-utils/util" ) diff --git a/cmd/krel/cmd/release.go b/cmd/krel/cmd/release.go index 4b5871d7d3f..4060d8b4d93 100644 --- a/cmd/krel/cmd/release.go +++ b/cmd/krel/cmd/release.go @@ -25,8 +25,8 @@ import ( "github.com/spf13/cobra" "k8s.io/release/pkg/anago" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/github" ) // releaseCmd represents the subcommand for `krel release` diff --git a/cmd/krel/cmd/release_notes.go b/cmd/krel/cmd/release_notes.go index b0972d26a4e..824de27fcdd 100644 --- a/cmd/krel/cmd/release_notes.go +++ b/cmd/krel/cmd/release_notes.go @@ -34,11 +34,11 @@ import ( "github.com/spf13/cobra" "gopkg.in/yaml.v2" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/notes" "k8s.io/release/pkg/notes/document" "k8s.io/release/pkg/notes/options" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-utils/command" "sigs.k8s.io/release-utils/editor" "sigs.k8s.io/release-utils/util" diff --git a/cmd/krel/cmd/stage.go b/cmd/krel/cmd/stage.go index 59836d71499..4d60a6bff4f 100644 --- a/cmd/krel/cmd/stage.go +++ b/cmd/krel/cmd/stage.go @@ -24,8 +24,8 @@ import ( "github.com/spf13/cobra" "k8s.io/release/pkg/anago" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/github" ) // stageCmd represents the subcommand for `krel stage` diff --git a/cmd/krel/cmd/sut_test.go b/cmd/krel/cmd/sut_test.go index 33aa9b17ac3..2a901bdc7c5 100644 --- a/cmd/krel/cmd/sut_test.go +++ b/cmd/krel/cmd/sut_test.go @@ -25,7 +25,7 @@ import ( "github.com/stretchr/testify/require" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/command" "sigs.k8s.io/release-utils/env" ) diff --git a/cmd/krel/cmd/testgrid.go b/cmd/krel/cmd/testgrid.go index e993b4693ab..fd0e6e6c1a3 100644 --- a/cmd/krel/cmd/testgrid.go +++ b/cmd/krel/cmd/testgrid.go @@ -32,8 +32,8 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-sdk/object" "sigs.k8s.io/release-utils/http" ) diff --git a/cmd/release-notes/main.go b/cmd/release-notes/main.go index 85adaa79bc9..eb64cf6b3a1 100644 --- a/cmd/release-notes/main.go +++ b/cmd/release-notes/main.go @@ -28,12 +28,12 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/notes" "k8s.io/release/pkg/notes/document" "k8s.io/release/pkg/notes/options" "k8s.io/release/pkg/release" "sigs.k8s.io/mdtoc/pkg/mdtoc" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/env" "sigs.k8s.io/release-utils/log" ) diff --git a/compile-release-tools b/compile-release-tools index 15e84e175c1..f1eaa5b1729 100755 --- a/compile-release-tools +++ b/compile-release-tools @@ -19,7 +19,6 @@ set -u set -o pipefail RELEASE_TOOLS=( - gh2gcs krel kubepkg schedule-builder diff --git a/go.mod b/go.mod index d637a2eb12d..82a63fc0c72 100644 --- a/go.mod +++ b/go.mod @@ -33,14 +33,13 @@ require ( github.com/yuin/goldmark v1.4.1 golang.org/x/mod v0.5.0 golang.org/x/net v0.0.0-20210525063256-abc453219eb5 - golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f golang.org/x/tools v0.1.5 google.golang.org/api v0.56.0 google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71 gopkg.in/yaml.v2 v2.4.0 sigs.k8s.io/k8s-container-image-promoter v1.339.0 sigs.k8s.io/mdtoc v1.0.1 - sigs.k8s.io/release-sdk v0.1.0 + sigs.k8s.io/release-sdk v0.2.0 sigs.k8s.io/release-utils v0.3.0 sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/zeitgeist v0.3.0 @@ -103,6 +102,7 @@ require ( github.com/xanzy/ssh-agent v0.3.0 // indirect go.opencensus.io v0.23.0 // indirect golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect + golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect golang.org/x/text v0.3.6 // indirect diff --git a/go.sum b/go.sum index 20b62ac975e..0859dc86ca6 100644 --- a/go.sum +++ b/go.sum @@ -1584,8 +1584,9 @@ sigs.k8s.io/k8s-container-image-promoter v1.339.0 h1:7GHS6BjS3+BhwgUF0lJVCx4gh4s sigs.k8s.io/k8s-container-image-promoter v1.339.0/go.mod h1:xOKpNZcaBOs6mImuFMUN4L+12izUeqIdelvgHV2u1tM= sigs.k8s.io/mdtoc v1.0.1 h1:6ECKhQnbetwZBR6R2IeT2LH+1w+2Zsip0iXjikgaXIk= sigs.k8s.io/mdtoc v1.0.1/go.mod h1:COYBtOjsaCg7o7SC4eaLwEXPuVRSuiVuLLRrHd7kShw= -sigs.k8s.io/release-sdk v0.1.0 h1:gesMqsV1W1r0PS9dbxeX0nuW45ZoRsIzILA23+WFjYU= sigs.k8s.io/release-sdk v0.1.0/go.mod h1:XhDgjf0bu2Vuyosp0Cc/mc3UUJiWS171S7WsNxA9iY0= +sigs.k8s.io/release-sdk v0.2.0 h1:DVTHyvEoim//zhckxQJBwofDcyHJIsxeo/WdPMm48Ow= +sigs.k8s.io/release-sdk v0.2.0/go.mod h1:zwNNQSkw9En31gqn2aRdCi0qxodxEaTgonDCINsdyoA= sigs.k8s.io/release-utils v0.2.0/go.mod h1:9O5livl2h3Q56jUkoZ7UnV22XVRB6MuD4l/51C2vAPg= sigs.k8s.io/release-utils v0.3.0 h1:cyNeXvm+2lPn67f4MWmq9xapZDAI5hekpT7iQPRxta4= sigs.k8s.io/release-utils v0.3.0/go.mod h1:J9xpziRNRI4mAeMZxPRryDodQMoMudMu6yC1aViFHU4= diff --git a/pkg/anago/anago.go b/pkg/anago/anago.go index c1f6d6c570d..f178c8ed826 100644 --- a/pkg/anago/anago.go +++ b/pkg/anago/anago.go @@ -23,9 +23,9 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" "k8s.io/release/pkg/version" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/log" "sigs.k8s.io/release-utils/util" ) diff --git a/pkg/anago/anago_test.go b/pkg/anago/anago_test.go index 9659d8f8dbd..2108d3e5f89 100644 --- a/pkg/anago/anago_test.go +++ b/pkg/anago/anago_test.go @@ -24,8 +24,8 @@ import ( "k8s.io/release/pkg/anago" "k8s.io/release/pkg/anago/anagofakes" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/git" ) var err = errors.New("error") diff --git a/pkg/anago/anagofakes/fake_stage_impl.go b/pkg/anago/anagofakes/fake_stage_impl.go index cc66ea32bb0..5d7b39ed7b2 100644 --- a/pkg/anago/anagofakes/fake_stage_impl.go +++ b/pkg/anago/anagofakes/fake_stage_impl.go @@ -24,9 +24,9 @@ import ( "k8s.io/release/pkg/build" "k8s.io/release/pkg/changelog" "k8s.io/release/pkg/gcp/gcb" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" "k8s.io/release/pkg/spdx" + "sigs.k8s.io/release-sdk/git" ) type FakeStageImpl struct { diff --git a/pkg/anago/release.go b/pkg/anago/release.go index b7e71da1f38..293ce4fbf58 100644 --- a/pkg/anago/release.go +++ b/pkg/anago/release.go @@ -28,8 +28,8 @@ import ( "k8s.io/release/pkg/announce" "k8s.io/release/pkg/build" "k8s.io/release/pkg/gcp/gcb" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-sdk/object" "sigs.k8s.io/release-utils/log" "sigs.k8s.io/release-utils/util" diff --git a/pkg/anago/stage.go b/pkg/anago/stage.go index 595daf3fe45..e4030012997 100644 --- a/pkg/anago/stage.go +++ b/pkg/anago/stage.go @@ -29,9 +29,9 @@ import ( "k8s.io/release/pkg/build" "k8s.io/release/pkg/changelog" "k8s.io/release/pkg/gcp/gcb" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" "k8s.io/release/pkg/spdx" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/log" ) diff --git a/pkg/anago/stage_test.go b/pkg/anago/stage_test.go index 5fd32f1d85c..26410051b47 100644 --- a/pkg/anago/stage_test.go +++ b/pkg/anago/stage_test.go @@ -23,9 +23,9 @@ import ( "github.com/stretchr/testify/require" "k8s.io/release/pkg/anago" "k8s.io/release/pkg/anago/anagofakes" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" "k8s.io/release/pkg/spdx" + "sigs.k8s.io/release-sdk/git" ) func generateTestingStageState(params *testStateParameters) *anago.StageState { diff --git a/pkg/announce/github_page.go b/pkg/announce/github_page.go index af9e23ddcf4..f1aae21b601 100644 --- a/pkg/announce/github_page.go +++ b/pkg/announce/github_page.go @@ -27,8 +27,8 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-utils/hash" "sigs.k8s.io/release-utils/util" ) diff --git a/pkg/build/buildfakes/fake_impl.go b/pkg/build/buildfakes/fake_impl.go index 20c64ec2724..1be81d6b906 100644 --- a/pkg/build/buildfakes/fake_impl.go +++ b/pkg/build/buildfakes/fake_impl.go @@ -20,7 +20,7 @@ package buildfakes import ( "sync" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" ) type FakeImpl struct { diff --git a/pkg/build/make.go b/pkg/build/make.go index 30c9eb3cfc1..a101ac7c83b 100644 --- a/pkg/build/make.go +++ b/pkg/build/make.go @@ -22,8 +22,8 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/command" ) diff --git a/pkg/changelog/changelog.go b/pkg/changelog/changelog.go index 50827f39b61..80f908f91f9 100644 --- a/pkg/changelog/changelog.go +++ b/pkg/changelog/changelog.go @@ -29,8 +29,8 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/notes/options" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/util" ) diff --git a/pkg/changelog/changelog_test.go b/pkg/changelog/changelog_test.go index 59498475b3c..a6cf8d12f06 100644 --- a/pkg/changelog/changelog_test.go +++ b/pkg/changelog/changelog_test.go @@ -25,8 +25,8 @@ import ( "k8s.io/release/pkg/changelog" "k8s.io/release/pkg/changelog/changelogfakes" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/notes" + "sigs.k8s.io/release-sdk/github" ) func TestRun(t *testing.T) { diff --git a/pkg/changelog/changelogfakes/fake_impl.go b/pkg/changelog/changelogfakes/fake_impl.go index 6d9030b7224..3f8752dc0b6 100644 --- a/pkg/changelog/changelogfakes/fake_impl.go +++ b/pkg/changelog/changelogfakes/fake_impl.go @@ -25,11 +25,11 @@ import ( "github.com/blang/semver" "github.com/yuin/goldmark/parser" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/notes" "k8s.io/release/pkg/notes/document" "k8s.io/release/pkg/notes/options" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" ) type FakeImpl struct { diff --git a/pkg/changelog/impl.go b/pkg/changelog/impl.go index e55fb54a76a..10eb05c0ad6 100644 --- a/pkg/changelog/impl.go +++ b/pkg/changelog/impl.go @@ -31,11 +31,11 @@ import ( "sigs.k8s.io/mdtoc/pkg/mdtoc" "k8s.io/release/pkg/cve" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/notes" "k8s.io/release/pkg/notes/document" "k8s.io/release/pkg/notes/options" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-sdk/object" "sigs.k8s.io/release-utils/http" "sigs.k8s.io/release-utils/util" diff --git a/pkg/fastforward/fastforward.go b/pkg/fastforward/fastforward.go index 7c22446078a..119cd60bda1 100644 --- a/pkg/fastforward/fastforward.go +++ b/pkg/fastforward/fastforward.go @@ -21,7 +21,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - kgit "k8s.io/release/pkg/git" + kgit "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/util" ) diff --git a/pkg/gcp/gcb/gcb.go b/pkg/gcp/gcb/gcb.go index 6ed35c2a78a..3d458583207 100644 --- a/pkg/gcp/gcb/gcb.go +++ b/pkg/gcp/gcb/gcb.go @@ -31,10 +31,10 @@ import ( "k8s.io/release/pkg/gcp/auth" "k8s.io/release/pkg/gcp/build" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/kubecross" "k8s.io/release/pkg/release" "sigs.k8s.io/release-sdk/gcli" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/util" ) diff --git a/pkg/gcp/gcb/gcb_test.go b/pkg/gcp/gcb/gcb_test.go index 5425be06acf..fb433d09f47 100644 --- a/pkg/gcp/gcb/gcb_test.go +++ b/pkg/gcp/gcb/gcb_test.go @@ -26,8 +26,8 @@ import ( "k8s.io/release/pkg/gcp/gcb" "k8s.io/release/pkg/gcp/gcb/gcbfakes" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/git" ) func mockRepo() gcb.Repository { diff --git a/pkg/gcp/gcb/history.go b/pkg/gcp/gcb/history.go index e04ca590c3c..b3506954453 100644 --- a/pkg/gcp/gcb/history.go +++ b/pkg/gcp/gcb/history.go @@ -27,8 +27,8 @@ import ( "google.golang.org/api/cloudbuild/v1" "k8s.io/release/pkg/gcp/build" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/git" ) // History is the main structure for retrieving the GCB history output. diff --git a/pkg/gh2gcs/gh2gcs.go b/pkg/gh2gcs/gh2gcs.go deleted file mode 100644 index c513a708e00..00000000000 --- a/pkg/gh2gcs/gh2gcs.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package gh2gcs - -import ( - "path/filepath" - "strings" - - "github.com/sirupsen/logrus" - - "k8s.io/release/pkg/github" - "sigs.k8s.io/release-sdk/object" -) - -// Config contains a slice of `ReleaseConfig` to be used when unmarshalling a -// yaml config containing multiple repository configs. -type Config struct { - ReleaseConfigs []ReleaseConfig `yaml:"releaseConfigs"` -} - -// ReleaseConfig contains source (GitHub) and destination (GCS) information -// to perform a copy/upload operation using gh2gcs. -type ReleaseConfig struct { - // GitHub options - Org string `yaml:"org"` - Repo string `yaml:"repo"` - Tags []string `yaml:"tags"` - IncludePrereleases bool `yaml:"includePrereleases"` - - // GCS options - GCSBucket string `yaml:"gcsBucket"` - ReleaseDir string `yaml:"releaseDir"` -} - -// DownloadReleases downloads release assets to a local directory -// Assets to download are derived from the tags specified in `ReleaseConfig`. -func DownloadReleases(releaseCfg *ReleaseConfig, ghClient *github.GitHub, outputDir string) error { - tags := releaseCfg.Tags - tagsString := strings.Join(tags, ", ") - - logrus.Infof( - "Downloading assets for the following %s/%s release tags: %s", - releaseCfg.Org, - releaseCfg.Repo, - tagsString, - ) - if err := ghClient.DownloadReleaseAssets(releaseCfg.Org, releaseCfg.Repo, tags, outputDir); err != nil { - return err - } - - return nil -} - -// Upload copies a set of release assets from local directory to GCS -// Assets to upload are derived from the tags specified in `ReleaseConfig`. -func Upload(cfg *ReleaseConfig, ghClient *github.GitHub, outputDir string) error { - uploadBase := filepath.Join(outputDir, cfg.Org, cfg.Repo) - - tags := cfg.Tags - for _, tag := range tags { - srcDir := filepath.Join(uploadBase, tag) - gcsPath := filepath.Join(cfg.GCSBucket, cfg.ReleaseDir, tag) - - gcs := object.NewGCS() - if err := gcs.CopyToRemote(srcDir, gcsPath); err != nil { - return err - } - } - - return nil -} diff --git a/pkg/git/describe.go b/pkg/git/describe.go deleted file mode 100644 index bb59cbcc45d..00000000000 --- a/pkg/git/describe.go +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package git - -import ( - "fmt" - - "github.com/pkg/errors" - - "sigs.k8s.io/release-utils/command" -) - -// DescribeOptions is the type for the argument passed to repo.Describe -type DescribeOptions struct { - revision string - abbrev int16 - always bool - dirty bool - tags bool -} - -// NewDescribeOptions creates new repository describe options -func NewDescribeOptions() *DescribeOptions { - return &DescribeOptions{ - revision: "", - abbrev: -1, - always: false, - dirty: false, - tags: false, - } -} - -// WithRevision sets the revision in the DescribeOptions -func (d *DescribeOptions) WithRevision(rev string) *DescribeOptions { - d.revision = rev - return d -} - -// WithAbbrev sets the --abbrev= in the DescribeOptions -func (d *DescribeOptions) WithAbbrev(abbrev uint8) *DescribeOptions { - d.abbrev = int16(abbrev) - return d -} - -// WithAlways sets always to true in the DescribeOptions -func (d *DescribeOptions) WithAlways() *DescribeOptions { - d.always = true - return d -} - -// WithDirty sets dirty to true in the DescribeOptions -func (d *DescribeOptions) WithDirty() *DescribeOptions { - d.dirty = true - return d -} - -// WithTags sets tags to true in the DescribeOptions -func (d *DescribeOptions) WithTags() *DescribeOptions { - d.tags = true - return d -} - -// toArgs converts DescribeOptions to string arguments -func (d *DescribeOptions) toArgs() (args []string) { - if d.tags { - args = append(args, "--tags") - } - if d.dirty { - args = append(args, "--dirty") - } - if d.always { - args = append(args, "--always") - } - if d.abbrev >= 0 { - args = append(args, fmt.Sprintf("--abbrev=%d", d.abbrev)) - } - if d.revision != "" { - args = append(args, d.revision) - } - return args -} - -// Describe runs `git describe` with the provided arguments -func (r *Repo) Describe(opts *DescribeOptions) (string, error) { - if opts == nil { - return "", errors.New("provided describe options are nil") - } - output, err := command.NewWithWorkDir( - r.Dir(), gitExecutable, append([]string{"describe"}, opts.toArgs()...)..., - ).RunSilentSuccessOutput() - if err != nil { - return "", err - } - return output.OutputTrimNL(), nil -} diff --git a/pkg/git/describe_test.go b/pkg/git/describe_test.go deleted file mode 100644 index ff61cd1163e..00000000000 --- a/pkg/git/describe_test.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package git - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestDescribeOptionsEmpty(t *testing.T) { - sut := NewDescribeOptions() - require.NotNil(t, sut) - require.Nil(t, sut.toArgs()) -} - -func TestDescribeOptionsArguments(t *testing.T) { - sut := NewDescribeOptions(). - WithTags(). - WithDirty(). - WithAbbrev(3). - WithAlways(). - WithRevision("rev") - require.NotNil(t, sut) - require.Equal(t, []string{ - "--tags", - "--dirty", - "--always", - "--abbrev=3", - "rev", - }, sut.toArgs()) -} diff --git a/pkg/git/git.go b/pkg/git/git.go deleted file mode 100644 index e4bf32de955..00000000000 --- a/pkg/git/git.go +++ /dev/null @@ -1,1428 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package git - -import ( - "bufio" - "bytes" - "fmt" - "io" - "math" - "net/url" - "os" - "path/filepath" - "regexp" - "sort" - "strings" - "time" - - "github.com/blang/semver" - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/storer" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - - "k8s.io/release/pkg/release/regex" - "sigs.k8s.io/release-utils/command" - "sigs.k8s.io/release-utils/util" -) - -const ( - DefaultGithubOrg = "kubernetes" - DefaultGithubRepo = "kubernetes" - DefaultGithubReleaseRepo = "sig-release" - DefaultRemote = "origin" - DefaultRef = "HEAD" - DefaultBranch = "master" - - defaultGithubAuthRoot = "git@github.com:" - defaultGitUser = "Anago GCB" - defaultGitEmail = "nobody@k8s.io" - gitExecutable = "git" -) - -// setVerboseTrace enables maximum verbosity output. -func setVerboseTrace() error { - return errors.Wrap(setVerbose(5, 2, 2, 2, 2, 2, 2, 2), "set verbose") -} - -// setVerboseDebug enables a higher verbosity output for git. -func setVerboseDebug() error { - return errors.Wrap(setVerbose(2, 2, 2, 0, 0, 0, 2, 0), "set verbose") -} - -// setVerbose changes the git verbosity output. -func setVerbose( - merge, - curl, - trace, - tracePackAccess, - tracePacket, - tracePerformance, - traceSetup, - traceShallow uint, -) error { - // Possible values taken from: - // https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#Debugging - for key, value := range map[string]string{ - // Controls the output for the recursive merge strategy. The allowed - // values are as follows: - // 0 outputs nothing, except possibly a single error message. - // 1 shows only conflicts. - // 2 also shows file changes. - // 3 shows when files are skipped because they haven’t changed. - // 4 shows all paths as they are processed. - // 5 and above show detailed debugging information. - // The default value is 2. - "GIT_MERGE_VERBOSITY": fmt.Sprint(merge), - - // Git uses the curl library to do network operations over HTTP, so - // GIT_CURL_VERBOSE tells Git to emit all the messages generated by - // that library. This is similar to doing curl -v on the command line. - "GIT_CURL_VERBOSE": fmt.Sprint(curl), - - // Controls general traces, which don’t fit into any specific category. - // This includes the expansion of aliases, and delegation to other - // sub-programs. - "GIT_TRACE": fmt.Sprint(trace), - - // Controls tracing of packfile access. The first field is the packfile - // being accessed, the second is the offset within that file. - "GIT_TRACE_PACK_ACCESS": fmt.Sprint(tracePackAccess), - - // Enables packet-level tracing for network operations. - "GIT_TRACE_PACKET": fmt.Sprint(tracePacket), - - // Controls logging of performance data. The output shows how long each - // particular git invocation takes. - "GIT_TRACE_PERFORMANCE": fmt.Sprint(tracePerformance), - - // Shows information about what Git is discovering about the repository - // and environment it’s interacting with. - "GIT_TRACE_SETUP": fmt.Sprint(traceSetup), - - // Debugging fetching/cloning of shallow repositories. - "GIT_TRACE_SHALLOW": fmt.Sprint(traceShallow), - } { - if err := os.Setenv(key, value); err != nil { - return errors.Wrapf(err, "unable to set %s=%s", key, value) - } - } - return nil -} - -// GetDefaultKubernetesRepoURL returns the default HTTPS repo URL for Kubernetes. -// Expected: https://github.com/kubernetes/kubernetes -func GetDefaultKubernetesRepoURL() string { - return GetKubernetesRepoURL(DefaultGithubOrg, false) -} - -// GetKubernetesRepoURL takes a GitHub org and repo, and useSSH as a boolean and -// returns a repo URL for Kubernetes. -// Expected result is one of the following: -// - https://github.com//kubernetes -// - git@github.com:/kubernetes -func GetKubernetesRepoURL(org string, useSSH bool) string { - if org == "" { - org = DefaultGithubOrg - } - - return GetRepoURL(org, DefaultGithubRepo, useSSH) -} - -// GetRepoURL takes a GitHub org and repo, and useSSH as a boolean and -// returns a repo URL for the specified repo. -// Expected result is one of the following: -// - https://github.com// -// - git@github.com:/ -func GetRepoURL(org, repo string, useSSH bool) (repoURL string) { - slug := filepath.Join(org, repo) - - if useSSH { - repoURL = fmt.Sprintf("%s%s", defaultGithubAuthRoot, slug) - } else { - repoURL = (&url.URL{ - Scheme: "https", - Host: "github.com", - Path: slug, - }).String() - } - - return repoURL -} - -// ConfigureGlobalDefaultUserAndEmail globally configures the default git -// user and email. -func ConfigureGlobalDefaultUserAndEmail() error { - if err := filterCommand( - "", "config", "--global", "user.name", defaultGitUser, - ).RunSuccess(); err != nil { - return errors.Wrap(err, "configure user name") - } - - if err := filterCommand( - "", "config", "--global", "user.email", defaultGitEmail, - ).RunSuccess(); err != nil { - return errors.Wrap(err, "configure user email") - } - - return nil -} - -// filterCommand returns a command which automatically filters sensitive information. -func filterCommand(workdir string, args ...string) *command.Command { - // Filter GitHub API keys - c, err := command.NewWithWorkDir( - workdir, gitExecutable, args..., - ).Filter(`(?m)git:[0-9a-zA-Z]{35,40}`, "[REDACTED]") - if err != nil { - // should never happen - logrus.Fatalf("git command creation failed: %v", err) - } - - return c -} - -// DiscoverResult is the result of a revision discovery -type DiscoverResult struct { - startSHA, startRev, endSHA, endRev string -} - -// StartSHA returns the start SHA for the DiscoverResult -func (d *DiscoverResult) StartSHA() string { - return d.startSHA -} - -// StartRev returns the start revision for the DiscoverResult -func (d *DiscoverResult) StartRev() string { - return d.startRev -} - -// EndSHA returns the end SHA for the DiscoverResult -func (d *DiscoverResult) EndSHA() string { - return d.endSHA -} - -// EndRev returns the end revision for the DiscoverResult -func (d *DiscoverResult) EndRev() string { - return d.endRev -} - -// Remote is a representation of a git remote location -type Remote struct { - name string - urls []string -} - -// NewRemote creates a new remote for the provided name and URLs -func NewRemote(name string, urls []string) *Remote { - return &Remote{name, urls} -} - -// Name returns the name of the remote -func (r *Remote) Name() string { - return r.name -} - -// URLs returns all available URLs of the remote -func (r *Remote) URLs() []string { - return r.urls -} - -// Wrapper type for a Kubernetes repository instance -type Repo struct { - inner Repository - worktree Worktree - dir string - dryRun bool - maxRetries int -} - -//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate - -// Repository is the main interface to the git.Repository functionality -//counterfeiter:generate . Repository -type Repository interface { - CreateTag(string, plumbing.Hash, *git.CreateTagOptions) (*plumbing.Reference, error) - Branches() (storer.ReferenceIter, error) - CommitObject(plumbing.Hash) (*object.Commit, error) - CreateRemote(*config.RemoteConfig) (*git.Remote, error) - DeleteRemote(name string) error - Head() (*plumbing.Reference, error) - Remote(string) (*git.Remote, error) - Remotes() ([]*git.Remote, error) - ResolveRevision(plumbing.Revision) (*plumbing.Hash, error) - Tags() (storer.ReferenceIter, error) -} - -// Worktree is the main interface to the git.Worktree functionality -//counterfeiter:generate . Worktree -type Worktree interface { - Add(string) (plumbing.Hash, error) - Commit(string, *git.CommitOptions) (plumbing.Hash, error) - Checkout(*git.CheckoutOptions) error - Status() (git.Status, error) -} - -// Dir returns the directory where the repository is stored on disk -func (r *Repo) Dir() string { - return r.dir -} - -// Set the repo into dry run mode, which does not modify any remote locations -// at all. -func (r *Repo) SetDry() { - r.dryRun = true -} - -// SetWorktree can be used to manually set the repository worktree -func (r *Repo) SetWorktree(worktree Worktree) { - r.worktree = worktree -} - -// SetInnerRepo can be used to manually set the inner repository -func (r *Repo) SetInnerRepo(repo Repository) { - r.inner = repo -} - -// SetMaxRetries defines the number of times, the git client will retry -// some operations when timing out or network failures. Setting it to -// 0 disables retrying -func (r *Repo) SetMaxRetries(numRetries int) { - r.maxRetries = numRetries -} - -func LSRemoteExec(repoURL string, args ...string) (string, error) { - cmdArgs := append([]string{"ls-remote", repoURL}, args...) - cmdStatus, err := filterCommand("", cmdArgs...). - RunSilentSuccessOutput() - if err != nil { - return "", errors.Wrap(err, "failed to execute the ls-remote command") - } - - return strings.TrimSpace(cmdStatus.Output()), nil -} - -// CloneOrOpenDefaultGitHubRepoSSH clones the default Kubernetes GitHub -// repository via SSH if the repoPath is empty, otherwise updates it at the -// expected repoPath. -func CloneOrOpenDefaultGitHubRepoSSH(repoPath string) (*Repo, error) { - return CloneOrOpenGitHubRepo( - repoPath, DefaultGithubOrg, DefaultGithubRepo, true, - ) -} - -// CleanCloneGitHubRepo creates a guaranteed fresh checkout of a given repository. The returned *Repo has a Cleanup() -// method that should be used to delete the repository on-disk afterwards. -func CleanCloneGitHubRepo(owner, repo string, useSSH bool) (*Repo, error) { - repoURL := GetRepoURL(owner, repo, useSSH) - // The use of a blank string for the repo path triggers special behaviour in CloneOrOpenRepo that causes a true - // temporary directory with a random name to be created. - return CloneOrOpenRepo("", repoURL, useSSH) -} - -// CloneOrOpenGitHubRepo works with a repository in the given directory, or creates one if the directory is empty. The -// repo uses the provided GitHub repository via the owner and repo. If useSSH is true, then it will clone the -// repository using the defaultGithubAuthRoot. -func CloneOrOpenGitHubRepo(repoPath, owner, repo string, useSSH bool) (*Repo, error) { - repoURL := GetRepoURL(owner, repo, useSSH) - return CloneOrOpenRepo(repoPath, repoURL, useSSH) -} - -// CloneOrOpenRepo creates a temp directory containing the provided -// GitHub repository via the url. -// -// If a repoPath is given, then the function tries to update the repository. -// -// The function returns the repository if cloning or updating of the repository -// was successful, otherwise an error. -func CloneOrOpenRepo(repoPath, repoURL string, useSSH bool) (*Repo, error) { - logrus.Debugf("Using repository url %q", repoURL) - targetDir := "" - if repoPath != "" { - logrus.Debugf("Using existing repository path %q", repoPath) - _, err := os.Stat(repoPath) - - if err == nil { - // The file or directory exists, just try to update the repo - return updateRepo(repoPath) - } else if os.IsNotExist(err) { - // The directory does not exists, we still have to clone it - targetDir = repoPath - } else { - // Something else bad happened - return nil, errors.Wrap(err, "unable to update repo") - } - } else { - // No repoPath given, use a random temp dir instead - t, err := os.MkdirTemp("", "k8s-") - if err != nil { - return nil, errors.Wrap(err, "unable to create temp dir") - } - targetDir = t - } - - progressBuffer := &bytes.Buffer{} - progressWriters := []io.Writer{progressBuffer} - - // Only output the clone progress on debug or trace level, - // otherwise it's too boring. - logLevel := logrus.StandardLogger().Level - if logLevel >= logrus.DebugLevel { - progressWriters = append(progressWriters, os.Stderr) - } - - if _, err := git.PlainClone(targetDir, false, &git.CloneOptions{ - URL: repoURL, - Progress: io.MultiWriter(progressWriters...), - }); err != nil { - // Print the stack only if not already done - if logLevel < logrus.DebugLevel { - logrus.Errorf( - "Clone repository failed. Tracked progress:\n%s", - progressBuffer.String(), - ) - } - return nil, errors.Wrap(err, "unable to clone repo") - } - return updateRepo(targetDir) -} - -// updateRepo tries to open the provided repoPath and fetches the latest -// changes from the configured remote location -func updateRepo(repoPath string) (*Repo, error) { - r, err := OpenRepo(repoPath) - if err != nil { - return nil, err - } - - // Update the repo - if err := filterCommand( - r.Dir(), "pull", "--rebase", - ).RunSilentSuccess(); err != nil { - return nil, errors.Wrap(err, "unable to pull from remote") - } - - return r, nil -} - -// OpenRepo tries to open the provided repoPath -func OpenRepo(repoPath string) (*Repo, error) { - if !command.Available(gitExecutable) { - return nil, errors.Errorf( - "%s executable is not available in $PATH", gitExecutable, - ) - } - logLevel := logrus.StandardLogger().Level - if logLevel == logrus.DebugLevel { - logrus.Info("Setting verbose git output (debug)") - if err := setVerboseDebug(); err != nil { - return nil, errors.Wrap(err, "set debug output") - } - } else if logLevel == logrus.TraceLevel { - logrus.Info("Setting verbose git output (trace)") - if err := setVerboseTrace(); err != nil { - return nil, errors.Wrap(err, "set trace output") - } - } - - if strings.HasPrefix(repoPath, "~/") { - repoPath = os.Getenv("HOME") + repoPath[1:] - logrus.Warnf("Normalizing repository to: %s", repoPath) - } - - r, err := git.PlainOpenWithOptions( - repoPath, &git.PlainOpenOptions{DetectDotGit: true}, - ) - if err != nil { - return nil, errors.Wrap(err, "opening repo") - } - - worktree, err := r.Worktree() - if err != nil { - return nil, errors.Wrap(err, "getting repository worktree") - } - - return &Repo{ - inner: r, - worktree: worktree, - dir: worktree.Filesystem.Root(), - }, nil -} - -func (r *Repo) Cleanup() error { - logrus.Debugf("Deleting %s", r.dir) - return os.RemoveAll(r.dir) -} - -// RevParseTag parses a git revision and returns a SHA1 on success, otherwise an -// error. -// If the revision does not match a tag add the remote origin in the revision. -func (r *Repo) RevParseTag(rev string) (string, error) { - matched, err := regexp.MatchString(`v\d+\.\d+\.\d+.*`, rev) - if err != nil { - return "", err - } - if !matched { - // Prefix all non-tags the default remote "origin" - rev = Remotify(rev) - } - - // Try to resolve the rev - ref, err := r.inner.ResolveRevision(plumbing.Revision(rev)) - if err != nil { - return "", err - } - - return ref.String(), nil -} - -// RevParse parses a git revision and returns a SHA1 on success, otherwise an -// error. -func (r *Repo) RevParse(rev string) (string, error) { - // Try to resolve the rev - ref, err := r.inner.ResolveRevision(plumbing.Revision(rev)) - if err != nil { - return "", err - } - - return ref.String(), nil -} - -// RevParseTagShort parses a git revision and returns a SHA1 trimmed to the length -// 10 on success, otherwise an error. -// If the revision does not match a tag add the remote origin in the revision. -func (r *Repo) RevParseTagShort(rev string) (string, error) { - fullRev, err := r.RevParseTag(rev) - if err != nil { - return "", err - } - - return fullRev[:10], nil -} - -// RevParseTagShort parses a git revision and returns a SHA1 trimmed to the length -// 10 on success, otherwise an error. -func (r *Repo) RevParseShort(rev string) (string, error) { - fullRev, err := r.RevParse(rev) - if err != nil { - return "", err - } - - return fullRev[:10], nil -} - -// LatestReleaseBranchMergeBaseToLatest tries to discover the start (latest -// v1.x.0 merge base) and end (release-1.(x+1) or DefaultBranch) revision inside the -// repository. -func (r *Repo) LatestReleaseBranchMergeBaseToLatest() (DiscoverResult, error) { - // Find the last non patch version tag, then resolve its revision - versions, err := r.latestNonPatchFinalVersions() - if err != nil { - return DiscoverResult{}, err - } - version := versions[0] - versionTag := util.SemverToTagString(version) - logrus.Debugf("Latest non patch version %s", versionTag) - - base, err := r.MergeBase( - DefaultBranch, - fmt.Sprintf("release-%d.%d", version.Major, version.Minor), - ) - if err != nil { - return DiscoverResult{}, err - } - - // If a release branch exists for the next version, we use it. Otherwise we - // fallback to the DefaultBranch. - end, branch, err := r.releaseBranchOrMainRef(version.Major, version.Minor+1) - if err != nil { - return DiscoverResult{}, err - } - - return DiscoverResult{ - startSHA: base, - startRev: versionTag, - endSHA: end, - endRev: branch, - }, nil -} - -func (r *Repo) LatestNonPatchFinalToMinor() (DiscoverResult, error) { - // Find the last non patch version tag, then resolve its revision - versions, err := r.latestNonPatchFinalVersions() - if err != nil { - return DiscoverResult{}, err - } - if len(versions) < 2 { - return DiscoverResult{}, errors.New("unable to find two latest non patch versions") - } - - latestVersion := versions[0] - latestVersionTag := util.SemverToTagString(latestVersion) - logrus.Debugf("Latest non patch version %s", latestVersionTag) - end, err := r.RevParseTag(latestVersionTag) - if err != nil { - return DiscoverResult{}, err - } - - previousVersion := versions[1] - previousVersionTag := util.SemverToTagString(previousVersion) - logrus.Debugf("Previous non patch version %s", previousVersionTag) - start, err := r.RevParseTag(previousVersionTag) - if err != nil { - return DiscoverResult{}, err - } - - return DiscoverResult{ - startSHA: start, - startRev: previousVersionTag, - endSHA: end, - endRev: latestVersionTag, - }, nil -} - -func (r *Repo) latestNonPatchFinalVersions() ([]semver.Version, error) { - latestVersions := []semver.Version{} - - tags, err := r.inner.Tags() - if err != nil { - return nil, err - } - - _ = tags.ForEach(func(t *plumbing.Reference) error { // nolint: errcheck - ver, err := util.TagStringToSemver(t.Name().Short()) - - if err == nil { - // We're searching for the latest, non patch final tag - if ver.Patch == 0 && len(ver.Pre) == 0 { - if len(latestVersions) == 0 || ver.GT(latestVersions[0]) { - latestVersions = append([]semver.Version{ver}, latestVersions...) - } - } - } - return nil - }) - if len(latestVersions) == 0 { - return nil, fmt.Errorf("unable to find latest non patch release") - } - return latestVersions, nil -} - -func (r *Repo) releaseBranchOrMainRef(major, minor uint64) (sha, rev string, err error) { - relBranch := fmt.Sprintf("release-%d.%d", major, minor) - sha, err = r.RevParseTag(relBranch) - if err == nil { - logrus.Debugf("Found release branch %s", relBranch) - return sha, relBranch, nil - } - - sha, err = r.RevParseTag(DefaultBranch) - if err == nil { - logrus.Debugf("No release branch found, using %s", DefaultBranch) - return sha, DefaultBranch, nil - } - - return "", "", err -} - -// HasBranch checks if a branch exists in the repo -func (r *Repo) HasBranch(branch string) (branchExists bool, err error) { - logrus.Infof("Verifying %s branch exists in the repo", branch) - - branches, err := r.inner.Branches() - if err != nil { - return branchExists, errors.Wrap(err, "getting branches from repository") - } - - branchExists = false - if err := branches.ForEach(func(ref *plumbing.Reference) error { - if ref.Name().Short() == branch { - logrus.Infof("Branch %s found in the repository", branch) - branchExists = true - } - return nil - }); err != nil { - return branchExists, errors.Wrap(err, "iterating branches to check for existence") - } - return branchExists, nil -} - -// HasRemoteBranch takes a branch string and verifies that it exists -// on the default remote -func (r *Repo) HasRemoteBranch(branch string) (branchExists bool, err error) { - logrus.Infof("Verifying %s branch exists on the remote", branch) - - remote, err := r.inner.Remote(DefaultRemote) - if err != nil { - return branchExists, NewNetworkError(err) - } - var refs []*plumbing.Reference - for i := r.maxRetries + 1; i > 0; i-- { - // We can then use every Remote functions to retrieve wanted information - refs, err = remote.List(&git.ListOptions{}) - if err == nil { - break - } - logrus.Warn("Could not list references on the remote repository.") - // Convert to network error to see if we can retry the push - err = NewNetworkError(err) - if !err.(NetworkError).CanRetry() || r.maxRetries == 0 || i == 1 { - return branchExists, err - } - waitTime := math.Pow(2, float64(r.maxRetries-i)) - logrus.Errorf( - "Error listing remote references (will retry %d more times in %.0f secs): %s", - i-1, waitTime, err.Error(), - ) - time.Sleep(time.Duration(waitTime) * time.Second) - } - - for _, ref := range refs { - if ref.Name().IsBranch() { - if ref.Name().Short() == branch { - logrus.Infof("Found branch %s", ref.Name().Short()) - return true, nil - } - } - } - logrus.Infof("Branch %v not found", branch) - return false, nil -} - -// Checkout can be used to checkout any revision inside the repository -func (r *Repo) Checkout(rev string, args ...string) error { - cmdArgs := append([]string{"checkout", rev}, args...) - return command. - NewWithWorkDir(r.Dir(), gitExecutable, cmdArgs...). - RunSilentSuccess() -} - -// IsReleaseBranch returns true if the provided branch is a Kubernetes release -// branch -func IsReleaseBranch(branch string) bool { - if !regex.BranchRegex.MatchString(branch) { - logrus.Warnf("%s is not a release branch", branch) - return false - } - - return true -} - -func (r *Repo) MergeBase(from, to string) (string, error) { - mainRef := Remotify(from) - releaseRef := Remotify(to) - - logrus.Debugf("MainRef: %s, releaseRef: %s", mainRef, releaseRef) - - commitRevs := []string{mainRef, releaseRef} - var res []*object.Commit - - hashes := []*plumbing.Hash{} - for _, rev := range commitRevs { - hash, err := r.inner.ResolveRevision(plumbing.Revision(rev)) - if err != nil { - return "", err - } - hashes = append(hashes, hash) - } - - commits := []*object.Commit{} - for _, hash := range hashes { - commit, err := r.inner.CommitObject(*hash) - if err != nil { - return "", err - } - commits = append(commits, commit) - } - - res, err := commits[0].MergeBase(commits[1]) - if err != nil { - return "", err - } - - if len(res) == 0 { - return "", errors.Errorf("could not find a merge base between %s and %s", from, to) - } - - mergeBase := res[0].Hash.String() - logrus.Infof("Merge base is %s", mergeBase) - - return mergeBase, nil -} - -// Remotify returns the name prepended with the default remote -func Remotify(name string) string { - split := strings.Split(name, "/") - if len(split) > 1 { - return name - } - return fmt.Sprintf("%s/%s", DefaultRemote, name) -} - -// Merge does a git merge into the current branch from the provided one -func (r *Repo) Merge(from string) error { - return errors.Wrap(filterCommand( - r.Dir(), "merge", "-X", "ours", from, - ).RunSilentSuccess(), "run git merge") -} - -// Push does push the specified branch to the default remote, but only if the -// repository is not in dry run mode -func (r *Repo) Push(remoteBranch string) (err error) { - args := []string{"push"} - if r.dryRun { - logrus.Infof("Won't push due to dry run repository") - args = append(args, "--dry-run") - } - args = append(args, DefaultRemote, remoteBranch) - - for i := r.maxRetries + 1; i > 0; i-- { - if err = filterCommand(r.Dir(), args...).RunSilentSuccess(); err == nil { - return nil - } - // Convert to network error to see if we can retry the push - err = NewNetworkError(err) - if !err.(NetworkError).CanRetry() || r.maxRetries == 0 { - return err - } - waitTime := math.Pow(2, float64(r.maxRetries-i)) - logrus.Errorf( - "Error pushing %s (will retry %d more times in %.0f secs): %s", - remoteBranch, i-1, waitTime, err.Error(), - ) - time.Sleep(time.Duration(waitTime) * time.Second) - } - return errors.Wrapf(err, "trying to push %s %d times", remoteBranch, r.maxRetries) -} - -// Head retrieves the current repository HEAD as a string -func (r *Repo) Head() (string, error) { - ref, err := r.inner.Head() - if err != nil { - return "", err - } - return ref.Hash().String(), nil -} - -// LatestPatchToPatch tries to discover the start (latest v1.x.[x-1]) and -// end (latest v1.x.x) revision inside the repository for the specified release -// branch. -func (r *Repo) LatestPatchToPatch(branch string) (DiscoverResult, error) { - latestTag, err := r.LatestTagForBranch(branch) - if err != nil { - return DiscoverResult{}, err - } - - if len(latestTag.Pre) > 0 && latestTag.Patch > 0 { - latestTag.Patch-- - latestTag.Pre = nil - } - - if latestTag.Patch == 0 { - return DiscoverResult{}, errors.Errorf( - "found non-patch version %v as latest tag on branch %s", - latestTag, branch, - ) - } - - prevTag := semver.Version{ - Major: latestTag.Major, - Minor: latestTag.Minor, - Patch: latestTag.Patch - 1, - } - - logrus.Debugf("Parsing latest tag %s%v", util.TagPrefix, latestTag) - latestVersionTag := util.SemverToTagString(latestTag) - end, err := r.RevParseTag(latestVersionTag) - if err != nil { - return DiscoverResult{}, errors.Wrapf(err, "parsing version %v", latestTag) - } - - logrus.Debugf("Parsing previous tag %s%v", util.TagPrefix, prevTag) - previousVersionTag := util.SemverToTagString(prevTag) - start, err := r.RevParseTag(previousVersionTag) - if err != nil { - return DiscoverResult{}, errors.Wrapf(err, "parsing previous version %v", prevTag) - } - - return DiscoverResult{ - startSHA: start, - startRev: previousVersionTag, - endSHA: end, - endRev: latestVersionTag, - }, nil -} - -// LatestPatchToLatest tries to discover the start (latest v1.x.x]) and -// end (release-1.x or DefaultBranch) revision inside the repository for the specified release -// branch. -func (r *Repo) LatestPatchToLatest(branch string) (DiscoverResult, error) { - latestTag, err := r.LatestTagForBranch(branch) - if err != nil { - return DiscoverResult{}, err - } - - if len(latestTag.Pre) > 0 && latestTag.Patch > 0 { - latestTag.Patch-- - latestTag.Pre = nil - } - - logrus.Debugf("Parsing latest tag %s%v", util.TagPrefix, latestTag) - latestVersionTag := util.SemverToTagString(latestTag) - start, err := r.RevParseTag(latestVersionTag) - if err != nil { - return DiscoverResult{}, errors.Wrapf(err, "parsing version %v", latestTag) - } - - // If a release branch exists for the latest version, we use it. Otherwise we - // fallback to the DefaultBranch. - end, branch, err := r.releaseBranchOrMainRef(latestTag.Major, latestTag.Minor) - if err != nil { - return DiscoverResult{}, errors.Wrapf(err, "getting release branch for %v", latestTag) - } - - return DiscoverResult{ - startSHA: start, - startRev: latestVersionTag, - endSHA: end, - endRev: branch, - }, nil -} - -// LatestTagForBranch returns the latest available semver tag for a given branch -func (r *Repo) LatestTagForBranch(branch string) (tag semver.Version, err error) { - tags, err := r.TagsForBranch(branch) - if err != nil { - return tag, err - } - if len(tags) == 0 { - return tag, errors.New("no tags found on branch") - } - - tag, err = util.TagStringToSemver(tags[0]) - if err != nil { - return tag, err - } - - return tag, nil -} - -// PreviousTag tries to find the previous tag for a provided branch and errors -// on any failure -func (r *Repo) PreviousTag(tag, branch string) (string, error) { - tags, err := r.TagsForBranch(branch) - if err != nil { - return "", err - } - - idx := -1 - for i, t := range tags { - if t == tag { - idx = i - break - } - } - if idx == -1 { - return "", errors.New("could not find specified tag in branch") - } - if len(tags) < idx+1 { - return "", errors.New("unable to find previous tag") - } - - return tags[idx+1], nil -} - -// TagsForBranch returns a list of tags for the provided branch sorted by -// creation date -func (r *Repo) TagsForBranch(branch string) (res []string, err error) { - previousBranch, err := r.CurrentBranch() - if err != nil { - return nil, errors.Wrap(err, "retrieving current branch") - } - if err := r.Checkout(branch); err != nil { - return nil, errors.Wrapf(err, "checking out %s", branch) - } - defer func() { err = r.Checkout(previousBranch) }() - - status, err := filterCommand( - r.Dir(), "tag", "--sort=creatordate", "--merged", - ).RunSilentSuccessOutput() - if err != nil { - return nil, errors.Wrapf(err, "retrieving merged tags for branch %s", branch) - } - - tags := strings.Fields(status.Output()) - sort.Sort(sort.Reverse(sort.StringSlice(tags))) - - return tags, nil -} - -// Tags returns a list of tags for the repository. -func (r *Repo) Tags() (res []string, err error) { - tags, err := r.inner.Tags() - if err != nil { - return nil, errors.Wrap(err, "get tags") - } - _ = tags.ForEach(func(t *plumbing.Reference) error { // nolint: errcheck - res = append(res, t.Name().Short()) - return nil - }) - return res, nil -} - -// Add adds a file to the staging area of the repo -func (r *Repo) Add(filename string) error { - return errors.Wrapf( - filterCommand( - r.Dir(), "add", filename, - ).RunSilentSuccess(), - "adding file %s to repository", filename, - ) -} - -// GetUserName Reads the local user's name from the git configuration -func GetUserName() (string, error) { - // Retrieve username from git - userName, err := filterCommand( - "", "config", "--get", "user.name", - ).RunSilentSuccessOutput() - if err != nil { - return "", errors.Wrap(err, "reading the user name from git") - } - return userName.OutputTrimNL(), nil -} - -// GetUserEmail reads the user's name from git -func GetUserEmail() (string, error) { - userEmail, err := filterCommand( - "", "config", "--get", "user.email", - ).RunSilentSuccessOutput() - if err != nil { - return "", errors.Wrap(err, "reading the user's email from git") - } - return userEmail.OutputTrimNL(), nil -} - -// UserCommit makes a commit using the local user's config as well as adding -// the Signed-off-by line to the commit message -func (r *Repo) UserCommit(msg string) error { - // Retrieve username and mail - userName, err := GetUserName() - if err != nil { - return errors.Wrap(err, "getting the user's name") - } - - userEmail, err := GetUserEmail() - if err != nil { - return errors.Wrap(err, "getting the user's email") - } - - // Add signed-off-by line - msg += fmt.Sprintf("\n\nSigned-off-by: %s <%s>", userName, userEmail) - - if err := r.CommitWithOptions(msg, &git.CommitOptions{ - Author: &object.Signature{ - Name: userName, - Email: userEmail, - When: time.Now(), - }, - }); err != nil { - return errors.Wrap(err, "commit changes") - } - - return nil -} - -// Commit commits the current repository state -func (r *Repo) Commit(msg string) error { - if err := r.CommitWithOptions(msg, &git.CommitOptions{ - Author: &object.Signature{ - Name: defaultGitUser, - Email: defaultGitEmail, - When: time.Now(), - }, - }); err != nil { - return err - } - return nil -} - -// CommitWithOptions commits the current repository state -func (r *Repo) CommitWithOptions(msg string, options *git.CommitOptions) error { - if _, err := r.worktree.Commit(msg, options); err != nil { - return err - } - return nil -} - -// CommitEmpty commits an empty commit into the repository -func (r *Repo) CommitEmpty(msg string) error { - return command. - NewWithWorkDir(r.Dir(), gitExecutable, - "commit", "--allow-empty", "-m", msg, - ). - RunSilentSuccess() -} - -// Tag creates a new annotated tag for the provided `name` and `message`. -func (r *Repo) Tag(name, message string) error { - head, err := r.inner.Head() - if err != nil { - return err - } - if _, err := r.inner.CreateTag( - name, - head.Hash(), - &git.CreateTagOptions{ - Tagger: &object.Signature{ - Name: defaultGitUser, - Email: defaultGitEmail, - When: time.Now(), - }, - Message: message, - }); err != nil { - return err - } - return nil -} - -// CurrentBranch returns the current branch of the repository or an error in -// case of any failure -func (r *Repo) CurrentBranch() (branch string, err error) { - branches, err := r.inner.Branches() - if err != nil { - return "", err - } - - head, err := r.inner.Head() - if err != nil { - return "", err - } - - if err := branches.ForEach(func(ref *plumbing.Reference) error { - if ref.Hash() == head.Hash() { - branch = ref.Name().Short() - return nil - } - - return nil - }); err != nil { - return "", err - } - - return branch, nil -} - -// Rm removes files from the repository -func (r *Repo) Rm(force bool, files ...string) error { - args := []string{"rm"} - if force { - args = append(args, "-f") - } - args = append(args, files...) - - return command. - NewWithWorkDir(r.Dir(), gitExecutable, args...). - RunSilentSuccess() -} - -// Remotes lists the currently available remotes for the repository -func (r *Repo) Remotes() (res []*Remote, err error) { - remotes, err := r.inner.Remotes() - if err != nil { - return nil, errors.Wrap(err, "unable to list remotes") - } - - // Sort the remotes by their name which is not always the case - sort.Slice(remotes, func(i, j int) bool { - return remotes[i].Config().Name < remotes[j].Config().Name - }) - - for _, remote := range remotes { - cfg := remote.Config() - res = append(res, &Remote{name: cfg.Name, urls: cfg.URLs}) - } - - return res, nil -} - -// HasRemote checks if the provided remote `name` is available and matches the -// expected `url` -func (r *Repo) HasRemote(name, expectedURL string) bool { - remotes, err := r.Remotes() - if err != nil { - logrus.Warnf("Unable to get repository remotes: %v", err) - return false - } - - for _, remote := range remotes { - if remote.Name() == name { - for _, url := range remote.URLs() { - if url == expectedURL { - return true - } - } - } - } - - return false -} - -// AddRemote adds a new remote to the current working tree -func (r *Repo) AddRemote(name, owner, repo string) error { - repoURL := GetRepoURL(owner, repo, true) - args := []string{"remote", "add", name, repoURL} - return command. - NewWithWorkDir(r.Dir(), gitExecutable, args...). - RunSilentSuccess() -} - -// PushToRemote push the current branch to a spcified remote, but only if the -// repository is not in dry run mode -func (r *Repo) PushToRemote(remote, remoteBranch string) error { - args := []string{"push", "--set-upstream"} - if r.dryRun { - logrus.Infof("Won't push due to dry run repository") - args = append(args, "--dry-run") - } - args = append(args, remote, remoteBranch) - - return filterCommand(r.Dir(), args...).RunSuccess() -} - -// LsRemote can be used to run `git ls-remote` with the provided args on the -// repository -func (r *Repo) LsRemote(args ...string) (output string, err error) { - for i := r.maxRetries + 1; i > 0; i-- { - output, err = r.runGitCmd("ls-remote", args...) - if err == nil { - return output, nil - } - err = NewNetworkError(err) - if !err.(NetworkError).CanRetry() || r.maxRetries == 0 || i == 1 { - return "", err - } - - waitTime := math.Pow(2, float64(r.maxRetries-i)) - logrus.Errorf( - "Executing ls-remote (will retry %d more times in %.0f secs): %s", - i-1, waitTime, err.Error(), - ) - time.Sleep(time.Duration(waitTime) * time.Second) - } - return "", err -} - -// Branch can be used to run `git branch` with the provided args on the -// repository -func (r *Repo) Branch(args ...string) (string, error) { - return r.runGitCmd("branch", args...) -} - -// runGitCmd runs the provided command in the repository root and appends the -// args. The command will run silently and return the captured output or an -// error in case of any failure. -func (r *Repo) runGitCmd(cmd string, args ...string) (string, error) { - cmdArgs := append([]string{cmd}, args...) - res, err := filterCommand(r.Dir(), cmdArgs...).RunSilentSuccessOutput() - if err != nil { - return "", errors.Wrapf(err, "running git %s", cmd) - } - return res.OutputTrimNL(), nil -} - -// IsDirty returns true if the worktree status is not clean. It can also error -// if the worktree status is not retrievable. -func (r *Repo) IsDirty() (bool, error) { - status, err := r.Status() - if err != nil { - return false, errors.Wrap(err, "retrieving worktree status") - } - return !status.IsClean(), nil -} - -// RemoteTags return the tags that currently exist in the -func (r *Repo) RemoteTags() (tags []string, err error) { - logrus.Debug("Listing remote tags with ls-remote") - output, err := r.LsRemote("--tags", DefaultRemote) - if err != nil { - return tags, errors.Wrap(err, "while listing tags using ls-remote") - } - const gitTagPreRef = "refs/tags/" - tags = make([]string, 0) - scanner := bufio.NewScanner(strings.NewReader(output)) - scanner.Split(bufio.ScanWords) - for scanner.Scan() { - if strings.HasPrefix(scanner.Text(), gitTagPreRef) { - tags = append(tags, strings.TrimPrefix(scanner.Text(), gitTagPreRef)) - } - } - logrus.Debugf("Remote repository contains %d tags", len(tags)) - return tags, nil -} - -// HasRemoteTag Checks if the default remote already has a tag -func (r *Repo) HasRemoteTag(tag string) (hasTag bool, err error) { - remoteTags, err := r.RemoteTags() - if err != nil { - return hasTag, errors.Wrap(err, "getting tags to check if tag exists") - } - for _, remoteTag := range remoteTags { - if tag == remoteTag { - logrus.Infof("Tag %s found in default remote", tag) - return true, nil - } - } - return false, nil -} - -// SetURL can be used to overwrite the URL for a remote -func (r *Repo) SetURL(remote, newURL string) error { - if err := r.inner.DeleteRemote(remote); err != nil { - return errors.Wrap(err, "delete remote") - } - if _, err := r.inner.CreateRemote(&config.RemoteConfig{ - Name: remote, - URLs: []string{newURL}, - }); err != nil { - return errors.Wrap(err, "create remote") - } - return nil -} - -// Status reads and returns the Status object from the repository -func (r *Repo) Status() (*git.Status, error) { - status, err := r.worktree.Status() - if err != nil { - return nil, errors.Wrap(err, "getting the repository status") - } - return &status, nil -} - -// ShowLastCommit is a simple function that runs git show and returns the -// last commit in the log -func (r *Repo) ShowLastCommit() (logData string, err error) { - logData, err = r.runGitCmd("show") - if err != nil { - return logData, errors.Wrap(err, "getting last commit log") - } - return logData, nil -} - -// FetchRemote gets the objects from the specified remote. It returns true as -// first argument if something has been fetched remotely. -func (r *Repo) FetchRemote(remoteName string) (bool, error) { - if remoteName == "" { - return false, errors.New("error fetching, remote repository name is empty") - } - // Verify the remote exists - remotes, err := r.Remotes() - if err != nil { - return false, errors.Wrap(err, "getting repository remotes") - } - - remoteExists := false - for _, remote := range remotes { - if remote.Name() == remoteName { - remoteExists = true - break - } - } - if !remoteExists { - return false, errors.New("cannot fetch repository, the specified remote does not exist") - } - - res, err := filterCommand(r.Dir(), "fetch", remoteName).RunSilentSuccessOutput() - if err != nil { - return false, errors.Wrapf(err, "fetching objects from %s", remoteName) - } - // git fetch outputs on stderr - output := strings.TrimSpace(res.Error()) - logrus.Debugf("Fetch result: %s", output) - return len(output) > 0, nil -} - -// Rebase calls rebase on the current repo to the specified branch -func (r *Repo) Rebase(branch string) error { - if branch == "" { - return errors.New("cannot rebase repository, branch is empty") - } - logrus.Infof("Rebasing repository to %s", branch) - _, err := r.runGitCmd("rebase", branch) - // If we get an error, try to interpret it to make more sense - if err != nil { - return errors.Wrap(err, "rebasing repository") - } - return nil -} - -// ParseRepoSlug parses a repository string and return the organization and repository name/ -func ParseRepoSlug(repoSlug string) (org, repo string, err error) { - match, err := regexp.MatchString(`(?i)^[a-z0-9-/]+$`, repoSlug) - if err != nil { - return "", "", errors.Wrap(err, "checking repository slug") - } - if !match { - return "", "", errors.New("repository slug contains invalid characters") - } - - parts := strings.Split(repoSlug, "/") - if len(parts) > 2 { - return "", "", errors.New("string is not a well formed org/repo slug") - } - org = parts[0] - if len(parts) > 1 { - repo = parts[1] - } - return org, repo, nil -} - -// NewNetworkError creates a new NetworkError -func NewNetworkError(err error) NetworkError { - gerror := NetworkError{ - error: err, - } - return gerror -} - -// NetworkError is a wrapper for the error class -type NetworkError struct { - error -} - -// CanRetry tells if an error can be retried -func (e NetworkError) CanRetry() bool { - // We consider these strings as part of errors we can retry - retryMessages := []string{ - "dial tcp", "read udp", "connection refused", - "ssh: connect to host", "Could not read from remote", - } - - // If any of them are in the error message, we consider it temporary - for _, message := range retryMessages { - if strings.Contains(e.Error(), message) { - return true - } - } - - // Otherwise permanent - return false -} diff --git a/pkg/git/git_integration_test.go b/pkg/git/git_integration_test.go deleted file mode 100644 index b7d8b63513c..00000000000 --- a/pkg/git/git_integration_test.go +++ /dev/null @@ -1,995 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package git_test - -import ( - "os" - "path/filepath" - "testing" - "time" - - "github.com/blang/semver" - gogit "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/stretchr/testify/require" - - "k8s.io/release/pkg/git" - "sigs.k8s.io/release-utils/command" - "sigs.k8s.io/release-utils/util" -) - -var testAuthor = &object.Signature{ - Name: "John Doe", - Email: "john@doe.org", - When: time.Now(), -} - -type testRepo struct { - sut *git.Repo - dir string - firstCommit string - firstBranchCommit string - secondBranchCommit string - thirdBranchCommit string - branchName string - firstTagCommit string - firstTagName string - secondTagCommit string - secondTagName string - thirdTagCommit string - thirdTagName string - testFileName string -} - -// newTestRepo creates a test repo with the following structure: -// -// * commit `thirdBranchCommit` (HEAD -> `branchName`, origin/`branchName`) -// | Author: John Doe -// | -// | Fourth commit -// | -// * commit `secondBranchCommit` (tag: `thirdTagName`, HEAD -> `branchName`, origin/`branchName`) -// | Author: John Doe -// | -// | Third commit -// | -// * commit `firstBranchCommit` (tag: `secondTagName`, HEAD -> `branchName`, origin/`branchName`) -// | Author: John Doe -// | -// | Second commit -// | -// * commit `firstCommit` (tag: `firstTagName`, origin/master, origin/HEAD, master) -// Author: John Doe -// -// First commit -// -func newTestRepo(t *testing.T) *testRepo { - // Setup the bare repo as base - bareTempDir, err := os.MkdirTemp("", "k8s-test-bare-") - require.Nil(t, err) - - bareRepo, err := gogit.PlainInit(bareTempDir, true) - require.Nil(t, err) - require.NotNil(t, bareRepo) - - // Clone from the bare to be able to add our test data - cloneTempDir, err := os.MkdirTemp("", "k8s-test-clone-") - require.Nil(t, err) - cloneRepo, err := gogit.PlainInit(cloneTempDir, false) - require.Nil(t, err) - - // Add the test data set - const testFileName = "test-file" - require.Nil(t, os.WriteFile( - filepath.Join(cloneTempDir, testFileName), - []byte("test-content"), - os.FileMode(0o644), - )) - - worktree, err := cloneRepo.Worktree() - require.Nil(t, err) - _, err = worktree.Add(testFileName) - require.Nil(t, err) - - firstCommit, err := worktree.Commit("First commit", &gogit.CommitOptions{ - Author: testAuthor, - }) - require.Nil(t, err) - - firstTagName := "v1.17.0" - firstTagRef, err := cloneRepo.CreateTag(firstTagName, firstCommit, - &gogit.CreateTagOptions{ - Tagger: testAuthor, - Message: firstTagName, - }, - ) - require.Nil(t, err) - - // Create a test branch and a test commit on top - branchName := "release-1.17" - require.Nil(t, command.NewWithWorkDir( - cloneTempDir, "git", "checkout", "-b", branchName, - ).RunSuccess()) - - const branchTestFileName = "branch-test-file" - require.Nil(t, os.WriteFile( - filepath.Join(cloneTempDir, branchTestFileName), - []byte("test-content"), - os.FileMode(0o644), - )) - _, err = worktree.Add(branchTestFileName) - require.Nil(t, err) - - firstBranchCommit, err := worktree.Commit("Second commit", &gogit.CommitOptions{ - Author: testAuthor, - All: true, - }) - require.Nil(t, err) - - secondTagName := "v0.1.1" - secondTagRef, err := cloneRepo.CreateTag(secondTagName, firstBranchCommit, - &gogit.CreateTagOptions{ - Tagger: testAuthor, - Message: secondTagName, - }, - ) - require.Nil(t, err) - - const secondBranchTestFileName = "branch-test-file-2" - require.Nil(t, os.WriteFile( - filepath.Join(cloneTempDir, secondBranchTestFileName), - []byte("test-content"), - os.FileMode(0o644), - )) - _, err = worktree.Add(secondBranchTestFileName) - require.Nil(t, err) - - secondBranchCommit, err := worktree.Commit("Third commit", &gogit.CommitOptions{ - Author: testAuthor, - All: true, - }) - require.Nil(t, err) - - thirdTagName := "v1.17.1" - thirdTagRef, err := cloneRepo.CreateTag(thirdTagName, secondBranchCommit, - &gogit.CreateTagOptions{ - Tagger: testAuthor, - Message: thirdTagName, - }, - ) - require.Nil(t, err) - - const thirdBranchTestFileName = "branch-test-file-3" - require.Nil(t, os.WriteFile( - filepath.Join(cloneTempDir, thirdBranchTestFileName), - []byte("test-content"), - os.FileMode(0o644), - )) - _, err = worktree.Add(thirdBranchTestFileName) - require.Nil(t, err) - - thirdBranchCommit, err := worktree.Commit("Fourth commit", &gogit.CommitOptions{ - Author: testAuthor, - All: true, - }) - require.Nil(t, err) - - // Push the test content into the bare repo - _, err = cloneRepo.CreateRemote(&config.RemoteConfig{ - Name: git.DefaultRemote, - URLs: []string{bareTempDir}, - }) - require.Nil(t, err) - require.Nil(t, cloneRepo.Push(&gogit.PushOptions{ - RemoteName: "origin", - RefSpecs: []config.RefSpec{"refs/*:refs/*"}, - })) - - require.Nil(t, os.RemoveAll(cloneTempDir)) - - // Provide a system under test inside the test repo - sut, err := git.CloneOrOpenRepo("", bareTempDir, false) - require.Nil(t, err) - require.Nil(t, command.NewWithWorkDir( - sut.Dir(), "git", "checkout", branchName, - ).RunSuccess()) - - return &testRepo{ - sut: sut, - dir: bareTempDir, - firstCommit: firstCommit.String(), - firstBranchCommit: firstBranchCommit.String(), - secondBranchCommit: secondBranchCommit.String(), - thirdBranchCommit: thirdBranchCommit.String(), - branchName: branchName, - firstTagName: firstTagName, - firstTagCommit: firstTagRef.Hash().String(), - secondTagName: secondTagName, - secondTagCommit: secondTagRef.Hash().String(), - thirdTagName: thirdTagName, - thirdTagCommit: thirdTagRef.Hash().String(), - testFileName: filepath.Join(sut.Dir(), testFileName), - } -} - -func (r *testRepo) cleanup(t *testing.T) { - require.Nil(t, os.RemoveAll(r.dir)) - require.Nil(t, os.RemoveAll(r.sut.Dir())) -} - -func TestSuccessCloneOrOpen(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - secondRepo, err := git.CloneOrOpenRepo(testRepo.sut.Dir(), testRepo.dir, false) - require.Nil(t, err) - - require.Equal(t, secondRepo.Dir(), testRepo.sut.Dir()) - require.Nil(t, secondRepo.Cleanup()) -} - -func TestSuccessDescribeTags(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - tag, err := testRepo.sut.Describe( - git.NewDescribeOptions(). - WithRevision(testRepo.firstTagCommit). - WithAbbrev(0). - WithTags(), - ) - require.Nil(t, err) - require.Equal(t, testRepo.firstTagName, tag) -} - -func TestFailureDescribeTags(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - _, err := testRepo.sut.Describe( - git.NewDescribeOptions(). - WithRevision("wrong"). - WithAbbrev(0). - WithTags(), - ) - require.NotNil(t, err) -} - -func TestSuccessHasRemoteBranch(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - for _, repo := range []string{testRepo.branchName, git.DefaultBranch} { - branchExists, err := testRepo.sut.HasRemoteBranch(repo) - require.Nil(t, err) - require.Equal(t, branchExists, true) - } -} - -func TestFailureHasRemoteBranch(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - // TODO: Let's simulate an actual git/network failure - - branchExists, err := testRepo.sut.HasRemoteBranch("wrong") - require.Equal(t, branchExists, false) - require.Nil(t, err) -} - -func TestSuccessHead(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - head, err := testRepo.sut.Head() - require.Nil(t, err) - require.Equal(t, testRepo.thirdBranchCommit, head) -} - -func TestSuccessMerge(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.Merge(git.DefaultBranch) - require.Nil(t, err) -} - -func TestFailureMerge(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.Merge("wrong") - require.NotNil(t, err) -} - -func TestSuccessMergeBase(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - mergeBase, err := testRepo.sut.MergeBase(git.DefaultBranch, testRepo.branchName) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit, mergeBase) -} - -func TestSuccessRevParse(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - mainRev, err := testRepo.sut.RevParse(git.DefaultBranch) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit, mainRev) - - branchRev, err := testRepo.sut.RevParse(testRepo.branchName) - require.Nil(t, err) - require.Equal(t, testRepo.thirdBranchCommit, branchRev) - - tagRev, err := testRepo.sut.RevParse(testRepo.firstTagName) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit, tagRev) - - tagRev, err = testRepo.sut.RevParse(testRepo.firstCommit) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit, tagRev) -} - -func TestSuccessRevTagParse(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - mainRev, err := testRepo.sut.RevParseTag(git.DefaultBranch) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit, mainRev) - - branchRev, err := testRepo.sut.RevParseTag(testRepo.branchName) - require.Nil(t, err) - require.Equal(t, testRepo.thirdBranchCommit, branchRev) - - tagRev, err := testRepo.sut.RevParseTag(testRepo.firstTagName) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit, tagRev) -} - -func TestFailureRevParse(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - _, err := testRepo.sut.RevParse("wrong") - require.NotNil(t, err) -} - -func TestFailureRevParseTag(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - _, err := testRepo.sut.RevParseTag("wrong") - require.NotNil(t, err) - - _, err = testRepo.sut.RevParseTag(testRepo.firstCommit) - require.NotNil(t, err) -} - -func TestSuccessRevParseShort(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - mainRev, err := testRepo.sut.RevParseShort(git.DefaultBranch) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit[:10], mainRev) - - branchRev, err := testRepo.sut.RevParseShort(testRepo.branchName) - require.Nil(t, err) - require.Equal(t, testRepo.thirdBranchCommit[:10], branchRev) - - tagRev, err := testRepo.sut.RevParseShort(testRepo.firstTagName) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit[:10], tagRev) - - tagRev, err = testRepo.sut.RevParseShort(testRepo.firstCommit) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit[:10], tagRev) -} - -func TestSuccessRevParseTagShort(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - mainRev, err := testRepo.sut.RevParseTagShort(git.DefaultBranch) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit[:10], mainRev) - - branchRev, err := testRepo.sut.RevParseTagShort(testRepo.branchName) - require.Nil(t, err) - require.Equal(t, testRepo.thirdBranchCommit[:10], branchRev) - - tagRev, err := testRepo.sut.RevParseTagShort(testRepo.firstTagName) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit[:10], tagRev) -} - -func TestFailureRevParseShort(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - _, err := testRepo.sut.RevParseShort("wrong") - require.NotNil(t, err) -} - -func TestFailureRevParseTagShort(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - _, err := testRepo.sut.RevParseTagShort("wrong") - require.NotNil(t, err) - - _, err = testRepo.sut.RevParseTagShort(testRepo.firstCommit) - require.NotNil(t, err) -} - -func TestSuccessPush(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.Push(git.DefaultBranch) - require.Nil(t, err) -} - -func TestFailurePush(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.Push("wrong") - require.NotNil(t, err) -} - -func TestSuccessRemotify(t *testing.T) { - newRemote := git.Remotify(git.DefaultBranch) - require.Equal(t, git.DefaultRemote+"/"+git.DefaultBranch, newRemote) -} - -func TestSuccessIsReleaseBranch(t *testing.T) { - require.True(t, git.IsReleaseBranch("release-1.17")) -} - -func TestFailureIsReleaseBranch(t *testing.T) { - require.False(t, git.IsReleaseBranch("wrong-branch")) -} - -func TestSuccessLatestTagForBranch(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - version, err := testRepo.sut.LatestTagForBranch(git.DefaultBranch) - require.Nil(t, err) - require.Equal(t, testRepo.firstTagName, util.SemverToTagString(version)) -} - -func TestSuccessLatestTagForBranchRelease(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - version, err := testRepo.sut.LatestTagForBranch("release-1.17") - require.Nil(t, err) - require.Equal(t, testRepo.thirdTagName, util.SemverToTagString(version)) -} - -func TestFailureLatestTagForBranchInvalidBranch(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - version, err := testRepo.sut.LatestTagForBranch("wrong-branch") - require.NotNil(t, err) - require.Equal(t, semver.Version{}, version) -} - -func TestSuccessLatestPatchToPatch(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - // This test case gets commits from v1.17.0 to v1.17.1 - result, err := testRepo.sut.LatestPatchToPatch(testRepo.branchName) - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit, result.StartSHA()) - require.Equal(t, testRepo.firstTagName, result.StartRev()) - require.Equal(t, testRepo.thirdTagName, result.EndRev()) -} - -func TestSuccessLatestPatchToPatchNewTag(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - // This test case gets commits from v1.17.1 to a new v1.17.2 - nextMinorTag := "v1.17.2" - require.Nil(t, command.NewWithWorkDir( - testRepo.sut.Dir(), "git", "tag", nextMinorTag, - ).RunSuccess()) - - result, err := testRepo.sut.LatestPatchToPatch(testRepo.branchName) - require.Nil(t, err) - require.Equal(t, testRepo.secondBranchCommit, result.StartSHA()) - require.Equal(t, testRepo.thirdTagName, result.StartRev()) - require.Equal(t, nextMinorTag, result.EndRev()) -} - -func TestFailureLatestPatchToPatchWrongBranch(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - result, err := testRepo.sut.LatestPatchToPatch("wrong-branch") - require.NotNil(t, err) - require.Equal(t, result, git.DiscoverResult{}) -} - -func TestSuccessLatestPatchToLatest(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - // This test case gets commits from v1.17.1 to head of release-1.17 - result, err := testRepo.sut.LatestPatchToLatest(testRepo.branchName) - require.Nil(t, err) - require.Equal(t, testRepo.secondBranchCommit, result.StartSHA()) - require.Equal(t, testRepo.thirdTagName, result.StartRev()) - require.Equal(t, testRepo.thirdBranchCommit, result.EndSHA()) -} - -func TestSuccessDry(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - testRepo.sut.SetDry() - - err := testRepo.sut.Push(git.DefaultBranch) - require.Nil(t, err) -} - -func TestSuccessLatestReleaseBranchMergeBaseToLatest(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - result, err := testRepo.sut.LatestReleaseBranchMergeBaseToLatest() - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit, result.StartSHA()) - require.Equal(t, testRepo.firstTagName, result.StartRev()) - require.Equal(t, testRepo.firstCommit, result.EndSHA()) - require.Equal(t, git.DefaultBranch, result.EndRev()) -} - -func TestFailureLatestReleaseBranchMergeBaseToLatestNoLatestTag(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - require.Nil(t, command.NewWithWorkDir( - testRepo.sut.Dir(), "git", "tag", "-d", testRepo.firstTagName, - ).RunSuccess()) - - result, err := testRepo.sut.LatestReleaseBranchMergeBaseToLatest() - require.NotNil(t, err) - require.Equal(t, result, git.DiscoverResult{}) -} - -func TestSuccessLatestNonPatchFinalToMinor(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - nextMinorTag := "v1.18.0" - require.Nil(t, command.NewWithWorkDir( - testRepo.sut.Dir(), "git", "tag", nextMinorTag, - ).RunSuccess()) - - result, err := testRepo.sut.LatestNonPatchFinalToMinor() - require.Nil(t, err) - require.Equal(t, testRepo.firstCommit, result.StartSHA()) - require.Equal(t, testRepo.firstTagName, result.StartRev()) - require.Equal(t, nextMinorTag, result.EndRev()) -} - -func TestFailureLatestNonPatchFinalToMinor(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - result, err := testRepo.sut.LatestNonPatchFinalToMinor() - require.NotNil(t, err) - require.Equal(t, result, git.DiscoverResult{}) -} - -func TestTagsForBranchMain(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - result, err := testRepo.sut.TagsForBranch(git.DefaultBranch) - require.Nil(t, err) - require.Equal(t, []string{testRepo.firstTagName}, result) -} - -func TestTagsForBranchOnBranch(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - result, err := testRepo.sut.TagsForBranch(testRepo.branchName) - require.Nil(t, err) - require.Equal(t, []string{ - testRepo.thirdTagName, - testRepo.firstTagName, - testRepo.secondTagName, - }, result) -} - -func TestTagsForBranchFailureWrongBranch(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - result, err := testRepo.sut.TagsForBranch("wrong-branch") - require.NotNil(t, err) - require.Nil(t, result) -} - -func TestCheckoutSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - require.Nil(t, os.WriteFile( - testRepo.testFileName, - []byte("hello world"), - os.FileMode(0o644), - )) - res, err := command.NewWithWorkDir( - testRepo.sut.Dir(), "git", "diff", "--name-only").Run() - require.Nil(t, err) - require.True(t, res.Success()) - require.Contains(t, res.Output(), filepath.Base(testRepo.testFileName)) - - err = testRepo.sut.Checkout(git.DefaultBranch, testRepo.testFileName) - require.Nil(t, err) - - res, err = command.NewWithWorkDir( - testRepo.sut.Dir(), "git", "diff", "--name-only").Run() - require.Nil(t, err) - require.True(t, res.Success()) - require.Empty(t, res.Output()) -} - -func TestCheckoutFailureWrongRevision(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.Checkout("wrong") - require.NotNil(t, err) - require.Contains(t, err.Error(), "checkout wrong did not succeed") -} - -func TestAddSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - f, err := os.CreateTemp(testRepo.sut.Dir(), "test") - require.Nil(t, err) - require.Nil(t, f.Close()) - - filename := filepath.Base(f.Name()) - err = testRepo.sut.Add(filename) - require.Nil(t, err) - - res, err := command.NewWithWorkDir( - testRepo.sut.Dir(), "git", "diff", "--cached", "--name-only").Run() - require.Nil(t, err) - require.True(t, res.Success()) - require.Contains(t, res.Output(), filename) -} - -func TestAddFailureWrongPath(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.Add("wrong") - require.NotNil(t, err) - require.Contains(t, err.Error(), "adding file wrong to repository") -} - -func TestCommitSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - commitMessage := "My commit message for this test" - err := testRepo.sut.Commit(commitMessage) - require.Nil(t, err) - - res, err := command.NewWithWorkDir( - testRepo.sut.Dir(), "git", "log", "-1", - ).Run() - require.Nil(t, err) - require.True(t, res.Success()) - require.Contains(t, res.Output(), "Author: Anago GCB ") - require.Contains(t, res.Output(), commitMessage) -} - -func TestCurrentBranchDefault(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - branch, err := testRepo.sut.CurrentBranch() - require.Nil(t, err) - require.Equal(t, branch, testRepo.branchName) -} - -func TestCurrentBranchMain(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - require.Nil(t, testRepo.sut.Checkout(git.DefaultBranch)) - - branch, err := testRepo.sut.CurrentBranch() - require.Nil(t, err) - require.Equal(t, branch, git.DefaultBranch) -} - -func TestRmSuccessForce(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - require.Nil(t, os.WriteFile(testRepo.testFileName, - []byte("test"), os.FileMode(0o755)), - ) - - require.Nil(t, testRepo.sut.Rm(true, testRepo.testFileName)) - - _, err := os.Stat(testRepo.testFileName) - require.True(t, os.IsNotExist(err)) -} - -func TestHasRemoteSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.AddRemote("test", "owner", "repo") - require.Nil(t, err) - - remotes, err := testRepo.sut.Remotes() - require.Nil(t, err) - - require.Len(t, remotes, 2) - - // The origin remote - require.Equal(t, remotes[0].Name(), git.DefaultRemote) - require.Len(t, remotes[0].URLs(), 1) - require.Equal(t, remotes[0].URLs()[0], testRepo.dir) - - // Or via the API - require.True(t, testRepo.sut.HasRemote("origin", testRepo.dir)) - - // The added test remote - require.Equal(t, remotes[1].Name(), "test") - require.Len(t, remotes[1].URLs(), 1) - - url := git.GetRepoURL("owner", "repo", true) - require.Equal(t, remotes[1].URLs()[0], url) - - // Or via the API - require.True(t, testRepo.sut.HasRemote("test", url)) -} - -func TestHasRemoteFailure(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - require.False(t, testRepo.sut.HasRemote("name", "some-url.com")) -} - -func TestRmFailureForce(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - require.NotNil(t, testRepo.sut.Rm(true, "invalid")) -} - -func TestRmSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - require.Nil(t, testRepo.sut.Rm(true, testRepo.testFileName)) - - _, err := os.Stat(testRepo.testFileName) - require.True(t, os.IsNotExist(err)) -} - -func TestRmFailureModified(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - require.Nil(t, os.WriteFile(testRepo.testFileName, - []byte("test"), os.FileMode(0o755)), - ) - require.NotNil(t, testRepo.sut.Rm(false, testRepo.testFileName)) -} - -func TestOpenRepoSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - repo, err := git.OpenRepo(testRepo.sut.Dir()) - require.Nil(t, err) - require.Equal(t, repo.Dir(), testRepo.sut.Dir()) -} - -func TestOpenRepoSuccessSearchGitDot(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - repo, err := git.OpenRepo(filepath.Join(testRepo.sut.Dir(), "not-existing")) - require.Nil(t, err) - require.Equal(t, repo.Dir(), testRepo.sut.Dir()) -} - -func TestOpenRepoFailure(t *testing.T) { - repo, err := git.OpenRepo("/invalid") - require.NotNil(t, err) - require.Nil(t, repo) -} - -func TestAddRemoteSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.AddRemote("remote", "owner", "repo") - require.Nil(t, err) -} - -func TestAddRemoteFailureAlreadyExisting(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.AddRemote(git.DefaultRemote, "owner", "repo") - require.NotNil(t, err) -} - -func TestPushToRemoteSuccessRemoteMain(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.PushToRemote(git.DefaultRemote, git.Remotify(git.DefaultBranch)) - require.Nil(t, err) -} - -func TestPushToRemoteSuccessBranchTracked(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.PushToRemote(git.DefaultRemote, testRepo.branchName) - require.Nil(t, err) -} - -func TestPushToRemoteFailureBranchNotExisting(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - err := testRepo.sut.PushToRemote(git.DefaultRemote, "some-branch") - require.NotNil(t, err) -} - -func TestLSRemoteSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - res, err := testRepo.sut.LsRemote() - require.Nil(t, err) - require.Contains(t, res, testRepo.firstCommit) - require.Contains(t, res, testRepo.secondBranchCommit) - require.Contains(t, res, testRepo.thirdBranchCommit) -} - -func TestLSRemoteFailure(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - res, err := testRepo.sut.LsRemote("invalid") - require.NotNil(t, err) - require.Empty(t, res) -} - -func TestBranchSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - res, err := testRepo.sut.Branch() - require.Nil(t, err) - require.Contains(t, res, testRepo.branchName) -} - -func TestBranchFailure(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - res, err := testRepo.sut.Branch("--invalid") - require.NotNil(t, err) - require.Empty(t, res) -} - -func TestIsDirtySuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - dirty, err := testRepo.sut.IsDirty() - require.Nil(t, err) - require.False(t, dirty) -} - -func TestIsDirtyFailure(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - require.Nil(t, os.WriteFile( - filepath.Join(testRepo.sut.Dir(), "any-file"), - []byte("test"), os.FileMode(0o755)), - ) - - dirty, err := testRepo.sut.IsDirty() - require.Nil(t, err) - require.True(t, dirty) -} - -func TestSetURLSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - const remote = "https://exmaple.com" - require.Nil(t, testRepo.sut.SetURL(git.DefaultRemote, remote)) - remotes, err := testRepo.sut.Remotes() - require.Nil(t, err) - require.Len(t, remotes, 1) - require.Equal(t, git.DefaultRemote, remotes[0].Name()) - require.Len(t, remotes[0].URLs(), 1) - require.Equal(t, remotes[0].URLs()[0], remote) -} - -func TestSetURLFailureRemoteDoesNotExists(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - require.NotNil(t, testRepo.sut.SetURL("some-remote", "")) -} - -func TestAllTags(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - tags, err := testRepo.sut.Tags() - require.Nil(t, err) - require.Len(t, tags, 3) - require.Equal(t, tags[0], testRepo.secondTagName) - require.Equal(t, tags[1], testRepo.firstTagName) - require.Equal(t, tags[2], testRepo.thirdTagName) -} - -func TestCommitEmptySuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - commitMessage := "This is an empty commit" - require.Nil(t, testRepo.sut.CommitEmpty(commitMessage)) - res, err := command.NewWithWorkDir( - testRepo.sut.Dir(), "git", "log", "-1", - ).Run() - require.Nil(t, err) - require.True(t, res.Success()) - require.Contains(t, res.Output(), commitMessage) -} - -func TestTagSuccess(t *testing.T) { - testRepo := newTestRepo(t) - defer testRepo.cleanup(t) - - testTag := "testTag" - require.Nil(t, testRepo.sut.Tag(testTag, "message")) - tags, err := testRepo.sut.TagsForBranch(testRepo.branchName) - require.Nil(t, err) - require.Contains(t, tags, testTag) -} diff --git a/pkg/git/git_test.go b/pkg/git/git_test.go deleted file mode 100644 index 9bba46d2096..00000000000 --- a/pkg/git/git_test.go +++ /dev/null @@ -1,578 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package git_test - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - "testing" - "time" - - gogit "github.com/go-git/go-git/v5" - "github.com/pkg/errors" - "github.com/stretchr/testify/require" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/git/gitfakes" - "sigs.k8s.io/release-utils/command" -) - -func newSUT() (*git.Repo, *gitfakes.FakeWorktree) { - repoMock := &gitfakes.FakeRepository{} - worktreeMock := &gitfakes.FakeWorktree{} - - repo := &git.Repo{} - repo.SetWorktree(worktreeMock) - repo.SetInnerRepo(repoMock) - - return repo, worktreeMock -} - -func TestCommit(t *testing.T) { - repo, worktreeMock := newSUT() - require.Nil(t, repo.Commit("msg")) - require.Equal(t, worktreeMock.CommitCallCount(), 1) -} - -func TestGetDefaultKubernetesRepoURLSuccess(t *testing.T) { - testcases := []struct { - name string - org string - useSSH bool - expected string - }{ - { - name: "default HTTPS", - expected: "https://github.com/kubernetes/kubernetes", - }, - } - - for _, tc := range testcases { - t.Logf("Test case: %s", tc.name) - - actual := git.GetDefaultKubernetesRepoURL() - require.Equal(t, tc.expected, actual) - } -} - -// createTestRepository creates a test repo, cd into it and returns the path -func createTestRepository() (repoPath string, err error) { - repoPath, err = os.MkdirTemp("", "sigrelease-test-repo-*") - if err != nil { - return "", errors.Wrap(err, "creating a directory for test repository") - } - if err := os.Chdir(repoPath); err != nil { - return "", errors.Wrap(err, "cd'ing into test repository") - } - out, err := exec.Command("git", "init").Output() - if err != nil { - return "", errors.Wrapf(err, "initializing test repository: %s", out) - } - return repoPath, nil -} - -func TestGetUserName(t *testing.T) { - const fakeUserName = "SIG Release Test User" - currentDir, err := os.Getwd() - require.Nil(t, err, "error reading the current directory") - defer os.Chdir(currentDir) // nolint: errcheck - - // Create an empty repo and configure the users name to test - repoPath, err := createTestRepository() - require.Nil(t, err, "getting a test repo") - - // Call git to configure the user's name: - _, err = exec.Command("git", "config", "user.name", fakeUserName).Output() - require.Nil(t, err, fmt.Sprintf("configuring fake user email in %s", repoPath)) - - testRepo, err := git.OpenRepo(repoPath) - require.Nil(t, err, fmt.Sprintf("opening test repo in %s", repoPath)) - defer testRepo.Cleanup() // nolint: errcheck - - actual, err := git.GetUserName() - require.Nil(t, err) - require.Equal(t, fakeUserName, actual) - require.NotEqual(t, fakeUserName, "") -} - -func TestGetUserEmail(t *testing.T) { - const fakeUserEmail = "kubernetes-test@example.com" - currentDir, err := os.Getwd() - require.Nil(t, err, "error reading the current directory") - defer os.Chdir(currentDir) // nolint: errcheck - - // Create an empty repo and configure the users name to test - repoPath, err := createTestRepository() - require.Nil(t, err, "getting a test repo") - - // Call git to configure the user's name: - _, err = exec.Command("git", "config", "user.email", fakeUserEmail).Output() - require.Nil(t, err, fmt.Sprintf("configuring fake user email in %s", repoPath)) - - testRepo, err := git.OpenRepo(repoPath) - require.Nil(t, err, fmt.Sprintf("opening test repo in %s", repoPath)) - defer testRepo.Cleanup() // nolint: errcheck - - // Do the actual call - actual, err := git.GetUserEmail() - require.Nil(t, err) - require.Equal(t, fakeUserEmail, actual) - require.NotEqual(t, fakeUserEmail, "") -} - -func TestGetKubernetesRepoURLSuccess(t *testing.T) { - testcases := []struct { - name string - org string - useSSH bool - expected string - }{ - { - name: "default HTTPS", - expected: "https://github.com/kubernetes/kubernetes", - }, - { - name: "ssh with custom org", - org: "fake-org", - useSSH: true, - expected: "git@github.com:fake-org/kubernetes", - }, - } - - for _, tc := range testcases { - t.Logf("Test case: %s", tc.name) - - actual := git.GetKubernetesRepoURL(tc.org, tc.useSSH) - require.Equal(t, tc.expected, actual) - } -} - -func TestGetRepoURLSuccess(t *testing.T) { - testcases := []struct { - name string - org string - repo string - useSSH bool - expected string - }{ - { - name: "default Kubernetes HTTPS", - org: "kubernetes", - repo: "kubernetes", - expected: "https://github.com/kubernetes/kubernetes", - }, - { - name: "ssh with custom org", - org: "fake-org", - repo: "repofoo", - useSSH: true, - expected: "git@github.com:fake-org/repofoo", - }, - } - - for _, tc := range testcases { - t.Logf("Test case: %s", tc.name) - - actual := git.GetRepoURL(tc.org, tc.repo, tc.useSSH) - require.Equal(t, tc.expected, actual) - } -} - -func TestRemotify(t *testing.T) { - testcases := []struct{ provided, expected string }{ - {provided: git.DefaultBranch, expected: git.DefaultRemote + "/" + git.DefaultBranch}, - {provided: "origin/ref", expected: "origin/ref"}, - {provided: "base/another_ref", expected: "base/another_ref"}, - } - - for _, tc := range testcases { - require.Equal(t, git.Remotify(tc.provided), tc.expected) - } -} - -func TestIsDirtyMockSuccess(t *testing.T) { - repo, _ := newSUT() - - dirty, err := repo.IsDirty() - - require.Nil(t, err) - require.False(t, dirty) -} - -func TestIsDirtyMockSuccessDirty(t *testing.T) { - repo, worktreeMock := newSUT() - worktreeMock.StatusReturns(gogit.Status{ - "file": &gogit.FileStatus{ - Worktree: gogit.Modified, - }, - }, nil) - - dirty, err := repo.IsDirty() - - require.Nil(t, err) - require.True(t, dirty) -} - -func TestIsDirtyMockFailureWorktreeStatus(t *testing.T) { - repo, worktreeMock := newSUT() - worktreeMock.StatusReturns(gogit.Status{}, errors.New("")) - - dirty, err := repo.IsDirty() - - require.NotNil(t, err) - require.False(t, dirty) -} - -func TestParseRepoSlug(t *testing.T) { - slugTests := []struct { - caseName, repoSlug, orgName, repoName string - isValid bool - }{ - { - caseName: "valid slug", repoSlug: "kubernetes/release", - orgName: "kubernetes", repoName: "release", isValid: true, - }, - - { - caseName: "slug with hyphens", repoSlug: "kubernetes/repo_with_underscores", - orgName: "", repoName: "", isValid: false, - }, - - { - caseName: "slug with dashes", repoSlug: "kubernetes-sigs/release-notes", - orgName: "kubernetes-sigs", repoName: "release-notes", isValid: true, - }, - - { - caseName: "slug with uppercase", repoSlug: "GoogleCloudPlatform/compute-image-tools", - orgName: "GoogleCloudPlatform", repoName: "compute-image-tools", isValid: true, - }, - - { - caseName: "slug with invalid chars", repoSlug: "kubern#etes/not.valid", - orgName: "", repoName: "", isValid: false, - }, - - { - caseName: "slug with extra slash", repoSlug: "kubernetes/not/valid", - orgName: "", repoName: "", isValid: false, - }, - - { - caseName: "slug with only org", repoSlug: "kubernetes", - orgName: "kubernetes", repoName: "", isValid: true, - }, - } - - for _, testCase := range slugTests { - org, repo, err := git.ParseRepoSlug(testCase.repoSlug) - if testCase.isValid { - require.Nil(t, err, testCase.caseName) - } else { - require.NotNil(t, err, testCase.caseName) - } - require.Equal(t, testCase.orgName, org, testCase.caseName) - require.Equal(t, testCase.repoName, repo, testCase.caseName) - } -} - -func TestRetryErrors(t *testing.T) { - retryErrorStrings := []string{ - "dial tcp: lookup github.com on [::1]:53", - "read udp [::1]:48087->[::1]:53", - "read: connection refused", - } - - nonRetryErrorStrings := []string{ - "could not list references on the remote repository", - "error checking remote branch", - "src refspec release-chorizo does not match", - } - - for _, message := range retryErrorStrings { - err := git.NewNetworkError(errors.New(message)) - require.True(t, err.CanRetry(), fmt.Sprintf("Checking retriable error '%s'", message)) - } - - for _, message := range nonRetryErrorStrings { - err := git.NewNetworkError(errors.New(message)) - require.False(t, err.CanRetry(), fmt.Sprintf("Checking non-retriable error '%s'", message)) - } -} - -func TestNetworkError(t *testing.T) { - // Return a NetWorkError in a fun that returns a standard error - err := func() error { - return git.NewNetworkError(errors.New("This is a test error")) - }() - require.NotNil(t, err, "checking if NewNetWork error returns nil") - require.NotEmpty(t, err.Error(), "checking if NetworkError returns a message") - require.False(t, err.(git.NetworkError).CanRetry(), "checking if network error can be properly asserted") -} - -func TestHasBranch(t *testing.T) { - testBranchName := "git-package-test-branch" - repoPath, err := createTestRepository() - require.Nil(t, err, "getting a test repo") - - // Create a file and a test commit - testfile := filepath.Join(repoPath, "README.md") - err = os.WriteFile(testfile, []byte("# WHY SIG-RELEASE ROCKS\n\n"), os.FileMode(0o644)) - require.Nil(t, err, "writing test file") - - err = command.NewWithWorkDir(repoPath, "git", "add", testfile).RunSuccess() - require.Nil(t, err, fmt.Sprintf("adding test file in %s", repoPath)) - - err = command.NewWithWorkDir(repoPath, "git", "commit", "-m", "adding test file").RunSuccess() - require.Nil(t, err, "creating first commit") - - // Call git to configure the user's name: - err = command.NewWithWorkDir(repoPath, "git", "branch", testBranchName).RunSuccess() - require.Nil(t, err, fmt.Sprintf("configuring test branch in %s", repoPath)) - - // Now, open the repo and test to see if branches are there - testRepo, err := git.OpenRepo(repoPath) - require.Nil(t, err, fmt.Sprintf("opening test repo in %s", repoPath)) - defer testRepo.Cleanup() // nolint: errcheck - - actual, err := testRepo.HasBranch(testBranchName) - require.Nil(t, err) - require.True(t, actual) - - actual, err = testRepo.HasBranch(git.DefaultBranch) - require.Nil(t, err) - require.True(t, actual) - - actual, err = testRepo.HasBranch("non-existing-branch") - require.Nil(t, err) - require.False(t, actual) -} - -func TestStatus(t *testing.T) { - rawRepoDir, err := os.MkdirTemp("", "k8s-test-repo") - require.Nil(t, err) - _, err = gogit.PlainInit(rawRepoDir, false) - require.Nil(t, err) - - testFile := "test-status.txt" - - testRepo, err := git.OpenRepo(rawRepoDir) - require.Nil(t, err) - defer testRepo.Cleanup() // nolint: errcheck - - // Get the status object - status, err := testRepo.Status() - require.Nil(t, err) - require.NotNil(t, status) - require.True(t, status.IsClean()) - - // Create an untracked file - require.Nil(t, os.WriteFile(filepath.Join(testRepo.Dir(), testFile), []byte("Hello SIG Release"), 0o644)) - - // Status should be modified now - status, err = testRepo.Status() - require.Nil(t, err) - require.Equal(t, fmt.Sprintf("?? %s\n", testFile), status.String()) - - // Add the file, should status should be A - require.Nil(t, testRepo.Add(testFile)) - status, err = testRepo.Status() - require.Nil(t, err) - require.Equal(t, fmt.Sprintf("A %s\n", testFile), status.String()) - - // Commit the file, status should be blank again - require.Nil(t, testRepo.Commit("Commit test file")) - status, err = testRepo.Status() - require.Nil(t, err) - require.Empty(t, status.String()) - - // Modify the file - require.Nil(t, os.WriteFile(filepath.Join(testRepo.Dir(), testFile), []byte("Bye SIG Release"), 0o644)) - status, err = testRepo.Status() - require.Nil(t, err) - require.Equal(t, fmt.Sprintf(" M %s\n", testFile), status.String()) -} - -func TestShowLastCommit(t *testing.T) { - rawRepoDir, err := os.MkdirTemp("", "k8s-test-repo") - require.Nil(t, err) - _, err = gogit.PlainInit(rawRepoDir, false) - require.Nil(t, err) - - testFile := "test-last-commit.txt" - timeNow := strconv.FormatInt(time.Now().UnixNano(), 10) - - testRepo, err := git.OpenRepo(rawRepoDir) - require.Nil(t, err) - defer testRepo.Cleanup() // nolint: errcheck - - // Create an untracked file - require.Nil(t, os.WriteFile(filepath.Join(testRepo.Dir(), testFile), []byte("Hello SIG Release"), 0o644)) - require.Nil(t, testRepo.Add(testFile)) - require.Nil(t, testRepo.Commit(fmt.Sprintf("Commit test file at %s", timeNow))) - - // Now get the log message back and check if it contains the time - lastLog, err := testRepo.ShowLastCommit() - require.Nil(t, err) - require.NotEmpty(t, lastLog) - require.True(t, strings.Contains(lastLog, timeNow)) -} - -func TestFetchRemote(t *testing.T) { - testTagName := "test-tag" + strconv.FormatInt(time.Now().UnixNano(), 10) - // Create a new empty repo - rawRepoDir, err := os.MkdirTemp("", "k8s-test-repo") - require.Nil(t, err) - gogitRepo, err := gogit.PlainInit(rawRepoDir, false) - require.Nil(t, err) - - // Create the foirst commit - wtree, err := gogitRepo.Worktree() - require.Nil(t, err) - require.Nil(t, err) - commitSha, err := wtree.Commit("Initial Commit", &gogit.CommitOptions{ - Author: testAuthor, - }) - require.Nil(t, err) - - // Create a git.Repo from it - originRepo, err := git.OpenRepo(rawRepoDir) - require.Nil(t, err) - - branchName, err := originRepo.CurrentBranch() - require.Nil(t, err) - defer originRepo.Cleanup() // nolint: errcheck - - // Create a new clone of the original repo - testRepo, err := git.CloneOrOpenRepo("", rawRepoDir, false) - require.Nil(t, err) - defer testRepo.Cleanup() // nolint: errcheck - - // The initial clone must not have any tags - testTags, err := testRepo.TagsForBranch(branchName) - require.Nil(t, err) - require.Empty(t, testTags) - - // Create a tag on the originRepo - _, err = gogitRepo.CreateTag(testTagName, commitSha, &gogit.CreateTagOptions{ - Message: testTagName, - Tagger: testAuthor, - }) - require.Nil(t, err) - - // Now, call fetch - newContent, err := testRepo.FetchRemote("origin") - require.Nil(t, err, "Calling fetch to get a test tag") - require.True(t, newContent) - - // Fetching again should provide no updates - newContent, err = testRepo.FetchRemote("origin") - require.Nil(t, err, "Calling fetch to get a test tag again") - require.False(t, newContent) - - // And now we can verify the tags was successfully transferred via FetchRemote() - testTags, err = testRepo.TagsForBranch(branchName) - require.Nil(t, err) - require.NotEmpty(t, testTags) - require.ElementsMatch(t, []string{testTagName}, testTags) -} - -func TestRebase(t *testing.T) { - testFile := "test-rebase.txt" - - // Create a new empty repo - rawRepoDir, err := os.MkdirTemp("", "k8s-test-repo") - require.Nil(t, err) - gogitRepo, err := gogit.PlainInit(rawRepoDir, false) - require.Nil(t, err) - - // Create the initial commit - wtree, err := gogitRepo.Worktree() - require.Nil(t, err) - _, err = wtree.Commit("Initial Commit", &gogit.CommitOptions{ - Author: testAuthor, - }) - require.Nil(t, err) - - // Create a git.Repo from it - originRepo, err := git.OpenRepo(rawRepoDir) - require.Nil(t, err) - - branchName, err := originRepo.CurrentBranch() - require.Nil(t, err) - defer originRepo.Cleanup() // nolint: errcheck - - // Create a new clone of the original repo - testRepo, err := git.CloneOrOpenRepo("", rawRepoDir, false) - require.Nil(t, err) - defer testRepo.Cleanup() // nolint: errcheck - - // Test 1. Rebase should not fail if both repos are in sync - require.Nil(t, testRepo.Rebase(fmt.Sprintf("origin/%s", branchName)), "cloning synchronizaed repos") - - // Test 2. Rebase should not fail with pulling changes in the remote - require.Nil(t, os.WriteFile(filepath.Join(rawRepoDir, testFile), []byte("Hello SIG Release"), 0o644)) - _, err = wtree.Add(testFile) - require.Nil(t, err) - - _, err = wtree.Commit("Test2-Commit", &gogit.CommitOptions{ - Author: testAuthor, - }) - require.Nil(t, err) - - // Pull the changes to the test repo - newContent, err := testRepo.FetchRemote("origin") - require.Nil(t, err) - require.True(t, newContent) - - // Do the Rebase - require.Nil(t, testRepo.Rebase(fmt.Sprintf("origin/%s", branchName)), "rebasing changes from origin") - - // Verify we got the commit - lastLog, err := testRepo.ShowLastCommit() - require.Nil(t, err) - require.True(t, strings.Contains(lastLog, "Test2-Commit")) - - // Test 3: Rebase must on an invalid branch - require.NotNil(t, testRepo.Rebase("origin/invalidBranch"), "rebasing to invalid branch") - - // Test 4: Rebase must fail on merge conflicts - require.Nil(t, os.WriteFile(filepath.Join(rawRepoDir, testFile), []byte("Hello again SIG Release"), 0o644)) - _, err = wtree.Add(testFile) - require.Nil(t, err) - - _, err = wtree.Commit("Test4-Commit", &gogit.CommitOptions{ - Author: testAuthor, - }) - require.Nil(t, err) - - // Commit the same file in the test repo - require.Nil(t, os.WriteFile(filepath.Join(testRepo.Dir(), testFile), []byte("Conflict me!"), 0o644)) - require.Nil(t, testRepo.Add(filepath.Join(testRepo.Dir(), testFile))) - require.Nil(t, testRepo.Commit("Adding file to cause conflict")) - - // Now, fetch and rebase - newContent, err = testRepo.FetchRemote("origin") - require.Nil(t, err) - require.True(t, newContent) - - err = testRepo.Rebase(fmt.Sprintf("origin/%s", branchName)) - require.NotNil(t, err, "testing for merge conflicts") -} diff --git a/pkg/git/gitfakes/fake_repository.go b/pkg/git/gitfakes/fake_repository.go deleted file mode 100644 index 65066d7d8e0..00000000000 --- a/pkg/git/gitfakes/fake_repository.go +++ /dev/null @@ -1,811 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by counterfeiter. DO NOT EDIT. -package gitfakes - -import ( - "sync" - - gita "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/storer" - "k8s.io/release/pkg/git" -) - -type FakeRepository struct { - BranchesStub func() (storer.ReferenceIter, error) - branchesMutex sync.RWMutex - branchesArgsForCall []struct { - } - branchesReturns struct { - result1 storer.ReferenceIter - result2 error - } - branchesReturnsOnCall map[int]struct { - result1 storer.ReferenceIter - result2 error - } - CommitObjectStub func(plumbing.Hash) (*object.Commit, error) - commitObjectMutex sync.RWMutex - commitObjectArgsForCall []struct { - arg1 plumbing.Hash - } - commitObjectReturns struct { - result1 *object.Commit - result2 error - } - commitObjectReturnsOnCall map[int]struct { - result1 *object.Commit - result2 error - } - CreateRemoteStub func(*config.RemoteConfig) (*gita.Remote, error) - createRemoteMutex sync.RWMutex - createRemoteArgsForCall []struct { - arg1 *config.RemoteConfig - } - createRemoteReturns struct { - result1 *gita.Remote - result2 error - } - createRemoteReturnsOnCall map[int]struct { - result1 *gita.Remote - result2 error - } - CreateTagStub func(string, plumbing.Hash, *gita.CreateTagOptions) (*plumbing.Reference, error) - createTagMutex sync.RWMutex - createTagArgsForCall []struct { - arg1 string - arg2 plumbing.Hash - arg3 *gita.CreateTagOptions - } - createTagReturns struct { - result1 *plumbing.Reference - result2 error - } - createTagReturnsOnCall map[int]struct { - result1 *plumbing.Reference - result2 error - } - DeleteRemoteStub func(string) error - deleteRemoteMutex sync.RWMutex - deleteRemoteArgsForCall []struct { - arg1 string - } - deleteRemoteReturns struct { - result1 error - } - deleteRemoteReturnsOnCall map[int]struct { - result1 error - } - HeadStub func() (*plumbing.Reference, error) - headMutex sync.RWMutex - headArgsForCall []struct { - } - headReturns struct { - result1 *plumbing.Reference - result2 error - } - headReturnsOnCall map[int]struct { - result1 *plumbing.Reference - result2 error - } - RemoteStub func(string) (*gita.Remote, error) - remoteMutex sync.RWMutex - remoteArgsForCall []struct { - arg1 string - } - remoteReturns struct { - result1 *gita.Remote - result2 error - } - remoteReturnsOnCall map[int]struct { - result1 *gita.Remote - result2 error - } - RemotesStub func() ([]*gita.Remote, error) - remotesMutex sync.RWMutex - remotesArgsForCall []struct { - } - remotesReturns struct { - result1 []*gita.Remote - result2 error - } - remotesReturnsOnCall map[int]struct { - result1 []*gita.Remote - result2 error - } - ResolveRevisionStub func(plumbing.Revision) (*plumbing.Hash, error) - resolveRevisionMutex sync.RWMutex - resolveRevisionArgsForCall []struct { - arg1 plumbing.Revision - } - resolveRevisionReturns struct { - result1 *plumbing.Hash - result2 error - } - resolveRevisionReturnsOnCall map[int]struct { - result1 *plumbing.Hash - result2 error - } - TagsStub func() (storer.ReferenceIter, error) - tagsMutex sync.RWMutex - tagsArgsForCall []struct { - } - tagsReturns struct { - result1 storer.ReferenceIter - result2 error - } - tagsReturnsOnCall map[int]struct { - result1 storer.ReferenceIter - result2 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeRepository) Branches() (storer.ReferenceIter, error) { - fake.branchesMutex.Lock() - ret, specificReturn := fake.branchesReturnsOnCall[len(fake.branchesArgsForCall)] - fake.branchesArgsForCall = append(fake.branchesArgsForCall, struct { - }{}) - stub := fake.BranchesStub - fakeReturns := fake.branchesReturns - fake.recordInvocation("Branches", []interface{}{}) - fake.branchesMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeRepository) BranchesCallCount() int { - fake.branchesMutex.RLock() - defer fake.branchesMutex.RUnlock() - return len(fake.branchesArgsForCall) -} - -func (fake *FakeRepository) BranchesCalls(stub func() (storer.ReferenceIter, error)) { - fake.branchesMutex.Lock() - defer fake.branchesMutex.Unlock() - fake.BranchesStub = stub -} - -func (fake *FakeRepository) BranchesReturns(result1 storer.ReferenceIter, result2 error) { - fake.branchesMutex.Lock() - defer fake.branchesMutex.Unlock() - fake.BranchesStub = nil - fake.branchesReturns = struct { - result1 storer.ReferenceIter - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) BranchesReturnsOnCall(i int, result1 storer.ReferenceIter, result2 error) { - fake.branchesMutex.Lock() - defer fake.branchesMutex.Unlock() - fake.BranchesStub = nil - if fake.branchesReturnsOnCall == nil { - fake.branchesReturnsOnCall = make(map[int]struct { - result1 storer.ReferenceIter - result2 error - }) - } - fake.branchesReturnsOnCall[i] = struct { - result1 storer.ReferenceIter - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) CommitObject(arg1 plumbing.Hash) (*object.Commit, error) { - fake.commitObjectMutex.Lock() - ret, specificReturn := fake.commitObjectReturnsOnCall[len(fake.commitObjectArgsForCall)] - fake.commitObjectArgsForCall = append(fake.commitObjectArgsForCall, struct { - arg1 plumbing.Hash - }{arg1}) - stub := fake.CommitObjectStub - fakeReturns := fake.commitObjectReturns - fake.recordInvocation("CommitObject", []interface{}{arg1}) - fake.commitObjectMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeRepository) CommitObjectCallCount() int { - fake.commitObjectMutex.RLock() - defer fake.commitObjectMutex.RUnlock() - return len(fake.commitObjectArgsForCall) -} - -func (fake *FakeRepository) CommitObjectCalls(stub func(plumbing.Hash) (*object.Commit, error)) { - fake.commitObjectMutex.Lock() - defer fake.commitObjectMutex.Unlock() - fake.CommitObjectStub = stub -} - -func (fake *FakeRepository) CommitObjectArgsForCall(i int) plumbing.Hash { - fake.commitObjectMutex.RLock() - defer fake.commitObjectMutex.RUnlock() - argsForCall := fake.commitObjectArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeRepository) CommitObjectReturns(result1 *object.Commit, result2 error) { - fake.commitObjectMutex.Lock() - defer fake.commitObjectMutex.Unlock() - fake.CommitObjectStub = nil - fake.commitObjectReturns = struct { - result1 *object.Commit - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) CommitObjectReturnsOnCall(i int, result1 *object.Commit, result2 error) { - fake.commitObjectMutex.Lock() - defer fake.commitObjectMutex.Unlock() - fake.CommitObjectStub = nil - if fake.commitObjectReturnsOnCall == nil { - fake.commitObjectReturnsOnCall = make(map[int]struct { - result1 *object.Commit - result2 error - }) - } - fake.commitObjectReturnsOnCall[i] = struct { - result1 *object.Commit - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) CreateRemote(arg1 *config.RemoteConfig) (*gita.Remote, error) { - fake.createRemoteMutex.Lock() - ret, specificReturn := fake.createRemoteReturnsOnCall[len(fake.createRemoteArgsForCall)] - fake.createRemoteArgsForCall = append(fake.createRemoteArgsForCall, struct { - arg1 *config.RemoteConfig - }{arg1}) - stub := fake.CreateRemoteStub - fakeReturns := fake.createRemoteReturns - fake.recordInvocation("CreateRemote", []interface{}{arg1}) - fake.createRemoteMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeRepository) CreateRemoteCallCount() int { - fake.createRemoteMutex.RLock() - defer fake.createRemoteMutex.RUnlock() - return len(fake.createRemoteArgsForCall) -} - -func (fake *FakeRepository) CreateRemoteCalls(stub func(*config.RemoteConfig) (*gita.Remote, error)) { - fake.createRemoteMutex.Lock() - defer fake.createRemoteMutex.Unlock() - fake.CreateRemoteStub = stub -} - -func (fake *FakeRepository) CreateRemoteArgsForCall(i int) *config.RemoteConfig { - fake.createRemoteMutex.RLock() - defer fake.createRemoteMutex.RUnlock() - argsForCall := fake.createRemoteArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeRepository) CreateRemoteReturns(result1 *gita.Remote, result2 error) { - fake.createRemoteMutex.Lock() - defer fake.createRemoteMutex.Unlock() - fake.CreateRemoteStub = nil - fake.createRemoteReturns = struct { - result1 *gita.Remote - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) CreateRemoteReturnsOnCall(i int, result1 *gita.Remote, result2 error) { - fake.createRemoteMutex.Lock() - defer fake.createRemoteMutex.Unlock() - fake.CreateRemoteStub = nil - if fake.createRemoteReturnsOnCall == nil { - fake.createRemoteReturnsOnCall = make(map[int]struct { - result1 *gita.Remote - result2 error - }) - } - fake.createRemoteReturnsOnCall[i] = struct { - result1 *gita.Remote - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) CreateTag(arg1 string, arg2 plumbing.Hash, arg3 *gita.CreateTagOptions) (*plumbing.Reference, error) { - fake.createTagMutex.Lock() - ret, specificReturn := fake.createTagReturnsOnCall[len(fake.createTagArgsForCall)] - fake.createTagArgsForCall = append(fake.createTagArgsForCall, struct { - arg1 string - arg2 plumbing.Hash - arg3 *gita.CreateTagOptions - }{arg1, arg2, arg3}) - stub := fake.CreateTagStub - fakeReturns := fake.createTagReturns - fake.recordInvocation("CreateTag", []interface{}{arg1, arg2, arg3}) - fake.createTagMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeRepository) CreateTagCallCount() int { - fake.createTagMutex.RLock() - defer fake.createTagMutex.RUnlock() - return len(fake.createTagArgsForCall) -} - -func (fake *FakeRepository) CreateTagCalls(stub func(string, plumbing.Hash, *gita.CreateTagOptions) (*plumbing.Reference, error)) { - fake.createTagMutex.Lock() - defer fake.createTagMutex.Unlock() - fake.CreateTagStub = stub -} - -func (fake *FakeRepository) CreateTagArgsForCall(i int) (string, plumbing.Hash, *gita.CreateTagOptions) { - fake.createTagMutex.RLock() - defer fake.createTagMutex.RUnlock() - argsForCall := fake.createTagArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *FakeRepository) CreateTagReturns(result1 *plumbing.Reference, result2 error) { - fake.createTagMutex.Lock() - defer fake.createTagMutex.Unlock() - fake.CreateTagStub = nil - fake.createTagReturns = struct { - result1 *plumbing.Reference - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) CreateTagReturnsOnCall(i int, result1 *plumbing.Reference, result2 error) { - fake.createTagMutex.Lock() - defer fake.createTagMutex.Unlock() - fake.CreateTagStub = nil - if fake.createTagReturnsOnCall == nil { - fake.createTagReturnsOnCall = make(map[int]struct { - result1 *plumbing.Reference - result2 error - }) - } - fake.createTagReturnsOnCall[i] = struct { - result1 *plumbing.Reference - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) DeleteRemote(arg1 string) error { - fake.deleteRemoteMutex.Lock() - ret, specificReturn := fake.deleteRemoteReturnsOnCall[len(fake.deleteRemoteArgsForCall)] - fake.deleteRemoteArgsForCall = append(fake.deleteRemoteArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.DeleteRemoteStub - fakeReturns := fake.deleteRemoteReturns - fake.recordInvocation("DeleteRemote", []interface{}{arg1}) - fake.deleteRemoteMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeRepository) DeleteRemoteCallCount() int { - fake.deleteRemoteMutex.RLock() - defer fake.deleteRemoteMutex.RUnlock() - return len(fake.deleteRemoteArgsForCall) -} - -func (fake *FakeRepository) DeleteRemoteCalls(stub func(string) error) { - fake.deleteRemoteMutex.Lock() - defer fake.deleteRemoteMutex.Unlock() - fake.DeleteRemoteStub = stub -} - -func (fake *FakeRepository) DeleteRemoteArgsForCall(i int) string { - fake.deleteRemoteMutex.RLock() - defer fake.deleteRemoteMutex.RUnlock() - argsForCall := fake.deleteRemoteArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeRepository) DeleteRemoteReturns(result1 error) { - fake.deleteRemoteMutex.Lock() - defer fake.deleteRemoteMutex.Unlock() - fake.DeleteRemoteStub = nil - fake.deleteRemoteReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeRepository) DeleteRemoteReturnsOnCall(i int, result1 error) { - fake.deleteRemoteMutex.Lock() - defer fake.deleteRemoteMutex.Unlock() - fake.DeleteRemoteStub = nil - if fake.deleteRemoteReturnsOnCall == nil { - fake.deleteRemoteReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.deleteRemoteReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeRepository) Head() (*plumbing.Reference, error) { - fake.headMutex.Lock() - ret, specificReturn := fake.headReturnsOnCall[len(fake.headArgsForCall)] - fake.headArgsForCall = append(fake.headArgsForCall, struct { - }{}) - stub := fake.HeadStub - fakeReturns := fake.headReturns - fake.recordInvocation("Head", []interface{}{}) - fake.headMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeRepository) HeadCallCount() int { - fake.headMutex.RLock() - defer fake.headMutex.RUnlock() - return len(fake.headArgsForCall) -} - -func (fake *FakeRepository) HeadCalls(stub func() (*plumbing.Reference, error)) { - fake.headMutex.Lock() - defer fake.headMutex.Unlock() - fake.HeadStub = stub -} - -func (fake *FakeRepository) HeadReturns(result1 *plumbing.Reference, result2 error) { - fake.headMutex.Lock() - defer fake.headMutex.Unlock() - fake.HeadStub = nil - fake.headReturns = struct { - result1 *plumbing.Reference - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) HeadReturnsOnCall(i int, result1 *plumbing.Reference, result2 error) { - fake.headMutex.Lock() - defer fake.headMutex.Unlock() - fake.HeadStub = nil - if fake.headReturnsOnCall == nil { - fake.headReturnsOnCall = make(map[int]struct { - result1 *plumbing.Reference - result2 error - }) - } - fake.headReturnsOnCall[i] = struct { - result1 *plumbing.Reference - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) Remote(arg1 string) (*gita.Remote, error) { - fake.remoteMutex.Lock() - ret, specificReturn := fake.remoteReturnsOnCall[len(fake.remoteArgsForCall)] - fake.remoteArgsForCall = append(fake.remoteArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.RemoteStub - fakeReturns := fake.remoteReturns - fake.recordInvocation("Remote", []interface{}{arg1}) - fake.remoteMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeRepository) RemoteCallCount() int { - fake.remoteMutex.RLock() - defer fake.remoteMutex.RUnlock() - return len(fake.remoteArgsForCall) -} - -func (fake *FakeRepository) RemoteCalls(stub func(string) (*gita.Remote, error)) { - fake.remoteMutex.Lock() - defer fake.remoteMutex.Unlock() - fake.RemoteStub = stub -} - -func (fake *FakeRepository) RemoteArgsForCall(i int) string { - fake.remoteMutex.RLock() - defer fake.remoteMutex.RUnlock() - argsForCall := fake.remoteArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeRepository) RemoteReturns(result1 *gita.Remote, result2 error) { - fake.remoteMutex.Lock() - defer fake.remoteMutex.Unlock() - fake.RemoteStub = nil - fake.remoteReturns = struct { - result1 *gita.Remote - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) RemoteReturnsOnCall(i int, result1 *gita.Remote, result2 error) { - fake.remoteMutex.Lock() - defer fake.remoteMutex.Unlock() - fake.RemoteStub = nil - if fake.remoteReturnsOnCall == nil { - fake.remoteReturnsOnCall = make(map[int]struct { - result1 *gita.Remote - result2 error - }) - } - fake.remoteReturnsOnCall[i] = struct { - result1 *gita.Remote - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) Remotes() ([]*gita.Remote, error) { - fake.remotesMutex.Lock() - ret, specificReturn := fake.remotesReturnsOnCall[len(fake.remotesArgsForCall)] - fake.remotesArgsForCall = append(fake.remotesArgsForCall, struct { - }{}) - stub := fake.RemotesStub - fakeReturns := fake.remotesReturns - fake.recordInvocation("Remotes", []interface{}{}) - fake.remotesMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeRepository) RemotesCallCount() int { - fake.remotesMutex.RLock() - defer fake.remotesMutex.RUnlock() - return len(fake.remotesArgsForCall) -} - -func (fake *FakeRepository) RemotesCalls(stub func() ([]*gita.Remote, error)) { - fake.remotesMutex.Lock() - defer fake.remotesMutex.Unlock() - fake.RemotesStub = stub -} - -func (fake *FakeRepository) RemotesReturns(result1 []*gita.Remote, result2 error) { - fake.remotesMutex.Lock() - defer fake.remotesMutex.Unlock() - fake.RemotesStub = nil - fake.remotesReturns = struct { - result1 []*gita.Remote - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) RemotesReturnsOnCall(i int, result1 []*gita.Remote, result2 error) { - fake.remotesMutex.Lock() - defer fake.remotesMutex.Unlock() - fake.RemotesStub = nil - if fake.remotesReturnsOnCall == nil { - fake.remotesReturnsOnCall = make(map[int]struct { - result1 []*gita.Remote - result2 error - }) - } - fake.remotesReturnsOnCall[i] = struct { - result1 []*gita.Remote - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) ResolveRevision(arg1 plumbing.Revision) (*plumbing.Hash, error) { - fake.resolveRevisionMutex.Lock() - ret, specificReturn := fake.resolveRevisionReturnsOnCall[len(fake.resolveRevisionArgsForCall)] - fake.resolveRevisionArgsForCall = append(fake.resolveRevisionArgsForCall, struct { - arg1 plumbing.Revision - }{arg1}) - stub := fake.ResolveRevisionStub - fakeReturns := fake.resolveRevisionReturns - fake.recordInvocation("ResolveRevision", []interface{}{arg1}) - fake.resolveRevisionMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeRepository) ResolveRevisionCallCount() int { - fake.resolveRevisionMutex.RLock() - defer fake.resolveRevisionMutex.RUnlock() - return len(fake.resolveRevisionArgsForCall) -} - -func (fake *FakeRepository) ResolveRevisionCalls(stub func(plumbing.Revision) (*plumbing.Hash, error)) { - fake.resolveRevisionMutex.Lock() - defer fake.resolveRevisionMutex.Unlock() - fake.ResolveRevisionStub = stub -} - -func (fake *FakeRepository) ResolveRevisionArgsForCall(i int) plumbing.Revision { - fake.resolveRevisionMutex.RLock() - defer fake.resolveRevisionMutex.RUnlock() - argsForCall := fake.resolveRevisionArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeRepository) ResolveRevisionReturns(result1 *plumbing.Hash, result2 error) { - fake.resolveRevisionMutex.Lock() - defer fake.resolveRevisionMutex.Unlock() - fake.ResolveRevisionStub = nil - fake.resolveRevisionReturns = struct { - result1 *plumbing.Hash - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) ResolveRevisionReturnsOnCall(i int, result1 *plumbing.Hash, result2 error) { - fake.resolveRevisionMutex.Lock() - defer fake.resolveRevisionMutex.Unlock() - fake.ResolveRevisionStub = nil - if fake.resolveRevisionReturnsOnCall == nil { - fake.resolveRevisionReturnsOnCall = make(map[int]struct { - result1 *plumbing.Hash - result2 error - }) - } - fake.resolveRevisionReturnsOnCall[i] = struct { - result1 *plumbing.Hash - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) Tags() (storer.ReferenceIter, error) { - fake.tagsMutex.Lock() - ret, specificReturn := fake.tagsReturnsOnCall[len(fake.tagsArgsForCall)] - fake.tagsArgsForCall = append(fake.tagsArgsForCall, struct { - }{}) - stub := fake.TagsStub - fakeReturns := fake.tagsReturns - fake.recordInvocation("Tags", []interface{}{}) - fake.tagsMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeRepository) TagsCallCount() int { - fake.tagsMutex.RLock() - defer fake.tagsMutex.RUnlock() - return len(fake.tagsArgsForCall) -} - -func (fake *FakeRepository) TagsCalls(stub func() (storer.ReferenceIter, error)) { - fake.tagsMutex.Lock() - defer fake.tagsMutex.Unlock() - fake.TagsStub = stub -} - -func (fake *FakeRepository) TagsReturns(result1 storer.ReferenceIter, result2 error) { - fake.tagsMutex.Lock() - defer fake.tagsMutex.Unlock() - fake.TagsStub = nil - fake.tagsReturns = struct { - result1 storer.ReferenceIter - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) TagsReturnsOnCall(i int, result1 storer.ReferenceIter, result2 error) { - fake.tagsMutex.Lock() - defer fake.tagsMutex.Unlock() - fake.TagsStub = nil - if fake.tagsReturnsOnCall == nil { - fake.tagsReturnsOnCall = make(map[int]struct { - result1 storer.ReferenceIter - result2 error - }) - } - fake.tagsReturnsOnCall[i] = struct { - result1 storer.ReferenceIter - result2 error - }{result1, result2} -} - -func (fake *FakeRepository) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.branchesMutex.RLock() - defer fake.branchesMutex.RUnlock() - fake.commitObjectMutex.RLock() - defer fake.commitObjectMutex.RUnlock() - fake.createRemoteMutex.RLock() - defer fake.createRemoteMutex.RUnlock() - fake.createTagMutex.RLock() - defer fake.createTagMutex.RUnlock() - fake.deleteRemoteMutex.RLock() - defer fake.deleteRemoteMutex.RUnlock() - fake.headMutex.RLock() - defer fake.headMutex.RUnlock() - fake.remoteMutex.RLock() - defer fake.remoteMutex.RUnlock() - fake.remotesMutex.RLock() - defer fake.remotesMutex.RUnlock() - fake.resolveRevisionMutex.RLock() - defer fake.resolveRevisionMutex.RUnlock() - fake.tagsMutex.RLock() - defer fake.tagsMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeRepository) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ git.Repository = new(FakeRepository) diff --git a/pkg/git/gitfakes/fake_worktree.go b/pkg/git/gitfakes/fake_worktree.go deleted file mode 100644 index 24fef8a4b75..00000000000 --- a/pkg/git/gitfakes/fake_worktree.go +++ /dev/null @@ -1,359 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by counterfeiter. DO NOT EDIT. -package gitfakes - -import ( - "sync" - - gita "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "k8s.io/release/pkg/git" -) - -type FakeWorktree struct { - AddStub func(string) (plumbing.Hash, error) - addMutex sync.RWMutex - addArgsForCall []struct { - arg1 string - } - addReturns struct { - result1 plumbing.Hash - result2 error - } - addReturnsOnCall map[int]struct { - result1 plumbing.Hash - result2 error - } - CheckoutStub func(*gita.CheckoutOptions) error - checkoutMutex sync.RWMutex - checkoutArgsForCall []struct { - arg1 *gita.CheckoutOptions - } - checkoutReturns struct { - result1 error - } - checkoutReturnsOnCall map[int]struct { - result1 error - } - CommitStub func(string, *gita.CommitOptions) (plumbing.Hash, error) - commitMutex sync.RWMutex - commitArgsForCall []struct { - arg1 string - arg2 *gita.CommitOptions - } - commitReturns struct { - result1 plumbing.Hash - result2 error - } - commitReturnsOnCall map[int]struct { - result1 plumbing.Hash - result2 error - } - StatusStub func() (gita.Status, error) - statusMutex sync.RWMutex - statusArgsForCall []struct { - } - statusReturns struct { - result1 gita.Status - result2 error - } - statusReturnsOnCall map[int]struct { - result1 gita.Status - result2 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeWorktree) Add(arg1 string) (plumbing.Hash, error) { - fake.addMutex.Lock() - ret, specificReturn := fake.addReturnsOnCall[len(fake.addArgsForCall)] - fake.addArgsForCall = append(fake.addArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.AddStub - fakeReturns := fake.addReturns - fake.recordInvocation("Add", []interface{}{arg1}) - fake.addMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeWorktree) AddCallCount() int { - fake.addMutex.RLock() - defer fake.addMutex.RUnlock() - return len(fake.addArgsForCall) -} - -func (fake *FakeWorktree) AddCalls(stub func(string) (plumbing.Hash, error)) { - fake.addMutex.Lock() - defer fake.addMutex.Unlock() - fake.AddStub = stub -} - -func (fake *FakeWorktree) AddArgsForCall(i int) string { - fake.addMutex.RLock() - defer fake.addMutex.RUnlock() - argsForCall := fake.addArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeWorktree) AddReturns(result1 plumbing.Hash, result2 error) { - fake.addMutex.Lock() - defer fake.addMutex.Unlock() - fake.AddStub = nil - fake.addReturns = struct { - result1 plumbing.Hash - result2 error - }{result1, result2} -} - -func (fake *FakeWorktree) AddReturnsOnCall(i int, result1 plumbing.Hash, result2 error) { - fake.addMutex.Lock() - defer fake.addMutex.Unlock() - fake.AddStub = nil - if fake.addReturnsOnCall == nil { - fake.addReturnsOnCall = make(map[int]struct { - result1 plumbing.Hash - result2 error - }) - } - fake.addReturnsOnCall[i] = struct { - result1 plumbing.Hash - result2 error - }{result1, result2} -} - -func (fake *FakeWorktree) Checkout(arg1 *gita.CheckoutOptions) error { - fake.checkoutMutex.Lock() - ret, specificReturn := fake.checkoutReturnsOnCall[len(fake.checkoutArgsForCall)] - fake.checkoutArgsForCall = append(fake.checkoutArgsForCall, struct { - arg1 *gita.CheckoutOptions - }{arg1}) - stub := fake.CheckoutStub - fakeReturns := fake.checkoutReturns - fake.recordInvocation("Checkout", []interface{}{arg1}) - fake.checkoutMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeWorktree) CheckoutCallCount() int { - fake.checkoutMutex.RLock() - defer fake.checkoutMutex.RUnlock() - return len(fake.checkoutArgsForCall) -} - -func (fake *FakeWorktree) CheckoutCalls(stub func(*gita.CheckoutOptions) error) { - fake.checkoutMutex.Lock() - defer fake.checkoutMutex.Unlock() - fake.CheckoutStub = stub -} - -func (fake *FakeWorktree) CheckoutArgsForCall(i int) *gita.CheckoutOptions { - fake.checkoutMutex.RLock() - defer fake.checkoutMutex.RUnlock() - argsForCall := fake.checkoutArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeWorktree) CheckoutReturns(result1 error) { - fake.checkoutMutex.Lock() - defer fake.checkoutMutex.Unlock() - fake.CheckoutStub = nil - fake.checkoutReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeWorktree) CheckoutReturnsOnCall(i int, result1 error) { - fake.checkoutMutex.Lock() - defer fake.checkoutMutex.Unlock() - fake.CheckoutStub = nil - if fake.checkoutReturnsOnCall == nil { - fake.checkoutReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.checkoutReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeWorktree) Commit(arg1 string, arg2 *gita.CommitOptions) (plumbing.Hash, error) { - fake.commitMutex.Lock() - ret, specificReturn := fake.commitReturnsOnCall[len(fake.commitArgsForCall)] - fake.commitArgsForCall = append(fake.commitArgsForCall, struct { - arg1 string - arg2 *gita.CommitOptions - }{arg1, arg2}) - stub := fake.CommitStub - fakeReturns := fake.commitReturns - fake.recordInvocation("Commit", []interface{}{arg1, arg2}) - fake.commitMutex.Unlock() - if stub != nil { - return stub(arg1, arg2) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeWorktree) CommitCallCount() int { - fake.commitMutex.RLock() - defer fake.commitMutex.RUnlock() - return len(fake.commitArgsForCall) -} - -func (fake *FakeWorktree) CommitCalls(stub func(string, *gita.CommitOptions) (plumbing.Hash, error)) { - fake.commitMutex.Lock() - defer fake.commitMutex.Unlock() - fake.CommitStub = stub -} - -func (fake *FakeWorktree) CommitArgsForCall(i int) (string, *gita.CommitOptions) { - fake.commitMutex.RLock() - defer fake.commitMutex.RUnlock() - argsForCall := fake.commitArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 -} - -func (fake *FakeWorktree) CommitReturns(result1 plumbing.Hash, result2 error) { - fake.commitMutex.Lock() - defer fake.commitMutex.Unlock() - fake.CommitStub = nil - fake.commitReturns = struct { - result1 plumbing.Hash - result2 error - }{result1, result2} -} - -func (fake *FakeWorktree) CommitReturnsOnCall(i int, result1 plumbing.Hash, result2 error) { - fake.commitMutex.Lock() - defer fake.commitMutex.Unlock() - fake.CommitStub = nil - if fake.commitReturnsOnCall == nil { - fake.commitReturnsOnCall = make(map[int]struct { - result1 plumbing.Hash - result2 error - }) - } - fake.commitReturnsOnCall[i] = struct { - result1 plumbing.Hash - result2 error - }{result1, result2} -} - -func (fake *FakeWorktree) Status() (gita.Status, error) { - fake.statusMutex.Lock() - ret, specificReturn := fake.statusReturnsOnCall[len(fake.statusArgsForCall)] - fake.statusArgsForCall = append(fake.statusArgsForCall, struct { - }{}) - stub := fake.StatusStub - fakeReturns := fake.statusReturns - fake.recordInvocation("Status", []interface{}{}) - fake.statusMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeWorktree) StatusCallCount() int { - fake.statusMutex.RLock() - defer fake.statusMutex.RUnlock() - return len(fake.statusArgsForCall) -} - -func (fake *FakeWorktree) StatusCalls(stub func() (gita.Status, error)) { - fake.statusMutex.Lock() - defer fake.statusMutex.Unlock() - fake.StatusStub = stub -} - -func (fake *FakeWorktree) StatusReturns(result1 gita.Status, result2 error) { - fake.statusMutex.Lock() - defer fake.statusMutex.Unlock() - fake.StatusStub = nil - fake.statusReturns = struct { - result1 gita.Status - result2 error - }{result1, result2} -} - -func (fake *FakeWorktree) StatusReturnsOnCall(i int, result1 gita.Status, result2 error) { - fake.statusMutex.Lock() - defer fake.statusMutex.Unlock() - fake.StatusStub = nil - if fake.statusReturnsOnCall == nil { - fake.statusReturnsOnCall = make(map[int]struct { - result1 gita.Status - result2 error - }) - } - fake.statusReturnsOnCall[i] = struct { - result1 gita.Status - result2 error - }{result1, result2} -} - -func (fake *FakeWorktree) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.addMutex.RLock() - defer fake.addMutex.RUnlock() - fake.checkoutMutex.RLock() - defer fake.checkoutMutex.RUnlock() - fake.commitMutex.RLock() - defer fake.commitMutex.RUnlock() - fake.statusMutex.RLock() - defer fake.statusMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeWorktree) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ git.Worktree = new(FakeWorktree) diff --git a/pkg/github/github.go b/pkg/github/github.go deleted file mode 100644 index abf90e589ea..00000000000 --- a/pkg/github/github.go +++ /dev/null @@ -1,1008 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package github - -import ( - "context" - "fmt" - "io" - "net/http" - "os" - "path/filepath" - "strings" - - "github.com/google/go-github/v37/github" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "golang.org/x/oauth2" - - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github/internal" - "sigs.k8s.io/release-utils/env" - "sigs.k8s.io/release-utils/util" -) - -const ( - // TokenEnvKey is the default GitHub token environemt variable key - TokenEnvKey = "GITHUB_TOKEN" - // GitHubURL Prefix for github URLs - GitHubURL = "https://github.com/" -) - -// GitHub is a wrapper around GitHub related functionality -type GitHub struct { - client Client - options *Options -} - -type githubClient struct { - *github.Client -} - -// Options is a set of options to configure the behavior of the GitHub package -type Options struct { - // How many items to request in calls to the github API - // that require pagination. - ItemsPerPage int -} - -func (o *Options) GetItemsPerPage() int { - return o.ItemsPerPage -} - -// DefaultOptions return an options struct with commonly used settings -func DefaultOptions() *Options { - return &Options{ - ItemsPerPage: 50, - } -} - -//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate -//counterfeiter:generate . Client -type Client interface { - GetCommit( - context.Context, string, string, string, - ) (*github.Commit, *github.Response, error) - - GetPullRequest( - context.Context, string, string, int, - ) (*github.PullRequest, *github.Response, error) - - GetIssue( - context.Context, string, string, int, - ) (*github.Issue, *github.Response, error) - - GetRepoCommit( - context.Context, string, string, string, - ) (*github.RepositoryCommit, *github.Response, error) - - ListCommits( - context.Context, string, string, *github.CommitsListOptions, - ) ([]*github.RepositoryCommit, *github.Response, error) - - ListPullRequestsWithCommit( - context.Context, string, string, string, *github.PullRequestListOptions, - ) ([]*github.PullRequest, *github.Response, error) - - ListMilestones( - context.Context, string, string, *github.MilestoneListOptions, - ) ([]*github.Milestone, *github.Response, error) - - ListReleases( - context.Context, string, string, *github.ListOptions, - ) ([]*github.RepositoryRelease, *github.Response, error) - - GetReleaseByTag( - context.Context, string, string, string, - ) (*github.RepositoryRelease, *github.Response, error) - - DownloadReleaseAsset( - context.Context, string, string, int64, - ) (io.ReadCloser, string, error) - - ListTags( - context.Context, string, string, *github.ListOptions, - ) ([]*github.RepositoryTag, *github.Response, error) - - ListBranches( - context.Context, string, string, *github.BranchListOptions, - ) ([]*github.Branch, *github.Response, error) - - CreatePullRequest( - context.Context, string, string, string, string, string, string, - ) (*github.PullRequest, error) - - CreateIssue( - context.Context, string, string, *github.IssueRequest, - ) (*github.Issue, error) - - GetRepository( - context.Context, string, string, - ) (*github.Repository, *github.Response, error) - - UpdateReleasePage( - context.Context, string, string, int64, *github.RepositoryRelease, - ) (*github.RepositoryRelease, error) - - UploadReleaseAsset( - context.Context, string, string, int64, *github.UploadOptions, *os.File, - ) (*github.ReleaseAsset, error) - - DeleteReleaseAsset( - context.Context, string, string, int64, - ) error - - ListReleaseAssets( - context.Context, string, string, int64, *github.ListOptions, - ) ([]*github.ReleaseAsset, error) - - CreateComment( - context.Context, string, string, int, string, - ) (*github.IssueComment, *github.Response, error) -} - -// NewIssueOptions is a struct of optional fields for new issues -type NewIssueOptions struct { - Milestone string // Name of milestone to set - State string // open, closed or all. Defaults to "open" - Assignees []string // List of GitHub handles of extra assignees, must be collaborators - Labels []string // List of labels to apply. They will be created if new -} - -// TODO: we should clean up the functions listed below and agree on the same -// return type (with or without error): -// - New -// - NewWithToken -// - NewEnterprise -// - NewEnterpriseWithToken - -// New creates a new default GitHub client. Tokens set via the $GITHUB_TOKEN -// environment variable will result in an authenticated client. -// If the $GITHUB_TOKEN is not set, then the client will do unauthenticated -// GitHub requests. -func New() *GitHub { - token := env.Default(TokenEnvKey, "") - client, _ := NewWithToken(token) // nolint: errcheck - return client -} - -// NewWithToken can be used to specify a GitHub token through parameters. -// Empty string will result in unauthenticated client, which makes -// unauthenticated requests. -func NewWithToken(token string) (*GitHub, error) { - ctx := context.Background() - client := http.DefaultClient - state := "unauthenticated" - if token != "" { - state = strings.TrimPrefix(state, "un") - client = oauth2.NewClient(ctx, oauth2.StaticTokenSource( - &oauth2.Token{AccessToken: token}, - )) - } - logrus.Debugf("Using %s GitHub client", state) - return &GitHub{ - client: &githubClient{github.NewClient(client)}, - options: DefaultOptions(), - }, nil -} - -func NewEnterprise(baseURL, uploadURL string) (*GitHub, error) { - token := env.Default(TokenEnvKey, "") - return NewEnterpriseWithToken(baseURL, uploadURL, token) -} - -func NewEnterpriseWithToken(baseURL, uploadURL, token string) (*GitHub, error) { - ctx := context.Background() - client := http.DefaultClient - state := "unauthenticated" - if token != "" { - state = strings.TrimPrefix(state, "un") - client = oauth2.NewClient(ctx, oauth2.StaticTokenSource( - &oauth2.Token{AccessToken: token}, - )) - } - logrus.Debugf("Using %s Enterprise GitHub client", state) - ghclient, err := github.NewEnterpriseClient(baseURL, uploadURL, client) - if err != nil { - return nil, fmt.Errorf("failed to new github client: %s", err) - } - return &GitHub{ - client: &githubClient{ghclient}, - options: DefaultOptions(), - }, nil -} - -func (g *githubClient) GetCommit( - ctx context.Context, owner, repo, sha string, -) (*github.Commit, *github.Response, error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - commit, resp, err := g.Git.GetCommit(ctx, owner, repo, sha) - if !shouldRetry(err) { - return commit, resp, err - } - } -} - -func (g *githubClient) GetPullRequest( - ctx context.Context, owner, repo string, number int, -) (*github.PullRequest, *github.Response, error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - pr, resp, err := g.PullRequests.Get(ctx, owner, repo, number) - if !shouldRetry(err) { - return pr, resp, err - } - } -} - -func (g *githubClient) GetIssue( - ctx context.Context, owner, repo string, number int, -) (*github.Issue, *github.Response, error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - issue, resp, err := g.Issues.Get(ctx, owner, repo, number) - if !shouldRetry(err) { - return issue, resp, err - } - } -} - -func (g *githubClient) GetRepoCommit( - ctx context.Context, owner, repo, sha string, -) (*github.RepositoryCommit, *github.Response, error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - commit, resp, err := g.Repositories.GetCommit(ctx, owner, repo, sha) - if !shouldRetry(err) { - return commit, resp, err - } - } -} - -func (g *githubClient) ListCommits( - ctx context.Context, owner, repo string, opt *github.CommitsListOptions, -) ([]*github.RepositoryCommit, *github.Response, error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - commits, resp, err := g.Repositories.ListCommits(ctx, owner, repo, opt) - if !shouldRetry(err) { - return commits, resp, err - } - } -} - -func (g *githubClient) ListPullRequestsWithCommit( - ctx context.Context, owner, repo, sha string, - opt *github.PullRequestListOptions, -) ([]*github.PullRequest, *github.Response, error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - prs, resp, err := g.PullRequests.ListPullRequestsWithCommit( - ctx, owner, repo, sha, opt, - ) - if !shouldRetry(err) { - return prs, resp, err - } - } -} - -func (g *githubClient) ListReleases( - ctx context.Context, owner, repo string, opt *github.ListOptions, -) ([]*github.RepositoryRelease, *github.Response, error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - releases, resp, err := g.Repositories.ListReleases( - ctx, owner, repo, opt, - ) - if !shouldRetry(err) { - return releases, resp, err - } - } -} - -func (g *githubClient) GetReleaseByTag( - ctx context.Context, owner, repo, tag string, -) (*github.RepositoryRelease, *github.Response, error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - release, resp, err := g.Repositories.GetReleaseByTag(ctx, owner, repo, tag) - if !shouldRetry(err) { - return release, resp, err - } - } -} - -func (g *githubClient) DownloadReleaseAsset( - ctx context.Context, owner, repo string, assetID int64, -) (io.ReadCloser, string, error) { - // TODO: Should we be getting this http client from somewhere else? - httpClient := http.DefaultClient - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - assetBody, redirectURL, err := g.Repositories.DownloadReleaseAsset(ctx, owner, repo, assetID, httpClient) - if !shouldRetry(err) { - return assetBody, redirectURL, err - } - } -} - -func (g *githubClient) ListTags( - ctx context.Context, owner, repo string, opt *github.ListOptions, -) ([]*github.RepositoryTag, *github.Response, error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - tags, resp, err := g.Repositories.ListTags(ctx, owner, repo, opt) - if !shouldRetry(err) { - return tags, resp, err - } - } -} - -func (g *githubClient) ListBranches( - ctx context.Context, owner, repo string, opt *github.BranchListOptions, -) ([]*github.Branch, *github.Response, error) { - branches, response, err := g.Repositories.ListBranches(ctx, owner, repo, opt) - if err != nil { - return nil, nil, errors.Wrap(err, "fetching brnaches from repo") - } - - return branches, response, nil -} - -// ListMilestones calls the github API to retrieve milestones (with retry) -func (g *githubClient) ListMilestones( - ctx context.Context, owner, repo string, opts *github.MilestoneListOptions, -) (mstones []*github.Milestone, resp *github.Response, err error) { - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - mstones, resp, err := g.Issues.ListMilestones(ctx, owner, repo, opts) - if !shouldRetry(err) { - return mstones, resp, err - } - } -} - -func (g *githubClient) CreatePullRequest( - ctx context.Context, owner, repo, baseBranchName, headBranchName, title, body string, -) (*github.PullRequest, error) { - newPullRequest := &github.NewPullRequest{ - Title: &title, - Head: &headBranchName, - Base: &baseBranchName, - Body: &body, - MaintainerCanModify: github.Bool(true), - } - - pr, _, err := g.PullRequests.Create(ctx, owner, repo, newPullRequest) - if err != nil { - return pr, errors.Wrap(err, "creating pull request") - } - - logrus.Infof("Successfully created PR #%d", pr.GetNumber()) - return pr, nil -} - -func (g *githubClient) CreateIssue( - ctx context.Context, owner, repo string, req *github.IssueRequest, -) (*github.Issue, error) { - // Create the issue on github - issue, _, err := g.Issues.Create(ctx, owner, repo, req) - if err != nil { - return issue, errors.Wrap(err, "creating new issue") - } - - logrus.Infof("Successfully created issue #%d: %s", issue.GetNumber(), issue.GetTitle()) - return issue, nil -} - -func (g *githubClient) GetRepository( - ctx context.Context, owner, repo string, -) (*github.Repository, *github.Response, error) { - pr, resp, err := g.Repositories.Get(ctx, owner, repo) - if err != nil { - return pr, resp, errors.Wrap(err, "getting repository") - } - - return pr, resp, nil -} - -func (g *githubClient) UpdateReleasePage( - ctx context.Context, owner, repo string, releaseID int64, - releaseData *github.RepositoryRelease, -) (release *github.RepositoryRelease, err error) { - // If release is 0, we create a new Release - if releaseID == 0 { - release, _, err = g.Repositories.CreateRelease(ctx, owner, repo, releaseData) - } else { - release, _, err = g.Repositories.EditRelease(ctx, owner, repo, releaseID, releaseData) - } - - if err != nil { - return nil, errors.Wrap(err, "updating release pagin in github") - } - - return release, nil -} - -func (g *githubClient) UploadReleaseAsset( - ctx context.Context, owner, repo string, releaseID int64, opts *github.UploadOptions, file *os.File, -) (release *github.ReleaseAsset, err error) { - logrus.Infof("Uploading %s to release %d", opts.Name, releaseID) - asset, _, err := g.Repositories.UploadReleaseAsset( - ctx, owner, repo, releaseID, opts, file, - ) - if err != nil { - return nil, errors.Wrap(err, "while uploading asset file") - } - - return asset, nil -} - -func (g *githubClient) DeleteReleaseAsset( - ctx context.Context, owner string, repo string, assetID int64) error { - _, err := g.Repositories.DeleteReleaseAsset(ctx, owner, repo, assetID) - if err != nil { - return errors.Wrapf(err, "deleting asset %d", assetID) - } - return nil -} - -// ListReleaseAssets queries the GitHub API to get a list of asset files -// that have been uploaded to a releases -func (g *githubClient) ListReleaseAssets( - ctx context.Context, owner, repo string, releaseID int64, options *github.ListOptions, -) ([]*github.ReleaseAsset, error) { - assets := []*github.ReleaseAsset{} - for { - moreAssets, r, err := g.Repositories.ListReleaseAssets(ctx, owner, repo, releaseID, options) - if err != nil { - return nil, errors.Wrap(err, "getting release assets from GitHub") - } - assets = append(assets, moreAssets...) - if r.NextPage == 0 { - break - } - options.Page = r.NextPage - } - return assets, nil -} - -func (g *githubClient) CreateComment( - ctx context.Context, owner, repo string, number int, message string, -) (*github.IssueComment, *github.Response, error) { - comment := &github.IssueComment{ - Body: &message, - } - - for shouldRetry := internal.DefaultGithubErrChecker(); ; { - issueComment, resp, err := g.Issues.CreateComment(ctx, owner, repo, number, comment) - if !shouldRetry(err) { - return issueComment, resp, err - } - } -} - -// SetClient can be used to manually set the internal GitHub client -func (g *GitHub) SetClient(client Client) { - g.client = client -} - -// Client can be used to retrieve the Client type -func (g *GitHub) Client() Client { - return g.client -} - -// SetOptions gets an options set for the GitHub object -func (g *GitHub) SetOptions(opts *Options) { - g.options = opts -} - -// Options return a pointer to the options struct -func (g *GitHub) Options() *Options { - return g.options -} - -// TagsPerBranch is an abstraction over a simple branch to latest tag association -type TagsPerBranch map[string]string - -// LatestGitHubTagsPerBranch returns the latest GitHub available tag for each -// branch. The logic how releases are associates with branches is motivated by -// the changelog generation and bound to the default Kubernetes release -// strategy, which is also the reason why we do not provide a repo and org -// parameter here. -// -// Releases are associated in the following way: -// - x.y.0-alpha.z releases are only associated with the main branch -// - x.y.0-beta.z releases are only associated with their release-x.y branch -// - x.y.0 final releases are associated with the main branch and the release-x.y branch -func (g *GitHub) LatestGitHubTagsPerBranch() (TagsPerBranch, error) { - // List tags for all pages - allTags := []*github.RepositoryTag{} - opts := &github.ListOptions{PerPage: g.options.GetItemsPerPage()} - for { - tags, resp, err := g.client.ListTags( - context.Background(), git.DefaultGithubOrg, git.DefaultGithubRepo, - opts, - ) - if err != nil { - return nil, errors.Wrap(err, "unable to retrieve GitHub tags") - } - allTags = append(allTags, tags...) - if resp.NextPage == 0 { - break - } - opts.Page = resp.NextPage - } - - releases := make(TagsPerBranch) - for _, t := range allTags { - tag := t.GetName() - - // alpha and beta releases are only available on the main branch - if strings.Contains(tag, "beta") || strings.Contains(tag, "alpha") { - releases.addIfNotExisting(git.DefaultBranch, tag) - continue - } - - // We skip non-semver tags because k/k contains tags like `v0.5` which - // are not valid - semverTag, err := util.TagStringToSemver(tag) - if err != nil { - logrus.Debugf("Skipping tag %s because it is not valid semver", tag) - continue - } - - // Latest vx.x.0 release are on both main and release branch - if len(semverTag.Pre) == 0 { - releases.addIfNotExisting(git.DefaultBranch, tag) - } - - branch := fmt.Sprintf("release-%d.%d", semverTag.Major, semverTag.Minor) - releases.addIfNotExisting(branch, tag) - } - - return releases, nil -} - -// addIfNotExisting adds a new `tag` for the `branch` if not already existing -// in the map `TagsForBranch` -func (t TagsPerBranch) addIfNotExisting(branch, tag string) { - if _, ok := t[branch]; !ok { - t[branch] = tag - } -} - -// Releases returns a list of GitHub releases for the provided `owner` and -// `repo`. If `includePrereleases` is `true`, then the resulting slice will -// also contain pre/drafted releases. -// TODO: Create a more descriptive method name and update references -func (g *GitHub) Releases(owner, repo string, includePrereleases bool) ([]*github.RepositoryRelease, error) { - allReleases, _, err := g.client.ListReleases( - context.Background(), owner, repo, nil, - ) - if err != nil { - return nil, errors.Wrap(err, "unable to retrieve GitHub releases") - } - - releases := []*github.RepositoryRelease{} - for _, release := range allReleases { - if release.GetPrerelease() { - if includePrereleases { - releases = append(releases, release) - } - } else { - releases = append(releases, release) - } - } - - return releases, nil -} - -// GetReleaseTags returns a list of GitHub release tags for the provided -// `owner` and `repo`. If `includePrereleases` is `true`, then the resulting -// slice will also contain pre/drafted releases. -func (g *GitHub) GetReleaseTags(owner, repo string, includePrereleases bool) ([]string, error) { - releases, err := g.Releases(owner, repo, includePrereleases) - if err != nil { - return nil, errors.Wrap(err, "getting releases") - } - - releaseTags := []string{} - for _, release := range releases { - releaseTags = append(releaseTags, *release.TagName) - } - - return releaseTags, nil -} - -// DownloadReleaseAssets downloads a set of GitHub release assets to an -// `outputDir`. Assets to download are derived from the `releaseTags`. -func (g *GitHub) DownloadReleaseAssets(owner, repo string, releaseTags []string, outputDir string) (finalErr error) { - var releases []*github.RepositoryRelease - - if len(releaseTags) > 0 { - for _, tag := range releaseTags { - release, _, err := g.client.GetReleaseByTag(context.Background(), owner, repo, tag) - if err != nil { - return errors.Wrapf(err, "getting release from tag %s", tag) - } - releases = append(releases, release) - } - } else { - return errors.New("no release tags were populated") - } - - errChan := make(chan error, len(releases)) - for i := range releases { - release := releases[i] - go func(f func() error) { errChan <- f() }(func() error { - releaseTag := release.GetTagName() - logrus.WithField("release", releaseTag).Infof("Download assets for %s/%s@%s", owner, repo, releaseTag) - - assets := release.Assets - if len(assets) == 0 { - logrus.Infof("Skipping download for %s/%s@%s as no release assets were found", owner, repo, releaseTag) - return nil - } - - releaseDir := filepath.Join(outputDir, owner, repo, releaseTag) - if err := os.MkdirAll(releaseDir, os.FileMode(0o775)); err != nil { - return errors.Wrap(err, "creating output directory for release assets") - } - - logrus.WithField("release", releaseTag).Infof("Writing assets to %s", releaseDir) - if err := g.downloadAssetsParallel(assets, owner, repo, releaseDir); err != nil { - return errors.Wrapf(err, "downloading assets for %s", releaseTag) - } - return nil - }) - } - - for i := 0; i < cap(errChan); i++ { - if err := <-errChan; err != nil { - if finalErr == nil { - finalErr = err - continue - } - finalErr = errors.Wrap(finalErr, err.Error()) - } - } - return finalErr -} - -func (g *GitHub) downloadAssetsParallel(assets []*github.ReleaseAsset, owner, repo, releaseDir string) (finalErr error) { - errChan := make(chan error, len(assets)) - for i := range assets { - asset := assets[i] - go func(f func() error) { errChan <- f() }(func() error { - if asset.GetID() == 0 { - return errors.New("asset ID should never be zero") - } - - logrus.Infof("GitHub asset ID: %v, download URL: %s", *asset.ID, *asset.BrowserDownloadURL) - assetBody, _, err := g.client.DownloadReleaseAsset(context.Background(), owner, repo, asset.GetID()) - if err != nil { - return errors.Wrap(err, "downloading release assets") - } - - absFile := filepath.Join(releaseDir, asset.GetName()) - defer assetBody.Close() - assetFile, err := os.Create(absFile) - if err != nil { - return errors.Wrap(err, "creating release asset file") - } - - defer assetFile.Close() - if _, err := io.Copy(assetFile, assetBody); err != nil { - return errors.Wrap(err, "copying release asset to file") - } - return nil - }) - } - - for i := 0; i < cap(errChan); i++ { - if err := <-errChan; err != nil { - if finalErr == nil { - finalErr = err - continue - } - finalErr = errors.Wrap(finalErr, err.Error()) - } - } - return finalErr -} - -// UploadReleaseAsset uploads a file onto the release assets -func (g *GitHub) UploadReleaseAsset( - owner, repo string, releaseID int64, fileName string, -) (*github.ReleaseAsset, error) { - fileLabel := "" - // We can get a label for the asset by appeding it to the path with a colon - if strings.Contains(fileName, ":") { - p := strings.SplitN(fileName, ":", 2) - if len(p) == 2 { - fileName = p[0] - fileLabel = p[1] - } - } - - // Check the file exists - if !util.Exists(fileName) { - return nil, errors.New("unable to upload asset, file not found") - } - - f, err := os.Open(fileName) - if err != nil { - return nil, errors.Wrap(err, "opening the asset file for reading") - } - - // Only the first 512 bytes are used to sniff the content type. - buffer := make([]byte, 512) - - _, err = f.Read(buffer) - if err != nil { - return nil, errors.Wrap(err, "reading file to determine mimetype") - } - // Reset the pointer to reuse the filehandle - _, err = f.Seek(0, 0) - if err != nil { - return nil, errors.Wrap(err, "rewinding the asset filepointer") - } - - contentType := http.DetectContentType(buffer) - logrus.Infof("Asset filetype will be %s", contentType) - - uopts := &github.UploadOptions{ - Name: filepath.Base(fileName), - Label: fileLabel, - MediaType: contentType, - } - - asset, err := g.Client().UploadReleaseAsset( - context.Background(), owner, repo, releaseID, uopts, f, - ) - if err != nil { - return nil, errors.Wrap(err, "uploading asset file to release") - } - - return asset, nil -} - -// ToRequest builds an issue request from the set of options -func (nio *NewIssueOptions) toRequest() *github.IssueRequest { - request := &github.IssueRequest{} - - if nio.State == "open" || nio.State == "closed" || nio.State == "all" { - request.State = &nio.State - } - - if len(nio.Labels) > 0 { - request.Labels = &nio.Labels - } - - if len(nio.Assignees) == 1 { - request.Assignee = &nio.Assignees[0] - } else if len(nio.Assignees) > 1 { - request.Assignees = &nio.Assignees - } - return request -} - -// CreateIssue files a new issue in the specified respoitory -func (g *GitHub) CreateIssue( - owner, repo, title, body string, opts *NewIssueOptions, -) (*github.Issue, error) { - // Create the issue request - issueRequest := opts.toRequest() - issueRequest.Title = &title - issueRequest.Body = &body - - // Create the issue using the cliente - return g.Client().CreateIssue(context.Background(), owner, repo, issueRequest) -} - -// CreatePullRequest Creates a new pull request in owner/repo:baseBranch to merge changes from headBranchName -// which is a string containing a branch in the same repository or a user:branch pair -func (g *GitHub) CreatePullRequest( - owner, repo, baseBranchName, headBranchName, title, body string, -) (*github.PullRequest, error) { - // Use the client to create a new PR - pr, err := g.Client().CreatePullRequest(context.Background(), owner, repo, baseBranchName, headBranchName, title, body) - if err != nil { - return pr, err - } - - return pr, nil -} - -// GetMilestone returns a milestone object from its string name -func (g *GitHub) GetMilestone(owner, repo, title string) ( - ms *github.Milestone, exists bool, err error) { - if title == "" { - return nil, false, errors.New("unable to search milestone. Title is empty") - } - opts := &github.MilestoneListOptions{ - State: "all", - ListOptions: github.ListOptions{PerPage: 100}, - } - for { - mstones, resp, err := g.Client().ListMilestones( - context.Background(), owner, repo, opts) - if err != nil { - return nil, exists, errors.Wrap(err, "listing repository milestones") - } - for _, ms = range mstones { - if ms.GetTitle() == title { - logrus.Debugf("Milestone %s is milestone ID#%d", ms.GetTitle(), ms.GetID()) - return ms, true, nil - } - } - if resp.NextPage == 0 { - break - } - opts.Page = resp.NextPage - } - - return nil, false, nil -} - -// GetRepository gets a repository using the current client -func (g *GitHub) GetRepository( - owner, repo string, -) (*github.Repository, error) { - repository, _, err := g.Client().GetRepository(context.Background(), owner, repo) - if err != nil { - return repository, err - } - - return repository, nil -} - -// ListBranches gets a repository using the current client -func (g *GitHub) ListBranches( - owner, repo string, -) ([]*github.Branch, error) { - options := &github.BranchListOptions{ - ListOptions: github.ListOptions{PerPage: g.Options().GetItemsPerPage()}, - } - branches := []*github.Branch{} - for { - moreBranches, r, err := g.Client().ListBranches(context.Background(), owner, repo, options) - if err != nil { - return branches, errors.Wrap(err, "getting branches from client") - } - branches = append(branches, moreBranches...) - if r.NextPage == 0 { - break - } - options.Page = r.NextPage - } - - return branches, nil -} - -// RepoIsForkOf Function that checks if a repository is a fork of another -func (g *GitHub) RepoIsForkOf( - forkOwner, forkRepo, parentOwner, parentRepo string, -) (bool, error) { - repository, _, err := g.Client().GetRepository(context.Background(), forkOwner, forkRepo) - if err != nil { - return false, errors.Wrap(err, "checking if repository is a fork") - } - - // First, repo has to be an actual fork - if !repository.GetFork() { - logrus.Infof("Repository %s/%s is not a fork", forkOwner, forkRepo) - return false, nil - } - - // Check if the parent repo matches the owner/repo string - if repository.GetParent().GetFullName() == fmt.Sprintf("%s/%s", parentOwner, parentRepo) { - logrus.Debugf("%s/%s is a fork of %s/%s", forkOwner, forkRepo, parentOwner, parentRepo) - return true, nil - } - - logrus.Infof("%s/%s is not a fork of %s/%s", forkOwner, forkRepo, parentOwner, parentRepo) - return false, nil -} - -// BranchExists checks if a branch exists in a given repo -func (g *GitHub) BranchExists( - owner, repo, branchname string, -) (isBranch bool, err error) { - branches, err := g.ListBranches(owner, repo) - if err != nil { - return false, errors.Wrap(err, "while listing repository branches") - } - - for _, branch := range branches { - if branch.GetName() == branchname { - logrus.Debugf("Branch %s already exists in %s/%s", branchname, owner, repo) - return true, nil - } - } - - logrus.Debugf("Repository %s/%s does not have a branch named %s", owner, repo, branchname) - return false, nil -} - -// UpdateReleasePage updates a release page in GitHub -func (g *GitHub) UpdateReleasePage( - owner, repo string, - releaseID int64, - tag, commitish, name, body string, - isDraft, isPrerelease bool, -) (release *github.RepositoryRelease, err error) { - logrus.Infof("Updating release page for %s", tag) - - // Create the options for the - releaseData := &github.RepositoryRelease{ - TagName: &tag, - TargetCommitish: &commitish, - Name: &name, - Body: &body, - Draft: &isDraft, - Prerelease: &isPrerelease, - } - - // Call the client - release, err = g.Client().UpdateReleasePage( - context.Background(), owner, repo, releaseID, releaseData, - ) - - if err != nil { - return nil, errors.Wrap(err, "updating the release page") - } - - return release, nil -} - -// DeleteReleaseAsset deletes an asset from a release -func (g *GitHub) DeleteReleaseAsset(owner, repo string, assetID int64) error { - return errors.Wrap(g.Client().DeleteReleaseAsset( - context.Background(), owner, repo, assetID, - ), "deleting asset from release") -} - -// ListReleaseAssets gets the assets uploaded to a GitHub release -func (g *GitHub) ListReleaseAssets( - owner, repo string, releaseID int64) ([]*github.ReleaseAsset, error) { - // Get the assets from the client - assets, err := g.Client().ListReleaseAssets( - context.Background(), owner, repo, releaseID, - &github.ListOptions{PerPage: g.Options().GetItemsPerPage()}, - ) - if err != nil { - return nil, errors.Wrap(err, "getting release assets") - } - return assets, nil -} - -// TagExists returns true is a specified tag exists in the repo -func (g *GitHub) TagExists(owner, repo, tag string) (exists bool, err error) { - options := &github.ListOptions{PerPage: g.Options().GetItemsPerPage()} - for { - tags, r, err := g.Client().ListTags( - context.Background(), owner, repo, options, - ) - if err != nil { - return exists, errors.Wrap(err, "listing repository tags") - } - - // List all tags returned and check if the one we're looking for exists - for _, testTag := range tags { - if testTag.GetName() == tag { - return true, nil - } - } - if r.NextPage == 0 { - break - } - options.Page = r.NextPage - } - return false, nil -} diff --git a/pkg/github/github_test.go b/pkg/github/github_test.go deleted file mode 100644 index 92e0708c881..00000000000 --- a/pkg/github/github_test.go +++ /dev/null @@ -1,503 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package github_test - -import ( - "errors" - "fmt" - "testing" - - gogithub "github.com/google/go-github/v37/github" - "github.com/stretchr/testify/require" - - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" - "k8s.io/release/pkg/github/githubfakes" -) - -func newSUT() (*github.GitHub, *githubfakes.FakeClient) { - client := &githubfakes.FakeClient{} - sut := github.New() - sut.SetClient(client) - - return sut, client -} - -func TestLatestGitHubTagsPerBranchSuccessEmptyResult(t *testing.T) { - // Given - sut, client := newSUT() - client.ListTagsReturns(nil, &gogithub.Response{NextPage: 0}, nil) - - // When - res, err := sut.LatestGitHubTagsPerBranch() - - // Then - require.Nil(t, err) - require.Empty(t, res) -} - -func TestLatestGitHubTagsPerBranchSuccessAlphaAfterMinor(t *testing.T) { - // Given - var ( - tag1 = "v1.18.0-alpha.2" - tag2 = "v1.18.0" - ) - sut, client := newSUT() - client.ListTagsReturns([]*gogithub.RepositoryTag{ - {Name: &tag1}, - {Name: &tag2}, - }, &gogithub.Response{NextPage: 0}, nil) - - // When - res, err := sut.LatestGitHubTagsPerBranch() - - // Then - require.Nil(t, err) - require.Len(t, res, 2) - require.Equal(t, tag1, res[git.DefaultBranch]) - require.Equal(t, tag2, res["release-1.18"]) -} - -func TestLatestGitHubTagsPerBranchMultiplePages(t *testing.T) { - // Given - var ( - tag1 = "v1.18.0-alpha.2" - tag2 = "v1.18.0" - ) - sut, client := newSUT() - client.ListTagsReturnsOnCall(0, []*gogithub.RepositoryTag{ - {Name: &tag1}, - }, &gogithub.Response{NextPage: 1}, nil) - client.ListTagsReturnsOnCall(1, []*gogithub.RepositoryTag{ - {Name: &tag2}, - }, &gogithub.Response{NextPage: 0}, nil) - - // When - res, err := sut.LatestGitHubTagsPerBranch() - - // Then - require.Nil(t, err) - require.Len(t, res, 2) - require.Equal(t, tag1, res[git.DefaultBranch]) - require.Equal(t, tag2, res["release-1.18"]) -} - -func TestLatestGitHubTagsPerBranchSuccessMultipleForSameBranch(t *testing.T) { - // Given - var ( - tag1 = "v1.18.0-beta.0" - tag2 = "v1.18.0-alpha.3" - tag3 = "v1.15.2" - tag4 = "v1.18.0-alpha.2" - tag5 = "v1.16.3" - tag6 = "v1.18.0-alpha.1" - tag7 = "v1.13.0" - tag8 = "v1.18.0-alpha.2" - ) - sut, client := newSUT() - client.ListTagsReturns([]*gogithub.RepositoryTag{ - {Name: &tag1}, - {Name: &tag2}, - {Name: &tag3}, - {Name: &tag4}, - {Name: &tag5}, - {Name: &tag6}, - {Name: &tag7}, - {Name: &tag8}, - }, &gogithub.Response{NextPage: 0}, nil) - - // When - res, err := sut.LatestGitHubTagsPerBranch() - - // Then - require.Nil(t, err) - require.Len(t, res, 4) - require.Equal(t, tag1, res[git.DefaultBranch]) - require.Empty(t, res["release-1.18"]) - require.Empty(t, res["release-1.17"]) - require.Equal(t, tag5, res["release-1.16"]) - require.Equal(t, tag3, res["release-1.15"]) - require.Empty(t, res["release-1.14"]) - require.Equal(t, tag7, res["release-1.13"]) -} - -func TestLatestGitHubTagsPerBranchSuccessPatchReleases(t *testing.T) { - // Given - var ( - tag1 = "v1.17.1" - tag2 = "v1.16.2" - tag3 = "v1.15.3" - ) - sut, client := newSUT() - client.ListTagsReturns([]*gogithub.RepositoryTag{ - {Name: &tag1}, - {Name: &tag2}, - {Name: &tag3}, - }, &gogithub.Response{NextPage: 0}, nil) - - // When - res, err := sut.LatestGitHubTagsPerBranch() - - // Then - require.Nil(t, err) - require.Len(t, res, 4) - require.Equal(t, tag1, res[git.DefaultBranch]) - require.Equal(t, tag1, res["release-1.17"]) - require.Equal(t, tag2, res["release-1.16"]) - require.Equal(t, tag3, res["release-1.15"]) - require.Empty(t, res["release-1.18"]) -} - -func TestLatestGitHubTagsPerBranchFailedOnList(t *testing.T) { - // Given - sut, client := newSUT() - client.ListTagsReturns(nil, nil, errors.New("error")) - - // When - res, err := sut.LatestGitHubTagsPerBranch() - - // Then - require.NotNil(t, err) - require.Nil(t, res) -} - -func TestLatestGitHubTagsPerBranchSkippedNonSemverTag(t *testing.T) { - // Given - tag1 := "not a semver tag" - sut, client := newSUT() - client.ListTagsReturns([]*gogithub.RepositoryTag{ - {Name: &tag1}, - }, &gogithub.Response{NextPage: 0}, nil) - - // When - res, err := sut.LatestGitHubTagsPerBranch() - - // Then - require.Nil(t, err) - require.Empty(t, res) -} - -func TestReleasesSuccessEmpty(t *testing.T) { - // Given - sut, client := newSUT() - client.ListReleasesReturns([]*gogithub.RepositoryRelease{}, nil, nil) - - // When - res, err := sut.Releases("", "", false) - - // Then - require.Nil(t, err) - require.Empty(t, res) -} - -func TestReleasesSuccessNoPreReleases(t *testing.T) { - // Given - var ( - tag1 = "v1.18.0" - tag2 = "v1.17.0" - tag3 = "v1.16.0" - tag4 = "v1.15.0" - aTrue = true - ) - sut, client := newSUT() - client.ListReleasesReturns([]*gogithub.RepositoryRelease{ - {TagName: &tag1}, - {TagName: &tag2}, - {TagName: &tag3, Prerelease: &aTrue}, - {TagName: &tag4}, - }, nil, nil) - - // When - res, err := sut.Releases("", "", false) - - // Then - require.Nil(t, err) - require.Len(t, res, 3) - require.Equal(t, tag1, res[0].GetTagName()) - require.Equal(t, tag2, res[1].GetTagName()) - require.Equal(t, tag4, res[2].GetTagName()) -} - -func TestReleasesSuccessWithPreReleases(t *testing.T) { - // Given - var ( - tag1 = "v1.18.0" - tag2 = "v1.17.0" - tag3 = "v1.16.0" - tag4 = "v1.15.0" - aTrue = true - ) - sut, client := newSUT() - client.ListReleasesReturns([]*gogithub.RepositoryRelease{ - {TagName: &tag1}, - {TagName: &tag2, Prerelease: &aTrue}, - {TagName: &tag3, Prerelease: &aTrue}, - {TagName: &tag4}, - }, nil, nil) - - // When - res, err := sut.Releases("", "", true) - - // Then - require.Nil(t, err) - require.Len(t, res, 4) - require.Equal(t, tag1, res[0].GetTagName()) - require.Equal(t, tag2, res[1].GetTagName()) - require.Equal(t, tag3, res[2].GetTagName()) - require.Equal(t, tag4, res[3].GetTagName()) -} - -func TestReleasesFailed(t *testing.T) { - // Given - sut, client := newSUT() - client.ListReleasesReturns(nil, nil, errors.New("error")) - - // When - res, err := sut.Releases("", "", false) - - // Then - require.NotNil(t, err) - require.Nil(t, res, nil) -} - -func TestCreatePullRequest(t *testing.T) { - // Given - sut, client := newSUT() - fakeID := int64(1234) - client.CreatePullRequestReturns(&gogithub.PullRequest{ID: &fakeID}, nil) - - // When - pr, err := sut.CreatePullRequest("kubernetes-fake-org", "kubernetes-fake-repo", git.DefaultBranch, "user:head-branch", "PR Title", "PR Body") - - // Then - require.Nil(t, err) - require.NotNil(t, pr, nil) - require.Equal(t, fakeID, pr.GetID()) -} - -func TestGetMilestone(t *testing.T) { - sut, client := newSUT() - // Given - searchTitle := "Target Milestone" - otherTitle := "Another Milestone" - fakeMstoneID := 9999 - - client.ListMilestonesReturns( - []*gogithub.Milestone{ - { - Title: &otherTitle, - }, - { - Number: &fakeMstoneID, - Title: &searchTitle, - }, - }, - &gogithub.Response{NextPage: 0}, - nil, - ) - - // When - for _, tc := range []struct { - Title string - Err bool - }{ - {Title: searchTitle}, - {Title: "Non existent"}, - {Title: "", Err: true}, - } { - ms, exists, err := sut.GetMilestone("test", "test", tc.Title) - - // Then - if searchTitle == tc.Title { - require.True(t, exists) - require.Equal(t, fakeMstoneID, ms.GetNumber()) - require.Equal(t, searchTitle, ms.GetTitle()) - } else { - require.False(t, exists) - } - - if tc.Err { - require.NotNil(t, err) - } else { - require.Nil(t, err) - } - } -} - -func TestGetRepository(t *testing.T) { - // Given - sut, client := newSUT() - fakeRepositoryID := int64(54596517) // k/release - kubernetesUserID := int64(13629408) - kubernetesLogin := "kubernetes" - repoName := "release" - client.GetRepositoryReturns(&gogithub.Repository{ - ID: &fakeRepositoryID, - Name: &repoName, - Owner: &gogithub.User{ - Login: &kubernetesLogin, - ID: &kubernetesUserID, - }, - }, &gogithub.Response{NextPage: 0}, nil) - - // When - repo, err := sut.GetRepository("kubernetes", "release") - - // Then - require.Nil(t, err) - require.NotNil(t, repo, nil) - require.Equal(t, fakeRepositoryID, repo.GetID()) - require.Equal(t, kubernetesUserID, repo.GetOwner().GetID()) - require.Equal(t, kubernetesLogin, repo.GetOwner().GetLogin()) - require.Equal(t, repoName, repo.GetName()) -} - -func TestRepoIsForkOf(t *testing.T) { - // Given - sut, client := newSUT() - - forkOwner := "fork" - parentOwner := "kubernetes" - repoName := "forkedRepo" - - parentFullName := fmt.Sprintf("%s/%s", parentOwner, repoName) - - trueVal := true - - client.GetRepositoryReturns(&gogithub.Repository{ - Name: &repoName, - Fork: &trueVal, - Owner: &gogithub.User{ - Login: &forkOwner, - }, - Parent: &gogithub.Repository{ - Name: &repoName, - Owner: &gogithub.User{ - Login: &parentOwner, - }, - FullName: &parentFullName, - }, - }, &gogithub.Response{NextPage: 0}, nil) - - // When - result, err := sut.RepoIsForkOf("fork", repoName, "kubernetes", repoName) - - // Then - require.Nil(t, err) - require.Equal(t, result, true) -} - -func TestRepoIsNotForkOf(t *testing.T) { - // Given - sut, client := newSUT() - - forkOwner := "fork" - parentOwner := "borg" - repoName := "notForkedRepo" - - parentFullName := fmt.Sprintf("%s/%s", parentOwner, repoName) - - trueVal := true - - client.GetRepositoryReturns(&gogithub.Repository{ - Name: &repoName, - Fork: &trueVal, - Owner: &gogithub.User{ - Login: &forkOwner, - }, - Parent: &gogithub.Repository{ - Name: &repoName, - Owner: &gogithub.User{ - Login: &parentOwner, - }, - FullName: &parentFullName, - }, - }, &gogithub.Response{NextPage: 0}, nil) - - // When - result, err := sut.RepoIsForkOf("fork", repoName, "kubernetes", repoName) - - // Then - require.Nil(t, err) - require.Equal(t, result, false) -} - -func TestListBranches(t *testing.T) { - // Given - sut, client := newSUT() - - branch0 := git.DefaultBranch - branch1 := "myfork" - branch2 := "feature-branch" - - branches := []*gogithub.Branch{ - { - Name: &branch0, - }, - { - Name: &branch1, - }, - { - Name: &branch2, - }, - } - - client.ListBranchesReturns(branches, &gogithub.Response{NextPage: 0}, nil) - - // When - result, err := sut.ListBranches("kubernetes", "kubernotia") - - // Then - require.Nil(t, err) - require.Len(t, result, 3) - require.Equal(t, result[1].GetName(), branch1) -} - -func TestCreateIssue(t *testing.T) { - // Given - sut, client := newSUT() - fakeID := 100000 - title := "Test Issue" - body := "Issue body text" - opts := &github.NewIssueOptions{ - Assignees: []string{"k8s-ci-robot"}, - Milestone: "v1.21", - State: "open", - Labels: []string{"bug"}, - } - issue := &gogithub.Issue{ - Number: &fakeID, - State: &opts.State, - Title: &title, - Body: &body, - } - - for _, tcErr := range []error{errors.New("Test error"), nil} { - // When - client.CreateIssueReturns(issue, tcErr) - newissue, err := sut.CreateIssue("kubernetes-fake-org", "kubernetes-fake-repo", title, body, opts) - - // Then - if tcErr == nil { - require.Nil(t, err) - require.NotNil(t, newissue) - require.Equal(t, fakeID, issue.GetNumber()) - } else { - require.NotNil(t, err) - } - } -} diff --git a/pkg/github/githubfakes/fake_client.go b/pkg/github/githubfakes/fake_client.go deleted file mode 100644 index 8b1e5b0e3b5..00000000000 --- a/pkg/github/githubfakes/fake_client.go +++ /dev/null @@ -1,1838 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by counterfeiter. DO NOT EDIT. -package githubfakes - -import ( - "context" - "io" - "os" - "sync" - - githuba "github.com/google/go-github/v37/github" - "k8s.io/release/pkg/github" -) - -type FakeClient struct { - CreateCommentStub func(context.Context, string, string, int, string) (*githuba.IssueComment, *githuba.Response, error) - createCommentMutex sync.RWMutex - createCommentArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int - arg5 string - } - createCommentReturns struct { - result1 *githuba.IssueComment - result2 *githuba.Response - result3 error - } - createCommentReturnsOnCall map[int]struct { - result1 *githuba.IssueComment - result2 *githuba.Response - result3 error - } - CreateIssueStub func(context.Context, string, string, *githuba.IssueRequest) (*githuba.Issue, error) - createIssueMutex sync.RWMutex - createIssueArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.IssueRequest - } - createIssueReturns struct { - result1 *githuba.Issue - result2 error - } - createIssueReturnsOnCall map[int]struct { - result1 *githuba.Issue - result2 error - } - CreatePullRequestStub func(context.Context, string, string, string, string, string, string) (*githuba.PullRequest, error) - createPullRequestMutex sync.RWMutex - createPullRequestArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - arg5 string - arg6 string - arg7 string - } - createPullRequestReturns struct { - result1 *githuba.PullRequest - result2 error - } - createPullRequestReturnsOnCall map[int]struct { - result1 *githuba.PullRequest - result2 error - } - DeleteReleaseAssetStub func(context.Context, string, string, int64) error - deleteReleaseAssetMutex sync.RWMutex - deleteReleaseAssetArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - } - deleteReleaseAssetReturns struct { - result1 error - } - deleteReleaseAssetReturnsOnCall map[int]struct { - result1 error - } - DownloadReleaseAssetStub func(context.Context, string, string, int64) (io.ReadCloser, string, error) - downloadReleaseAssetMutex sync.RWMutex - downloadReleaseAssetArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - } - downloadReleaseAssetReturns struct { - result1 io.ReadCloser - result2 string - result3 error - } - downloadReleaseAssetReturnsOnCall map[int]struct { - result1 io.ReadCloser - result2 string - result3 error - } - GetCommitStub func(context.Context, string, string, string) (*githuba.Commit, *githuba.Response, error) - getCommitMutex sync.RWMutex - getCommitArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - } - getCommitReturns struct { - result1 *githuba.Commit - result2 *githuba.Response - result3 error - } - getCommitReturnsOnCall map[int]struct { - result1 *githuba.Commit - result2 *githuba.Response - result3 error - } - GetIssueStub func(context.Context, string, string, int) (*githuba.Issue, *githuba.Response, error) - getIssueMutex sync.RWMutex - getIssueArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int - } - getIssueReturns struct { - result1 *githuba.Issue - result2 *githuba.Response - result3 error - } - getIssueReturnsOnCall map[int]struct { - result1 *githuba.Issue - result2 *githuba.Response - result3 error - } - GetPullRequestStub func(context.Context, string, string, int) (*githuba.PullRequest, *githuba.Response, error) - getPullRequestMutex sync.RWMutex - getPullRequestArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int - } - getPullRequestReturns struct { - result1 *githuba.PullRequest - result2 *githuba.Response - result3 error - } - getPullRequestReturnsOnCall map[int]struct { - result1 *githuba.PullRequest - result2 *githuba.Response - result3 error - } - GetReleaseByTagStub func(context.Context, string, string, string) (*githuba.RepositoryRelease, *githuba.Response, error) - getReleaseByTagMutex sync.RWMutex - getReleaseByTagArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - } - getReleaseByTagReturns struct { - result1 *githuba.RepositoryRelease - result2 *githuba.Response - result3 error - } - getReleaseByTagReturnsOnCall map[int]struct { - result1 *githuba.RepositoryRelease - result2 *githuba.Response - result3 error - } - GetRepoCommitStub func(context.Context, string, string, string) (*githuba.RepositoryCommit, *githuba.Response, error) - getRepoCommitMutex sync.RWMutex - getRepoCommitArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - } - getRepoCommitReturns struct { - result1 *githuba.RepositoryCommit - result2 *githuba.Response - result3 error - } - getRepoCommitReturnsOnCall map[int]struct { - result1 *githuba.RepositoryCommit - result2 *githuba.Response - result3 error - } - GetRepositoryStub func(context.Context, string, string) (*githuba.Repository, *githuba.Response, error) - getRepositoryMutex sync.RWMutex - getRepositoryArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - } - getRepositoryReturns struct { - result1 *githuba.Repository - result2 *githuba.Response - result3 error - } - getRepositoryReturnsOnCall map[int]struct { - result1 *githuba.Repository - result2 *githuba.Response - result3 error - } - ListBranchesStub func(context.Context, string, string, *githuba.BranchListOptions) ([]*githuba.Branch, *githuba.Response, error) - listBranchesMutex sync.RWMutex - listBranchesArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.BranchListOptions - } - listBranchesReturns struct { - result1 []*githuba.Branch - result2 *githuba.Response - result3 error - } - listBranchesReturnsOnCall map[int]struct { - result1 []*githuba.Branch - result2 *githuba.Response - result3 error - } - ListCommitsStub func(context.Context, string, string, *githuba.CommitsListOptions) ([]*githuba.RepositoryCommit, *githuba.Response, error) - listCommitsMutex sync.RWMutex - listCommitsArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.CommitsListOptions - } - listCommitsReturns struct { - result1 []*githuba.RepositoryCommit - result2 *githuba.Response - result3 error - } - listCommitsReturnsOnCall map[int]struct { - result1 []*githuba.RepositoryCommit - result2 *githuba.Response - result3 error - } - ListMilestonesStub func(context.Context, string, string, *githuba.MilestoneListOptions) ([]*githuba.Milestone, *githuba.Response, error) - listMilestonesMutex sync.RWMutex - listMilestonesArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.MilestoneListOptions - } - listMilestonesReturns struct { - result1 []*githuba.Milestone - result2 *githuba.Response - result3 error - } - listMilestonesReturnsOnCall map[int]struct { - result1 []*githuba.Milestone - result2 *githuba.Response - result3 error - } - ListPullRequestsWithCommitStub func(context.Context, string, string, string, *githuba.PullRequestListOptions) ([]*githuba.PullRequest, *githuba.Response, error) - listPullRequestsWithCommitMutex sync.RWMutex - listPullRequestsWithCommitArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - arg5 *githuba.PullRequestListOptions - } - listPullRequestsWithCommitReturns struct { - result1 []*githuba.PullRequest - result2 *githuba.Response - result3 error - } - listPullRequestsWithCommitReturnsOnCall map[int]struct { - result1 []*githuba.PullRequest - result2 *githuba.Response - result3 error - } - ListReleaseAssetsStub func(context.Context, string, string, int64, *githuba.ListOptions) ([]*githuba.ReleaseAsset, error) - listReleaseAssetsMutex sync.RWMutex - listReleaseAssetsArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - arg5 *githuba.ListOptions - } - listReleaseAssetsReturns struct { - result1 []*githuba.ReleaseAsset - result2 error - } - listReleaseAssetsReturnsOnCall map[int]struct { - result1 []*githuba.ReleaseAsset - result2 error - } - ListReleasesStub func(context.Context, string, string, *githuba.ListOptions) ([]*githuba.RepositoryRelease, *githuba.Response, error) - listReleasesMutex sync.RWMutex - listReleasesArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.ListOptions - } - listReleasesReturns struct { - result1 []*githuba.RepositoryRelease - result2 *githuba.Response - result3 error - } - listReleasesReturnsOnCall map[int]struct { - result1 []*githuba.RepositoryRelease - result2 *githuba.Response - result3 error - } - ListTagsStub func(context.Context, string, string, *githuba.ListOptions) ([]*githuba.RepositoryTag, *githuba.Response, error) - listTagsMutex sync.RWMutex - listTagsArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.ListOptions - } - listTagsReturns struct { - result1 []*githuba.RepositoryTag - result2 *githuba.Response - result3 error - } - listTagsReturnsOnCall map[int]struct { - result1 []*githuba.RepositoryTag - result2 *githuba.Response - result3 error - } - UpdateReleasePageStub func(context.Context, string, string, int64, *githuba.RepositoryRelease) (*githuba.RepositoryRelease, error) - updateReleasePageMutex sync.RWMutex - updateReleasePageArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - arg5 *githuba.RepositoryRelease - } - updateReleasePageReturns struct { - result1 *githuba.RepositoryRelease - result2 error - } - updateReleasePageReturnsOnCall map[int]struct { - result1 *githuba.RepositoryRelease - result2 error - } - UploadReleaseAssetStub func(context.Context, string, string, int64, *githuba.UploadOptions, *os.File) (*githuba.ReleaseAsset, error) - uploadReleaseAssetMutex sync.RWMutex - uploadReleaseAssetArgsForCall []struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - arg5 *githuba.UploadOptions - arg6 *os.File - } - uploadReleaseAssetReturns struct { - result1 *githuba.ReleaseAsset - result2 error - } - uploadReleaseAssetReturnsOnCall map[int]struct { - result1 *githuba.ReleaseAsset - result2 error - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeClient) CreateComment(arg1 context.Context, arg2 string, arg3 string, arg4 int, arg5 string) (*githuba.IssueComment, *githuba.Response, error) { - fake.createCommentMutex.Lock() - ret, specificReturn := fake.createCommentReturnsOnCall[len(fake.createCommentArgsForCall)] - fake.createCommentArgsForCall = append(fake.createCommentArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int - arg5 string - }{arg1, arg2, arg3, arg4, arg5}) - stub := fake.CreateCommentStub - fakeReturns := fake.createCommentReturns - fake.recordInvocation("CreateComment", []interface{}{arg1, arg2, arg3, arg4, arg5}) - fake.createCommentMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4, arg5) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) CreateCommentCallCount() int { - fake.createCommentMutex.RLock() - defer fake.createCommentMutex.RUnlock() - return len(fake.createCommentArgsForCall) -} - -func (fake *FakeClient) CreateCommentCalls(stub func(context.Context, string, string, int, string) (*githuba.IssueComment, *githuba.Response, error)) { - fake.createCommentMutex.Lock() - defer fake.createCommentMutex.Unlock() - fake.CreateCommentStub = stub -} - -func (fake *FakeClient) CreateCommentArgsForCall(i int) (context.Context, string, string, int, string) { - fake.createCommentMutex.RLock() - defer fake.createCommentMutex.RUnlock() - argsForCall := fake.createCommentArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5 -} - -func (fake *FakeClient) CreateCommentReturns(result1 *githuba.IssueComment, result2 *githuba.Response, result3 error) { - fake.createCommentMutex.Lock() - defer fake.createCommentMutex.Unlock() - fake.CreateCommentStub = nil - fake.createCommentReturns = struct { - result1 *githuba.IssueComment - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) CreateCommentReturnsOnCall(i int, result1 *githuba.IssueComment, result2 *githuba.Response, result3 error) { - fake.createCommentMutex.Lock() - defer fake.createCommentMutex.Unlock() - fake.CreateCommentStub = nil - if fake.createCommentReturnsOnCall == nil { - fake.createCommentReturnsOnCall = make(map[int]struct { - result1 *githuba.IssueComment - result2 *githuba.Response - result3 error - }) - } - fake.createCommentReturnsOnCall[i] = struct { - result1 *githuba.IssueComment - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) CreateIssue(arg1 context.Context, arg2 string, arg3 string, arg4 *githuba.IssueRequest) (*githuba.Issue, error) { - fake.createIssueMutex.Lock() - ret, specificReturn := fake.createIssueReturnsOnCall[len(fake.createIssueArgsForCall)] - fake.createIssueArgsForCall = append(fake.createIssueArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.IssueRequest - }{arg1, arg2, arg3, arg4}) - stub := fake.CreateIssueStub - fakeReturns := fake.createIssueReturns - fake.recordInvocation("CreateIssue", []interface{}{arg1, arg2, arg3, arg4}) - fake.createIssueMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeClient) CreateIssueCallCount() int { - fake.createIssueMutex.RLock() - defer fake.createIssueMutex.RUnlock() - return len(fake.createIssueArgsForCall) -} - -func (fake *FakeClient) CreateIssueCalls(stub func(context.Context, string, string, *githuba.IssueRequest) (*githuba.Issue, error)) { - fake.createIssueMutex.Lock() - defer fake.createIssueMutex.Unlock() - fake.CreateIssueStub = stub -} - -func (fake *FakeClient) CreateIssueArgsForCall(i int) (context.Context, string, string, *githuba.IssueRequest) { - fake.createIssueMutex.RLock() - defer fake.createIssueMutex.RUnlock() - argsForCall := fake.createIssueArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) CreateIssueReturns(result1 *githuba.Issue, result2 error) { - fake.createIssueMutex.Lock() - defer fake.createIssueMutex.Unlock() - fake.CreateIssueStub = nil - fake.createIssueReturns = struct { - result1 *githuba.Issue - result2 error - }{result1, result2} -} - -func (fake *FakeClient) CreateIssueReturnsOnCall(i int, result1 *githuba.Issue, result2 error) { - fake.createIssueMutex.Lock() - defer fake.createIssueMutex.Unlock() - fake.CreateIssueStub = nil - if fake.createIssueReturnsOnCall == nil { - fake.createIssueReturnsOnCall = make(map[int]struct { - result1 *githuba.Issue - result2 error - }) - } - fake.createIssueReturnsOnCall[i] = struct { - result1 *githuba.Issue - result2 error - }{result1, result2} -} - -func (fake *FakeClient) CreatePullRequest(arg1 context.Context, arg2 string, arg3 string, arg4 string, arg5 string, arg6 string, arg7 string) (*githuba.PullRequest, error) { - fake.createPullRequestMutex.Lock() - ret, specificReturn := fake.createPullRequestReturnsOnCall[len(fake.createPullRequestArgsForCall)] - fake.createPullRequestArgsForCall = append(fake.createPullRequestArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - arg5 string - arg6 string - arg7 string - }{arg1, arg2, arg3, arg4, arg5, arg6, arg7}) - stub := fake.CreatePullRequestStub - fakeReturns := fake.createPullRequestReturns - fake.recordInvocation("CreatePullRequest", []interface{}{arg1, arg2, arg3, arg4, arg5, arg6, arg7}) - fake.createPullRequestMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4, arg5, arg6, arg7) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeClient) CreatePullRequestCallCount() int { - fake.createPullRequestMutex.RLock() - defer fake.createPullRequestMutex.RUnlock() - return len(fake.createPullRequestArgsForCall) -} - -func (fake *FakeClient) CreatePullRequestCalls(stub func(context.Context, string, string, string, string, string, string) (*githuba.PullRequest, error)) { - fake.createPullRequestMutex.Lock() - defer fake.createPullRequestMutex.Unlock() - fake.CreatePullRequestStub = stub -} - -func (fake *FakeClient) CreatePullRequestArgsForCall(i int) (context.Context, string, string, string, string, string, string) { - fake.createPullRequestMutex.RLock() - defer fake.createPullRequestMutex.RUnlock() - argsForCall := fake.createPullRequestArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5, argsForCall.arg6, argsForCall.arg7 -} - -func (fake *FakeClient) CreatePullRequestReturns(result1 *githuba.PullRequest, result2 error) { - fake.createPullRequestMutex.Lock() - defer fake.createPullRequestMutex.Unlock() - fake.CreatePullRequestStub = nil - fake.createPullRequestReturns = struct { - result1 *githuba.PullRequest - result2 error - }{result1, result2} -} - -func (fake *FakeClient) CreatePullRequestReturnsOnCall(i int, result1 *githuba.PullRequest, result2 error) { - fake.createPullRequestMutex.Lock() - defer fake.createPullRequestMutex.Unlock() - fake.CreatePullRequestStub = nil - if fake.createPullRequestReturnsOnCall == nil { - fake.createPullRequestReturnsOnCall = make(map[int]struct { - result1 *githuba.PullRequest - result2 error - }) - } - fake.createPullRequestReturnsOnCall[i] = struct { - result1 *githuba.PullRequest - result2 error - }{result1, result2} -} - -func (fake *FakeClient) DeleteReleaseAsset(arg1 context.Context, arg2 string, arg3 string, arg4 int64) error { - fake.deleteReleaseAssetMutex.Lock() - ret, specificReturn := fake.deleteReleaseAssetReturnsOnCall[len(fake.deleteReleaseAssetArgsForCall)] - fake.deleteReleaseAssetArgsForCall = append(fake.deleteReleaseAssetArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - }{arg1, arg2, arg3, arg4}) - stub := fake.DeleteReleaseAssetStub - fakeReturns := fake.deleteReleaseAssetReturns - fake.recordInvocation("DeleteReleaseAsset", []interface{}{arg1, arg2, arg3, arg4}) - fake.deleteReleaseAssetMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeClient) DeleteReleaseAssetCallCount() int { - fake.deleteReleaseAssetMutex.RLock() - defer fake.deleteReleaseAssetMutex.RUnlock() - return len(fake.deleteReleaseAssetArgsForCall) -} - -func (fake *FakeClient) DeleteReleaseAssetCalls(stub func(context.Context, string, string, int64) error) { - fake.deleteReleaseAssetMutex.Lock() - defer fake.deleteReleaseAssetMutex.Unlock() - fake.DeleteReleaseAssetStub = stub -} - -func (fake *FakeClient) DeleteReleaseAssetArgsForCall(i int) (context.Context, string, string, int64) { - fake.deleteReleaseAssetMutex.RLock() - defer fake.deleteReleaseAssetMutex.RUnlock() - argsForCall := fake.deleteReleaseAssetArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) DeleteReleaseAssetReturns(result1 error) { - fake.deleteReleaseAssetMutex.Lock() - defer fake.deleteReleaseAssetMutex.Unlock() - fake.DeleteReleaseAssetStub = nil - fake.deleteReleaseAssetReturns = struct { - result1 error - }{result1} -} - -func (fake *FakeClient) DeleteReleaseAssetReturnsOnCall(i int, result1 error) { - fake.deleteReleaseAssetMutex.Lock() - defer fake.deleteReleaseAssetMutex.Unlock() - fake.DeleteReleaseAssetStub = nil - if fake.deleteReleaseAssetReturnsOnCall == nil { - fake.deleteReleaseAssetReturnsOnCall = make(map[int]struct { - result1 error - }) - } - fake.deleteReleaseAssetReturnsOnCall[i] = struct { - result1 error - }{result1} -} - -func (fake *FakeClient) DownloadReleaseAsset(arg1 context.Context, arg2 string, arg3 string, arg4 int64) (io.ReadCloser, string, error) { - fake.downloadReleaseAssetMutex.Lock() - ret, specificReturn := fake.downloadReleaseAssetReturnsOnCall[len(fake.downloadReleaseAssetArgsForCall)] - fake.downloadReleaseAssetArgsForCall = append(fake.downloadReleaseAssetArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - }{arg1, arg2, arg3, arg4}) - stub := fake.DownloadReleaseAssetStub - fakeReturns := fake.downloadReleaseAssetReturns - fake.recordInvocation("DownloadReleaseAsset", []interface{}{arg1, arg2, arg3, arg4}) - fake.downloadReleaseAssetMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) DownloadReleaseAssetCallCount() int { - fake.downloadReleaseAssetMutex.RLock() - defer fake.downloadReleaseAssetMutex.RUnlock() - return len(fake.downloadReleaseAssetArgsForCall) -} - -func (fake *FakeClient) DownloadReleaseAssetCalls(stub func(context.Context, string, string, int64) (io.ReadCloser, string, error)) { - fake.downloadReleaseAssetMutex.Lock() - defer fake.downloadReleaseAssetMutex.Unlock() - fake.DownloadReleaseAssetStub = stub -} - -func (fake *FakeClient) DownloadReleaseAssetArgsForCall(i int) (context.Context, string, string, int64) { - fake.downloadReleaseAssetMutex.RLock() - defer fake.downloadReleaseAssetMutex.RUnlock() - argsForCall := fake.downloadReleaseAssetArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) DownloadReleaseAssetReturns(result1 io.ReadCloser, result2 string, result3 error) { - fake.downloadReleaseAssetMutex.Lock() - defer fake.downloadReleaseAssetMutex.Unlock() - fake.DownloadReleaseAssetStub = nil - fake.downloadReleaseAssetReturns = struct { - result1 io.ReadCloser - result2 string - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) DownloadReleaseAssetReturnsOnCall(i int, result1 io.ReadCloser, result2 string, result3 error) { - fake.downloadReleaseAssetMutex.Lock() - defer fake.downloadReleaseAssetMutex.Unlock() - fake.DownloadReleaseAssetStub = nil - if fake.downloadReleaseAssetReturnsOnCall == nil { - fake.downloadReleaseAssetReturnsOnCall = make(map[int]struct { - result1 io.ReadCloser - result2 string - result3 error - }) - } - fake.downloadReleaseAssetReturnsOnCall[i] = struct { - result1 io.ReadCloser - result2 string - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetCommit(arg1 context.Context, arg2 string, arg3 string, arg4 string) (*githuba.Commit, *githuba.Response, error) { - fake.getCommitMutex.Lock() - ret, specificReturn := fake.getCommitReturnsOnCall[len(fake.getCommitArgsForCall)] - fake.getCommitArgsForCall = append(fake.getCommitArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - }{arg1, arg2, arg3, arg4}) - stub := fake.GetCommitStub - fakeReturns := fake.getCommitReturns - fake.recordInvocation("GetCommit", []interface{}{arg1, arg2, arg3, arg4}) - fake.getCommitMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) GetCommitCallCount() int { - fake.getCommitMutex.RLock() - defer fake.getCommitMutex.RUnlock() - return len(fake.getCommitArgsForCall) -} - -func (fake *FakeClient) GetCommitCalls(stub func(context.Context, string, string, string) (*githuba.Commit, *githuba.Response, error)) { - fake.getCommitMutex.Lock() - defer fake.getCommitMutex.Unlock() - fake.GetCommitStub = stub -} - -func (fake *FakeClient) GetCommitArgsForCall(i int) (context.Context, string, string, string) { - fake.getCommitMutex.RLock() - defer fake.getCommitMutex.RUnlock() - argsForCall := fake.getCommitArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) GetCommitReturns(result1 *githuba.Commit, result2 *githuba.Response, result3 error) { - fake.getCommitMutex.Lock() - defer fake.getCommitMutex.Unlock() - fake.GetCommitStub = nil - fake.getCommitReturns = struct { - result1 *githuba.Commit - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetCommitReturnsOnCall(i int, result1 *githuba.Commit, result2 *githuba.Response, result3 error) { - fake.getCommitMutex.Lock() - defer fake.getCommitMutex.Unlock() - fake.GetCommitStub = nil - if fake.getCommitReturnsOnCall == nil { - fake.getCommitReturnsOnCall = make(map[int]struct { - result1 *githuba.Commit - result2 *githuba.Response - result3 error - }) - } - fake.getCommitReturnsOnCall[i] = struct { - result1 *githuba.Commit - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetIssue(arg1 context.Context, arg2 string, arg3 string, arg4 int) (*githuba.Issue, *githuba.Response, error) { - fake.getIssueMutex.Lock() - ret, specificReturn := fake.getIssueReturnsOnCall[len(fake.getIssueArgsForCall)] - fake.getIssueArgsForCall = append(fake.getIssueArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int - }{arg1, arg2, arg3, arg4}) - stub := fake.GetIssueStub - fakeReturns := fake.getIssueReturns - fake.recordInvocation("GetIssue", []interface{}{arg1, arg2, arg3, arg4}) - fake.getIssueMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) GetIssueCallCount() int { - fake.getIssueMutex.RLock() - defer fake.getIssueMutex.RUnlock() - return len(fake.getIssueArgsForCall) -} - -func (fake *FakeClient) GetIssueCalls(stub func(context.Context, string, string, int) (*githuba.Issue, *githuba.Response, error)) { - fake.getIssueMutex.Lock() - defer fake.getIssueMutex.Unlock() - fake.GetIssueStub = stub -} - -func (fake *FakeClient) GetIssueArgsForCall(i int) (context.Context, string, string, int) { - fake.getIssueMutex.RLock() - defer fake.getIssueMutex.RUnlock() - argsForCall := fake.getIssueArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) GetIssueReturns(result1 *githuba.Issue, result2 *githuba.Response, result3 error) { - fake.getIssueMutex.Lock() - defer fake.getIssueMutex.Unlock() - fake.GetIssueStub = nil - fake.getIssueReturns = struct { - result1 *githuba.Issue - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetIssueReturnsOnCall(i int, result1 *githuba.Issue, result2 *githuba.Response, result3 error) { - fake.getIssueMutex.Lock() - defer fake.getIssueMutex.Unlock() - fake.GetIssueStub = nil - if fake.getIssueReturnsOnCall == nil { - fake.getIssueReturnsOnCall = make(map[int]struct { - result1 *githuba.Issue - result2 *githuba.Response - result3 error - }) - } - fake.getIssueReturnsOnCall[i] = struct { - result1 *githuba.Issue - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetPullRequest(arg1 context.Context, arg2 string, arg3 string, arg4 int) (*githuba.PullRequest, *githuba.Response, error) { - fake.getPullRequestMutex.Lock() - ret, specificReturn := fake.getPullRequestReturnsOnCall[len(fake.getPullRequestArgsForCall)] - fake.getPullRequestArgsForCall = append(fake.getPullRequestArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int - }{arg1, arg2, arg3, arg4}) - stub := fake.GetPullRequestStub - fakeReturns := fake.getPullRequestReturns - fake.recordInvocation("GetPullRequest", []interface{}{arg1, arg2, arg3, arg4}) - fake.getPullRequestMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) GetPullRequestCallCount() int { - fake.getPullRequestMutex.RLock() - defer fake.getPullRequestMutex.RUnlock() - return len(fake.getPullRequestArgsForCall) -} - -func (fake *FakeClient) GetPullRequestCalls(stub func(context.Context, string, string, int) (*githuba.PullRequest, *githuba.Response, error)) { - fake.getPullRequestMutex.Lock() - defer fake.getPullRequestMutex.Unlock() - fake.GetPullRequestStub = stub -} - -func (fake *FakeClient) GetPullRequestArgsForCall(i int) (context.Context, string, string, int) { - fake.getPullRequestMutex.RLock() - defer fake.getPullRequestMutex.RUnlock() - argsForCall := fake.getPullRequestArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) GetPullRequestReturns(result1 *githuba.PullRequest, result2 *githuba.Response, result3 error) { - fake.getPullRequestMutex.Lock() - defer fake.getPullRequestMutex.Unlock() - fake.GetPullRequestStub = nil - fake.getPullRequestReturns = struct { - result1 *githuba.PullRequest - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetPullRequestReturnsOnCall(i int, result1 *githuba.PullRequest, result2 *githuba.Response, result3 error) { - fake.getPullRequestMutex.Lock() - defer fake.getPullRequestMutex.Unlock() - fake.GetPullRequestStub = nil - if fake.getPullRequestReturnsOnCall == nil { - fake.getPullRequestReturnsOnCall = make(map[int]struct { - result1 *githuba.PullRequest - result2 *githuba.Response - result3 error - }) - } - fake.getPullRequestReturnsOnCall[i] = struct { - result1 *githuba.PullRequest - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetReleaseByTag(arg1 context.Context, arg2 string, arg3 string, arg4 string) (*githuba.RepositoryRelease, *githuba.Response, error) { - fake.getReleaseByTagMutex.Lock() - ret, specificReturn := fake.getReleaseByTagReturnsOnCall[len(fake.getReleaseByTagArgsForCall)] - fake.getReleaseByTagArgsForCall = append(fake.getReleaseByTagArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - }{arg1, arg2, arg3, arg4}) - stub := fake.GetReleaseByTagStub - fakeReturns := fake.getReleaseByTagReturns - fake.recordInvocation("GetReleaseByTag", []interface{}{arg1, arg2, arg3, arg4}) - fake.getReleaseByTagMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) GetReleaseByTagCallCount() int { - fake.getReleaseByTagMutex.RLock() - defer fake.getReleaseByTagMutex.RUnlock() - return len(fake.getReleaseByTagArgsForCall) -} - -func (fake *FakeClient) GetReleaseByTagCalls(stub func(context.Context, string, string, string) (*githuba.RepositoryRelease, *githuba.Response, error)) { - fake.getReleaseByTagMutex.Lock() - defer fake.getReleaseByTagMutex.Unlock() - fake.GetReleaseByTagStub = stub -} - -func (fake *FakeClient) GetReleaseByTagArgsForCall(i int) (context.Context, string, string, string) { - fake.getReleaseByTagMutex.RLock() - defer fake.getReleaseByTagMutex.RUnlock() - argsForCall := fake.getReleaseByTagArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) GetReleaseByTagReturns(result1 *githuba.RepositoryRelease, result2 *githuba.Response, result3 error) { - fake.getReleaseByTagMutex.Lock() - defer fake.getReleaseByTagMutex.Unlock() - fake.GetReleaseByTagStub = nil - fake.getReleaseByTagReturns = struct { - result1 *githuba.RepositoryRelease - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetReleaseByTagReturnsOnCall(i int, result1 *githuba.RepositoryRelease, result2 *githuba.Response, result3 error) { - fake.getReleaseByTagMutex.Lock() - defer fake.getReleaseByTagMutex.Unlock() - fake.GetReleaseByTagStub = nil - if fake.getReleaseByTagReturnsOnCall == nil { - fake.getReleaseByTagReturnsOnCall = make(map[int]struct { - result1 *githuba.RepositoryRelease - result2 *githuba.Response - result3 error - }) - } - fake.getReleaseByTagReturnsOnCall[i] = struct { - result1 *githuba.RepositoryRelease - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetRepoCommit(arg1 context.Context, arg2 string, arg3 string, arg4 string) (*githuba.RepositoryCommit, *githuba.Response, error) { - fake.getRepoCommitMutex.Lock() - ret, specificReturn := fake.getRepoCommitReturnsOnCall[len(fake.getRepoCommitArgsForCall)] - fake.getRepoCommitArgsForCall = append(fake.getRepoCommitArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - }{arg1, arg2, arg3, arg4}) - stub := fake.GetRepoCommitStub - fakeReturns := fake.getRepoCommitReturns - fake.recordInvocation("GetRepoCommit", []interface{}{arg1, arg2, arg3, arg4}) - fake.getRepoCommitMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) GetRepoCommitCallCount() int { - fake.getRepoCommitMutex.RLock() - defer fake.getRepoCommitMutex.RUnlock() - return len(fake.getRepoCommitArgsForCall) -} - -func (fake *FakeClient) GetRepoCommitCalls(stub func(context.Context, string, string, string) (*githuba.RepositoryCommit, *githuba.Response, error)) { - fake.getRepoCommitMutex.Lock() - defer fake.getRepoCommitMutex.Unlock() - fake.GetRepoCommitStub = stub -} - -func (fake *FakeClient) GetRepoCommitArgsForCall(i int) (context.Context, string, string, string) { - fake.getRepoCommitMutex.RLock() - defer fake.getRepoCommitMutex.RUnlock() - argsForCall := fake.getRepoCommitArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) GetRepoCommitReturns(result1 *githuba.RepositoryCommit, result2 *githuba.Response, result3 error) { - fake.getRepoCommitMutex.Lock() - defer fake.getRepoCommitMutex.Unlock() - fake.GetRepoCommitStub = nil - fake.getRepoCommitReturns = struct { - result1 *githuba.RepositoryCommit - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetRepoCommitReturnsOnCall(i int, result1 *githuba.RepositoryCommit, result2 *githuba.Response, result3 error) { - fake.getRepoCommitMutex.Lock() - defer fake.getRepoCommitMutex.Unlock() - fake.GetRepoCommitStub = nil - if fake.getRepoCommitReturnsOnCall == nil { - fake.getRepoCommitReturnsOnCall = make(map[int]struct { - result1 *githuba.RepositoryCommit - result2 *githuba.Response - result3 error - }) - } - fake.getRepoCommitReturnsOnCall[i] = struct { - result1 *githuba.RepositoryCommit - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetRepository(arg1 context.Context, arg2 string, arg3 string) (*githuba.Repository, *githuba.Response, error) { - fake.getRepositoryMutex.Lock() - ret, specificReturn := fake.getRepositoryReturnsOnCall[len(fake.getRepositoryArgsForCall)] - fake.getRepositoryArgsForCall = append(fake.getRepositoryArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - }{arg1, arg2, arg3}) - stub := fake.GetRepositoryStub - fakeReturns := fake.getRepositoryReturns - fake.recordInvocation("GetRepository", []interface{}{arg1, arg2, arg3}) - fake.getRepositoryMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) GetRepositoryCallCount() int { - fake.getRepositoryMutex.RLock() - defer fake.getRepositoryMutex.RUnlock() - return len(fake.getRepositoryArgsForCall) -} - -func (fake *FakeClient) GetRepositoryCalls(stub func(context.Context, string, string) (*githuba.Repository, *githuba.Response, error)) { - fake.getRepositoryMutex.Lock() - defer fake.getRepositoryMutex.Unlock() - fake.GetRepositoryStub = stub -} - -func (fake *FakeClient) GetRepositoryArgsForCall(i int) (context.Context, string, string) { - fake.getRepositoryMutex.RLock() - defer fake.getRepositoryMutex.RUnlock() - argsForCall := fake.getRepositoryArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 -} - -func (fake *FakeClient) GetRepositoryReturns(result1 *githuba.Repository, result2 *githuba.Response, result3 error) { - fake.getRepositoryMutex.Lock() - defer fake.getRepositoryMutex.Unlock() - fake.GetRepositoryStub = nil - fake.getRepositoryReturns = struct { - result1 *githuba.Repository - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) GetRepositoryReturnsOnCall(i int, result1 *githuba.Repository, result2 *githuba.Response, result3 error) { - fake.getRepositoryMutex.Lock() - defer fake.getRepositoryMutex.Unlock() - fake.GetRepositoryStub = nil - if fake.getRepositoryReturnsOnCall == nil { - fake.getRepositoryReturnsOnCall = make(map[int]struct { - result1 *githuba.Repository - result2 *githuba.Response - result3 error - }) - } - fake.getRepositoryReturnsOnCall[i] = struct { - result1 *githuba.Repository - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListBranches(arg1 context.Context, arg2 string, arg3 string, arg4 *githuba.BranchListOptions) ([]*githuba.Branch, *githuba.Response, error) { - fake.listBranchesMutex.Lock() - ret, specificReturn := fake.listBranchesReturnsOnCall[len(fake.listBranchesArgsForCall)] - fake.listBranchesArgsForCall = append(fake.listBranchesArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.BranchListOptions - }{arg1, arg2, arg3, arg4}) - stub := fake.ListBranchesStub - fakeReturns := fake.listBranchesReturns - fake.recordInvocation("ListBranches", []interface{}{arg1, arg2, arg3, arg4}) - fake.listBranchesMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) ListBranchesCallCount() int { - fake.listBranchesMutex.RLock() - defer fake.listBranchesMutex.RUnlock() - return len(fake.listBranchesArgsForCall) -} - -func (fake *FakeClient) ListBranchesCalls(stub func(context.Context, string, string, *githuba.BranchListOptions) ([]*githuba.Branch, *githuba.Response, error)) { - fake.listBranchesMutex.Lock() - defer fake.listBranchesMutex.Unlock() - fake.ListBranchesStub = stub -} - -func (fake *FakeClient) ListBranchesArgsForCall(i int) (context.Context, string, string, *githuba.BranchListOptions) { - fake.listBranchesMutex.RLock() - defer fake.listBranchesMutex.RUnlock() - argsForCall := fake.listBranchesArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) ListBranchesReturns(result1 []*githuba.Branch, result2 *githuba.Response, result3 error) { - fake.listBranchesMutex.Lock() - defer fake.listBranchesMutex.Unlock() - fake.ListBranchesStub = nil - fake.listBranchesReturns = struct { - result1 []*githuba.Branch - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListBranchesReturnsOnCall(i int, result1 []*githuba.Branch, result2 *githuba.Response, result3 error) { - fake.listBranchesMutex.Lock() - defer fake.listBranchesMutex.Unlock() - fake.ListBranchesStub = nil - if fake.listBranchesReturnsOnCall == nil { - fake.listBranchesReturnsOnCall = make(map[int]struct { - result1 []*githuba.Branch - result2 *githuba.Response - result3 error - }) - } - fake.listBranchesReturnsOnCall[i] = struct { - result1 []*githuba.Branch - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListCommits(arg1 context.Context, arg2 string, arg3 string, arg4 *githuba.CommitsListOptions) ([]*githuba.RepositoryCommit, *githuba.Response, error) { - fake.listCommitsMutex.Lock() - ret, specificReturn := fake.listCommitsReturnsOnCall[len(fake.listCommitsArgsForCall)] - fake.listCommitsArgsForCall = append(fake.listCommitsArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.CommitsListOptions - }{arg1, arg2, arg3, arg4}) - stub := fake.ListCommitsStub - fakeReturns := fake.listCommitsReturns - fake.recordInvocation("ListCommits", []interface{}{arg1, arg2, arg3, arg4}) - fake.listCommitsMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) ListCommitsCallCount() int { - fake.listCommitsMutex.RLock() - defer fake.listCommitsMutex.RUnlock() - return len(fake.listCommitsArgsForCall) -} - -func (fake *FakeClient) ListCommitsCalls(stub func(context.Context, string, string, *githuba.CommitsListOptions) ([]*githuba.RepositoryCommit, *githuba.Response, error)) { - fake.listCommitsMutex.Lock() - defer fake.listCommitsMutex.Unlock() - fake.ListCommitsStub = stub -} - -func (fake *FakeClient) ListCommitsArgsForCall(i int) (context.Context, string, string, *githuba.CommitsListOptions) { - fake.listCommitsMutex.RLock() - defer fake.listCommitsMutex.RUnlock() - argsForCall := fake.listCommitsArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) ListCommitsReturns(result1 []*githuba.RepositoryCommit, result2 *githuba.Response, result3 error) { - fake.listCommitsMutex.Lock() - defer fake.listCommitsMutex.Unlock() - fake.ListCommitsStub = nil - fake.listCommitsReturns = struct { - result1 []*githuba.RepositoryCommit - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListCommitsReturnsOnCall(i int, result1 []*githuba.RepositoryCommit, result2 *githuba.Response, result3 error) { - fake.listCommitsMutex.Lock() - defer fake.listCommitsMutex.Unlock() - fake.ListCommitsStub = nil - if fake.listCommitsReturnsOnCall == nil { - fake.listCommitsReturnsOnCall = make(map[int]struct { - result1 []*githuba.RepositoryCommit - result2 *githuba.Response - result3 error - }) - } - fake.listCommitsReturnsOnCall[i] = struct { - result1 []*githuba.RepositoryCommit - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListMilestones(arg1 context.Context, arg2 string, arg3 string, arg4 *githuba.MilestoneListOptions) ([]*githuba.Milestone, *githuba.Response, error) { - fake.listMilestonesMutex.Lock() - ret, specificReturn := fake.listMilestonesReturnsOnCall[len(fake.listMilestonesArgsForCall)] - fake.listMilestonesArgsForCall = append(fake.listMilestonesArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.MilestoneListOptions - }{arg1, arg2, arg3, arg4}) - stub := fake.ListMilestonesStub - fakeReturns := fake.listMilestonesReturns - fake.recordInvocation("ListMilestones", []interface{}{arg1, arg2, arg3, arg4}) - fake.listMilestonesMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) ListMilestonesCallCount() int { - fake.listMilestonesMutex.RLock() - defer fake.listMilestonesMutex.RUnlock() - return len(fake.listMilestonesArgsForCall) -} - -func (fake *FakeClient) ListMilestonesCalls(stub func(context.Context, string, string, *githuba.MilestoneListOptions) ([]*githuba.Milestone, *githuba.Response, error)) { - fake.listMilestonesMutex.Lock() - defer fake.listMilestonesMutex.Unlock() - fake.ListMilestonesStub = stub -} - -func (fake *FakeClient) ListMilestonesArgsForCall(i int) (context.Context, string, string, *githuba.MilestoneListOptions) { - fake.listMilestonesMutex.RLock() - defer fake.listMilestonesMutex.RUnlock() - argsForCall := fake.listMilestonesArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) ListMilestonesReturns(result1 []*githuba.Milestone, result2 *githuba.Response, result3 error) { - fake.listMilestonesMutex.Lock() - defer fake.listMilestonesMutex.Unlock() - fake.ListMilestonesStub = nil - fake.listMilestonesReturns = struct { - result1 []*githuba.Milestone - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListMilestonesReturnsOnCall(i int, result1 []*githuba.Milestone, result2 *githuba.Response, result3 error) { - fake.listMilestonesMutex.Lock() - defer fake.listMilestonesMutex.Unlock() - fake.ListMilestonesStub = nil - if fake.listMilestonesReturnsOnCall == nil { - fake.listMilestonesReturnsOnCall = make(map[int]struct { - result1 []*githuba.Milestone - result2 *githuba.Response - result3 error - }) - } - fake.listMilestonesReturnsOnCall[i] = struct { - result1 []*githuba.Milestone - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListPullRequestsWithCommit(arg1 context.Context, arg2 string, arg3 string, arg4 string, arg5 *githuba.PullRequestListOptions) ([]*githuba.PullRequest, *githuba.Response, error) { - fake.listPullRequestsWithCommitMutex.Lock() - ret, specificReturn := fake.listPullRequestsWithCommitReturnsOnCall[len(fake.listPullRequestsWithCommitArgsForCall)] - fake.listPullRequestsWithCommitArgsForCall = append(fake.listPullRequestsWithCommitArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 string - arg5 *githuba.PullRequestListOptions - }{arg1, arg2, arg3, arg4, arg5}) - stub := fake.ListPullRequestsWithCommitStub - fakeReturns := fake.listPullRequestsWithCommitReturns - fake.recordInvocation("ListPullRequestsWithCommit", []interface{}{arg1, arg2, arg3, arg4, arg5}) - fake.listPullRequestsWithCommitMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4, arg5) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) ListPullRequestsWithCommitCallCount() int { - fake.listPullRequestsWithCommitMutex.RLock() - defer fake.listPullRequestsWithCommitMutex.RUnlock() - return len(fake.listPullRequestsWithCommitArgsForCall) -} - -func (fake *FakeClient) ListPullRequestsWithCommitCalls(stub func(context.Context, string, string, string, *githuba.PullRequestListOptions) ([]*githuba.PullRequest, *githuba.Response, error)) { - fake.listPullRequestsWithCommitMutex.Lock() - defer fake.listPullRequestsWithCommitMutex.Unlock() - fake.ListPullRequestsWithCommitStub = stub -} - -func (fake *FakeClient) ListPullRequestsWithCommitArgsForCall(i int) (context.Context, string, string, string, *githuba.PullRequestListOptions) { - fake.listPullRequestsWithCommitMutex.RLock() - defer fake.listPullRequestsWithCommitMutex.RUnlock() - argsForCall := fake.listPullRequestsWithCommitArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5 -} - -func (fake *FakeClient) ListPullRequestsWithCommitReturns(result1 []*githuba.PullRequest, result2 *githuba.Response, result3 error) { - fake.listPullRequestsWithCommitMutex.Lock() - defer fake.listPullRequestsWithCommitMutex.Unlock() - fake.ListPullRequestsWithCommitStub = nil - fake.listPullRequestsWithCommitReturns = struct { - result1 []*githuba.PullRequest - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListPullRequestsWithCommitReturnsOnCall(i int, result1 []*githuba.PullRequest, result2 *githuba.Response, result3 error) { - fake.listPullRequestsWithCommitMutex.Lock() - defer fake.listPullRequestsWithCommitMutex.Unlock() - fake.ListPullRequestsWithCommitStub = nil - if fake.listPullRequestsWithCommitReturnsOnCall == nil { - fake.listPullRequestsWithCommitReturnsOnCall = make(map[int]struct { - result1 []*githuba.PullRequest - result2 *githuba.Response - result3 error - }) - } - fake.listPullRequestsWithCommitReturnsOnCall[i] = struct { - result1 []*githuba.PullRequest - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListReleaseAssets(arg1 context.Context, arg2 string, arg3 string, arg4 int64, arg5 *githuba.ListOptions) ([]*githuba.ReleaseAsset, error) { - fake.listReleaseAssetsMutex.Lock() - ret, specificReturn := fake.listReleaseAssetsReturnsOnCall[len(fake.listReleaseAssetsArgsForCall)] - fake.listReleaseAssetsArgsForCall = append(fake.listReleaseAssetsArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - arg5 *githuba.ListOptions - }{arg1, arg2, arg3, arg4, arg5}) - stub := fake.ListReleaseAssetsStub - fakeReturns := fake.listReleaseAssetsReturns - fake.recordInvocation("ListReleaseAssets", []interface{}{arg1, arg2, arg3, arg4, arg5}) - fake.listReleaseAssetsMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4, arg5) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeClient) ListReleaseAssetsCallCount() int { - fake.listReleaseAssetsMutex.RLock() - defer fake.listReleaseAssetsMutex.RUnlock() - return len(fake.listReleaseAssetsArgsForCall) -} - -func (fake *FakeClient) ListReleaseAssetsCalls(stub func(context.Context, string, string, int64, *githuba.ListOptions) ([]*githuba.ReleaseAsset, error)) { - fake.listReleaseAssetsMutex.Lock() - defer fake.listReleaseAssetsMutex.Unlock() - fake.ListReleaseAssetsStub = stub -} - -func (fake *FakeClient) ListReleaseAssetsArgsForCall(i int) (context.Context, string, string, int64, *githuba.ListOptions) { - fake.listReleaseAssetsMutex.RLock() - defer fake.listReleaseAssetsMutex.RUnlock() - argsForCall := fake.listReleaseAssetsArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5 -} - -func (fake *FakeClient) ListReleaseAssetsReturns(result1 []*githuba.ReleaseAsset, result2 error) { - fake.listReleaseAssetsMutex.Lock() - defer fake.listReleaseAssetsMutex.Unlock() - fake.ListReleaseAssetsStub = nil - fake.listReleaseAssetsReturns = struct { - result1 []*githuba.ReleaseAsset - result2 error - }{result1, result2} -} - -func (fake *FakeClient) ListReleaseAssetsReturnsOnCall(i int, result1 []*githuba.ReleaseAsset, result2 error) { - fake.listReleaseAssetsMutex.Lock() - defer fake.listReleaseAssetsMutex.Unlock() - fake.ListReleaseAssetsStub = nil - if fake.listReleaseAssetsReturnsOnCall == nil { - fake.listReleaseAssetsReturnsOnCall = make(map[int]struct { - result1 []*githuba.ReleaseAsset - result2 error - }) - } - fake.listReleaseAssetsReturnsOnCall[i] = struct { - result1 []*githuba.ReleaseAsset - result2 error - }{result1, result2} -} - -func (fake *FakeClient) ListReleases(arg1 context.Context, arg2 string, arg3 string, arg4 *githuba.ListOptions) ([]*githuba.RepositoryRelease, *githuba.Response, error) { - fake.listReleasesMutex.Lock() - ret, specificReturn := fake.listReleasesReturnsOnCall[len(fake.listReleasesArgsForCall)] - fake.listReleasesArgsForCall = append(fake.listReleasesArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.ListOptions - }{arg1, arg2, arg3, arg4}) - stub := fake.ListReleasesStub - fakeReturns := fake.listReleasesReturns - fake.recordInvocation("ListReleases", []interface{}{arg1, arg2, arg3, arg4}) - fake.listReleasesMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) ListReleasesCallCount() int { - fake.listReleasesMutex.RLock() - defer fake.listReleasesMutex.RUnlock() - return len(fake.listReleasesArgsForCall) -} - -func (fake *FakeClient) ListReleasesCalls(stub func(context.Context, string, string, *githuba.ListOptions) ([]*githuba.RepositoryRelease, *githuba.Response, error)) { - fake.listReleasesMutex.Lock() - defer fake.listReleasesMutex.Unlock() - fake.ListReleasesStub = stub -} - -func (fake *FakeClient) ListReleasesArgsForCall(i int) (context.Context, string, string, *githuba.ListOptions) { - fake.listReleasesMutex.RLock() - defer fake.listReleasesMutex.RUnlock() - argsForCall := fake.listReleasesArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) ListReleasesReturns(result1 []*githuba.RepositoryRelease, result2 *githuba.Response, result3 error) { - fake.listReleasesMutex.Lock() - defer fake.listReleasesMutex.Unlock() - fake.ListReleasesStub = nil - fake.listReleasesReturns = struct { - result1 []*githuba.RepositoryRelease - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListReleasesReturnsOnCall(i int, result1 []*githuba.RepositoryRelease, result2 *githuba.Response, result3 error) { - fake.listReleasesMutex.Lock() - defer fake.listReleasesMutex.Unlock() - fake.ListReleasesStub = nil - if fake.listReleasesReturnsOnCall == nil { - fake.listReleasesReturnsOnCall = make(map[int]struct { - result1 []*githuba.RepositoryRelease - result2 *githuba.Response - result3 error - }) - } - fake.listReleasesReturnsOnCall[i] = struct { - result1 []*githuba.RepositoryRelease - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListTags(arg1 context.Context, arg2 string, arg3 string, arg4 *githuba.ListOptions) ([]*githuba.RepositoryTag, *githuba.Response, error) { - fake.listTagsMutex.Lock() - ret, specificReturn := fake.listTagsReturnsOnCall[len(fake.listTagsArgsForCall)] - fake.listTagsArgsForCall = append(fake.listTagsArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 *githuba.ListOptions - }{arg1, arg2, arg3, arg4}) - stub := fake.ListTagsStub - fakeReturns := fake.listTagsReturns - fake.recordInvocation("ListTags", []interface{}{arg1, arg2, arg3, arg4}) - fake.listTagsMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4) - } - if specificReturn { - return ret.result1, ret.result2, ret.result3 - } - return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 -} - -func (fake *FakeClient) ListTagsCallCount() int { - fake.listTagsMutex.RLock() - defer fake.listTagsMutex.RUnlock() - return len(fake.listTagsArgsForCall) -} - -func (fake *FakeClient) ListTagsCalls(stub func(context.Context, string, string, *githuba.ListOptions) ([]*githuba.RepositoryTag, *githuba.Response, error)) { - fake.listTagsMutex.Lock() - defer fake.listTagsMutex.Unlock() - fake.ListTagsStub = stub -} - -func (fake *FakeClient) ListTagsArgsForCall(i int) (context.Context, string, string, *githuba.ListOptions) { - fake.listTagsMutex.RLock() - defer fake.listTagsMutex.RUnlock() - argsForCall := fake.listTagsArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4 -} - -func (fake *FakeClient) ListTagsReturns(result1 []*githuba.RepositoryTag, result2 *githuba.Response, result3 error) { - fake.listTagsMutex.Lock() - defer fake.listTagsMutex.Unlock() - fake.ListTagsStub = nil - fake.listTagsReturns = struct { - result1 []*githuba.RepositoryTag - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) ListTagsReturnsOnCall(i int, result1 []*githuba.RepositoryTag, result2 *githuba.Response, result3 error) { - fake.listTagsMutex.Lock() - defer fake.listTagsMutex.Unlock() - fake.ListTagsStub = nil - if fake.listTagsReturnsOnCall == nil { - fake.listTagsReturnsOnCall = make(map[int]struct { - result1 []*githuba.RepositoryTag - result2 *githuba.Response - result3 error - }) - } - fake.listTagsReturnsOnCall[i] = struct { - result1 []*githuba.RepositoryTag - result2 *githuba.Response - result3 error - }{result1, result2, result3} -} - -func (fake *FakeClient) UpdateReleasePage(arg1 context.Context, arg2 string, arg3 string, arg4 int64, arg5 *githuba.RepositoryRelease) (*githuba.RepositoryRelease, error) { - fake.updateReleasePageMutex.Lock() - ret, specificReturn := fake.updateReleasePageReturnsOnCall[len(fake.updateReleasePageArgsForCall)] - fake.updateReleasePageArgsForCall = append(fake.updateReleasePageArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - arg5 *githuba.RepositoryRelease - }{arg1, arg2, arg3, arg4, arg5}) - stub := fake.UpdateReleasePageStub - fakeReturns := fake.updateReleasePageReturns - fake.recordInvocation("UpdateReleasePage", []interface{}{arg1, arg2, arg3, arg4, arg5}) - fake.updateReleasePageMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4, arg5) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeClient) UpdateReleasePageCallCount() int { - fake.updateReleasePageMutex.RLock() - defer fake.updateReleasePageMutex.RUnlock() - return len(fake.updateReleasePageArgsForCall) -} - -func (fake *FakeClient) UpdateReleasePageCalls(stub func(context.Context, string, string, int64, *githuba.RepositoryRelease) (*githuba.RepositoryRelease, error)) { - fake.updateReleasePageMutex.Lock() - defer fake.updateReleasePageMutex.Unlock() - fake.UpdateReleasePageStub = stub -} - -func (fake *FakeClient) UpdateReleasePageArgsForCall(i int) (context.Context, string, string, int64, *githuba.RepositoryRelease) { - fake.updateReleasePageMutex.RLock() - defer fake.updateReleasePageMutex.RUnlock() - argsForCall := fake.updateReleasePageArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5 -} - -func (fake *FakeClient) UpdateReleasePageReturns(result1 *githuba.RepositoryRelease, result2 error) { - fake.updateReleasePageMutex.Lock() - defer fake.updateReleasePageMutex.Unlock() - fake.UpdateReleasePageStub = nil - fake.updateReleasePageReturns = struct { - result1 *githuba.RepositoryRelease - result2 error - }{result1, result2} -} - -func (fake *FakeClient) UpdateReleasePageReturnsOnCall(i int, result1 *githuba.RepositoryRelease, result2 error) { - fake.updateReleasePageMutex.Lock() - defer fake.updateReleasePageMutex.Unlock() - fake.UpdateReleasePageStub = nil - if fake.updateReleasePageReturnsOnCall == nil { - fake.updateReleasePageReturnsOnCall = make(map[int]struct { - result1 *githuba.RepositoryRelease - result2 error - }) - } - fake.updateReleasePageReturnsOnCall[i] = struct { - result1 *githuba.RepositoryRelease - result2 error - }{result1, result2} -} - -func (fake *FakeClient) UploadReleaseAsset(arg1 context.Context, arg2 string, arg3 string, arg4 int64, arg5 *githuba.UploadOptions, arg6 *os.File) (*githuba.ReleaseAsset, error) { - fake.uploadReleaseAssetMutex.Lock() - ret, specificReturn := fake.uploadReleaseAssetReturnsOnCall[len(fake.uploadReleaseAssetArgsForCall)] - fake.uploadReleaseAssetArgsForCall = append(fake.uploadReleaseAssetArgsForCall, struct { - arg1 context.Context - arg2 string - arg3 string - arg4 int64 - arg5 *githuba.UploadOptions - arg6 *os.File - }{arg1, arg2, arg3, arg4, arg5, arg6}) - stub := fake.UploadReleaseAssetStub - fakeReturns := fake.uploadReleaseAssetReturns - fake.recordInvocation("UploadReleaseAsset", []interface{}{arg1, arg2, arg3, arg4, arg5, arg6}) - fake.uploadReleaseAssetMutex.Unlock() - if stub != nil { - return stub(arg1, arg2, arg3, arg4, arg5, arg6) - } - if specificReturn { - return ret.result1, ret.result2 - } - return fakeReturns.result1, fakeReturns.result2 -} - -func (fake *FakeClient) UploadReleaseAssetCallCount() int { - fake.uploadReleaseAssetMutex.RLock() - defer fake.uploadReleaseAssetMutex.RUnlock() - return len(fake.uploadReleaseAssetArgsForCall) -} - -func (fake *FakeClient) UploadReleaseAssetCalls(stub func(context.Context, string, string, int64, *githuba.UploadOptions, *os.File) (*githuba.ReleaseAsset, error)) { - fake.uploadReleaseAssetMutex.Lock() - defer fake.uploadReleaseAssetMutex.Unlock() - fake.UploadReleaseAssetStub = stub -} - -func (fake *FakeClient) UploadReleaseAssetArgsForCall(i int) (context.Context, string, string, int64, *githuba.UploadOptions, *os.File) { - fake.uploadReleaseAssetMutex.RLock() - defer fake.uploadReleaseAssetMutex.RUnlock() - argsForCall := fake.uploadReleaseAssetArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5, argsForCall.arg6 -} - -func (fake *FakeClient) UploadReleaseAssetReturns(result1 *githuba.ReleaseAsset, result2 error) { - fake.uploadReleaseAssetMutex.Lock() - defer fake.uploadReleaseAssetMutex.Unlock() - fake.UploadReleaseAssetStub = nil - fake.uploadReleaseAssetReturns = struct { - result1 *githuba.ReleaseAsset - result2 error - }{result1, result2} -} - -func (fake *FakeClient) UploadReleaseAssetReturnsOnCall(i int, result1 *githuba.ReleaseAsset, result2 error) { - fake.uploadReleaseAssetMutex.Lock() - defer fake.uploadReleaseAssetMutex.Unlock() - fake.UploadReleaseAssetStub = nil - if fake.uploadReleaseAssetReturnsOnCall == nil { - fake.uploadReleaseAssetReturnsOnCall = make(map[int]struct { - result1 *githuba.ReleaseAsset - result2 error - }) - } - fake.uploadReleaseAssetReturnsOnCall[i] = struct { - result1 *githuba.ReleaseAsset - result2 error - }{result1, result2} -} - -func (fake *FakeClient) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.createCommentMutex.RLock() - defer fake.createCommentMutex.RUnlock() - fake.createIssueMutex.RLock() - defer fake.createIssueMutex.RUnlock() - fake.createPullRequestMutex.RLock() - defer fake.createPullRequestMutex.RUnlock() - fake.deleteReleaseAssetMutex.RLock() - defer fake.deleteReleaseAssetMutex.RUnlock() - fake.downloadReleaseAssetMutex.RLock() - defer fake.downloadReleaseAssetMutex.RUnlock() - fake.getCommitMutex.RLock() - defer fake.getCommitMutex.RUnlock() - fake.getIssueMutex.RLock() - defer fake.getIssueMutex.RUnlock() - fake.getPullRequestMutex.RLock() - defer fake.getPullRequestMutex.RUnlock() - fake.getReleaseByTagMutex.RLock() - defer fake.getReleaseByTagMutex.RUnlock() - fake.getRepoCommitMutex.RLock() - defer fake.getRepoCommitMutex.RUnlock() - fake.getRepositoryMutex.RLock() - defer fake.getRepositoryMutex.RUnlock() - fake.listBranchesMutex.RLock() - defer fake.listBranchesMutex.RUnlock() - fake.listCommitsMutex.RLock() - defer fake.listCommitsMutex.RUnlock() - fake.listMilestonesMutex.RLock() - defer fake.listMilestonesMutex.RUnlock() - fake.listPullRequestsWithCommitMutex.RLock() - defer fake.listPullRequestsWithCommitMutex.RUnlock() - fake.listReleaseAssetsMutex.RLock() - defer fake.listReleaseAssetsMutex.RUnlock() - fake.listReleasesMutex.RLock() - defer fake.listReleasesMutex.RUnlock() - fake.listTagsMutex.RLock() - defer fake.listTagsMutex.RUnlock() - fake.updateReleasePageMutex.RLock() - defer fake.updateReleasePageMutex.RUnlock() - fake.uploadReleaseAssetMutex.RLock() - defer fake.uploadReleaseAssetMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeClient) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ github.Client = new(FakeClient) diff --git a/pkg/github/internal/retry.go b/pkg/github/internal/retry.go deleted file mode 100644 index db004e09d90..00000000000 --- a/pkg/github/internal/retry.go +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package internal - -import ( - "time" - - "github.com/google/go-github/v37/github" - "github.com/sirupsen/logrus" -) - -const ( - // MaxGithubRetries is the maximum amount of times we flag a GitHub error as - // retryable before we give up and do not flag the same call as retryable - // anymore. - MaxGithubRetries = 3 - - // defaultGithubSleep is the amount of time we wait between two consecutive - // GitHub calls in case we cannot extract that information from the error - // itself. - defaultGithubSleep = time.Minute -) - -// DefaultGithubErrChecker is a GithubErrChecker set up with a default amount -// of retries and the default sleep function. -func DefaultGithubErrChecker() func(error) bool { - return GithubErrChecker(MaxGithubRetries, time.Sleep) -} - -// GithubErrChecker returns a function that checks errors from GitHub and -// decides if they can / should be retried. -// It needs to be called with `maxTries`, a number of retries a single call -// should be retried at max, and `sleeper`, a function which implements the -// sleeping. -// -// Currently the only special error that is flagged as retryable is the -// `AbuseRateLimitError`. If such an error occurs, we sleep for a while (the -// amount of time the error told us to wait) and then report back that we can -// retry. -// Other special errors should be easy to implement too. -// -// It can be used like this: -// for shouldRetry := GithubErrChecker(10, time.Sleep); ; { -// commit, res, err := github_client.GetCommit(...) -// if !shouldRetry(err) { -// return commit, res, err -// } -// } -func GithubErrChecker(maxTries int, sleeper func(time.Duration)) func(error) bool { - try := 0 - - return func(err error) bool { - if err == nil { - return false - } - if try >= maxTries { - logrus.Errorf("Max retries (%d) reached, not retrying anymore: %v", maxTries, err) - return false - } - - try++ - - if aerr, ok := err.(*github.AbuseRateLimitError); ok { - waitDuration := defaultGithubSleep - if d := aerr.RetryAfter; d != nil { - waitDuration = *d - } - logrus. - WithField("err", aerr). - Infof("Hit the abuse rate limit on try %d, sleeping for %s", try, waitDuration) - sleeper(waitDuration) - return true - } - - return false - } -} diff --git a/pkg/github/internal/retry_test.go b/pkg/github/internal/retry_test.go deleted file mode 100644 index 77aa0732df8..00000000000 --- a/pkg/github/internal/retry_test.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package internal_test - -import ( - "fmt" - "io" - "os" - "testing" - "time" - - "github.com/google/go-github/v37/github" - "github.com/sirupsen/logrus" - "k8s.io/release/pkg/github/internal" -) - -func TestMain(m *testing.M) { - // logrus, shut up - logrus.SetOutput(io.Discard) - os.Exit(m.Run()) -} - -func TestGithubRetryer(t *testing.T) { - tests := map[string]struct { - maxTries int - sleeper func(time.Duration) - errs []error - expectedResults []bool - }{ - "never retry": { - maxTries: 0, - }, - "when error is nil, don't retry": { - maxTries: 1, - sleeper: nilSleeper, - errs: []error{nil}, - expectedResults: []bool{false}, - }, - "when error is a random error, don't retry": { - maxTries: 1, - sleeper: nilSleeper, - errs: []error{fmt.Errorf("some randm error")}, - expectedResults: []bool{false}, - }, - "when the error is a github abuse rate limit error, retry": { - maxTries: 1, - sleeper: nilSleeper, - errs: []error{&github.AbuseRateLimitError{}}, - expectedResults: []bool{true}, - }, - "when the error is a github abuse rate limit error but max tries have been reached, don't retry": { - maxTries: 2, - sleeper: nilSleeper, - errs: []error{ - &github.AbuseRateLimitError{}, - &github.AbuseRateLimitError{}, - &github.AbuseRateLimitError{}, - }, - expectedResults: []bool{ - true, true, false, - }, - }, - "when no RetryAfter is specified on the abuse rate limit error, sleep the default amount of time": { - maxTries: 1, - sleeper: sleepChecker(t, 1*time.Minute), - errs: []error{&github.AbuseRateLimitError{}}, - expectedResults: []bool{true}, - }, - "when a RetryAfter is specified on the abuse rate limit error, sleep that amount of time": { - maxTries: 1, - sleeper: sleepChecker(t, 42*time.Minute), - errs: []error{&github.AbuseRateLimitError{RetryAfter: durPtr(42 * time.Minute)}}, - expectedResults: []bool{true}, - }, - } - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - tc := tc - t.Parallel() - - shouldRetry := internal.GithubErrChecker(tc.maxTries, nilSleeper) - - for i, err := range tc.errs { - if a, e := shouldRetry(err), tc.expectedResults[i]; e != a { - t.Errorf("Expected to get %t, got: %t", e, a) - } - } - }) - } -} - -func sleepChecker(t *testing.T, expectedSleep time.Duration) func(time.Duration) { - return func(d time.Duration) { - if d != expectedSleep { - t.Errorf("Expected the sleeper to be called with a duration %s, got called with %s", expectedSleep, d) - } - } -} - -func nilSleeper(_ time.Duration) { -} - -func durPtr(d time.Duration) *time.Duration { - return &d -} diff --git a/pkg/github/record.go b/pkg/github/record.go deleted file mode 100644 index 4afabfccc30..00000000000 --- a/pkg/github/record.go +++ /dev/null @@ -1,326 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package github - -import ( - "context" - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" - "sync" - - "github.com/google/go-github/v37/github" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -type gitHubAPI string - -const ( - gitHubAPIGetCommit gitHubAPI = "GetCommit" - gitHubAPIGetPullRequest gitHubAPI = "GetPullRequest" - gitHubAPIGetIssue gitHubAPI = "GetIssue" - gitHubAPIGetRepoCommit gitHubAPI = "GetRepoCommit" - gitHubAPIListCommits gitHubAPI = "ListCommits" - gitHubAPIListPullRequestsWithCommit gitHubAPI = "ListPullRequestsWithCommit" - gitHubAPIListReleases gitHubAPI = "ListReleases" - gitHubAPIListTags gitHubAPI = "ListTags" - gitHubAPIGetRepository gitHubAPI = "GetRepository" - gitHubAPIListBranches gitHubAPI = "ListBranches" - gitHubAPIGetReleaseByTag gitHubAPI = "GetReleaseByTag" - gitHubAPIListReleaseAssets gitHubAPI = "ListReleaseAssets" - gitHubAPICreateComment gitHubAPI = "CreateComment" - gitHubAPIListMilestones gitHubAPI = "ListMilestones" -) - -type apiRecord struct { - Result interface{} - LastPage int -} - -func (a *apiRecord) response() *github.Response { - return &github.Response{LastPage: a.LastPage} -} - -func NewRecorder(c Client, recordDir string) Client { - return &githubNotesRecordClient{ - client: c, - recordDir: recordDir, - recordState: map[gitHubAPI]int{}, - } -} - -type githubNotesRecordClient struct { - client Client - recordDir string - recordMutex sync.Mutex - recordState map[gitHubAPI]int -} - -func (c *githubNotesRecordClient) GetCommit(ctx context.Context, owner, repo, sha string) (*github.Commit, *github.Response, error) { - commit, resp, err := c.client.GetCommit(ctx, owner, repo, sha) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIGetCommit, commit, resp); err != nil { - return nil, nil, err - } - return commit, resp, nil -} - -func (c *githubNotesRecordClient) ListCommits(ctx context.Context, owner, repo string, opt *github.CommitsListOptions) ([]*github.RepositoryCommit, *github.Response, error) { - commits, resp, err := c.client.ListCommits(ctx, owner, repo, opt) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIListCommits, commits, resp); err != nil { - return nil, nil, err - } - return commits, resp, nil -} - -func (c *githubNotesRecordClient) ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opt *github.PullRequestListOptions) ([]*github.PullRequest, *github.Response, error) { - prs, resp, err := c.client.ListPullRequestsWithCommit(ctx, owner, repo, sha, opt) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIListPullRequestsWithCommit, prs, resp); err != nil { - return nil, nil, err - } - return prs, resp, nil -} - -func (c *githubNotesRecordClient) GetPullRequest(ctx context.Context, owner, repo string, number int) (*github.PullRequest, *github.Response, error) { - pr, resp, err := c.client.GetPullRequest(ctx, owner, repo, number) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIGetPullRequest, pr, resp); err != nil { - return nil, nil, err - } - return pr, resp, nil -} - -func (c *githubNotesRecordClient) GetIssue(ctx context.Context, owner, repo string, number int) (*github.Issue, *github.Response, error) { - issue, resp, err := c.client.GetIssue(ctx, owner, repo, number) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIGetIssue, issue, resp); err != nil { - return nil, nil, err - } - return issue, resp, nil -} - -func (c *githubNotesRecordClient) GetRepoCommit(ctx context.Context, owner, repo, sha string) (*github.RepositoryCommit, *github.Response, error) { - commit, resp, err := c.client.GetRepoCommit(ctx, owner, repo, sha) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIGetRepoCommit, commit, resp); err != nil { - return nil, nil, err - } - return commit, resp, nil -} - -func (c *githubNotesRecordClient) ListReleases( - ctx context.Context, owner, repo string, opt *github.ListOptions, -) ([]*github.RepositoryRelease, *github.Response, error) { - releases, resp, err := c.client.ListReleases(ctx, owner, repo, opt) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIListReleases, releases, resp); err != nil { - return nil, nil, err - } - return releases, resp, nil -} - -func (c *githubNotesRecordClient) GetReleaseByTag( - ctx context.Context, owner, repo, tag string, -) (*github.RepositoryRelease, *github.Response, error) { - release, resp, err := c.client.GetReleaseByTag(ctx, owner, repo, tag) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIGetReleaseByTag, release, resp); err != nil { - return nil, nil, err - } - return release, resp, nil -} - -// TODO: Complete logic -func (c *githubNotesRecordClient) DownloadReleaseAsset( - context.Context, string, string, int64, -) (io.ReadCloser, string, error) { - return nil, "", nil -} - -func (c *githubNotesRecordClient) ListTags( - ctx context.Context, owner, repo string, opt *github.ListOptions, -) ([]*github.RepositoryTag, *github.Response, error) { - tags, resp, err := c.client.ListTags(ctx, owner, repo, opt) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIListTags, tags, resp); err != nil { - return nil, nil, err - } - return tags, resp, nil -} - -func (c *githubNotesRecordClient) CreatePullRequest( - ctx context.Context, owner, repo, baseBranchName, headBranchName, title, body string, -) (*github.PullRequest, error) { - return &github.PullRequest{}, nil -} - -func (c *githubNotesRecordClient) CreateIssue( - ctx context.Context, owner, repo string, req *github.IssueRequest, -) (*github.Issue, error) { - return &github.Issue{}, nil -} - -func (c *githubNotesRecordClient) GetRepository( - ctx context.Context, owner, repo string, -) (*github.Repository, *github.Response, error) { - repository, resp, err := c.client.GetRepository(ctx, owner, repo) - if err != nil { - return repository, resp, err - } - - if err := c.recordAPICall(gitHubAPIGetRepository, repository, resp); err != nil { - return nil, nil, err - } - - return repository, resp, nil -} - -func (c *githubNotesRecordClient) ListBranches( - ctx context.Context, owner, repo string, opts *github.BranchListOptions, -) ([]*github.Branch, *github.Response, error) { - branches, resp, err := c.client.ListBranches(ctx, owner, repo, opts) - if err != nil { - return branches, resp, err - } - - if err := c.recordAPICall(gitHubAPIListBranches, branches, resp); err != nil { - return nil, nil, err - } - - return branches, resp, nil -} - -// UpdateReleasePage modifies a release, not recorded -func (c *githubNotesRecordClient) UpdateReleasePage( - ctx context.Context, owner, repo string, releaseID int64, releaseData *github.RepositoryRelease, -) (*github.RepositoryRelease, error) { - return &github.RepositoryRelease{}, nil -} - -// UploadReleaseAsset uploads files, not recorded -func (c *githubNotesRecordClient) UploadReleaseAsset( - context.Context, string, string, int64, *github.UploadOptions, *os.File, -) (*github.ReleaseAsset, error) { - return &github.ReleaseAsset{}, nil -} - -// DeleteReleaseAsset removes an asset from a page, note recorded -func (c *githubNotesRecordClient) DeleteReleaseAsset( - ctx context.Context, owner, repo string, assetID int64) error { - return nil -} - -func (c *githubNotesRecordClient) ListReleaseAssets( - ctx context.Context, owner, repo string, releaseID int64, opts *github.ListOptions, -) ([]*github.ReleaseAsset, error) { - assets, err := c.client.ListReleaseAssets(ctx, owner, repo, releaseID, opts) - if err != nil { - return assets, err - } - - if err := c.recordAPICall(gitHubAPIListReleaseAssets, assets, nil); err != nil { - return nil, err - } - - return assets, nil -} - -func (c *githubNotesRecordClient) ListMilestones( - ctx context.Context, owner, repo string, opts *github.MilestoneListOptions, -) ([]*github.Milestone, *github.Response, error) { - mstones, resp, err := c.client.ListMilestones(ctx, owner, repo, opts) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIListMilestones, mstones, resp); err != nil { - return nil, nil, err - } - return mstones, resp, nil -} - -func (c *githubNotesRecordClient) CreateComment(ctx context.Context, owner, repo string, number int, message string) (*github.IssueComment, *github.Response, error) { - issueComment, resp, err := c.client.CreateComment(ctx, owner, repo, number, message) - if err != nil { - return nil, nil, err - } - if err := c.recordAPICall(gitHubAPIGetIssue, issueComment, resp); err != nil { - return nil, nil, err - } - return issueComment, resp, nil -} - -// recordAPICall records a single GitHub API call into a JSON file by ensuring -// naming conventions -func (c *githubNotesRecordClient) recordAPICall( - api gitHubAPI, result interface{}, response *github.Response, -) error { - if result == nil { - return errors.New("no result to record") - } - logrus.Debugf("Recording API call %s to %s", api, c.recordDir) - - c.recordMutex.Lock() - defer c.recordMutex.Unlock() - - i := 0 - if j, ok := c.recordState[api]; ok { - i = j + 1 - } - c.recordState[api] = i - - fileName := fmt.Sprintf("%s-%d.json", api, i) - - lastPage := 0 - if response != nil { - lastPage = response.LastPage - } - - file, err := json.MarshalIndent(&apiRecord{result, lastPage}, "", " ") - if err != nil { - return err - } - if err := os.WriteFile( - filepath.Join(c.recordDir, fileName), file, os.FileMode(0o644), - ); err != nil { - return err - } - - return nil -} diff --git a/pkg/github/replay.go b/pkg/github/replay.go deleted file mode 100644 index 0776eee56bd..00000000000 --- a/pkg/github/replay.go +++ /dev/null @@ -1,296 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package github - -import ( - "context" - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" - "sync" - - "github.com/google/go-github/v37/github" -) - -func NewReplayer(replayDir string) Client { - return &githubNotesReplayClient{ - replayDir: replayDir, - replayState: map[gitHubAPI]int{}, - } -} - -type githubNotesReplayClient struct { - replayDir string - replayMutex sync.Mutex - replayState map[gitHubAPI]int -} - -func (c *githubNotesReplayClient) GetCommit(ctx context.Context, owner, repo, sha string) (*github.Commit, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIGetCommit) - if err != nil { - return nil, nil, err - } - result := &github.Commit{} - record := apiRecord{Result: result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} - -func (c *githubNotesReplayClient) ListCommits(ctx context.Context, owner, repo string, opt *github.CommitsListOptions) ([]*github.RepositoryCommit, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIListCommits) - if err != nil { - return nil, nil, err - } - result := []*github.RepositoryCommit{} - record := apiRecord{Result: &result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} - -func (c *githubNotesReplayClient) ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opt *github.PullRequestListOptions) ([]*github.PullRequest, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIListPullRequestsWithCommit) - if err != nil { - return nil, nil, err - } - result := []*github.PullRequest{} - record := apiRecord{Result: &result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} - -func (c *githubNotesReplayClient) GetPullRequest(ctx context.Context, owner, repo string, number int) (*github.PullRequest, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIGetPullRequest) - if err != nil { - return nil, nil, err - } - result := &github.PullRequest{} - record := apiRecord{Result: result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} - -func (c *githubNotesReplayClient) GetIssue(ctx context.Context, owner, repo string, number int) (*github.Issue, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIGetIssue) - if err != nil { - return nil, nil, err - } - result := &github.Issue{} - record := apiRecord{Result: result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} - -func (c *githubNotesReplayClient) GetRepoCommit(ctx context.Context, owner, repo, sha string) (*github.RepositoryCommit, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIGetRepoCommit) - if err != nil { - return nil, nil, err - } - result := &github.RepositoryCommit{} - record := apiRecord{Result: result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} - -func (c *githubNotesReplayClient) ListReleases( - ctx context.Context, owner, repo string, opt *github.ListOptions, -) ([]*github.RepositoryRelease, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIListReleases) - if err != nil { - return nil, nil, err - } - result := []*github.RepositoryRelease{} - record := apiRecord{Result: result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} - -func (c *githubNotesReplayClient) GetReleaseByTag( - ctx context.Context, owner, repo, tag string, -) (*github.RepositoryRelease, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIGetReleaseByTag) - if err != nil { - return nil, nil, err - } - result := &github.RepositoryRelease{} - record := apiRecord{Result: result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} - -// TODO: Complete logic -func (c *githubNotesReplayClient) DownloadReleaseAsset( - context.Context, string, string, int64, -) (io.ReadCloser, string, error) { - return nil, "", nil -} - -func (c *githubNotesReplayClient) ListTags( - ctx context.Context, owner, repo string, opt *github.ListOptions, -) ([]*github.RepositoryTag, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIListTags) - if err != nil { - return nil, nil, err - } - result := []*github.RepositoryTag{} - record := apiRecord{Result: result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} - -func (c *githubNotesReplayClient) CreatePullRequest( - ctx context.Context, owner, repo, baseBranchName, headBranchName, title, body string, -) (*github.PullRequest, error) { - return &github.PullRequest{}, nil -} - -func (c *githubNotesReplayClient) CreateIssue( - ctx context.Context, owner, repo string, req *github.IssueRequest, -) (*github.Issue, error) { - return &github.Issue{}, nil -} - -func (c *githubNotesReplayClient) GetRepository( - ctx context.Context, owner, repo string, -) (*github.Repository, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIGetRepository) - if err != nil { - return nil, nil, err - } - repository := &github.Repository{} - record := apiRecord{Result: repository} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return repository, record.response(), nil -} - -func (c *githubNotesReplayClient) ListBranches( - ctx context.Context, owner, repo string, opts *github.BranchListOptions, -) ([]*github.Branch, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPIListBranches) - if err != nil { - return nil, nil, err - } - branches := make([]*github.Branch, 0) - record := apiRecord{Result: branches} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return branches, record.response(), nil -} - -func (c *githubNotesReplayClient) ListMilestones( - ctx context.Context, owner, repo string, opts *github.MilestoneListOptions, -) (mstones []*github.Milestone, resp *github.Response, err error) { - data, err := c.readRecordedData(gitHubAPIListMilestones) - if err != nil { - return nil, nil, err - } - mstones = make([]*github.Milestone, 0) - record := apiRecord{Result: mstones} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return mstones, record.response(), nil -} - -func (c *githubNotesReplayClient) readRecordedData(api gitHubAPI) ([]byte, error) { - c.replayMutex.Lock() - defer c.replayMutex.Unlock() - - i := 0 - if j, ok := c.replayState[api]; ok { - i = j - } - - path := filepath.Join(c.replayDir, fmt.Sprintf("%s-%d.json", api, i)) - file, err := os.ReadFile(path) - if err != nil { - return nil, err - } - - c.replayState[api]++ - return file, nil -} - -// UpdateReleasePage modifies a release, not recorded -func (c *githubNotesReplayClient) UpdateReleasePage( - ctx context.Context, owner, repo string, releaseID int64, releaseData *github.RepositoryRelease, -) (*github.RepositoryRelease, error) { - return &github.RepositoryRelease{}, nil -} - -// UploadReleaseAsset uploads files, not recorded -func (c *githubNotesReplayClient) UploadReleaseAsset( - context.Context, string, string, int64, *github.UploadOptions, *os.File, -) (*github.ReleaseAsset, error) { - return &github.ReleaseAsset{}, nil -} - -// DeleteReleaseAsset removes an asset from a page, note recorded -func (c *githubNotesReplayClient) DeleteReleaseAsset( - ctx context.Context, owner, repo string, assetID int64) error { - return nil -} - -func (c *githubNotesReplayClient) ListReleaseAssets( - ctx context.Context, owner, repo string, releaseID int64, opts *github.ListOptions, -) ([]*github.ReleaseAsset, error) { - data, err := c.readRecordedData(gitHubAPIListReleaseAssets) - if err != nil { - return nil, err - } - assets := make([]*github.ReleaseAsset, 0) - record := apiRecord{Result: assets} - if err := json.Unmarshal(data, &record); err != nil { - return nil, err - } - return assets, nil -} - -func (c *githubNotesReplayClient) CreateComment(ctx context.Context, owner, repo string, number int, message string) (*github.IssueComment, *github.Response, error) { - data, err := c.readRecordedData(gitHubAPICreateComment) - if err != nil { - return nil, nil, err - } - result := &github.IssueComment{} - record := apiRecord{Result: result} - if err := json.Unmarshal(data, &record); err != nil { - return nil, nil, err - } - return result, record.response(), nil -} diff --git a/pkg/kubecross/kubecross.go b/pkg/kubecross/kubecross.go index 2f19a9f0cd7..7616c15ad45 100644 --- a/pkg/kubecross/kubecross.go +++ b/pkg/kubecross/kubecross.go @@ -22,7 +22,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" ) // KubeCross is the main structure of this package. diff --git a/pkg/kubepkg/kubepkg.go b/pkg/kubepkg/kubepkg.go index 6d15dd947c0..1a5739e120a 100644 --- a/pkg/kubepkg/kubepkg.go +++ b/pkg/kubepkg/kubepkg.go @@ -29,9 +29,9 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/kubepkg/options" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-utils/command" "sigs.k8s.io/release-utils/util" ) diff --git a/pkg/notes/dependencies.go b/pkg/notes/dependencies.go index feb010bca8f..e8b2c12fb05 100644 --- a/pkg/notes/dependencies.go +++ b/pkg/notes/dependencies.go @@ -22,7 +22,7 @@ import ( "github.com/pkg/errors" "github.com/saschagrunert/go-modiff/pkg/modiff" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" ) type Dependencies struct { diff --git a/pkg/notes/notes.go b/pkg/notes/notes.go index 6f3a12b9e36..091aafd67c2 100644 --- a/pkg/notes/notes.go +++ b/pkg/notes/notes.go @@ -36,8 +36,8 @@ import ( "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/notes/options" + "sigs.k8s.io/release-sdk/github" ) var ( diff --git a/pkg/notes/notes_gatherer_test.go b/pkg/notes/notes_gatherer_test.go index 01d8bf387c2..1e12a678b69 100644 --- a/pkg/notes/notes_gatherer_test.go +++ b/pkg/notes/notes_gatherer_test.go @@ -30,8 +30,8 @@ import ( "github.com/google/go-github/v37/github" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github/githubfakes" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github/githubfakes" ) func TestMain(m *testing.M) { diff --git a/pkg/notes/notes_test.go b/pkg/notes/notes_test.go index 31c1e88245f..1e053743d32 100644 --- a/pkg/notes/notes_test.go +++ b/pkg/notes/notes_test.go @@ -26,7 +26,7 @@ import ( "github.com/stretchr/testify/require" - kgithub "k8s.io/release/pkg/github" + kgithub "sigs.k8s.io/release-sdk/github" ) func githubClient(t *testing.T) (kgithub.Client, context.Context) { diff --git a/pkg/notes/options/options.go b/pkg/notes/options/options.go index ddeac253772..70d8f698dc0 100644 --- a/pkg/notes/options/options.go +++ b/pkg/notes/options/options.go @@ -23,8 +23,8 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" ) // Options is the global options structure which can be used to build release diff --git a/pkg/notes/options/options_test.go b/pkg/notes/options/options_test.go index 0fa3adfad5a..8acc8c1626f 100644 --- a/pkg/notes/options/options_test.go +++ b/pkg/notes/options/options_test.go @@ -29,10 +29,10 @@ import ( "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" - "k8s.io/release/pkg/github" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-utils/command" - kgit "k8s.io/release/pkg/git" + kgit "sigs.k8s.io/release-sdk/git" ) type testOptions struct { diff --git a/pkg/release/branch_checker.go b/pkg/release/branch_checker.go index 85e3129e4cd..e0e1f776372 100644 --- a/pkg/release/branch_checker.go +++ b/pkg/release/branch_checker.go @@ -23,7 +23,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" ) type BranchChecker struct { diff --git a/pkg/release/branch_checker_test.go b/pkg/release/branch_checker_test.go index 96e7e06e5b5..b19fb661e22 100644 --- a/pkg/release/branch_checker_test.go +++ b/pkg/release/branch_checker_test.go @@ -23,9 +23,9 @@ import ( "github.com/blang/semver" "github.com/stretchr/testify/require" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" "k8s.io/release/pkg/release/releasefakes" + "sigs.k8s.io/release-sdk/git" ) func TestNeedsCreation(t *testing.T) { diff --git a/pkg/release/prerequisites.go b/pkg/release/prerequisites.go index e899bba4968..05e5a216943 100644 --- a/pkg/release/prerequisites.go +++ b/pkg/release/prerequisites.go @@ -23,9 +23,9 @@ import ( "github.com/shirou/gopsutil/v3/disk" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" "sigs.k8s.io/release-sdk/gcli" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-utils/command" "sigs.k8s.io/release-utils/env" ) diff --git a/pkg/release/push_git_objects.go b/pkg/release/push_git_objects.go index 213373b0af9..d1241f9cfba 100644 --- a/pkg/release/push_git_objects.go +++ b/pkg/release/push_git_objects.go @@ -22,7 +22,7 @@ import ( "github.com/blang/semver" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/util" ) diff --git a/pkg/release/push_git_objects_test.go b/pkg/release/push_git_objects_test.go index c009951f6d5..35e6049d401 100644 --- a/pkg/release/push_git_objects_test.go +++ b/pkg/release/push_git_objects_test.go @@ -23,7 +23,7 @@ import ( "github.com/pkg/errors" "github.com/stretchr/testify/require" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/command" ) diff --git a/pkg/release/regex/regex.go b/pkg/release/regex/regex.go deleted file mode 100644 index 34b85e1b734..00000000000 --- a/pkg/release/regex/regex.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package regex - -import ( - "regexp" -) - -const ( - branchRegexStr = `master|release-([0-9]{1,})\.([0-9]{1,})(\.([0-9]{1,}))*$` -) - -var BranchRegex = regexp.MustCompile(branchRegexStr) diff --git a/pkg/release/release.go b/pkg/release/release.go index e231a249ce9..425a00140aa 100644 --- a/pkg/release/release.go +++ b/pkg/release/release.go @@ -33,8 +33,8 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-sdk/object" "sigs.k8s.io/release-utils/command" "sigs.k8s.io/release-utils/env" diff --git a/pkg/release/release_test.go b/pkg/release/release_test.go index bd24312e21e..65101f82b72 100644 --- a/pkg/release/release_test.go +++ b/pkg/release/release_test.go @@ -30,7 +30,7 @@ import ( "github.com/stretchr/testify/require" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" ) func TestGetToolRefSuccess(t *testing.T) { diff --git a/pkg/release/release_version.go b/pkg/release/release_version.go index 022e6a834eb..a157dad1fc5 100644 --- a/pkg/release/release_version.go +++ b/pkg/release/release_version.go @@ -25,7 +25,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/release/regex" + "sigs.k8s.io/release-sdk/regex" "sigs.k8s.io/release-utils/util" ) diff --git a/pkg/release/release_version_test.go b/pkg/release/release_version_test.go index bcbe220c221..3ae4a16badf 100644 --- a/pkg/release/release_version_test.go +++ b/pkg/release/release_version_test.go @@ -21,8 +21,8 @@ import ( "github.com/stretchr/testify/require" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/git" ) func TestGenerateReleaseVersion(t *testing.T) { diff --git a/pkg/release/releasefakes/fake_repository.go b/pkg/release/releasefakes/fake_repository.go index d05302cc86f..7e268fb8f77 100644 --- a/pkg/release/releasefakes/fake_repository.go +++ b/pkg/release/releasefakes/fake_repository.go @@ -20,8 +20,8 @@ package releasefakes import ( "sync" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" + "sigs.k8s.io/release-sdk/git" ) type FakeRepository struct { diff --git a/pkg/release/repository.go b/pkg/release/repository.go index be35a8ea92f..80b3079aa71 100644 --- a/pkg/release/repository.go +++ b/pkg/release/repository.go @@ -26,7 +26,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" ) // Repo is a wrapper around a kubernetes/release repository diff --git a/pkg/release/repository_test.go b/pkg/release/repository_test.go index 9ee7b68d541..8b8c323b3ae 100644 --- a/pkg/release/repository_test.go +++ b/pkg/release/repository_test.go @@ -24,9 +24,9 @@ import ( gogit "github.com/go-git/go-git/v5" "github.com/stretchr/testify/require" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/release" "k8s.io/release/pkg/release/releasefakes" + "sigs.k8s.io/release-sdk/git" ) type sut struct { diff --git a/pkg/release/version.go b/pkg/release/version.go index e0143b880db..a190bbf88d8 100644 --- a/pkg/release/version.go +++ b/pkg/release/version.go @@ -22,7 +22,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" + "sigs.k8s.io/release-sdk/git" "sigs.k8s.io/release-utils/http" ) diff --git a/pkg/release/workspace.go b/pkg/release/workspace.go index 7bce3c4afc0..d630f88c154 100644 --- a/pkg/release/workspace.go +++ b/pkg/release/workspace.go @@ -26,10 +26,10 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "k8s.io/release/pkg/git" - "k8s.io/release/pkg/github" "k8s.io/release/pkg/license" "k8s.io/release/pkg/spdx" + "sigs.k8s.io/release-sdk/git" + "sigs.k8s.io/release-sdk/github" "sigs.k8s.io/release-sdk/object" "sigs.k8s.io/release-utils/tar" "sigs.k8s.io/release-utils/util" diff --git a/pkg/testgrid/testgrid_test.go b/pkg/testgrid/testgrid_test.go index 34e50376e2a..9b85b9a8281 100644 --- a/pkg/testgrid/testgrid_test.go +++ b/pkg/testgrid/testgrid_test.go @@ -24,9 +24,9 @@ import ( "github.com/golang/protobuf/proto" // nolint: staticcheck "github.com/stretchr/testify/require" - "k8s.io/release/pkg/git" "k8s.io/release/pkg/testgrid" "k8s.io/release/pkg/testgrid/testgridfakes" + "sigs.k8s.io/release-sdk/git" ) func newSut() (*testgrid.TestGrid, *testgridfakes.FakeClient) {