diff --git a/BUILD.bazel b/BUILD.bazel index f0f5f2b5a59..ced0ac8d28b 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -32,7 +32,6 @@ filegroup( "//cmd/gh2gcs:all-srcs", "//cmd/krel:all-srcs", "//cmd/kubepkg:all-srcs", - "//cmd/patch-announce:all-srcs", "//cmd/release-notes:all-srcs", "//lib:all-srcs", "//pkg/command:all-srcs", diff --git a/cmd/krel/cmd/BUILD.bazel b/cmd/krel/cmd/BUILD.bazel index 81b2b4d8dc0..e05925eac17 100644 --- a/cmd/krel/cmd/BUILD.bazel +++ b/cmd/krel/cmd/BUILD.bazel @@ -8,7 +8,6 @@ go_library( "changelog.go", "ff.go", "gcbmgr.go", - "patch-announce.go", "push.go", "release_notes.go", "root.go", @@ -29,7 +28,6 @@ go_library( "//pkg/notes:go_default_library", "//pkg/notes/document:go_default_library", "//pkg/notes/options:go_default_library", - "//pkg/patch:go_default_library", "//pkg/release:go_default_library", "//pkg/util:go_default_library", "//pkg/version:go_default_library", diff --git a/cmd/krel/cmd/patch-announce.go b/cmd/krel/cmd/patch-announce.go deleted file mode 100644 index 61d872c5eae..00000000000 --- a/cmd/krel/cmd/patch-announce.go +++ /dev/null @@ -1,97 +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 ( - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - "k8s.io/release/pkg/github" - "k8s.io/release/pkg/log" - "k8s.io/release/pkg/patch" - "k8s.io/release/pkg/util" -) - -// slap the subcommand onto the parent/root -func init() { - cmd := patchAnnounceCommand() - rootCmd.AddCommand(cmd) -} - -func patchAnnounceCommand() *cobra.Command { - opts := patch.AnnounceOptions{} - - cmd := &cobra.Command{ - Use: "patch-announce", - Short: "Send out patch release announcement mails", - SilenceUsage: true, - SilenceErrors: true, - Args: cobra.MaximumNArgs(0), // no additional/positional args allowed - } - - // setup local flags - cmd.PersistentFlags().StringVarP(&opts.SenderName, "sender-name", "n", "", "email sender's name") - cmd.PersistentFlags().StringVarP(&opts.SenderEmail, "sender-email", "e", "", "email sender's address") - cmd.PersistentFlags().StringVarP(&opts.FreezeDate, "freeze-date", "f", "", "date when no CPs are allowed anymore") - cmd.PersistentFlags().StringVarP(&opts.CutDate, "cut-date", "c", "", "date when the patch release is planned to be cut") - cmd.PersistentFlags().StringVarP(&opts.ReleaseRepoPath, "release-repo", "r", "./release", "local path of the k/release checkout") - - // TODO: figure out, how we can read env vars and also be able to set the flags to required in a cobra-native way - cmd.PersistentFlags().StringVarP(&opts.SendgridAPIKey, "sendgrid-api-key", "s", util.EnvDefault("SENDGRID_API_KEY", ""), "API key for sendgrid") - cmd.PersistentFlags().StringVarP(&opts.GithubToken, "github-token", "g", util.EnvDefault(github.TokenEnvKey, ""), "a GitHub token, used r/o for generating the release notes") - - cmd.PreRunE = func(cmd *cobra.Command, _ []string) error { - // TODO: make github-token & sendgrid-api-key required too - if err := setFlagsRequired(cmd, "sender-name", "sender-email", "freeze-date", "cut-date"); err != nil { - return err - } - - var err error - if opts.Nomock, err = cmd.Flags().GetBool("nomock"); err != nil { - return err - } - if opts.K8sRepoPath, err = cmd.Flags().GetString("repo"); err != nil { - return err - } - return nil - } - - cmd.RunE = func(cmd *cobra.Command, args []string) error { - // Get the global logger, add the command's name as an initial tracing - // field and use that from here on - localLogger := logrus.NewEntry(logrus.StandardLogger()) - logger := log.AddTracePath(localLogger, cmd.Name()).WithField("mock", !opts.Nomock) - - announcer := &patch.Announcer{ - Opts: opts, - } - announcer.SetLogger(logger, "announcer") - - logger.Debug("run announcer") - return announcer.Run() - } - - return cmd -} - -func setFlagsRequired(cmd *cobra.Command, flags ...string) error { - for _, f := range flags { - if err := cmd.MarkPersistentFlagRequired(f); err != nil { - return err - } - } - return nil -} diff --git a/cmd/patch-announce/BUILD.bazel b/cmd/patch-announce/BUILD.bazel deleted file mode 100644 index d92534b2fe0..00000000000 --- a/cmd/patch-announce/BUILD.bazel +++ /dev/null @@ -1,35 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") - -go_library( - name = "go_default_library", - srcs = ["main.go"], - importpath = "k8s.io/release/cmd/patch-announce", - visibility = ["//visibility:private"], - deps = [ - "//pkg/log:go_default_library", - "//pkg/patch:go_default_library", - "//pkg/release:go_default_library", - "@com_github_sirupsen_logrus//:go_default_library", - "@com_github_spf13_cobra//:go_default_library", - ], -) - -go_binary( - name = "patch-announce", - embed = [":go_default_library"], - visibility = ["//visibility:public"], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], - visibility = ["//visibility:public"], -) diff --git a/cmd/patch-announce/main.go b/cmd/patch-announce/main.go deleted file mode 100755 index 7a238928660..00000000000 --- a/cmd/patch-announce/main.go +++ /dev/null @@ -1,180 +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 ( - "fmt" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - "syscall" - - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - "k8s.io/release/pkg/log" - "k8s.io/release/pkg/patch" - "k8s.io/release/pkg/release" -) - -type opts struct { - patch.AnnounceOptions - K8sRepoURL string - K8sBranch string - ReleaseRepoURL string - ReleaseBranch string - ProjectID string - BuildConfigPath string - Loglevel string - Tail bool -} - -const ( - defaultK8sRepoURL = "https://github.com/kubernetes/kubernetes" - defaultK8sBranch = "master" - defaultReleaseRepoURL = "https://github.com/kubernetes/release" - defaultReleaseBranch = "master" - defaultLogLevel = "info" - - // separator which hopefully never appears in any of our keys/values. - sep = "\001\002\001" -) - -func main() { - cmd := getCommand() - if err := cmd.Execute(); err != nil { - os.Exit(1) - } -} - -func getCommand() *cobra.Command { - opts := opts{} - - cmd := &cobra.Command{ - Use: "patch-announce ", - Long: "submits a GCB job to run `krel patch-announce` in the clouds", - SilenceUsage: true, - Args: cobra.ExactArgs(0), - } - - cmd.Flags().StringVarP(&opts.SenderName, "sender-name", "n", "", "email sender's name") - cmd.Flags().StringVarP(&opts.SenderEmail, "sender-email", "m", "", "email sender's address") - cmd.Flags().StringVarP(&opts.FreezeDate, "freeze-date", "f", "", "date when no CPs are allowed anymore") - cmd.Flags().StringVarP(&opts.CutDate, "cut-date", "c", "", "date when the patch release is planned to be cut") - cmd.Flags().StringVarP(&opts.BuildConfigPath, "config", "C", "", "file path to the patch-announce cloudbuild.yaml") - cmd.Flags().StringVarP(&opts.ProjectID, "project-id", "p", release.DefaultRelengStagingProject, "Google Project ID") - cmd.Flags().StringVarP(&opts.K8sRepoURL, "kubernetes-repo-url", "r", defaultK8sRepoURL, `git URL for the kubernetes repo ("k/k")`) - cmd.Flags().StringVarP(&opts.K8sBranch, "kubernetes-branch", "b", defaultK8sBranch, `branch to checkout for the kubernetes repo ("k/k")`) - cmd.Flags().StringVarP(&opts.ReleaseRepoURL, "release-repo-url", "R", defaultReleaseRepoURL, `git URL for the release repo ("k/release)`) - cmd.Flags().StringVarP(&opts.ReleaseBranch, "release-branch", "B", defaultReleaseBranch, `branch to checkout for the release repo ("k/release")`) - cmd.Flags().StringVarP(&opts.Loglevel, "log-level", "l", defaultLogLevel, "log level on the GCB job") - cmd.Flags().BoolVarP(&opts.Tail, "tail", "t", false, "tail the build") - cmd.Flags().BoolVar(&opts.Nomock, "nomock", false, `run in nomock (="real") mode or not`) - - cmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error { - return log.SetupGlobalLogger(opts.Loglevel) - } - - cmd.PreRunE = func(cmd *cobra.Command, _ []string) error { - for _, f := range []string{"sender-name", "sender-email", "freeze-date", "cut-date"} { - if err := cmd.MarkFlagRequired(f); err != nil { - return err - } - } - - if opts.BuildConfigPath == "" { - p, err := kReleaseLocalPath() - if err != nil { - return err - } - opts.BuildConfigPath = filepath.Join(p, "..", "..", "gcb", "patch-announce", "cloudbuild.yaml") - logrus.Debugf("no config filed specified, defaulting to %q", opts.BuildConfigPath) - } - - return nil - } - - // TODO: Refactor to use pkg/gcp/build - cmd.RunE = func(cmd *cobra.Command, _ []string) error { - exeName := "gcloud" - exe, err := exec.LookPath(exeName) - if err != nil { - return err - } - - args := []string{ - exeName, "builds", "submit", - "--no-source", - "--project=" + opts.ProjectID, - "--config=" + opts.BuildConfigPath, - } - - if !opts.Tail { - args = append(args, "--async") - } - - subst := substitutions{ - "_K8S_GIT_URL": opts.K8sRepoURL, - "_K8S_GIT_BRANCH": opts.K8sBranch, - "_FREEZE_DATE": opts.FreezeDate, - "_CUT_DATE": opts.CutDate, - "_SENDER_NAME": opts.SenderName, - "_SENDER_EMAIL": opts.SenderEmail, - "_RELEASE_GIT_URL": opts.ReleaseRepoURL, - "_RELEASE_GIT_BRANCH": opts.ReleaseBranch, - "_LOG_LEVEL": opts.Loglevel, - "_NOMOCK": fmt.Sprintf("%t", opts.Nomock), - } - logrus.Debugf("about to run %q with substitutions [%s]", args, subst.human()) - - args = append(args, "--substitutions="+subst.string()) - - logrus.Infof("execing %q", exeName) - return syscall.Exec(exe, args, os.Environ()) - } - - return cmd -} - -type substitutions map[string]string - -func (s substitutions) join(sep string) string { - a := []string{} - - for k, v := range s { - a = append(a, k+"="+v) - } - - return strings.Join(a, sep) -} - -func (s substitutions) string() string { - // https://cloud.google.com/sdk/gcloud/reference/topic/escaping - return "^" + sep + "^" + s.join(sep) -} - -func (s substitutions) human() string { - return s.join(", ") -} - -func kReleaseLocalPath() (string, error) { - if _, filename, _, ok := runtime.Caller(0); ok { - return filepath.Dir(filename), nil - } - return "", fmt.Errorf("could not find the local path to k/release") -} diff --git a/docs/krel/README.md b/docs/krel/README.md index 2800032df36..01050743bbe 100644 --- a/docs/krel/README.md +++ b/docs/krel/README.md @@ -33,7 +33,6 @@ krel has several subcommands that perform various tasks during the release lifec | [changelog](changelog.md) | Automate the lifecycle of CHANGELOG-x.y.{md,html} files in a k/k repository | | [ff](ff.md) | Fast forward a Kubernetes release branch | | [gcbmgr](gcbmgr.md) | Submit Kubernetes staging and release jobs to Google Cloud Build | -| [patch-announce](patch-announce.md) | Send out patch release announcement mails | | [push](push.md) | Push Kubernetes release artifacts to Google Cloud Storage (GCS) | | [release-notes](release-notes.md) | The subcommand of choice for the Release Notes subteam of SIG Release | diff --git a/docs/krel/patch-announce.md b/docs/krel/patch-announce.md deleted file mode 100644 index e593761ba90..00000000000 --- a/docs/krel/patch-announce.md +++ /dev/null @@ -1,43 +0,0 @@ -# krel patch-anounce - -Send out patch release announcement emails - -- [Summary](#summary) -- [Installation](#installation) -- [Usage](#usage) -- [Important notes](#important-notes) - -## Summary - -The `krel patch-announce` subcommand sends out email messages to notify developers about a release. To send the email messages, it needs a Sendgrid API Key and an GitHub token - -## Installation - -Tu run the `patch-announce` subcommand, [install krel](README.md#installation). You will need a Sendgrid token to be able to send messages and a GitHub token to generate the release notes. - -## Usage - -``` - krel patch-announce [flags] -``` - -### Command line flags - -``` - -c, --cut-date string date when the patch release is planned to be cut - -f, --freeze-date string date when no CPs are allowed anymore - -g, --github-token string a GitHub token, used r/o for generating the release notes (default $GITHUB_TOKEN) - -h, --help help for patch-announce - -r, --release-repo string local path of the k/release checkout (default "./release") - -e, --sender-email string email sender's address - -n, --sender-name string email sender's name - -s, --sendgrid-api-key string API key for sendgrid -``` - -### Notification recipients - -Currently, `patch-announce` will notify the following addresses: -| Recipient | E-Mail Address | -| --------- | -------------- | -| Kubernetes developer/contributor discussion | kubernetes-dev@googlegroups.com | -| kubernetes-dev-announce | kubernetes-dev-announce@googlegroups.com | diff --git a/gcb/patch-announce/cloudbuild.yaml b/gcb/patch-announce/cloudbuild.yaml deleted file mode 100644 index cca8df29d26..00000000000 --- a/gcb/patch-announce/cloudbuild.yaml +++ /dev/null @@ -1,108 +0,0 @@ -timeout: 1200s - -#### SECURITY NOTICE #### -# Google Cloud Build (GCB) supports the usage of secrets for build requests. -# Secrets appear within GCB configs as base64-encoded strings. -# These secrets are GCP Cloud KMS-encrypted and cannot be decrypted by any human or system -# outside of GCP Cloud KMS for the GCP project this encrypted resource was created for. -# Seeing the base64-encoded encrypted blob here is not a security event for the project. -# -# More details on using encrypted resources on Google Cloud Build can be found here: -# https://cloud.google.com/cloud-build/docs/securing-builds/use-encrypted-secrets-credentials -# -# (Please do not remove this security notice.) -secrets: -- kmsKeyName: projects/k8s-releng-prod/locations/global/keyRings/release/cryptoKeys/encrypt-0 - secretEnv: - GITHUB_TOKEN: CiQAIkWjMKxKm2TA5DQNxwDfoAvnT/MQvfwlaxFUiFfyCmplqHESUQBLz1D+nejo8OWfiQF2DW+1QJXcb/XCWb9uPtBvcBdR9a9MwadgS2P85IseuBmqYVgSDvgdEVP3Zj9MXaHj60towEGlaRonA2uNYAgxRWhD6Q== -# TODO: move to the k8s-releng-prod -- kmsKeyName: projects/cf-london-servces-k8s/locations/global/keyRings/hhorl-k8s-release/cryptoKeys/sendgrid - secretEnv: - SENDGRID_API_KEY: CiQAkn5y0WUR0kZIqj1v4UW2McFdlceel2zptSa468+Ir/gDeh0SbwDMTYRJdFtqt2x2hGPN7oOoMs2lCLFoY+oh4Mb1b/nQehooMYQuNwupxOpnwE+d/GbEFhwtMg9wbA5zhOMYPe0OLsSAXvt4w/IC1Z701Ev3CMdT6ZjicillZoBlFYhVlFPQLWcm8jtobdQcDj91eg== - -steps: -- id: clone-k8s - waitFor: [ '-' ] - name: gcr.io/cloud-builders/git - dir: "go/src/k8s.io" - args: - - "clone" - - "${_K8S_GIT_URL}" - - "--branch=${_K8S_GIT_BRANCH}" -- id: clone-release - waitFor: [ '-' ] - name: gcr.io/cloud-builders/git - dir: "go/src/k8s.io" - args: - - "clone" - - "${_RELEASE_GIT_URL}" - - "--branch=${_RELEASE_GIT_BRANCH}" - -- id: prepare-and-send - name: "gcr.io/k8s-staging-releng/k8s-cloud-builder:v1.13.9-2" - env: - - "SENDER_NAME=${_SENDER_NAME}" - - "SENDER_EMAIL=${_SENDER_EMAIL}" - - "FREEZE_DATE=${_FREEZE_DATE}" - - "CUT_DATE=${_CUT_DATE}" - - "NOMOCK=${_NOMOCK}" - - "LOG_LEVEL=${_LOG_LEVEL}" - secretEnv: - - GITHUB_TOKEN - - SENDGRID_API_KEY - dir: "go/src/k8s.io/release" - entrypoint: bash - args: - - -c - - | - set -e - set -u - set -o pipefail - - export GOPATH="/workspace/go" - export GOBIN="$${GOPATH}/bin" - export PATH="$${PATH}:$${GOBIN}" - - # TODO: Until we've switched away from the shell release note tool, we - # still need this binary in the PATH - go install ./cmd/blocking-testgrid-tests - - # Notes: - # - GITHUB_TOKEN & SENDGRID_API_KEY need to be picked up by the - # application from the env, we don't want to log or pass those - # sensitive values as flags. - # - Once we've removed all external dependencies and the tool does not - # shell out any more, we can also compile, bake and release this tool - # as a container image and use that instead of `go run`ing it. - go run ./cmd/krel \ - patch-announce \ - --repo=../kubernetes \ - --release-repo=. \ - --sender-name="$${SENDER_NAME}" \ - --sender-email="$${SENDER_EMAIL}" \ - --cut-date="$${CUT_DATE}" \ - --freeze-date="$${FREEZE_DATE}" \ - --log-level="$${LOG_LEVEL}" \ - --nomock="$${NOMOCK}" - -substitutions: - # The branch of k/kubernetes to check out, the branch to announce a patch release for (e.g.: release-1.15) - _K8S_GIT_BRANCH: null - # Date of CP freeze, ISO 8601 (e.g.: 2019-12-06) - _FREEZE_DATE: null - # Date of planned cut, ISO 8601 (e.g.: 2019-12-11) - _CUT_DATE: null - # The mail sender's name. Will also be used as a receipient in mock mode. (e.g.: "Jane Doe") - _SENDER_NAME: null - # The mail sender's email. Will also be used as a receipient in mock mode. (e.g.: jane.doe@example.org") - _SENDER_EMAIL: null - # For the real run, set to 'nomock' (e.g.: 0,1,f,t,false,true) - _NOMOCK: '0' - # git-clone'able URL for k/kubernetes - _K8S_GIT_URL: https://github.com/kubernetes/kubernetes - # git-clone'able URL for k/release - _RELEASE_GIT_URL: https://github.com/kubernetes/release - # The branch of k/release to check out - _RELEASE_GIT_BRANCH: master - # The log level to be used with the patch-announce tool - _LOG_LEVEL: info