This commit is contained in:
Antonio Murdaca 2017-10-30 08:14:03 +00:00 committed by GitHub
commit 0c4591ed55
7 changed files with 403 additions and 3 deletions

1
.gitignore vendored
View file

@ -5,6 +5,7 @@
/docs/*.[158] /docs/*.[158]
/docs/*.[158].gz /docs/*.[158].gz
/kpod /kpod
/crio-release
/crioctl /crioctl
/crio /crio
/crio.conf /crio.conf

View file

@ -45,7 +45,7 @@ help:
@echo "Usage: make <target>" @echo "Usage: make <target>"
@echo @echo
@echo " * 'install' - Install binaries to system locations" @echo " * 'install' - Install binaries to system locations"
@echo " * 'binaries' - Build crio, conmon and crioctl" @echo " * 'binaries' - Build crio, conmon, crio-release and crioctl"
@echo " * 'integration' - Execute integration tests" @echo " * 'integration' - Execute integration tests"
@echo " * 'clean' - Clean artifacts" @echo " * 'clean' - Clean artifacts"
@echo " * 'lint' - Execute the source code linter" @echo " * 'lint' - Execute the source code linter"
@ -86,6 +86,9 @@ crio: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crio $(PROJECT))
crioctl: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crioctl $(PROJECT)) crioctl: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crioctl $(PROJECT))
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/cmd/crioctl $(GO) build $(LDFLAGS) -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/cmd/crioctl
crio-release: .gopathok
$(GO) build -o $@ $(PROJECT)/cmd/crio-release
kpod: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/kpod $(PROJECT)) kpod: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/kpod $(PROJECT))
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/cmd/kpod $(GO) build $(LDFLAGS) -tags "$(BUILDTAGS)" -o $@ $(PROJECT)/cmd/kpod
@ -101,7 +104,7 @@ endif
rm -fr test/testdata/redis-image rm -fr test/testdata/redis-image
find . -name \*~ -delete find . -name \*~ -delete
find . -name \#\* -delete find . -name \#\* -delete
rm -f crioctl crio kpod rm -f crioctl crio kpod crio-release
make -C conmon clean make -C conmon clean
make -C pause clean make -C pause clean
rm -f test/bin2img/bin2img rm -f test/bin2img/bin2img
@ -123,7 +126,7 @@ testunit:
localintegration: clean binaries localintegration: clean binaries
./test/test_runner.sh ${TESTFLAGS} ./test/test_runner.sh ${TESTFLAGS}
binaries: crio crioctl kpod conmon pause test/bin2img/bin2img test/copyimg/copyimg test/checkseccomp/checkseccomp binaries: crio crio-release crioctl kpod conmon pause test/bin2img/bin2img test/copyimg/copyimg test/checkseccomp/checkseccomp
MANPAGES_MD := $(wildcard docs/*.md) MANPAGES_MD := $(wildcard docs/*.md)
MANPAGES := $(MANPAGES_MD:%.md=%) MANPAGES := $(MANPAGES_MD:%.md=%)

43
cmd/crio-release/build.go Normal file
View file

@ -0,0 +1,43 @@
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"os"
"os/exec"
"runtime"
)
func build() error {
out, err := exec.Command("make").CombinedOutput()
if err != nil {
return fmt.Errorf("%s: %s", err, out)
}
return nil
}
const tarFormat = "cri-o-%s.%s-%s.tar.gz"
func tarRelease(tag string) (string, error) {
path := fmt.Sprintf(tarFormat, tag, runtime.GOOS, runtime.GOARCH)
out, err := exec.Command("tar", "-zcf", path, "bin/").CombinedOutput()
if err != nil {
return "", fmt.Errorf("%s: %s", err, out)
}
return path, nil
}
func hash(path string) (string, error) {
f, err := os.Open(path)
if err != nil {
return "", err
}
defer f.Close()
s := sha256.New()
if _, err := io.Copy(s, f); err != nil {
return "", err
}
return hex.EncodeToString(s.Sum(nil)), nil
}

115
cmd/crio-release/main.go Normal file
View file

@ -0,0 +1,115 @@
package main
import (
"fmt"
"os"
"text/template"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
const vendorConf = "vendor.conf"
type note struct {
Title string `toml:"title"`
Description string `toml:"description"`
}
type change struct {
Commit string `toml:"commit"`
Description string `toml:"description"`
}
type dependency struct {
Name string
Commit string
Previous string
}
type download struct {
Filename string
Hash string
}
type release struct {
Commit string `toml:"commit"`
Previous string `toml:"previous"`
PreRelease bool `toml:"pre_release"`
Preface string `toml:"preface"`
Notes map[string]note `toml:"notes"`
BreakingChanges map[string]change `toml:"breaking"`
// generated fields
Changes []change
Contributors []string
Dependencies []dependency
Version string
Downloads []download
}
func main() {
app := cli.NewApp()
app.Name = "crio-release"
app.Description = `release tooling for CRI-O.
This tool should be ran from the root of the CRI-O repository for a new release.
`
app.Flags = []cli.Flag{
cli.BoolFlag{
Name: "dry,n",
Usage: "run the release tooling as a dry run to print the release notes to stdout",
},
}
app.Action = func(context *cli.Context) error {
logrus.Info("Welcome to the CRI-O release tool...")
var (
path = context.Args().First()
tag = parseTag(path)
)
r, err := loadRelease(path)
if err != nil {
return err
}
previous, err := getPreviousDeps(r.Previous)
if err != nil {
return err
}
changes, err := changelog(r.Previous, r.Commit)
if err != nil {
return err
}
logrus.Infof("creating new release %s with %d new changes...", tag, len(changes))
rd, err := fileFromRev(r.Commit, vendorConf)
if err != nil {
return err
}
deps, err := parseDependencies(rd)
if err != nil {
return err
}
updatedDeps := updatedDeps(previous, deps)
contributors, err := getContributors(r.Previous, r.Commit)
if err != nil {
return err
}
// update the release fields with generated data
r.Contributors = contributors
r.Dependencies = updatedDeps
r.Changes = changes
r.Version = tag
if context.Bool("dry") {
t, err := template.New("release-notes").Parse(releaseNotes)
if err != nil {
return err
}
return t.Execute(os.Stdout, r)
}
logrus.Info("release complete!")
return nil
}
if err := app.Run(os.Args); err != nil {
fmt.Fprint(os.Stderr, err)
os.Exit(1)
}
}

View file

@ -0,0 +1,35 @@
package main
const releaseNotes = `Welcome to the release of CRI-O {{.Version}}!
{{if .PreRelease}}
*This is a pre-release of CRI-O*
{{- end}}
{{.Preface}}
Please try out the release binaries and report any issues at
https://github.com/kubernetes-incubator/cri-o/issues.
{{range $note := .Notes}}
### {{$note.Title}}
{{$note.Description}}
{{- end}}
### Contributors
{{range $contributor := .Contributors}}
* {{$contributor}}
{{- end}}
### Changes
{{range $change := .Changes}}
* {{$change.Commit}} {{$change.Description}}
{{- end}}
### Dependency Changes
Previous release can be found at [{{.Previous}}](https://github.com/kubernetes-incubator/cri-o/releases/tag/{{.Previous}})
{{range $dep := .Dependencies}}
* {{$dep.Previous}} -> {{$dep.Commit}} **{{$dep.Name}}**
{{- end}}
`

165
cmd/crio-release/util.go Normal file
View file

@ -0,0 +1,165 @@
package main
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
"github.com/BurntSushi/toml"
)
func loadRelease(path string) (*release, error) {
var r release
if _, err := toml.DecodeFile(path, &r); err != nil {
if os.IsNotExist(err) {
return nil, errors.New("please specify the release file as the first argument")
}
return nil, err
}
return &r, nil
}
func parseTag(path string) string {
return strings.TrimSuffix(filepath.Base(path), ".toml")
}
func parseDependencies(r io.Reader) ([]dependency, error) {
var deps []dependency
s := bufio.NewScanner(r)
for s.Scan() {
ln := strings.TrimSpace(s.Text())
if strings.HasPrefix(ln, "#") || ln == "" {
continue
}
cidx := strings.Index(ln, "#")
if cidx > 0 {
ln = ln[:cidx]
}
ln = strings.TrimSpace(ln)
parts := strings.Fields(ln)
if len(parts) != 2 && len(parts) != 3 {
return nil, fmt.Errorf("invalid config format: %s", ln)
}
deps = append(deps, dependency{
Name: parts[0],
Commit: parts[1],
})
}
if err := s.Err(); err != nil {
return nil, err
}
return deps, nil
}
func getPreviousDeps(previous string) ([]dependency, error) {
r, err := fileFromRev(previous, vendorConf)
if err != nil {
return nil, err
}
return parseDependencies(r)
}
func changelog(previous, commit string) ([]change, error) {
raw, err := getChangelog(previous, commit)
if err != nil {
return nil, err
}
return parseChangelog(raw)
}
func getChangelog(previous, commit string) ([]byte, error) {
return git("log", "--oneline", fmt.Sprintf("%s..%s", previous, commit))
}
func parseChangelog(changelog []byte) ([]change, error) {
var (
changes []change
s = bufio.NewScanner(bytes.NewReader(changelog))
)
for s.Scan() {
fields := strings.Fields(s.Text())
changes = append(changes, change{
Commit: fields[0],
Description: strings.Join(fields[1:], " "),
})
}
if err := s.Err(); err != nil {
return nil, err
}
return changes, nil
}
func fileFromRev(rev, file string) (io.Reader, error) {
p, err := git("show", fmt.Sprintf("%s:%s", rev, file))
if err != nil {
return nil, err
}
return bytes.NewReader(p), nil
}
func git(args ...string) ([]byte, error) {
o, err := exec.Command("git", args...).CombinedOutput()
if err != nil {
return nil, fmt.Errorf("%s: %s", err, o)
}
return o, nil
}
func updatedDeps(previous, deps []dependency) []dependency {
var updated []dependency
pm, cm := toDepMap(previous), toDepMap(deps)
for name, c := range cm {
d, ok := pm[name]
if !ok {
// it is a new dep and should be noted
updated = append(updated, c)
continue
}
// it exists, see if its updated
if d.Commit != c.Commit {
// set the previous commit
c.Previous = d.Commit
updated = append(updated, c)
}
}
return updated
}
func toDepMap(deps []dependency) map[string]dependency {
out := make(map[string]dependency)
for _, d := range deps {
out[d.Name] = d
}
return out
}
func getContributors(previous, commit string) ([]string, error) {
raw, err := git("log", "--format=%aN", fmt.Sprintf("%s..%s", previous, commit))
if err != nil {
return nil, err
}
var (
set = make(map[string]struct{})
s = bufio.NewScanner(bytes.NewReader(raw))
out []string
)
for s.Scan() {
set[s.Text()] = struct{}{}
}
if err := s.Err(); err != nil {
return nil, err
}
for name := range set {
out = append(out, name)
}
sort.Strings(out)
return out, nil
}

38
releases/v1.0.1.toml Normal file
View file

@ -0,0 +1,38 @@
# commit to be tagged for new release
commit = "HEAD"
# previous release
previous = "v1.0.0"
pre_release = false
preface = """\
This releases is the first patch release in the v1.0.0 release. It includes
bugfixes and performance fixes. No new features have been added."""
# notable prs to include in the release notes, 1234 is the pr number
#[notes]
#[notes.gc]
#title = "Garbage Collection"
#description = """\
#Full garbage collection support for cleaning up content, snapshots and metadata
#for containerd resources. The implementation is based on well-known concurrent
#mark and sweep and the approach allows for extensibility in collection
#policies.
#The GC is triggered `Container.Delete and Image.Delete. Note that images may
#need to be re-pulled for proper support."""
#[notes.migrations]
#title = "Migrations"
#description = """\
#A lightweight migration framework is now part of containerd. This allows us to
#safely evolve the schema between releases with the groundwork laid early.
#As part of this release, a migration will be run to add back references in
#support of garbage collection."""
#[breaking]
#[breaking.metrics]
#pr = 1235
#description = """ """