diff --git a/Makefile b/Makefile index 0bb754eec28..9fea4a4408b 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ test: .PHONY: test validate-vendor: + go version GO111MODULE=on GOPROXY=https://proxy.golang.org go mod tidy GO111MODULE=on GOPROXY=https://proxy.golang.org go mod vendor git status -s ./vendor/ go.mod go.sum diff --git a/go.mod b/go.mod index 702c818d6de..fa590794c66 100644 --- a/go.mod +++ b/go.mod @@ -30,5 +30,5 @@ require ( k8s.io/api v0.0.0-20190816222004-e3a6b8045b0b k8s.io/apimachinery v0.0.0-20190816221834-a9f1d8a9c101 k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible - k8s.io/test-infra v0.0.0-20190903192658-86fbc418c31d + k8s.io/test-infra v0.0.0-20190908161317-466f8ffd615d ) diff --git a/go.sum b/go.sum index cd8b55aee4d..d3d00c27958 100644 --- a/go.sum +++ b/go.sum @@ -547,8 +547,8 @@ k8s.io/kubernetes v1.14.6 h1:t8Q3aaWanmiariBBr3qYIcAL9o0pv4MB5tZtfbILJGk= k8s.io/kubernetes v1.14.6/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/repo-infra v0.0.0-20190329054012-df02ded38f95/go.mod h1:+G1xBfZDfVFsm1Tj/HNCvg4QqWx8rJ2Fxpqr1rqp/gQ= k8s.io/test-infra v0.0.0-20181019233642-2e10a0bbe9b3/go.mod h1:2NzXB13Ji0nqpyublHeiPC4FZwU0TknfvyaaNfl/BTA= -k8s.io/test-infra v0.0.0-20190903192658-86fbc418c31d h1:4J8+AGrpi5FmWnEDWaFXuqmdvbQWWpZglosQhrpPWHA= -k8s.io/test-infra v0.0.0-20190903192658-86fbc418c31d/go.mod h1:D7pZIojdfj0WCmk9XEun96EFY3ArFxL7QdobtsK5TzU= +k8s.io/test-infra v0.0.0-20190908161317-466f8ffd615d h1:w/0hAl0G+NaknJKNJZLPV/lfqivEn0rdZ0ilY5sDsB8= +k8s.io/test-infra v0.0.0-20190908161317-466f8ffd615d/go.mod h1:D7pZIojdfj0WCmk9XEun96EFY3ArFxL7QdobtsK5TzU= k8s.io/utils v0.0.0-20181019225348-5e321f9a457c/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5 h1:VBM/0P5TWxwk+Nw6Z+lAw3DKgO76g90ETOiA6rfLV1Y= k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= diff --git a/vendor/k8s.io/test-infra/experiment/autobumper/bumper/bumper.go b/vendor/k8s.io/test-infra/experiment/autobumper/bumper/bumper.go index 35ffbab6120..4a6dadf5c46 100644 --- a/vendor/k8s.io/test-infra/experiment/autobumper/bumper/bumper.go +++ b/vendor/k8s.io/test-infra/experiment/autobumper/bumper/bumper.go @@ -51,21 +51,16 @@ func Call(cmd string, args ...string) error { // "images" contains the tag replacements that have been made which is returned from "UpdateReferences([]string{"."}, extraFiles)" // "images" and "extraLineInPRBody" are used to generate commit summary and body of the PR func UpdatePR(gc github.Client, org, repo string, images map[string]string, extraLineInPRBody string, matchTitle, source, branch string) error { - return updatePR(gc, org, repo, makeCommitSummary(images), generatePRBody(images, extraLineInPRBody), matchTitle, source, branch) + return UpdatePullRequest(gc, org, repo, makeCommitSummary(images), generatePRBody(images, extraLineInPRBody), matchTitle, source, branch) } -func updatePR(gc github.Client, org, repo, title, body, matchTitle, source, branch string) error { - logrus.Info("Creating PR...") - n, err := updater.UpdatePR(org, repo, title, body, matchTitle, gc) +// UpdatePullRequest updates with github client "gc" the PR of github repo org/repo +// with "title" and "body" of PR matching "matchTitle" from "source" to "branch" +func UpdatePullRequest(gc github.Client, org, repo, title, body, matchTitle, source, branch string) error { + logrus.Info("Creating or updating PR...") + n, err := updater.EnsurePR(org, repo, title, body, source, branch, matchTitle, gc) if err != nil { - return fmt.Errorf("failed to update %d: %v", n, err) - } - if n == nil { - pr, err := gc.CreatePullRequest(org, repo, title, body, source, branch, true) - if err != nil { - return fmt.Errorf("failed to create PR: %v", err) - } - n = &pr + return fmt.Errorf("failed to ensure PR exists: %v", err) } logrus.Infof("PR %s/%s#%d will merge %s into %s: %s", org, repo, *n, source, branch, title) @@ -115,11 +110,17 @@ func makeCommitSummary(images map[string]string) string { // "images" contains the tag replacements that have been made which is returned from "UpdateReferences([]string{"."}, extraFiles)" // "images" is used to generate commit message func MakeGitCommit(remote, remoteBranch, name, email string, images map[string]string) error { + return GitCommitAndPush(remote, remoteBranch, name, email, makeCommitSummary(images)) +} + +// GitCommitAndPush runs a sequence of git commands to +// commit and push the changes the "remote" on "remoteBranch" +// "name", "email", and "message" are used for git-commit command +func GitCommitAndPush(remote, remoteBranch, name, email, message string) error { logrus.Info("Making git commit...") if err := Call("git", "add", "-A"); err != nil { return fmt.Errorf("failed to git add: %v", err) } - message := makeCommitSummary(images) commitArgs := []string{"commit", "-m", message} if name != "" && email != "" { commitArgs = append(commitArgs, "--author", fmt.Sprintf("%s <%s>", name, email)) diff --git a/vendor/k8s.io/test-infra/prow/config/config.go b/vendor/k8s.io/test-infra/prow/config/config.go index bc8b088725d..9de33a49fb4 100644 --- a/vendor/k8s.io/test-infra/prow/config/config.go +++ b/vendor/k8s.io/test-infra/prow/config/config.go @@ -77,6 +77,10 @@ type JobConfig struct { // Periodics are not associated with any repo. Periodics []Periodic `json:"periodics,omitempty"` + + // AllRepos contains all Repos that have one or more jobs configured or + // for which a tide query is configured. + AllRepos sets.String `json:"-"` } // ProwConfig is config for all prow controllers @@ -248,9 +252,6 @@ func (rg *RefGetterForGitHubPullRequest) BaseSHA() (string, error) { // also need the result of that GitHub call just keep a pointer to its result, bust must // nilcheck that pointer before accessing it. func (c *Config) GetPresubmits(gc *git.Client, identifier string, baseSHAGetter RefGetter, headSHAGetters ...RefGetter) ([]Presubmit, error) { - if gc == nil { - return nil, errors.New("gitClient is nil") - } if identifier == "" { return nil, errors.New("no identifier for repo given") } @@ -258,6 +259,9 @@ func (c *Config) GetPresubmits(gc *git.Client, identifier string, baseSHAGetter return c.Presubmits[identifier], nil } + if gc == nil { + return nil, errors.New("gitClient is nil") + } baseSHA, err := baseSHAGetter() if err != nil { return nil, fmt.Errorf("failed to get baseSHA: %v", err) @@ -373,11 +377,6 @@ type Plank struct { // DefaultDecorationConfig are defaults for shared fields for ProwJobs // that request to have their PodSpecs decorated DefaultDecorationConfig *prowapi.DecorationConfig `json:"default_decoration_config,omitempty"` - // Deprecated, use JobURLPrefixConfig instead - // JobURLPrefix is the host and path prefix under - // which job details will be viewable - // TODO @alvaroaleman: Remove in September 2019 - JobURLPrefix string `json:"job_url_prefix,omitempty"` // JobURLPrefixConfig is the host and path prefix under which job details // will be viewable. Use `org/repo`, `org` or `*`as key and an url as value JobURLPrefixConfig map[string]string `json:"job_url_prefix_config,omitempty"` @@ -709,6 +708,12 @@ func loadConfig(prowConfig, jobConfig string) (*Config, error) { return nil, err } + nc.AllRepos = sets.String{} + for _, query := range nc.Tide.Queries { + for _, repo := range query.Repos { + nc.AllRepos.Insert(repo) + } + } // TODO(krzyzacy): temporary allow empty jobconfig // also temporary allow job config in prow config if jobConfig == "" { @@ -889,16 +894,18 @@ func (c *Config) finalizeJobConfig() error { return errors.New("no default GCS credentials secret provided for plank") } - for _, vs := range c.Presubmits { + for repo, vs := range c.Presubmits { for i := range vs { setPresubmitDecorationDefaults(c, &vs[i]) } + c.AllRepos.Insert(repo) } - for _, js := range c.Postsubmits { + for repo, js := range c.Postsubmits { for i := range js { setPostsubmitDecorationDefaults(c, &js[i]) } + c.AllRepos.Insert(repo) } for i := range c.Periodics { @@ -945,9 +952,6 @@ func (c *Config) finalizeJobConfig() error { // validateComponentConfig validates the infrastructure component configuration func (c *Config) validateComponentConfig() error { - if c.Plank.JobURLPrefix != "" && c.Plank.JobURLPrefixConfig["*"] != "" { - return errors.New(`Planks job_url_prefix must be unset when job_url_prefix_config["*"] is set. The former is deprecated, use the latter`) - } for k, v := range c.Plank.JobURLPrefixConfig { if _, err := url.Parse(v); err != nil { return fmt.Errorf(`Invalid value for Planks job_url_prefix_config["%s"]: %v`, k, err) @@ -1304,13 +1308,6 @@ func parseProwConfig(c *Config) error { if c.Plank.JobURLPrefixConfig == nil { c.Plank.JobURLPrefixConfig = map[string]string{} } - if c.Plank.JobURLPrefix != "" && c.Plank.JobURLPrefixConfig["*"] == "" { - c.Plank.JobURLPrefixConfig["*"] = c.Plank.JobURLPrefix - // Set JobURLPrefix to an empty string to indicate we've moved - // it to JobURLPrefixConfig["*"] without overwriting the latter - // so validation succeeds - c.Plank.JobURLPrefix = "" - } if c.GitHubOptions.LinkURLFromConfig == "" { c.GitHubOptions.LinkURLFromConfig = "https://github.com" diff --git a/vendor/k8s.io/test-infra/prow/github/client.go b/vendor/k8s.io/test-infra/prow/github/client.go index 754d159f4fd..f1e2883b03e 100644 --- a/vendor/k8s.io/test-infra/prow/github/client.go +++ b/vendor/k8s.io/test-infra/prow/github/client.go @@ -152,6 +152,7 @@ type RepositoryClient interface { IsCollaborator(org, repo, user string) (bool, error) ListCollaborators(org, repo string) ([]User, error) CreateFork(owner, repo string) error + ListRepoTeams(org, repo string) ([]Team, error) } // TeamClient interface for team related API actions @@ -174,6 +175,7 @@ type TeamClient interface { // UserClient interface for user related API actions type UserClient interface { BotName() (string, error) + BotUser() (*User, error) Email() (string, error) } @@ -251,9 +253,8 @@ type delegate struct { getToken func() []byte censor func([]byte) []byte - mut sync.Mutex // protects botName and email - botName string - email string + mut sync.Mutex // protects botName and email + userData *User } // WithFields clones the client, keeping the underlying delegate the same but adding @@ -753,11 +754,10 @@ func (c *client) getUserData() error { if err != nil { return err } - c.botName = u.Login + c.userData = &u // email needs to be publicly accessible via the profile // of the current account. Read below for more info // https://developer.github.com/v3/users/#get-a-single-user - c.email = u.Email return nil } @@ -767,12 +767,26 @@ func (c *client) getUserData() error { func (c *client) BotName() (string, error) { c.mut.Lock() defer c.mut.Unlock() - if c.botName == "" { + if c.userData == nil { if err := c.getUserData(); err != nil { return "", fmt.Errorf("fetching bot name from GitHub: %v", err) } } - return c.botName, nil + return c.userData.Login, nil +} + +// BotUser returns the user data of the authenticated identity. +// +// See https://developer.github.com/v3/users/#get-the-authenticated-user +func (c *client) BotUser() (*User, error) { + c.mut.Lock() + defer c.mut.Unlock() + if c.userData == nil { + if err := c.getUserData(); err != nil { + return nil, fmt.Errorf("fetching bot name from GitHub: %v", err) + } + } + return c.userData, nil } // Email returns the user-configured email for the authenticated identity. @@ -781,12 +795,12 @@ func (c *client) BotName() (string, error) { func (c *client) Email() (string, error) { c.mut.Lock() defer c.mut.Unlock() - if c.email == "" { + if c.userData == nil { if err := c.getUserData(); err != nil { return "", fmt.Errorf("fetching e-mail from GitHub: %v", err) } } - return c.email, nil + return c.userData.Email, nil } // IsMember returns whether or not the user is a member of the org. @@ -1507,7 +1521,7 @@ func (c *client) UpdatePullRequest(org, repo string, number int, title, body *st op := "open" data.State = &op } else if open != nil { - cl := "clossed" + cl := "closed" data.State = &cl } _, err := c.request(&request{ @@ -2827,6 +2841,31 @@ func (c *client) CreateFork(owner, repo string) error { return err } +// ListRepoTeams gets a list of all the teams with access to a repository +// See https://developer.github.com/v3/repos/#list-teams +func (c *client) ListRepoTeams(org, repo string) ([]Team, error) { + c.log("ListRepoTeams", org, repo) + if c.fake { + return nil, nil + } + path := fmt.Sprintf("/repos/%s/%s/teams", org, repo) + var teams []Team + err := c.readPaginatedResults( + path, + acceptNone, + func() interface{} { + return &[]Team{} + }, + func(obj interface{}) { + teams = append(teams, *(obj.(*[]Team))...) + }, + ) + if err != nil { + return nil, err + } + return teams, nil +} + // ListIssueEvents gets a list events from GitHub's events API that pertain to the specified issue. // The events that are returned have a different format than webhook events and certain event types // are excluded. diff --git a/vendor/k8s.io/test-infra/prow/github/types.go b/vendor/k8s.io/test-infra/prow/github/types.go index c9ce49fe0b1..6bdc42c4b81 100644 --- a/vendor/k8s.io/test-infra/prow/github/types.go +++ b/vendor/k8s.io/test-infra/prow/github/types.go @@ -153,11 +153,12 @@ type CombinedStatus struct { // User is a GitHub user account. type User struct { - Login string `json:"login"` - Name string `json:"name"` - Email string `json:"email"` - ID int `json:"id"` - HTMLURL string `json:"html_url"` + Login string `json:"login"` + Name string `json:"name"` + Email string `json:"email"` + ID int `json:"id"` + HTMLURL string `json:"html_url"` + Permissions RepoPermissions `json:"permissions"` } // NormLogin normalizes GitHub login strings @@ -354,6 +355,14 @@ func (l *RepoPermissionLevel) UnmarshalText(text []byte) error { return nil } +type TeamPermission string + +const ( + RepoPull TeamPermission = "pull" + RepoPush TeamPermission = "push" + RepoAdmin TeamPermission = "admin" +) + // Branch contains general branch information. type Branch struct { Name string `json:"name"` @@ -805,13 +814,14 @@ const ( // Team is a github organizational team type Team struct { - ID int `json:"id,omitempty"` - Name string `json:"name"` - Slug string `json:"slug"` - Description string `json:"description,omitempty"` - Privacy string `json:"privacy,omitempty"` - Parent *Team `json:"parent,omitempty"` // Only present in responses - ParentTeamID *int `json:"parent_team_id,omitempty"` // Only valid in creates/edits + ID int `json:"id,omitempty"` + Name string `json:"name"` + Slug string `json:"slug"` + Description string `json:"description,omitempty"` + Privacy string `json:"privacy,omitempty"` + Parent *Team `json:"parent,omitempty"` // Only present in responses + ParentTeamID *int `json:"parent_team_id,omitempty"` // Only valid in creates/edits + Permission TeamPermission `json:"permission"` } // TeamMember is a member of an organizational team diff --git a/vendor/k8s.io/test-infra/prow/plugins/label/BUILD.bazel b/vendor/k8s.io/test-infra/prow/plugins/label/BUILD.bazel index 38cc44d90c7..0de132c4eb0 100644 --- a/vendor/k8s.io/test-infra/prow/plugins/label/BUILD.bazel +++ b/vendor/k8s.io/test-infra/prow/plugins/label/BUILD.bazel @@ -28,6 +28,7 @@ go_library( "//prow/pluginhelp:go_default_library", "//prow/plugins:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", + "@io_k8s_apimachinery//pkg/util/sets:go_default_library", ], ) diff --git a/vendor/k8s.io/test-infra/prow/plugins/label/label.go b/vendor/k8s.io/test-infra/prow/plugins/label/label.go index 8db2df75328..f1c03841e62 100644 --- a/vendor/k8s.io/test-infra/prow/plugins/label/label.go +++ b/vendor/k8s.io/test-infra/prow/plugins/label/label.go @@ -23,6 +23,7 @@ import ( "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/test-infra/prow/github" "k8s.io/test-infra/prow/pluginhelp" "k8s.io/test-infra/prow/plugins" @@ -31,12 +32,11 @@ import ( const pluginName = "label" var ( - defaultLabels = []string{"kind", "priority", "area"} - labelRegex = regexp.MustCompile(`(?m)^/(area|committee|kind|language|priority|sig|triage|wg)\s*(.*)$`) - removeLabelRegex = regexp.MustCompile(`(?m)^/remove-(area|committee|kind|language|priority|sig|triage|wg)\s*(.*)$`) - customLabelRegex = regexp.MustCompile(`(?m)^/label\s*(.*)$`) - customRemoveLabelRegex = regexp.MustCompile(`(?m)^/remove-label\s*(.*)$`) - nonExistentLabelOnIssue = "Those labels are not set on the issue: `%v`" + defaultLabels = []string{"kind", "priority", "area"} + labelRegex = regexp.MustCompile(`(?m)^/(area|committee|kind|language|priority|sig|triage|wg)\s*(.*)$`) + removeLabelRegex = regexp.MustCompile(`(?m)^/remove-(area|committee|kind|language|priority|sig|triage|wg)\s*(.*)$`) + customLabelRegex = regexp.MustCompile(`(?m)^/label\s*(.*)$`) + customRemoveLabelRegex = regexp.MustCompile(`(?m)^/remove-label\s*(.*)$`) ) func init() { @@ -66,7 +66,7 @@ func helpProvider(config *plugins.Configuration, enabledRepos []string) (*plugin Description: "Applies or removes a label from one of the recognized types of labels.", Featured: false, WhoCanUse: "Anyone can trigger this command on a PR.", - Examples: []string{"/kind bug", "/remove-area prow", "/sig testing", "/language zh"}, + Examples: []string{"/kind bug", "/remove-area prow", "/sig testing", "/language zh", "/label foo-bar-baz"}, }) return pluginHelp, nil } @@ -96,20 +96,24 @@ func getLabelsFromREMatches(matches [][]string) (labels []string) { // getLabelsFromGenericMatches returns label matches with extra labels if those // have been configured in the plugin config. -func getLabelsFromGenericMatches(matches [][]string, additionalLabels []string) []string { +func getLabelsFromGenericMatches(matches [][]string, additionalLabels []string, invalidLabels *[]string) []string { if len(additionalLabels) == 0 { return nil } var labels []string + labelFilter := sets.String{} + for _, l := range additionalLabels { + labelFilter.Insert(strings.ToLower(l)) + } for _, match := range matches { parts := strings.Split(match[0], " ") if ((parts[0] != "/label") && (parts[0] != "/remove-label")) || len(parts) != 2 { continue } - for _, l := range additionalLabels { - if l == parts[1] { - labels = append(labels, parts[1]) - } + if labelFilter.Has(strings.ToLower(parts[1])) { + labels = append(labels, parts[1]) + } else { + *invalidLabels = append(*invalidLabels, match[0]) } } return labels @@ -136,9 +140,9 @@ func handle(gc githubClient, log *logrus.Entry, additionalLabels []string, e *gi return err } - RepoLabelsExisting := map[string]string{} + RepoLabelsExisting := sets.String{} for _, l := range repoLabels { - RepoLabelsExisting[strings.ToLower(l.Name)] = l.Name + RepoLabelsExisting.Insert(strings.ToLower(l.Name)) } var ( nonexistent []string @@ -146,23 +150,21 @@ func handle(gc githubClient, log *logrus.Entry, additionalLabels []string, e *gi labelsToAdd []string labelsToRemove []string ) - // Get labels to add and labels to remove from regexp matches - labelsToAdd = append(getLabelsFromREMatches(labelMatches), getLabelsFromGenericMatches(customLabelMatches, additionalLabels)...) - labelsToRemove = append(getLabelsFromREMatches(removeLabelMatches), getLabelsFromGenericMatches(customRemoveLabelMatches, additionalLabels)...) - + labelsToAdd = append(getLabelsFromREMatches(labelMatches), getLabelsFromGenericMatches(customLabelMatches, additionalLabels, &nonexistent)...) + labelsToRemove = append(getLabelsFromREMatches(removeLabelMatches), getLabelsFromGenericMatches(customRemoveLabelMatches, additionalLabels, &nonexistent)...) // Add labels for _, labelToAdd := range labelsToAdd { if github.HasLabel(labelToAdd, labels) { continue } - if _, ok := RepoLabelsExisting[labelToAdd]; !ok { + if !RepoLabelsExisting.Has(labelToAdd) { nonexistent = append(nonexistent, labelToAdd) continue } - if err := gc.AddLabel(org, repo, e.Number, RepoLabelsExisting[labelToAdd]); err != nil { + if err := gc.AddLabel(org, repo, e.Number, labelToAdd); err != nil { log.WithError(err).Errorf("GitHub failed to add the following label: %s", labelToAdd) } } @@ -174,7 +176,7 @@ func handle(gc githubClient, log *logrus.Entry, additionalLabels []string, e *gi continue } - if _, ok := RepoLabelsExisting[labelToRemove]; !ok { + if !RepoLabelsExisting.Has(labelToRemove) { nonexistent = append(nonexistent, labelToRemove) continue } @@ -184,14 +186,15 @@ func handle(gc githubClient, log *logrus.Entry, additionalLabels []string, e *gi } } - //TODO(grodrigues3): Once labels are standardized, make this reply with a comment. if len(nonexistent) > 0 { log.Infof("Nonexistent labels: %v", nonexistent) + msg := fmt.Sprintf("The label(s) `%s` cannot be appled. These labels are supported: `%s`", strings.Join(nonexistent, ", "), strings.Join(additionalLabels, ", ")) + return gc.CreateComment(org, repo, e.Number, plugins.FormatResponseRaw(e.Body, e.HTMLURL, e.User.Login, msg)) } // Tried to remove Labels that were not present on the Issue if len(noSuchLabelsOnIssue) > 0 { - msg := fmt.Sprintf(nonExistentLabelOnIssue, strings.Join(noSuchLabelsOnIssue, ", ")) + msg := fmt.Sprintf("Those labels are not set on the issue: `%v`", strings.Join(noSuchLabelsOnIssue, ", ")) return gc.CreateComment(org, repo, e.Number, plugins.FormatResponseRaw(e.Body, e.HTMLURL, e.User.Login, msg)) } diff --git a/vendor/k8s.io/test-infra/robots/pr-creator/updater/updater.go b/vendor/k8s.io/test-infra/robots/pr-creator/updater/updater.go index 25e7ba34427..0d5ff667c1c 100644 --- a/vendor/k8s.io/test-infra/robots/pr-creator/updater/updater.go +++ b/vendor/k8s.io/test-infra/robots/pr-creator/updater/updater.go @@ -30,6 +30,11 @@ type updateClient interface { FindIssues(query, sort string, asc bool) ([]github.Issue, error) } +type ensureClient interface { + updateClient + CreatePullRequest(org, repo, title, body, head, base string, canModify bool) (int, error) +} + func UpdatePR(org, repo, title, body, matchTitle string, gc updateClient) (*int, error) { if matchTitle == "" { return nil, nil @@ -41,7 +46,7 @@ func UpdatePR(org, repo, title, body, matchTitle string, gc updateClient) (*int, return nil, fmt.Errorf("bot name: %v", err) } - issues, err := gc.FindIssues("is:open is:pr archived:false in:title author:"+me+" "+matchTitle, "updated", true) + issues, err := gc.FindIssues("is:open is:pr archived:false in:title author:"+me+" "+matchTitle, "updated", false) if err != nil { return nil, fmt.Errorf("find issues: %v", err) } else if len(issues) == 0 { @@ -59,3 +64,19 @@ func UpdatePR(org, repo, title, body, matchTitle string, gc updateClient) (*int, return &n, nil } + +func EnsurePR(org, repo, title, body, source, branch, matchTitle string, gc ensureClient) (*int, error) { + n, err := UpdatePR(org, repo, title, body, matchTitle, gc) + if err != nil { + return nil, fmt.Errorf("update error: %v", err) + } + if n == nil { + allowMods := true + pr, err := gc.CreatePullRequest(org, repo, title, body, source, branch, allowMods) + if err != nil { + return nil, fmt.Errorf("create error: %v", err) + } + n = &pr + } + return n, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 424298a0dd6..b5c5a78919d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -506,7 +506,7 @@ k8s.io/client-go/third_party/forked/golang/template k8s.io/klog # k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c k8s.io/kube-openapi/pkg/util/proto -# k8s.io/test-infra v0.0.0-20190903192658-86fbc418c31d +# k8s.io/test-infra v0.0.0-20190908161317-466f8ffd615d k8s.io/test-infra/experiment/autobumper/bumper k8s.io/test-infra/prow/config/secret k8s.io/test-infra/prow/github