-
Notifications
You must be signed in to change notification settings - Fork 578
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Chuck Ha <[email protected]>
- Loading branch information
Showing
3 changed files
with
295 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") | ||
|
||
go_library( | ||
name = "go_default_library", | ||
srcs = ["main.go"], | ||
importpath = "sigs.k8s.io/cluster-api-provider-aws/cmd/release", | ||
visibility = ["//visibility:private"], | ||
) | ||
|
||
go_binary( | ||
name = "release", | ||
embed = [":go_default_library"], | ||
visibility = ["//visibility:public"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,266 @@ | ||
/* | ||
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 main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"path" | ||
) | ||
|
||
/* | ||
required parameters | ||
https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line | ||
github token for modifying release | ||
# dependencies | ||
* requires a build environment (make artifact-release must work) | ||
* github.com/itchio/gothub | ||
*/ | ||
|
||
const ( | ||
// TODO(chuckha): figure this out based on directory name | ||
repository = "cluster-api-provider-aws" | ||
) | ||
|
||
func main() { | ||
var remote, user, version string | ||
|
||
fs := flag.NewFlagSet("main", flag.ExitOnError) | ||
fs.Usage = documentation | ||
fs.StringVar(&remote, "remote", "origin", "name of the remote in local git") | ||
fs.StringVar(&user, "user", "kubernetes-sigs", "the github user/organization of the repo to release a version to") | ||
|
||
// TODO(chuckha): it would be ideal if we could release major/minor/patch and have it | ||
// automatically bump the latest tag git finds | ||
// until then, hard code it | ||
fs.StringVar(&version, "version", "", "the version number, for example v0.2.0") | ||
if err := fs.Parse(os.Args[1:]); err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
required("version", version) | ||
|
||
checkDependencies() | ||
|
||
cfg := config{ | ||
version: version, | ||
artifactDir: "out", | ||
artifacts: []string{ | ||
"cluster-api-provider-aws-examples.tar", | ||
"clusterawsadm-darwin-amd64", | ||
"clusterawsadm-linux-amd64", | ||
"clusterctl-darwin-amd64", | ||
"clusterctl-linux-amd64", | ||
}, | ||
} | ||
|
||
run := &runner{ | ||
releaser: gothubReleaser{ | ||
artifactsDir: cfg.artifactDir, | ||
user: user, | ||
repository: repository, | ||
}, | ||
tagger: git{ | ||
repository: repository, | ||
remote: remote, | ||
}, | ||
config: cfg, | ||
} | ||
|
||
if err := run.run(); err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
|
||
fmt.Println("The next steps are:") | ||
fmt.Println() | ||
// TODO(chuckha): automate writing the release notes | ||
fmt.Println("- Write the release notes. It is a manual process") | ||
// TODO(chuckha): something something docker container | ||
fmt.Println("- push the container images") | ||
// TODO(chuckha): send an email or at least print out the contents of an | ||
// email to | ||
fmt.Println("- Email [email protected] to announce that a release happened") | ||
} | ||
|
||
func required(arg, val string) { | ||
if val == "" { | ||
fmt.Printf("%v is a required parameter\n", arg) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func checkDependencies() { | ||
_, err := exec.LookPath("gothub") | ||
if err != nil { | ||
fmt.Println("Please install gothub:") | ||
fmt.Println() | ||
fmt.Println(" go get github.com/itchio/gothub") | ||
os.Exit(1) | ||
} | ||
|
||
if ght := os.Getenv("GITHUB_TOKEN"); len(ght) == 0 { | ||
fmt.Println("Please set the GITHUB_TOKEN environment variable.") | ||
fmt.Println("Read this guide for more information on creating Personal Access Tokens") | ||
fmt.Println() | ||
fmt.Println("https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line") | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func documentation() { | ||
fmt.Println(` | ||
This tool is designed to help automate the release process. | ||
Usage: | ||
release [-remote <remote>] [-user <user>] -version <version> | ||
Options: | ||
-remote | ||
The local name of the remote repository. | ||
The default is origin. | ||
-user | ||
The github username or organization of the repository to publish a release to. | ||
The default is kubernetes-sigs. | ||
-version | ||
The name of the version to release. | ||
Examples: | ||
1. | ||
origin is github.com/kubernetes-sigs/cluster-api-provider-aws | ||
local master points to origin/master branch | ||
To release: | ||
./release -remote origin -version v1.1.1 | ||
2. | ||
origin is github.com/myuser/cluster-api-provider-aws | ||
upstream is github.com/kubernetes-sigs/cluster-api-provider-aws | ||
local master points to upstream/master branch | ||
To release: | ||
./release -remote upstream -version v1.1.1 | ||
3. | ||
To test release | ||
./release -remote YOUR_FORK -user YOUR_GITHUB_USER_NAME -version v1.1.1`) | ||
} | ||
|
||
type config struct { | ||
version string | ||
artifacts []string | ||
artifactDir string | ||
} | ||
|
||
type runner struct { | ||
releaser releaser | ||
tagger tagger | ||
config config | ||
} | ||
|
||
func (r runner) run() error { | ||
if err := r.tagger.tag(r.config.version); err != nil { | ||
return err | ||
} | ||
if err := r.tagger.pushTag(r.config.version); err != nil { | ||
return err | ||
} | ||
if err := r.releaser.draft(r.config.version); err != nil { | ||
return err | ||
} | ||
for _, artifact := range r.config.artifacts { | ||
if err := r.releaser.upload(r.config.version, artifact); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
type releaser interface { | ||
draft(string) error | ||
upload(string, string) error | ||
} | ||
|
||
type gothubReleaser struct { | ||
// github user or organization (kubernetes-sigs, heptiolabs, chuckha, etc) | ||
user string | ||
// repository is the name of the repository | ||
repository string | ||
|
||
artifactsDir string | ||
} | ||
|
||
func (g gothubReleaser) draft(version string) error { | ||
cmd := exec.Command("gothub", "release", "--tag", version, "--user", g.user, "--repo", g.repository, "--draft") | ||
out, err := cmd.CombinedOutput() | ||
if err != nil { | ||
fmt.Println(string(out)) | ||
} | ||
return err | ||
} | ||
func (g gothubReleaser) upload(version, file string) error { | ||
cmd := exec.Command("gothub", "upload", "--tag", version, "--user", g.user, "--repo", g.repository, "--file", path.Join(g.artifactsDir, file), "--name", file) | ||
out, err := cmd.CombinedOutput() | ||
if err != nil { | ||
fmt.Println(string(out)) | ||
} | ||
return err | ||
} | ||
|
||
type tagger interface { | ||
tag(string) error | ||
pushTag(string) error | ||
} | ||
|
||
type git struct { | ||
// repository is the name of the repository | ||
repository string | ||
|
||
// remote is the local name of the remote | ||
remote string | ||
} | ||
|
||
func (g git) tag(version string) error { | ||
cmd := exec.Command("git", "tag", "-s", "-m", fmt.Sprintf("A release of %q for version %q", g.repository, version), version) | ||
out, err := cmd.CombinedOutput() | ||
if err != nil { | ||
fmt.Println(string(out)) | ||
} | ||
return err | ||
} | ||
|
||
func (g git) pushTag(version string) error { | ||
// TODO(chuckha): this shouldn't exit if it fails because the tag already | ||
cmd := exec.Command("git", "push", g.remote, version) | ||
out, err := cmd.CombinedOutput() | ||
if err != nil { | ||
fmt.Println(string(out)) | ||
} | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,24 @@ | ||
# Release process | ||
|
||
## Semi-automatic | ||
|
||
1. Run the release tool found in `cmd/release` | ||
2. Pick up the manual steps starting with step 6 | ||
|
||
## Manual | ||
|
||
1. Create a draft release in github | ||
3. Tag the repository and push the tag `git tag -s $VERSION ` | ||
4. Run `make release-artifacts` | ||
5. Attach the tarball to the drafted release | ||
6. Attach `clusterawsadm` and `clusterctl` to the drafted release (for darwin | ||
2. Tag the repository and push the tag `git tag -s $VERSION ` | ||
3. Run `make release-artifacts` | ||
4. Attach the tarball to the drafted release | ||
5. Attach `clusterawsadm` and `clusterctl` to the drafted release (for darwin | ||
and linux architectures) | ||
7. Write the release notes (see note below on release notes) | ||
8. Get someone with permission to copy the container image from your own | ||
6. Write the release notes (see note below on release notes) | ||
7. Get someone with permission to copy the container image from your own | ||
personal gcr registry to the production one, or have them build and push the | ||
container image themselves. | ||
9. Publish release | ||
10. Email `[email protected]` to announce the release | ||
8. Publish release | ||
9. Email `[email protected]` to announce the release | ||
|
||
## Expected artifacts | ||
|
||
|